2 * $Id: zoomsh.c,v 1.18 2003-03-03 19:57:36 adam Exp $
12 #if HAVE_READLINE_READLINE_H
13 #include <readline/readline.h>
15 #if HAVE_READLINE_HISTORY_H
16 #include <readline/history.h>
19 #include <yaz/xmalloc.h>
27 static int next_token (const char **cpp, const char **t_start)
30 const char *cp = *cpp;
34 while (*cp && *cp != ' ' && *cp != '\r' && *cp != '\n')
43 static int next_token_copy (const char **cpp, char *buf_out, int buf_max)
46 int len = next_token (cpp, &start);
54 memcpy (buf_out, start, len);
59 static int is_command (const char *cmd_str, const char *this_str, int this_len)
61 int cmd_len = strlen(cmd_str);
62 if (cmd_len != this_len)
64 if (memcmp (cmd_str, this_str, cmd_len))
69 static void cmd_set (ZOOM_connection *c, ZOOM_resultset *r,
73 char key[40], val[80];
75 if (!next_token_copy (args, key, sizeof(key)))
77 printf ("missing argument for set\n");
80 if (!next_token_copy (args, val, sizeof(val)))
81 ZOOM_options_set(options, key, 0);
83 ZOOM_options_set(options, key, val);
86 static void cmd_get (ZOOM_connection *c, ZOOM_resultset *r,
91 if (!next_token_copy (args, key, sizeof(key)))
93 printf ("missing argument for get\n");
97 const char *val = ZOOM_options_get(options, key);
98 printf ("%s = %s\n", key, val ? val : "<null>");
102 static void cmd_close (ZOOM_connection *c, ZOOM_resultset *r,
103 ZOOM_options options,
108 next_token_copy (args, host, sizeof(host));
109 for (i = 0; i<MAX_CON; i++)
114 if ((h = ZOOM_connection_option_get(c[i], "host"))
115 && !strcmp (h, host))
117 ZOOM_connection_destroy (c[i]);
120 else if (*host == '\0')
122 ZOOM_connection_destroy (c[i]);
128 static void display_records (ZOOM_connection c,
130 int start, int count)
133 for (i = 0; i<count; i++)
136 ZOOM_record rec = ZOOM_resultset_record (r, pos);
137 const char *db = ZOOM_record_get (rec, "database", 0);
139 const char *render = ZOOM_record_get (rec, "render", &len);
140 const char *syntax = ZOOM_record_get (rec, "syntax", 0);
141 /* if rec is non-null, we got a record for display */
144 printf ("%d %s %s\n", pos+1, (db ? db : "unknown"), syntax);
146 fwrite (render, 1, len, stdout);
152 static void cmd_show (ZOOM_connection *c, ZOOM_resultset *r,
153 ZOOM_options options,
157 char start_str[10], count_str[10];
159 if (next_token_copy (args, start_str, sizeof(start_str)))
160 ZOOM_options_set (options, "start", start_str);
162 if (next_token_copy (args, count_str, sizeof(count_str)))
163 ZOOM_options_set (options, "count", count_str);
165 for (i = 0; i<MAX_CON; i++)
166 ZOOM_resultset_records (r[i], 0, atoi(start_str), atoi(count_str));
167 while (ZOOM_event (MAX_CON, c))
170 for (i = 0; i<MAX_CON; i++)
173 const char *errmsg, *addinfo, *dset;
174 /* display errors if any */
177 if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
178 printf ("%s error: %s (%s:%d) %s\n",
179 ZOOM_connection_option_get(c[i], "host"), errmsg,
180 dset, error, addinfo);
183 /* OK, no major errors. Display records... */
184 int start = ZOOM_options_get_int (options, "start", 0);
185 int count = ZOOM_options_get_int (options, "count", 0);
186 display_records (c[i], r[i], start, count);
189 ZOOM_options_set (options, "count", "0");
190 ZOOM_options_set (options, "start", "0");
193 static void cmd_ext (ZOOM_connection *c, ZOOM_resultset *r,
194 ZOOM_options options,
197 ZOOM_package p[MAX_CON];
201 for (i = 0; i<MAX_CON; i++)
205 p[i] = ZOOM_connection_package (c[i], 0);
206 ZOOM_package_send(p[i], "itemorder");
212 while (ZOOM_event (MAX_CON, c))
215 for (i = 0; i<MAX_CON; i++)
218 const char *errmsg, *addinfo, *dset;
219 /* display errors if any */
222 if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
223 printf ("%s error: %s (%s:%d) %s\n",
224 ZOOM_connection_option_get(c[i], "host"), errmsg,
225 dset, error, addinfo);
230 ZOOM_package_destroy (p[i]);
234 static void cmd_debug (ZOOM_connection *c, ZOOM_resultset *r,
235 ZOOM_options options,
238 yaz_log_init_level(LOG_ALL);
241 static void cmd_search (ZOOM_connection *c, ZOOM_resultset *r,
242 ZOOM_options options,
246 const char *query_str = *args;
249 s = ZOOM_query_create ();
250 while (*query_str == ' ')
252 if (memcmp(query_str, "cql:", 4) == 0)
254 ZOOM_query_cql (s, query_str + 4);
256 else if (ZOOM_query_prefix (s, query_str))
258 printf ("Bad PQF: %s\n", query_str);
261 for (i = 0; i<MAX_CON; i++)
265 ZOOM_resultset_destroy (r[i]);
269 r[i] = ZOOM_connection_search (c[i], s);
272 while (ZOOM_event (MAX_CON, c))
275 for (i = 0; i<MAX_CON; i++)
278 const char *errmsg, *addinfo, *dset;
279 /* display errors if any */
282 if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
283 printf ("%s error: %s (%s:%d) %s\n",
284 ZOOM_connection_option_get(c[i], "host"), errmsg,
285 dset, error, addinfo);
288 /* OK, no major errors. Look at the result count */
289 int start = ZOOM_options_get_int (options, "start", 0);
290 int count = ZOOM_options_get_int (options, "count", 0);
292 printf ("%s: %d hits\n", ZOOM_connection_option_get(c[i], "host"),
293 ZOOM_resultset_size(r[i]));
295 display_records (c[i], r[i], start, count);
298 ZOOM_query_destroy (s);
301 static void cmd_scan (ZOOM_connection *c, ZOOM_resultset *r,
302 ZOOM_options options,
305 const char *start_term = *args;
307 ZOOM_scanset s[MAX_CON];
309 while (*start_term == ' ')
312 for (i = 0; i<MAX_CON; i++)
315 s[i] = ZOOM_connection_scan(c[i], start_term);
319 while (ZOOM_event(MAX_CON, c))
321 for (i = 0; i<MAX_CON; i++)
324 size_t p, sz = ZOOM_scanset_size(s[i]);
325 for (p = 0; p < sz; p++)
329 const char *term = ZOOM_scanset_term(s[i], p, &occ, &len);
330 fwrite(term, 1, len, stdout);
331 printf (" %d\n", occ);
333 ZOOM_scanset_destroy(s[i]);
338 static void cmd_help (ZOOM_connection *c, ZOOM_resultset *r,
339 ZOOM_options options,
342 printf ("connect <zurl>\n");
343 printf ("search <pqf>\n");
344 printf ("show [<start> [<count>]\n");
345 printf ("scan <term>\n");
347 printf ("close <zurl>\n");
348 printf ("set <option> [<value>]\n");
349 printf ("get <option>\n");
351 printf ("options:\n");
354 printf (" databaseName\n");
355 printf (" preferredRecordSyntax\n");
357 printf (" elementSetName\n");
358 printf (" maximumRecordSize\n");
359 printf (" preferredRecordSize\n");
361 printf (" piggyback\n");
365 printf (" implementationName\n");
366 printf (" charset\n");
370 static void cmd_connect (ZOOM_connection *c, ZOOM_resultset *r,
371 ZOOM_options options,
375 const char *errmsg, *addinfo, *dset;
378 if (!next_token_copy (args, host, sizeof(host)))
380 printf ("missing host after connect\n");
383 for (j = -1, i = 0; i<MAX_CON; i++)
386 if (c[i] && (h = ZOOM_connection_option_get(c[i], "host")) &&
389 ZOOM_connection_destroy (c[i]);
392 else if (c[i] == 0 && j == -1)
395 if (i == MAX_CON) /* no match .. */
399 printf ("no more connection available\n");
402 i = j; /* OK, use this one is available */
404 c[i] = ZOOM_connection_create (options);
405 ZOOM_connection_connect (c[i], host, 0);
407 if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
408 printf ("%s error: %s (%s:%d) %s\n",
409 ZOOM_connection_option_get(c[i], "host"), errmsg,
410 dset, error, addinfo);
413 static int cmd_parse (ZOOM_connection *c, ZOOM_resultset *r,
414 ZOOM_options options,
420 cmd_len = next_token (buf, &cmd_str);
423 if (is_command ("quit", cmd_str, cmd_len))
425 else if (is_command ("set", cmd_str, cmd_len))
426 cmd_set (c, r, options, buf);
427 else if (is_command ("get", cmd_str, cmd_len))
428 cmd_get (c, r, options, buf);
429 else if (is_command ("connect", cmd_str, cmd_len))
430 cmd_connect (c, r, options, buf);
431 else if (is_command ("open", cmd_str, cmd_len))
432 cmd_connect (c, r, options, buf);
433 else if (is_command ("search", cmd_str, cmd_len))
434 cmd_search (c, r, options, buf);
435 else if (is_command ("find", cmd_str, cmd_len))
436 cmd_search (c, r, options, buf);
437 else if (is_command ("show", cmd_str, cmd_len))
438 cmd_show (c, r, options, buf);
439 else if (is_command ("close", cmd_str, cmd_len))
440 cmd_close (c, r, options, buf);
441 else if (is_command ("help", cmd_str, cmd_len))
442 cmd_help(c, r, options, buf);
443 else if (is_command ("ext", cmd_str, cmd_len))
444 cmd_ext(c, r, options, buf);
445 else if (is_command ("debug", cmd_str, cmd_len))
446 cmd_debug(c, r, options, buf);
447 else if (is_command ("scan", cmd_str, cmd_len))
448 cmd_scan(c, r, options, buf);
450 printf ("unknown command %.*s\n", cmd_len, cmd_str);
454 void shell(ZOOM_connection *c, ZOOM_resultset *r,
455 ZOOM_options options)
461 const char *bp = buf;
462 #if HAVE_READLINE_READLINE_H
464 line_in=readline("ZOOM>");
467 #if HAVE_READLINE_HISTORY_H
469 add_history(line_in);
471 if(strlen(line_in) > 999) {
472 printf("Input line too long\n");
478 printf ("ZOOM>"); fflush (stdout);
479 if (!fgets (buf, 999, stdin))
482 if ((cp = strchr(buf, '\n')))
484 if (!cmd_parse (c, r, options, &bp))
489 int main (int argc, char **argv)
491 ZOOM_options options = ZOOM_options_create();
493 ZOOM_connection z39_con[MAX_CON];
494 ZOOM_resultset z39_res[MAX_CON];
497 for (i = 0; i<MAX_CON; i++)
503 for (i = 0; i<MAX_CON; i++)
507 for (i = 1; i<argc; i++)
509 const char *bp = argv[i];
510 res = cmd_parse(z39_con, z39_res, options, &bp);
511 if (res == 0) /* received quit */
514 if (res) /* do cmdline shell only if not quitting */
515 shell(z39_con, z39_res, options);
516 ZOOM_options_destroy(options);
518 for (i = 0; i<MAX_CON; i++)
520 ZOOM_connection_destroy(z39_con[i]);
521 ZOOM_resultset_destroy(z39_res[i]);