1 |
/************************************************************************************************* |
2 |
* The command line interface for the node API |
3 |
* Copyright (C) 2004-2005 Mikio Hirabayashi |
4 |
* This file is part of Hyper Estraier. |
5 |
* Hyper Estraier is free software; you can redistribute it and/or modify it under the terms of |
6 |
* the GNU Lesser General Public License as published by the Free Software Foundation; either |
7 |
* version 2.1 of the License or any later version. Hyper Estraier is distributed in the hope |
8 |
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
10 |
* License for more details. |
11 |
* You should have received a copy of the GNU Lesser General Public License along with Hyper |
12 |
* Estraier; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
13 |
* Boston, MA 02111-1307 USA. |
14 |
*************************************************************************************************/ |
15 |
|
16 |
|
17 |
#include "estraier.h" |
18 |
#include "estmtdb.h" |
19 |
#include "estnode.h" |
20 |
#include "myconf.h" |
21 |
|
22 |
#define AGENTNAME "EstCall" /* name of the agent */ |
23 |
#define NUMBUFSIZ 32 /* size of a buffer for a number */ |
24 |
#define IOBUFSIZ 8192 /* size of a buffer for I/O */ |
25 |
#define MINIBNUM 31 /* bucket number of a small map */ |
26 |
#define SEARCHMAX 10 /* maximum number of shown documents */ |
27 |
|
28 |
enum { /* enumeration for viewing modes */ |
29 |
VM_PROT, /* protocol simulation */ |
30 |
VM_XML /* XML */ |
31 |
}; |
32 |
|
33 |
/* global variables */ |
34 |
const char *g_progname = NULL; /* program name */ |
35 |
const char *g_pxhost = NULL; /* host name of the proxy */ |
36 |
int g_pxport = 0; /* host name of the proxy */ |
37 |
int g_timeout = -1; /* timeout in seconds */ |
38 |
const char *g_authname = NULL; /* name of authority */ |
39 |
const char *g_authpass = NULL; /* password of authority */ |
40 |
int g_viewmode = VM_PROT; /* viewing mode */ |
41 |
int g_nonparse = FALSE; /* whether to output response headers */ |
42 |
CBLIST *g_exheaders = NULL; /* extension headers */ |
43 |
|
44 |
|
45 |
/* function prototypes */ |
46 |
int main(int argc, char **argv); |
47 |
static void usage(void); |
48 |
static void printferror(const char *format, ...); |
49 |
static void setproxy(const char *pxstr); |
50 |
static int runput(int argc, char **argv); |
51 |
static int runout(int argc, char **argv); |
52 |
static int runget(int argc, char **argv); |
53 |
static int runuriid(int argc, char **argv); |
54 |
static int runinform(int argc, char **argv); |
55 |
static int runsearch(int argc, char **argv); |
56 |
static int runsetuser(int argc, char **argv); |
57 |
static int runsetlink(int argc, char **argv); |
58 |
static int runraw(int argc, char **argv); |
59 |
static void xmlprintf(const char *format, ...); |
60 |
static int procput(const char *nurl, const char *file); |
61 |
static int procout(const char *nurl, int id, const char *uri); |
62 |
static int procget(const char *nurl, int id, const char *uri, const char *attr); |
63 |
static int procuriid(const char *nurl, const char *uri); |
64 |
static int procinform(const char *nurl); |
65 |
static int procsearch(const char *nurl, const char *phrase, |
66 |
const CBLIST *attrs, const char *ord, int max, int depth); |
67 |
static int procsetuser(const char *nurl, const char *name, int mode); |
68 |
static int procsetlink(const char *nurl, const char *url, const char *label, int credit); |
69 |
static int procraw(const char *url, const char *file); |
70 |
|
71 |
|
72 |
/* main routine */ |
73 |
int main(int argc, char **argv){ |
74 |
int rv; |
75 |
cbstdiobin(); |
76 |
g_progname = argv[0]; |
77 |
if(!est_init_net_env()){ |
78 |
printferror("could not initialize network environment"); |
79 |
exit(1); |
80 |
} |
81 |
if(argc < 2) usage(); |
82 |
rv = 0; |
83 |
if(!strcmp(argv[1], "put")){ |
84 |
rv = runput(argc, argv); |
85 |
} else if(!strcmp(argv[1], "out")){ |
86 |
rv = runout(argc, argv); |
87 |
} else if(!strcmp(argv[1], "get")){ |
88 |
rv = runget(argc, argv); |
89 |
} else if(!strcmp(argv[1], "uriid")){ |
90 |
rv = runuriid(argc, argv); |
91 |
} else if(!strcmp(argv[1], "inform")){ |
92 |
rv = runinform(argc, argv); |
93 |
} else if(!strcmp(argv[1], "search")){ |
94 |
rv = runsearch(argc, argv); |
95 |
} else if(!strcmp(argv[1], "setuser")){ |
96 |
rv = runsetuser(argc, argv); |
97 |
} else if(!strcmp(argv[1], "setlink")){ |
98 |
rv = runsetlink(argc, argv); |
99 |
} else if(!strcmp(argv[1], "raw")){ |
100 |
rv = runraw(argc, argv); |
101 |
} else { |
102 |
usage(); |
103 |
} |
104 |
return rv; |
105 |
} |
106 |
|
107 |
|
108 |
/* print the usage and exit */ |
109 |
static void usage(void){ |
110 |
fprintf(stderr, "%s: command line utility for the node API of Hyper Estraier\n", g_progname); |
111 |
fprintf(stderr, "\n"); |
112 |
fprintf(stderr, "usage:\n"); |
113 |
fprintf(stderr, " %s put [-proxy host:port] [-tout num] [-auth user pass]" |
114 |
" nurl [file]\n", g_progname); |
115 |
fprintf(stderr, " %s out [-proxy host:port] [-tout num] [-auth user pass]" |
116 |
" nurl expr\n", g_progname); |
117 |
fprintf(stderr, " %s get [-proxy host:port] [-tout num] [-auth user pass]" |
118 |
" nurl expr [attr]\n", g_progname); |
119 |
fprintf(stderr, " %s uriid [-proxy host:port] [-tout num] [-auth user pass]" |
120 |
" nurl uri\n",g_progname); |
121 |
fprintf(stderr, " %s inform [-proxy host:port] [-tout num] [-auth user pass]" |
122 |
" nurl\n", g_progname); |
123 |
fprintf(stderr, " %s search [-proxy host:port] [-tout num] [-auth user pass]" |
124 |
" [-attr expr] [-ord expr] [-max num] [-dpt num] nurl [phrase]\n", g_progname); |
125 |
fprintf(stderr, " %s setuser [-proxy host:port] [-tout num] [-auth user pass]" |
126 |
" nurl name mode\n", g_progname); |
127 |
fprintf(stderr, " %s setlink [-proxy host:port] [-tout num] [-auth user pass]" |
128 |
" nurl url label credit\n", g_progname); |
129 |
fprintf(stderr, " %s raw [-proxy host:port] [-tout num] [-auth user pass] [-np] [-eh expr]" |
130 |
" url [file]\n", g_progname); |
131 |
fprintf(stderr, "\n"); |
132 |
exit(1); |
133 |
} |
134 |
|
135 |
|
136 |
/* print formatted error string and flush the buffer */ |
137 |
static void printferror(const char *format, ...){ |
138 |
va_list ap; |
139 |
va_start(ap, format); |
140 |
fprintf(stderr, "%s: ERROR: ", g_progname); |
141 |
vfprintf(stderr, format, ap); |
142 |
fputc('\n', stderr); |
143 |
fflush(stderr); |
144 |
va_end(ap); |
145 |
} |
146 |
|
147 |
|
148 |
/* set proxy information */ |
149 |
static void setproxy(const char *pxstr){ |
150 |
char *rp, *tmp; |
151 |
if((rp = strchr(pxstr, ':')) != NULL){ |
152 |
tmp = cbmemdup(pxstr, rp - pxstr); |
153 |
if((g_pxport = atoi(rp + 1)) < 1) g_pxport = 80; |
154 |
} else { |
155 |
tmp = cbmemdup(pxstr, -1); |
156 |
g_pxport = 80; |
157 |
} |
158 |
cbglobalgc(tmp, free); |
159 |
g_pxhost = tmp; |
160 |
} |
161 |
|
162 |
|
163 |
/* parse arguments of the put command */ |
164 |
static int runput(int argc, char **argv){ |
165 |
char *nurl, *file; |
166 |
int i, rv; |
167 |
nurl = NULL; |
168 |
file = NULL; |
169 |
for(i = 2; i < argc; i++){ |
170 |
if(!nurl && argv[i][0] == '-'){ |
171 |
if(!strcmp(argv[i], "-proxy")){ |
172 |
if(++i >= argc) usage(); |
173 |
setproxy(argv[i]); |
174 |
} else if(!strcmp(argv[i], "-tout")){ |
175 |
if(++i >= argc) usage(); |
176 |
g_timeout = atoi(argv[i]); |
177 |
} else if(!strcmp(argv[i], "-auth")){ |
178 |
if(++i >= argc) usage(); |
179 |
g_authname = argv[i]; |
180 |
if(++i >= argc) usage(); |
181 |
g_authpass = argv[i]; |
182 |
} else { |
183 |
usage(); |
184 |
} |
185 |
} else if(!nurl){ |
186 |
nurl = argv[i]; |
187 |
} else if(!file){ |
188 |
file = argv[i]; |
189 |
} else { |
190 |
usage(); |
191 |
} |
192 |
} |
193 |
if(!nurl) usage(); |
194 |
rv = procput(nurl, file); |
195 |
return rv; |
196 |
} |
197 |
|
198 |
|
199 |
/* parse arguments of the out command */ |
200 |
static int runout(int argc, char **argv){ |
201 |
char *nurl, *expr; |
202 |
int i, id, rv; |
203 |
nurl = NULL; |
204 |
expr = NULL; |
205 |
id = 0; |
206 |
for(i = 2; i < argc; i++){ |
207 |
if(!nurl && argv[i][0] == '-'){ |
208 |
if(!strcmp(argv[i], "-proxy")){ |
209 |
if(++i >= argc) usage(); |
210 |
setproxy(argv[i]); |
211 |
} else if(!strcmp(argv[i], "-tout")){ |
212 |
if(++i >= argc) usage(); |
213 |
g_timeout = atoi(argv[i]); |
214 |
} else if(!strcmp(argv[i], "-auth")){ |
215 |
if(++i >= argc) usage(); |
216 |
g_authname = argv[i]; |
217 |
if(++i >= argc) usage(); |
218 |
g_authpass = argv[i]; |
219 |
} else { |
220 |
usage(); |
221 |
} |
222 |
} else if(!nurl){ |
223 |
nurl = argv[i]; |
224 |
} else if(!expr){ |
225 |
expr = argv[i]; |
226 |
} else { |
227 |
usage(); |
228 |
} |
229 |
} |
230 |
if(!nurl || !expr) usage(); |
231 |
if((id = atoi(expr)) > 0) expr = NULL; |
232 |
rv = procout(nurl, id, expr); |
233 |
return rv; |
234 |
} |
235 |
|
236 |
|
237 |
/* parse arguments of the get command */ |
238 |
static int runget(int argc, char **argv){ |
239 |
char *nurl, *expr, *attr; |
240 |
int i, id, rv; |
241 |
nurl = NULL; |
242 |
expr = NULL; |
243 |
attr = NULL; |
244 |
for(i = 2; i < argc; i++){ |
245 |
if(!nurl && argv[i][0] == '-'){ |
246 |
if(!strcmp(argv[i], "-proxy")){ |
247 |
if(++i >= argc) usage(); |
248 |
setproxy(argv[i]); |
249 |
} else if(!strcmp(argv[i], "-tout")){ |
250 |
if(++i >= argc) usage(); |
251 |
g_timeout = atoi(argv[i]); |
252 |
} else if(!strcmp(argv[i], "-auth")){ |
253 |
if(++i >= argc) usage(); |
254 |
g_authname = argv[i]; |
255 |
if(++i >= argc) usage(); |
256 |
g_authpass = argv[i]; |
257 |
} else { |
258 |
usage(); |
259 |
} |
260 |
} else if(!nurl){ |
261 |
nurl = argv[i]; |
262 |
} else if(!expr){ |
263 |
expr = argv[i]; |
264 |
} else if(!attr){ |
265 |
attr = argv[i]; |
266 |
} else { |
267 |
usage(); |
268 |
} |
269 |
} |
270 |
if(!nurl || !expr) usage(); |
271 |
if((id = atoi(expr)) > 0) expr = NULL; |
272 |
rv = procget(nurl, id, expr, attr); |
273 |
return rv; |
274 |
} |
275 |
|
276 |
|
277 |
/* parse arguments of the uriid command */ |
278 |
static int runuriid(int argc, char **argv){ |
279 |
char *nurl, *uri; |
280 |
int i, rv; |
281 |
nurl = NULL; |
282 |
uri = NULL; |
283 |
for(i = 2; i < argc; i++){ |
284 |
if(!nurl && argv[i][0] == '-'){ |
285 |
if(!strcmp(argv[i], "-proxy")){ |
286 |
if(++i >= argc) usage(); |
287 |
setproxy(argv[i]); |
288 |
} else if(!strcmp(argv[i], "-tout")){ |
289 |
if(++i >= argc) usage(); |
290 |
g_timeout = atoi(argv[i]); |
291 |
} else if(!strcmp(argv[i], "-auth")){ |
292 |
if(++i >= argc) usage(); |
293 |
g_authname = argv[i]; |
294 |
if(++i >= argc) usage(); |
295 |
g_authpass = argv[i]; |
296 |
} else { |
297 |
usage(); |
298 |
} |
299 |
} else if(!nurl){ |
300 |
nurl = argv[i]; |
301 |
} else if(!uri){ |
302 |
uri = argv[i]; |
303 |
} else { |
304 |
usage(); |
305 |
} |
306 |
} |
307 |
if(!nurl || !uri) usage(); |
308 |
rv = procuriid(nurl, uri); |
309 |
return rv; |
310 |
} |
311 |
|
312 |
|
313 |
/* parse arguments of the inform command */ |
314 |
static int runinform(int argc, char **argv){ |
315 |
char *nurl; |
316 |
int i, rv; |
317 |
nurl = NULL; |
318 |
for(i = 2; i < argc; i++){ |
319 |
if(!nurl && argv[i][0] == '-'){ |
320 |
if(!strcmp(argv[i], "-proxy")){ |
321 |
if(++i >= argc) usage(); |
322 |
setproxy(argv[i]); |
323 |
} else if(!strcmp(argv[i], "-tout")){ |
324 |
if(++i >= argc) usage(); |
325 |
g_timeout = atoi(argv[i]); |
326 |
} else if(!strcmp(argv[i], "-auth")){ |
327 |
if(++i >= argc) usage(); |
328 |
g_authname = argv[i]; |
329 |
if(++i >= argc) usage(); |
330 |
g_authpass = argv[i]; |
331 |
} else { |
332 |
usage(); |
333 |
} |
334 |
} else if(!nurl){ |
335 |
nurl = argv[i]; |
336 |
} else { |
337 |
usage(); |
338 |
} |
339 |
} |
340 |
if(!nurl) usage(); |
341 |
rv = procinform(nurl); |
342 |
return rv; |
343 |
} |
344 |
|
345 |
|
346 |
/* parse arguments of the search command */ |
347 |
static int runsearch(int argc, char **argv){ |
348 |
CBDATUM *pbuf; |
349 |
CBLIST *attrs; |
350 |
char *nurl, *ord; |
351 |
int i, max, depth, rv; |
352 |
nurl = NULL; |
353 |
ord = NULL; |
354 |
max = SEARCHMAX; |
355 |
depth = 0; |
356 |
pbuf = cbdatumopen("", 0); |
357 |
cbglobalgc(pbuf, (void (*)(void *))cbdatumclose); |
358 |
attrs = cblistopen(); |
359 |
cbglobalgc(attrs, (void (*)(void *))cblistclose); |
360 |
for(i = 2; i < argc; i++){ |
361 |
if(!nurl && argv[i][0] == '-'){ |
362 |
if(!strcmp(argv[i], "-proxy")){ |
363 |
if(++i >= argc) usage(); |
364 |
setproxy(argv[i]); |
365 |
} else if(!strcmp(argv[i], "-tout")){ |
366 |
if(++i >= argc) usage(); |
367 |
g_timeout = atoi(argv[i]); |
368 |
} else if(!strcmp(argv[i], "-auth")){ |
369 |
if(++i >= argc) usage(); |
370 |
g_authname = argv[i]; |
371 |
if(++i >= argc) usage(); |
372 |
g_authpass = argv[i]; |
373 |
} else if(!strcmp(argv[i], "-vx")){ |
374 |
g_viewmode = VM_XML; |
375 |
} else if(!strcmp(argv[i], "-attr")){ |
376 |
if(++i >= argc) usage(); |
377 |
cblistpush(attrs, argv[i], -1); |
378 |
} else if(!strcmp(argv[i], "-ord")){ |
379 |
if(++i >= argc) usage(); |
380 |
ord = argv[i]; |
381 |
} else if(!strcmp(argv[i], "-max")){ |
382 |
if(++i >= argc) usage(); |
383 |
max = atoi(argv[i]); |
384 |
} else if(!strcmp(argv[i], "-dpt")){ |
385 |
if(++i >= argc) usage(); |
386 |
depth = atoi(argv[i]); |
387 |
} else { |
388 |
usage(); |
389 |
} |
390 |
} else if(!nurl){ |
391 |
nurl = argv[i]; |
392 |
} else { |
393 |
if(cbdatumsize(pbuf) > 0) cbdatumcat(pbuf, " ", 1); |
394 |
cbdatumcat(pbuf, argv[i], -1); |
395 |
} |
396 |
} |
397 |
if(!nurl || depth < 0) usage(); |
398 |
rv = procsearch(nurl, cbdatumptr(pbuf), attrs, ord, max, depth); |
399 |
return rv; |
400 |
} |
401 |
|
402 |
|
403 |
/* parse arguments of the setuser command */ |
404 |
static int runsetuser(int argc, char **argv){ |
405 |
char *nurl, *name, *mstr; |
406 |
int i, mode, rv; |
407 |
nurl = NULL; |
408 |
name = NULL; |
409 |
mstr = NULL; |
410 |
mode = 0; |
411 |
for(i = 2; i < argc; i++){ |
412 |
if(!nurl && argv[i][0] == '-'){ |
413 |
if(!strcmp(argv[i], "-proxy")){ |
414 |
if(++i >= argc) usage(); |
415 |
setproxy(argv[i]); |
416 |
} else if(!strcmp(argv[i], "-tout")){ |
417 |
if(++i >= argc) usage(); |
418 |
g_timeout = atoi(argv[i]); |
419 |
} else if(!strcmp(argv[i], "-auth")){ |
420 |
if(++i >= argc) usage(); |
421 |
g_authname = argv[i]; |
422 |
if(++i >= argc) usage(); |
423 |
g_authpass = argv[i]; |
424 |
} else { |
425 |
usage(); |
426 |
} |
427 |
} else if(!nurl){ |
428 |
nurl = argv[i]; |
429 |
} else if(!name){ |
430 |
name = argv[i]; |
431 |
} else if(!mstr){ |
432 |
mstr = argv[i]; |
433 |
} else { |
434 |
usage(); |
435 |
} |
436 |
} |
437 |
if(!nurl || !name || !mstr || (mode = atoi(mstr)) < 0) usage(); |
438 |
rv = procsetuser(nurl, name, mode); |
439 |
return rv; |
440 |
} |
441 |
|
442 |
|
443 |
/* parse arguments of the setlink command */ |
444 |
static int runsetlink(int argc, char **argv){ |
445 |
char *nurl, *url, *label, *cstr; |
446 |
int i, credit, rv; |
447 |
nurl = NULL; |
448 |
url = NULL; |
449 |
label = NULL; |
450 |
cstr = NULL; |
451 |
for(i = 2; i < argc; i++){ |
452 |
if(!nurl && argv[i][0] == '-'){ |
453 |
if(!strcmp(argv[i], "-proxy")){ |
454 |
if(++i >= argc) usage(); |
455 |
setproxy(argv[i]); |
456 |
} else if(!strcmp(argv[i], "-tout")){ |
457 |
if(++i >= argc) usage(); |
458 |
g_timeout = atoi(argv[i]); |
459 |
} else if(!strcmp(argv[i], "-auth")){ |
460 |
if(++i >= argc) usage(); |
461 |
g_authname = argv[i]; |
462 |
if(++i >= argc) usage(); |
463 |
g_authpass = argv[i]; |
464 |
} else { |
465 |
usage(); |
466 |
} |
467 |
} else if(!nurl){ |
468 |
nurl = argv[i]; |
469 |
} else if(!url){ |
470 |
url = argv[i]; |
471 |
} else if(!label){ |
472 |
label = argv[i]; |
473 |
} else if(!cstr){ |
474 |
cstr = argv[i]; |
475 |
} else { |
476 |
usage(); |
477 |
} |
478 |
} |
479 |
if(!nurl || !url || !label || !cstr) usage(); |
480 |
credit = atoi(cstr); |
481 |
rv = procsetlink(nurl, url, label, credit); |
482 |
return rv; |
483 |
} |
484 |
|
485 |
|
486 |
/* parse arguments of the raw command */ |
487 |
static int runraw(int argc, char **argv){ |
488 |
char *url, *file; |
489 |
int i, rv; |
490 |
g_exheaders = cblistopen(); |
491 |
cbglobalgc(g_exheaders, (void (*)(void *))cblistclose); |
492 |
url = NULL; |
493 |
file = NULL; |
494 |
for(i = 2; i < argc; i++){ |
495 |
if(!url && argv[i][0] == '-'){ |
496 |
if(!strcmp(argv[i], "-proxy")){ |
497 |
if(++i >= argc) usage(); |
498 |
setproxy(argv[i]); |
499 |
} else if(!strcmp(argv[i], "-tout")){ |
500 |
if(++i >= argc) usage(); |
501 |
g_timeout = atoi(argv[i]); |
502 |
} else if(!strcmp(argv[i], "-auth")){ |
503 |
if(++i >= argc) usage(); |
504 |
g_authname = argv[i]; |
505 |
if(++i >= argc) usage(); |
506 |
g_authpass = argv[i]; |
507 |
} else if(!strcmp(argv[i], "-np")){ |
508 |
g_nonparse = TRUE; |
509 |
} else if(!strcmp(argv[i], "-eh")){ |
510 |
if(++i >= argc) usage(); |
511 |
cblistpush(g_exheaders, argv[i], -1); |
512 |
} else { |
513 |
usage(); |
514 |
} |
515 |
} else if(!url){ |
516 |
url = argv[i]; |
517 |
} else if(!file){ |
518 |
file = argv[i]; |
519 |
} else { |
520 |
usage(); |
521 |
} |
522 |
} |
523 |
if(!url) usage(); |
524 |
rv = procraw(url, file); |
525 |
return rv; |
526 |
} |
527 |
|
528 |
|
529 |
/* output escaped string */ |
530 |
static void xmlprintf(const char *format, ...){ |
531 |
va_list ap; |
532 |
char *tmp, cbuf[32]; |
533 |
unsigned char c; |
534 |
int cblen; |
535 |
va_start(ap, format); |
536 |
while(*format != '\0'){ |
537 |
if(*format == '%'){ |
538 |
cbuf[0] = '%'; |
539 |
cblen = 1; |
540 |
format++; |
541 |
while(strchr("0123456789 .+-", *format) && *format != '\0' && cblen < 31){ |
542 |
cbuf[cblen++] = *format; |
543 |
format++; |
544 |
} |
545 |
cbuf[cblen++] = *format; |
546 |
cbuf[cblen] = '\0'; |
547 |
switch(*format){ |
548 |
case 's': |
549 |
tmp = va_arg(ap, char *); |
550 |
if(!tmp) tmp = "(null)"; |
551 |
printf(cbuf, tmp); |
552 |
break; |
553 |
case 'd': |
554 |
printf(cbuf, va_arg(ap, int)); |
555 |
break; |
556 |
case 'o': case 'u': case 'x': case 'X': case 'c': |
557 |
printf(cbuf, va_arg(ap, unsigned int)); |
558 |
break; |
559 |
case 'e': case 'E': case 'f': case 'g': case 'G': |
560 |
printf(cbuf, va_arg(ap, double)); |
561 |
break; |
562 |
case '@': |
563 |
tmp = va_arg(ap, char *); |
564 |
if(!tmp) tmp = "(null)"; |
565 |
while(*tmp){ |
566 |
switch(*tmp){ |
567 |
case '&': printf("&"); break; |
568 |
case '<': printf("<"); break; |
569 |
case '>': printf(">"); break; |
570 |
case '"': printf("""); break; |
571 |
default: |
572 |
if(!((*tmp >= 0 && *tmp <= 0x8) || (*tmp >= 0x0e && *tmp <= 0x1f))) putchar(*tmp); |
573 |
break; |
574 |
} |
575 |
tmp++; |
576 |
} |
577 |
break; |
578 |
case '?': |
579 |
tmp = va_arg(ap, char *); |
580 |
if(!tmp) tmp = "(null)"; |
581 |
while(*tmp){ |
582 |
c = *(unsigned char *)tmp; |
583 |
if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || |
584 |
(c >= '0' && c <= '9') || (c != '\0' && strchr("_-.", c))){ |
585 |
putchar(c); |
586 |
} else { |
587 |
printf("%%%02X", c); |
588 |
} |
589 |
tmp++; |
590 |
} |
591 |
break; |
592 |
case '%': |
593 |
putchar('%'); |
594 |
break; |
595 |
} |
596 |
} else { |
597 |
putchar(*format); |
598 |
} |
599 |
format++; |
600 |
} |
601 |
va_end(ap); |
602 |
} |
603 |
|
604 |
|
605 |
/* perform the put command */ |
606 |
static int procput(const char *nurl, const char *file){ |
607 |
ESTNODE *node; |
608 |
ESTDOC *doc; |
609 |
char *draft; |
610 |
int err; |
611 |
if(!(draft = cbreadfile(file, NULL))){ |
612 |
printferror("%s: could not open", file ? file : "(stdin)"); |
613 |
return 1; |
614 |
} |
615 |
err = FALSE; |
616 |
node = est_node_new(nurl); |
617 |
if(g_pxhost) est_node_set_proxy(node, g_pxhost, g_pxport); |
618 |
if(g_timeout >= 0) est_node_set_timeout(node, g_timeout); |
619 |
if(g_authname && g_authpass) est_node_set_auth(node, g_authname, g_authpass); |
620 |
doc = est_doc_new_from_draft(draft); |
621 |
if(!est_node_put_doc(node, doc)){ |
622 |
printferror("failed: %d", est_node_status(node)); |
623 |
err = TRUE; |
624 |
} |
625 |
est_doc_delete(doc); |
626 |
est_node_delete(node); |
627 |
free(draft); |
628 |
return err ? 1 : 0; |
629 |
} |
630 |
|
631 |
|
632 |
/* perform the out command */ |
633 |
static int procout(const char *nurl, int id, const char *uri){ |
634 |
ESTNODE *node; |
635 |
int err; |
636 |
err = FALSE; |
637 |
node = est_node_new(nurl); |
638 |
if(g_pxhost) est_node_set_proxy(node, g_pxhost, g_pxport); |
639 |
if(g_timeout >= 0) est_node_set_timeout(node, g_timeout); |
640 |
if(g_authname && g_authpass) est_node_set_auth(node, g_authname, g_authpass); |
641 |
if(uri ? !est_node_out_doc_by_uri(node, uri) : !est_node_out_doc(node, id)){ |
642 |
printferror("failed: %d", est_node_status(node)); |
643 |
err = TRUE; |
644 |
} |
645 |
est_node_delete(node); |
646 |
return err ? 1 : 0; |
647 |
} |
648 |
|
649 |
|
650 |
/* perform the get command */ |
651 |
static int procget(const char *nurl, int id, const char *uri, const char *attr){ |
652 |
ESTNODE *node; |
653 |
ESTDOC *doc; |
654 |
char *draft; |
655 |
int err; |
656 |
err = FALSE; |
657 |
node = est_node_new(nurl); |
658 |
if(g_pxhost) est_node_set_proxy(node, g_pxhost, g_pxport); |
659 |
if(g_timeout >= 0) est_node_set_timeout(node, g_timeout); |
660 |
if(g_authname && g_authpass) est_node_set_auth(node, g_authname, g_authpass); |
661 |
err = FALSE; |
662 |
if(attr){ |
663 |
if((draft = uri ? est_node_get_doc_attr_by_uri(node, uri, attr) : |
664 |
est_node_get_doc_attr(node, id, attr)) != NULL){ |
665 |
printf("%s\n", draft); |
666 |
free(draft); |
667 |
} else { |
668 |
printferror("failed: %d", est_node_status(node)); |
669 |
err = TRUE; |
670 |
} |
671 |
} else { |
672 |
if((doc = uri ? est_node_get_doc_by_uri(node, uri) : est_node_get_doc(node, id)) != NULL){ |
673 |
draft = est_doc_dump_draft(doc); |
674 |
printf("%s", draft); |
675 |
free(draft); |
676 |
est_doc_delete(doc); |
677 |
} else { |
678 |
printferror("failed: %d", est_node_status(node)); |
679 |
err = TRUE; |
680 |
} |
681 |
} |
682 |
est_node_delete(node); |
683 |
return err ? 1 : 0; |
684 |
} |
685 |
|
686 |
|
687 |
/* perform the uriid command */ |
688 |
static int procuriid(const char *nurl, const char *uri){ |
689 |
ESTNODE *node; |
690 |
int err, id; |
691 |
err = FALSE; |
692 |
node = est_node_new(nurl); |
693 |
if(g_pxhost) est_node_set_proxy(node, g_pxhost, g_pxport); |
694 |
if(g_timeout >= 0) est_node_set_timeout(node, g_timeout); |
695 |
if(g_authname && g_authpass) est_node_set_auth(node, g_authname, g_authpass); |
696 |
err = FALSE; |
697 |
if((id = est_node_uri_to_id(node, uri)) != -1){ |
698 |
printf("%d\n", id); |
699 |
} else { |
700 |
printferror("failed: %d", est_node_status(node)); |
701 |
err = TRUE; |
702 |
} |
703 |
est_node_delete(node); |
704 |
return err ? 1 : 0; |
705 |
} |
706 |
|
707 |
|
708 |
/* perform the inform command */ |
709 |
static int procinform(const char *nurl){ |
710 |
ESTNODE *node; |
711 |
const char *name, *label; |
712 |
int err, dnum, wnum; |
713 |
double size; |
714 |
err = FALSE; |
715 |
node = est_node_new(nurl); |
716 |
if(g_pxhost) est_node_set_proxy(node, g_pxhost, g_pxport); |
717 |
if(g_timeout >= 0) est_node_set_timeout(node, g_timeout); |
718 |
if(g_authname && g_authpass) est_node_set_auth(node, g_authname, g_authpass); |
719 |
err = FALSE; |
720 |
name = est_node_name(node); |
721 |
label = est_node_label(node); |
722 |
dnum = est_node_doc_num(node); |
723 |
wnum = est_node_word_num(node); |
724 |
size = est_node_size(node); |
725 |
if(name && label && dnum >= 0 && wnum >= 0 && size >= 0.0){ |
726 |
printf("%s\t%s\t%d\t%d\t%.0f\n", name, label, dnum, wnum, size); |
727 |
} else { |
728 |
printferror("failed: %d", est_node_status(node)); |
729 |
err = TRUE; |
730 |
} |
731 |
est_node_delete(node); |
732 |
return err ? 1 : 0; |
733 |
} |
734 |
|
735 |
|
736 |
/* perform the inform command */ |
737 |
static int procsearch(const char *nurl, const char *phrase, |
738 |
const CBLIST *attrs, const char *ord, int max, int depth){ |
739 |
ESTNODE *node; |
740 |
ESTNODERES *nres; |
741 |
ESTRESDOC *rdoc; |
742 |
ESTCOND *cond; |
743 |
CBMAP *hints; |
744 |
CBLIST *names, *elems, *lines; |
745 |
const char *kbuf, *vbuf; |
746 |
char tbuf[NUMBUFSIZ]; |
747 |
int i, j, err, ksiz, vsiz, dnum, wnum, id, ld; |
748 |
err = FALSE; |
749 |
node = est_node_new(nurl); |
750 |
if(g_pxhost) est_node_set_proxy(node, g_pxhost, g_pxport); |
751 |
if(g_timeout >= 0) est_node_set_timeout(node, g_timeout); |
752 |
if(g_authname && g_authpass) est_node_set_auth(node, g_authname, g_authpass); |
753 |
err = FALSE; |
754 |
cond = est_cond_new(); |
755 |
while(*phrase > '\0' && *phrase <= ' '){ |
756 |
phrase++; |
757 |
} |
758 |
if(phrase[0] != '\0' || cblistnum(attrs) < 1) est_cond_set_phrase(cond, phrase); |
759 |
for(i = 0; i < cblistnum(attrs); i++){ |
760 |
est_cond_add_attr(cond, cblistval(attrs, i, NULL)); |
761 |
} |
762 |
if(ord) est_cond_set_order(cond, ord); |
763 |
if(max >= 0) est_cond_set_max(cond, max); |
764 |
if((nres = est_node_search(node, cond, depth)) != NULL){ |
765 |
hints = est_noderes_hints(nres); |
766 |
switch(g_viewmode){ |
767 |
case VM_XML: |
768 |
xmlprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); |
769 |
xmlprintf("<estresult version=\"%@\">\n", est_version); |
770 |
xmlprintf("<meta>\n"); |
771 |
if((vbuf = cbmapget(hints, "NODE", -1, NULL)) != NULL) |
772 |
xmlprintf("<node url=\"%@\"/>\n", vbuf); |
773 |
if((vbuf = cbmapget(hints, "HIT", -1, NULL)) != NULL) |
774 |
xmlprintf("<hit number=\"%@\"/>\n", vbuf); |
775 |
for(i = 1; i < cbmaprnum(hints); i++){ |
776 |
sprintf(tbuf, "HINT#%d", i); |
777 |
if(!(vbuf = cbmapget(hints, tbuf, -1, &vsiz))) break; |
778 |
elems = cbsplit(vbuf, vsiz, "\t"); |
779 |
if(cblistnum(elems) == 2){ |
780 |
xmlprintf("<hit key=\"%@\" number=\"%@\"/>\n", |
781 |
cblistval(elems, 0, NULL), cblistval(elems, 1, NULL)); |
782 |
} |
783 |
cblistclose(elems); |
784 |
} |
785 |
if((vbuf = cbmapget(hints, "TIME", -1, NULL)) != NULL) |
786 |
xmlprintf("<time time=\"%@\"/>\n", vbuf); |
787 |
dnum = 0; |
788 |
wnum = 0; |
789 |
if((vbuf = cbmapget(hints, "DOCNUM", -1, NULL)) != NULL) dnum = atoi(vbuf); |
790 |
if((vbuf = cbmapget(hints, "WORDNUM", -1, NULL)) != NULL) wnum = atoi(vbuf); |
791 |
xmlprintf("<total documents=\"%d\" words=\"%d\"/>\n", dnum, wnum); |
792 |
for(i = 0; i < cbmaprnum(hints); i++){ |
793 |
sprintf(tbuf, "LINK#%d", i); |
794 |
if(!(vbuf = cbmapget(hints, tbuf, -1, &vsiz))) break; |
795 |
elems = cbsplit(vbuf, vsiz, "\t"); |
796 |
if(cblistnum(elems) == 7){ |
797 |
xmlprintf("<link url=\"%@\" label=\"%@\" credit=\"%@\" docnum=\"%@\" wordnum=\"%@\"" |
798 |
" size=\"%@\" hit=\"%@\"/>\n", |
799 |
cblistval(elems, 0, NULL), cblistval(elems, 1, NULL), |
800 |
cblistval(elems, 2, NULL), cblistval(elems, 3, NULL), |
801 |
cblistval(elems, 4, NULL), cblistval(elems, 5, NULL), |
802 |
cblistval(elems, 6, NULL)); |
803 |
} |
804 |
cblistclose(elems); |
805 |
} |
806 |
xmlprintf("</meta>\n"); |
807 |
for(i = 0; i < est_noderes_doc_num(nres); i++){ |
808 |
rdoc = est_noderes_get_doc(nres, i); |
809 |
id = -1; |
810 |
if((vbuf = est_resdoc_attr(rdoc, ESTDATTRID)) != NULL) id = atoi(vbuf); |
811 |
xmlprintf("<document id=\"%d\" uri=\"%@\">\n", id, est_resdoc_uri(rdoc)); |
812 |
names = est_resdoc_attr_names(rdoc); |
813 |
for(j = 0; j < cblistnum(names); j++){ |
814 |
kbuf = cblistval(names, j, NULL); |
815 |
if(!strcmp(kbuf, ESTDATTRID) || !strcmp(kbuf, ESTDATTRURI)) continue; |
816 |
xmlprintf("<attribute name=\"%@\" value=\"%s\"/>\n", |
817 |
kbuf, est_resdoc_attr(rdoc, kbuf)); |
818 |
} |
819 |
cblistclose(names); |
820 |
xmlprintf("<snippet>"); |
821 |
lines = cbsplit(est_resdoc_snippet(rdoc), -1, "\n"); |
822 |
ld = TRUE; |
823 |
for(j = 0; j < cblistnum(lines); j++){ |
824 |
vbuf = cblistval(lines, j, &vsiz); |
825 |
elems = cbsplit(vbuf, vsiz, "\t"); |
826 |
if(vbuf[0] == '\0'){ |
827 |
if(!ld) xmlprintf("<delimiter/>"); |
828 |
ld = TRUE; |
829 |
} else if(cblistnum(elems) == 1){ |
830 |
xmlprintf("%@", cblistval(elems, 0, NULL)); |
831 |
ld = FALSE; |
832 |
} else { |
833 |
xmlprintf("<key normal=\"%@\">%@</key>", |
834 |
cblistval(elems, 1, NULL), cblistval(elems, 0, NULL)); |
835 |
ld = FALSE; |
836 |
} |
837 |
cblistclose(elems); |
838 |
} |
839 |
cblistclose(lines); |
840 |
xmlprintf("</snippet>\n"); |
841 |
xmlprintf("</document>\n"); |
842 |
} |
843 |
xmlprintf("</estresult>\n"); |
844 |
break; |
845 |
default: |
846 |
printf("%s\n", est_border_str()); |
847 |
cbmapiterinit(hints); |
848 |
while((kbuf = cbmapiternext(hints, &ksiz)) != NULL){ |
849 |
printf("%s\t%s\n", kbuf, cbmapget(hints, kbuf, ksiz, NULL)); |
850 |
} |
851 |
printf("\n"); |
852 |
for(i = 0; i < est_noderes_doc_num(nres); i++){ |
853 |
printf("%s\n", est_border_str()); |
854 |
rdoc = est_noderes_get_doc(nres, i); |
855 |
names = est_resdoc_attr_names(rdoc); |
856 |
for(j = 0; j < cblistnum(names); j++){ |
857 |
kbuf = cblistval(names, j, NULL); |
858 |
printf("%s=%s\n", kbuf, est_resdoc_attr(rdoc, kbuf)); |
859 |
} |
860 |
cblistclose(names); |
861 |
printf("\n"); |
862 |
printf("%s", est_resdoc_snippet(rdoc)); |
863 |
} |
864 |
printf("%s:END\n", est_border_str()); |
865 |
break; |
866 |
} |
867 |
est_noderes_delete(nres); |
868 |
} else { |
869 |
printferror("failed: %d", est_node_status(node)); |
870 |
err = TRUE; |
871 |
} |
872 |
est_cond_delete(cond); |
873 |
est_node_delete(node); |
874 |
return err ? 1 : 0; |
875 |
} |
876 |
|
877 |
|
878 |
/* perform the setuser command */ |
879 |
static int procsetuser(const char *nurl, const char *name, int mode){ |
880 |
ESTNODE *node; |
881 |
int err; |
882 |
err = FALSE; |
883 |
node = est_node_new(nurl); |
884 |
if(g_pxhost) est_node_set_proxy(node, g_pxhost, g_pxport); |
885 |
if(g_timeout >= 0) est_node_set_timeout(node, g_timeout); |
886 |
if(g_authname && g_authpass) est_node_set_auth(node, g_authname, g_authpass); |
887 |
err = FALSE; |
888 |
if(!est_node_set_user(node, name, mode)){ |
889 |
printferror("failed: %d", est_node_status(node)); |
890 |
err = TRUE; |
891 |
} |
892 |
est_node_delete(node); |
893 |
return err ? 1 : 0; |
894 |
} |
895 |
|
896 |
|
897 |
/* perform the setlink command */ |
898 |
static int procsetlink(const char *nurl, const char *url, const char *label, int credit){ |
899 |
ESTNODE *node; |
900 |
int err; |
901 |
err = FALSE; |
902 |
node = est_node_new(nurl); |
903 |
if(g_pxhost) est_node_set_proxy(node, g_pxhost, g_pxport); |
904 |
if(g_timeout >= 0) est_node_set_timeout(node, g_timeout); |
905 |
if(g_authname && g_authpass) est_node_set_auth(node, g_authname, g_authpass); |
906 |
err = FALSE; |
907 |
if(!est_node_set_link(node, url, label, credit)){ |
908 |
printferror("failed: %d", est_node_status(node)); |
909 |
err = TRUE; |
910 |
} |
911 |
est_node_delete(node); |
912 |
return err ? 1 : 0; |
913 |
} |
914 |
|
915 |
|
916 |
/* perform the raw command */ |
917 |
static int procraw(const char *url, const char *file){ |
918 |
CBMAP *resheads; |
919 |
CBDATUM *resbody; |
920 |
const char *ptr; |
921 |
char *auth, *reqbody; |
922 |
int i, err, rbsiz, rescode, size; |
923 |
if(file){ |
924 |
if(!(reqbody = cbreadfile(strcmp(file, "-") ? file : NULL, &rbsiz))){ |
925 |
printferror("%s: could not open", file); |
926 |
return 1; |
927 |
} |
928 |
} else { |
929 |
reqbody = NULL; |
930 |
rbsiz = 0; |
931 |
} |
932 |
err = FALSE; |
933 |
resheads = cbmapopenex(MINIBNUM); |
934 |
resbody = cbdatumopen("", 0); |
935 |
auth = (g_authname && g_authpass) ? cbsprintf("%s:%s", g_authname, g_authpass) : NULL; |
936 |
if(est_url_shuttle(url, g_pxhost, g_pxport, g_timeout, auth, |
937 |
g_exheaders, reqbody, rbsiz, &rescode, resheads, resbody)){ |
938 |
if(rescode < 200 && rescode >= 300) err = TRUE; |
939 |
if(g_nonparse){ |
940 |
printf("%s\r\n", cbmapget(resheads, "", 0, NULL)); |
941 |
cbmapiterinit(resheads); |
942 |
while((ptr = cbmapiternext(resheads, &size)) != NULL){ |
943 |
if(size < 1) continue; |
944 |
printf("%s: %s\r\n", ptr, cbmapget(resheads, ptr, size, NULL)); |
945 |
} |
946 |
printf("\r\n"); |
947 |
} |
948 |
ptr = cbdatumptr(resbody); |
949 |
size = cbdatumsize(resbody); |
950 |
for(i = 0; i < size; i++){ |
951 |
putchar(ptr[i]); |
952 |
} |
953 |
} else { |
954 |
printferror("%s: connection failed", url); |
955 |
err = TRUE; |
956 |
} |
957 |
free(auth); |
958 |
cbdatumclose(resbody); |
959 |
cbmapclose(resheads); |
960 |
free(reqbody); |
961 |
return err ? 1 : 0; |
962 |
} |
963 |
|
964 |
|
965 |
|
966 |
/* END OF FILE */ |