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