1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2010 Index Data
3 * See the file LICENSE for details.
7 \brief ZOOM C command line tool (shell)
14 #include <yaz/wrbuf.h>
16 #if HAVE_READLINE_READLINE_H
17 #include <readline/readline.h>
19 #if HAVE_READLINE_HISTORY_H
20 #include <readline/history.h>
28 static void process_events(ZOOM_connection *c)
32 printf("process_events\n");
33 while ((i = ZOOM_event(MAX_CON, c)) != 0)
35 int peek = ZOOM_connection_peek_event(c[i-1]);
36 int event = ZOOM_connection_last_event(c[i-1]);
37 printf ("no = %d peek = %d event = %d %s\n", i-1,
40 ZOOM_get_event_str(event));
44 static int next_token(const char **cpp, const char **t_start)
47 const char *cp = *cpp;
54 while (*cp && *cp != '"')
65 while (*cp && *cp != ' ' && *cp != '\r' && *cp != '\n')
74 return len; /* return -1 if no token was read .. */
77 static WRBUF next_token_new_wrbuf(const char **cpp)
81 int len = next_token(cpp, &start);
86 wrbuf_write(w, start, len);
90 static int is_command(const char *cmd_str, const char *this_str, int this_len)
92 int cmd_len = strlen(cmd_str);
93 if (cmd_len != this_len)
95 if (memcmp(cmd_str, this_str, cmd_len))
100 static void cmd_set(ZOOM_connection *c, ZOOM_resultset *r,
101 ZOOM_options options,
106 if (!(key = next_token_new_wrbuf(args)))
108 printf("missing argument for set\n");
111 if ((val = next_token_new_wrbuf(args)))
113 ZOOM_options_set(options, wrbuf_cstr(key), wrbuf_cstr(val));
117 ZOOM_options_set(options, wrbuf_cstr(key), 0);
121 static void cmd_get(ZOOM_connection *c, ZOOM_resultset *r,
122 ZOOM_options options,
126 if (!(key = next_token_new_wrbuf(args)))
128 printf("missing argument for get\n");
132 const char *val = ZOOM_options_get(options, wrbuf_cstr(key));
133 printf("%s = %s\n", wrbuf_cstr(key), val ? val : "<null>");
138 static void cmd_rget(ZOOM_connection *c, ZOOM_resultset *r,
139 ZOOM_options options,
143 if (!(key = next_token_new_wrbuf(args)))
145 printf("missing argument for get\n");
150 for (i = 0; i<MAX_CON; i++)
156 val = ZOOM_resultset_option_get(r[i], wrbuf_cstr(key));
157 printf("%s = %s\n", wrbuf_cstr(key), val ? val : "<null>");
163 static void cmd_close(ZOOM_connection *c, ZOOM_resultset *r,
164 ZOOM_options options,
169 host = next_token_new_wrbuf(args);
170 for (i = 0; i<MAX_CON; i++)
177 ZOOM_connection_destroy(c[i]);
180 else if ((h = ZOOM_connection_option_get(c[i], "host"))
181 && !strcmp(h, wrbuf_cstr(host)))
183 ZOOM_connection_destroy(c[i]);
191 static void display_records(ZOOM_connection c,
193 size_t start, size_t count, const char *type)
196 for (i = 0; i < count; i++)
198 size_t pos = i + start;
199 ZOOM_record rec = ZOOM_resultset_record(r, pos);
200 const char *db = ZOOM_record_get(rec, "database", 0);
202 if (ZOOM_record_error(rec, 0, 0, 0))
207 int error = ZOOM_record_error(rec, &msg, &addinfo, &diagset);
209 printf("%lld %s: %s (%s:%d) %s\n", (long long) pos,
210 (db ? db : "unknown"),
211 msg, diagset, error, addinfo ? addinfo : "none");
216 const char *render = ZOOM_record_get(rec, type, &len);
217 const char *syntax = ZOOM_record_get(rec, "syntax", 0);
218 const char *schema = ZOOM_record_get(rec, "schema", 0);
219 /* if rec is non-null, we got a record for display */
222 printf("%lld database=%s syntax=%s schema=%s\n",
223 (long long) pos, (db ? db : "unknown"), syntax,
224 schema ? schema : "unknown");
227 if (fwrite(render, 1, len, stdout) != (size_t) len)
229 printf("write to stdout failed\n");
238 static void cmd_show(ZOOM_connection *c, ZOOM_resultset *r,
239 ZOOM_options options,
243 size_t start = 0, count = 1;
244 const char *type = "render";
245 WRBUF render_str = 0;
250 if ((tmp = next_token_new_wrbuf(args)))
252 start = atoi(wrbuf_cstr(tmp));
256 if ((tmp = next_token_new_wrbuf(args)))
258 count = atoi(wrbuf_cstr(tmp));
261 render_str = next_token_new_wrbuf(args);
264 type = wrbuf_cstr(render_str);
266 for (i = 0; i < MAX_CON; i++)
267 ZOOM_resultset_records(r[i], 0, start, count);
270 for (i = 0; i < MAX_CON; i++)
273 const char *errmsg, *addinfo, *dset;
274 /* display errors if any */
277 if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
278 printf("%s error: %s (%s:%d) %s\n",
279 ZOOM_connection_option_get(c[i], "host"), errmsg,
280 dset, error, addinfo);
283 /* OK, no major errors. Display records... */
284 display_records(c[i], r[i], start, count, type);
288 wrbuf_destroy(render_str);
292 static void display_facets(ZOOM_facet_field *facets, int count) {
294 printf("Facets: \n");
295 for (index = 0; index < count; index++) {
297 const char *facet_name = ZOOM_facet_field_name(facets[index]);
298 printf(" %s: \n", facet_name);
299 for (term_index = 0; term_index < ZOOM_facet_field_term_count(facets[index]); term_index++) {
301 const char *term = ZOOM_facet_field_get_term(facets[index], term_index, &freq);
302 printf(" %s(%d) \n", term, freq);
307 static void cmd_facets(ZOOM_connection *c, ZOOM_resultset *r,
308 ZOOM_options options,
312 size_t start = 0, count = 1;
313 const char *type = "render";
314 WRBUF render_str = 0;
320 if ((tmp = next_token_new_wrbuf(args)))
322 start = atoi(wrbuf_cstr(tmp));
326 if ((tmp = next_token_new_wrbuf(args)))
328 count = atoi(wrbuf_cstr(tmp));
331 render_str = next_token_new_wrbuf(args);
334 type = wrbuf_cstr(render_str);
338 for (i = 0; i < MAX_CON; i++)
341 const char *errmsg, *addinfo, *dset;
342 /* display errors if any */
345 if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
346 printf("%s error: %s (%s:%d) %s\n",
347 ZOOM_connection_option_get(c[i], "host"), errmsg,
348 dset, error, addinfo);
351 int num_facets = ZOOM_resultset_facets_size(r[i]);
353 ZOOM_facet_field *facets = ZOOM_resultset_facets(r[i]);
354 display_facets(facets, num_facets);
359 wrbuf_destroy(render_str);
363 static void cmd_ext(ZOOM_connection *c, ZOOM_resultset *r,
364 ZOOM_options options,
367 ZOOM_package p[MAX_CON];
369 WRBUF ext_type_str = next_token_new_wrbuf(args);
371 for (i = 0; i<MAX_CON; i++)
375 p[i] = ZOOM_connection_package(c[i], 0);
376 ZOOM_package_send(p[i], ext_type_str ? wrbuf_cstr(ext_type_str):0);
384 for (i = 0; i<MAX_CON; i++)
387 const char *errmsg, *addinfo, *dset;
388 /* display errors if any */
391 if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
392 printf("%s error: %s (%s:%d) %s\n",
393 ZOOM_connection_option_get(c[i], "host"), errmsg,
394 dset, error, addinfo);
399 v = ZOOM_package_option_get(p[i], "targetReference");
401 printf("targetReference: %s\n", v);
402 v = ZOOM_package_option_get(p[i], "xmlUpdateDoc");
404 printf("xmlUpdateDoc: %s\n", v);
406 ZOOM_package_destroy(p[i]);
409 wrbuf_destroy(ext_type_str);
412 static void cmd_debug(ZOOM_connection *c, ZOOM_resultset *r,
413 ZOOM_options options,
416 yaz_log_init_level(YLOG_ALL);
419 static void cmd_search(ZOOM_connection *c, ZOOM_resultset *r,
420 ZOOM_options options,
424 const char *query_str = *args;
427 s = ZOOM_query_create();
428 while (*query_str == ' ')
430 if (memcmp(query_str, "cql:", 4) == 0)
432 ZOOM_query_cql(s, query_str + 4);
434 else if (ZOOM_query_prefix(s, query_str))
436 printf("Bad PQF: %s\n", query_str);
439 for (i = 0; i<MAX_CON; i++)
444 ZOOM_resultset_destroy(r[i]);
448 r[i] = ZOOM_connection_search(c[i], s);
450 ZOOM_query_destroy(s);
454 for (i = 0; i<MAX_CON; i++)
457 const char *errmsg, *addinfo, *dset;
458 /* display errors if any */
461 if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
462 printf("%s error: %s (%s:%d) %s\n",
463 ZOOM_connection_option_get(c[i], "host"), errmsg,
464 dset, error, addinfo);
467 /* OK, no major errors. Look at the result count */
468 int start = ZOOM_options_get_int(options, "start", 0);
469 int count = ZOOM_options_get_int(options, "count", 0);
471 printf("%s: %lld hits\n", ZOOM_connection_option_get(c[i], "host"),
472 (long long int) ZOOM_resultset_size(r[i]));
474 display_records(c[i], r[i], start, count, "render");
479 static void cmd_scan(ZOOM_connection *c, ZOOM_resultset *r,
480 ZOOM_options options,
483 const char *query_str = *args;
484 ZOOM_query query = ZOOM_query_create();
486 ZOOM_scanset s[MAX_CON];
488 while (*query_str == ' ')
491 if (memcmp(query_str, "cql:", 4) == 0)
493 ZOOM_query_cql(query, query_str + 4);
495 else if (ZOOM_query_prefix(query, query_str))
497 printf("Bad PQF: %s\n", query_str);
501 for (i = 0; i<MAX_CON; i++)
504 s[i] = ZOOM_connection_scan1(c[i], query);
508 ZOOM_query_destroy(query);
512 for (i = 0; i<MAX_CON; i++)
515 const char *errmsg, *addinfo, *dset;
516 /* display errors if any */
519 if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
520 printf("%s error: %s (%s:%d) %s\n",
521 ZOOM_connection_option_get(c[i], "host"), errmsg,
522 dset, error, addinfo);
525 size_t p, sz = ZOOM_scanset_size(s[i]);
526 for (p = 0; p < sz; p++)
530 const char *term = ZOOM_scanset_display_term(s[i], p,
532 printf("%.*s %lld\n", (int) len, term, (long long int) occ);
534 ZOOM_scanset_destroy(s[i]);
539 static void cmd_sort(ZOOM_connection *c, ZOOM_resultset *r,
540 ZOOM_options options,
543 const char *sort_spec = *args;
546 while (*sort_spec == ' ')
549 for (i = 0; i<MAX_CON; i++)
552 ZOOM_resultset_sort(r[i], "yaz", sort_spec);
557 static void cmd_help(ZOOM_connection *c, ZOOM_resultset *r,
558 ZOOM_options options,
561 printf("connect <zurl>\n");
562 printf("search <pqf>\n");
563 printf("show [<start> [<count> [<type]]]\n");
565 printf("scan <term>\n");
567 printf("close <zurl>\n");
568 printf("ext <type>\n");
569 printf("set <option> [<value>]\n");
570 printf("get <option>\n");
572 printf("options:\n");
575 printf(" databaseName\n");
576 printf(" preferredRecordSyntax\n");
578 printf(" elementSetName\n");
579 printf(" maximumRecordSize\n");
580 printf(" preferredRecordSize\n");
582 printf(" piggyback\n");
585 printf(" password\n");
586 printf(" implementationName\n");
587 printf(" charset\n");
589 printf(" timeout\n");
593 static void cmd_connect(ZOOM_connection *c, ZOOM_resultset *r,
594 ZOOM_options options,
598 const char *errmsg, *addinfo, *dset;
600 WRBUF host = next_token_new_wrbuf(args);
603 printf("missing host after connect\n");
606 for (j = -1, i = 0; i<MAX_CON; i++)
609 if (c[i] && (h = ZOOM_connection_option_get(c[i], "host")) &&
610 !strcmp(h, wrbuf_cstr(host)))
612 ZOOM_connection_destroy(c[i]);
615 else if (c[i] == 0 && j == -1)
618 if (i == MAX_CON) /* no match .. */
622 printf("no more connection available\n");
626 i = j; /* OK, use this one is available */
628 c[i] = ZOOM_connection_create(options);
629 ZOOM_connection_connect(c[i], wrbuf_cstr(host), 0);
631 if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
632 printf("%s error: %s (%s:%d) %s\n",
633 ZOOM_connection_option_get(c[i], "host"), errmsg,
634 dset, error, addinfo);
638 static int cmd_parse(ZOOM_connection *c, ZOOM_resultset *r,
639 ZOOM_options options,
645 cmd_len = next_token(buf, &cmd_str);
648 if (is_command("quit", cmd_str, cmd_len))
650 else if (is_command("set", cmd_str, cmd_len))
651 cmd_set(c, r, options, buf);
652 else if (is_command("get", cmd_str, cmd_len))
653 cmd_get(c, r, options, buf);
654 else if (is_command("rget", cmd_str, cmd_len))
655 cmd_rget(c, r, options, buf);
656 else if (is_command("connect", cmd_str, cmd_len))
657 cmd_connect(c, r, options, buf);
658 else if (is_command("open", cmd_str, cmd_len))
659 cmd_connect(c, r, options, buf);
660 else if (is_command("search", cmd_str, cmd_len))
661 cmd_search(c, r, options, buf);
662 else if (is_command("facets", cmd_str, cmd_len))
663 cmd_facets(c, r, options, buf);
664 else if (is_command("find", cmd_str, cmd_len))
665 cmd_search(c, r, options, buf);
666 else if (is_command("show", cmd_str, cmd_len))
667 cmd_show(c, r, options, buf);
668 else if (is_command("close", cmd_str, cmd_len))
669 cmd_close(c, r, options, buf);
670 else if (is_command("help", cmd_str, cmd_len))
671 cmd_help(c, r, options, buf);
672 else if (is_command("ext", cmd_str, cmd_len))
673 cmd_ext(c, r, options, buf);
674 else if (is_command("debug", cmd_str, cmd_len))
675 cmd_debug(c, r, options, buf);
676 else if (is_command("scan", cmd_str, cmd_len))
677 cmd_scan(c, r, options, buf);
678 else if (is_command("sort", cmd_str, cmd_len))
679 cmd_sort(c, r, options, buf);
681 printf("unknown command %.*s\n", cmd_len, cmd_str);
685 void shell(ZOOM_connection *c, ZOOM_resultset *r,
686 ZOOM_options options)
692 const char *bp = buf;
693 #if HAVE_READLINE_READLINE_H
695 line_in=readline("ZOOM>");
698 #if HAVE_READLINE_HISTORY_H
700 add_history(line_in);
702 if(strlen(line_in) > 999) {
703 printf("Input line too long\n");
709 printf("ZOOM>"); fflush(stdout);
710 if (!fgets(buf, 999, stdin))
713 if ((cp = strchr(buf, '\n')))
715 if (!cmd_parse(c, r, options, &bp))
720 static void zoomsh(int argc, char **argv)
722 ZOOM_options options = ZOOM_options_create();
724 ZOOM_connection z39_con[MAX_CON];
725 ZOOM_resultset z39_res[MAX_CON];
727 for (i = 0; i<MAX_CON; i++)
733 for (i = 0; i<MAX_CON; i++)
737 for (i = 1; i<argc; i++)
739 const char *bp = argv[i];
740 res = cmd_parse(z39_con, z39_res, options, &bp);
741 if (res == 0) /* received quit */
744 if (res) /* do cmdline shell only if not quitting */
745 shell(z39_con, z39_res, options);
746 ZOOM_options_destroy(options);
748 for (i = 0; i<MAX_CON; i++)
750 ZOOM_connection_destroy(z39_con[i]);
751 ZOOM_resultset_destroy(z39_res[i]);
755 int main(int argc, char **argv)
757 const char *maskstr = 0;
758 if (argc > 2 && !strcmp(argv[1], "-v"))
764 else if (argc > 1 && !strncmp(argv[1], "-v", 2))
772 int mask = yaz_log_mask_str(maskstr);
773 yaz_log_init_level(mask);
781 * c-file-style: "Stroustrup"
782 * indent-tabs-mode: nil
784 * vim: shiftwidth=4 tabstop=8 expandtab