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