+
+ if (!*info.database )
+ {
+ fprintf (reply_fd, "%s\n",
+ gw_res_get (info.kernel_res, "gw.err.no.database",
+ "You must select database"));
+ return -3;
+ }
+ gw_log (GW_LOG_DEBUG, KERNEL_LOG, "Searching in database %s",
+ info.database );
+ assert (info.zass);
+ p = zass_p_search (info.zass, rpn, setname, info.database, info.sets);
+ if (!p)
+ {
+ fprintf (reply_fd, "%s\n",
+ gw_res_get (info.kernel_res, "gw.err.search.fail",
+ "Search fail."));
+ return -1;
+ }
+ if (p->errcode != -1)
+ {
+ display_diag_error (p->errcode, p->errstring);
+ return -2;
+ }
+ fprintf (reply_fd, "%d %s %s\n", p->num,
+ gw_res_get (info.kernel_res, "gw.msg.hits", "hit(s) in set "),
+ setname);
+ us = user_set_add (setname, p->num, info.database, rpn, 1, search_str);
+ autoshow = gw_res_int (info.kernel_res, "gw.auto.show", 0);
+ if (autoshow && p->num > 0)
+ {
+ if (autoshow > p->num)
+ {
+ present (setname, 1, p->num, NULL);
+ info.next_position = 1+p->num;
+ }
+ else
+ {
+ present (setname, 1, autoshow, NULL);
+ info.next_position = 1+autoshow;
+ }
+ }
+ return 0;
+}
+
+static int exec_account (struct ccl_token *list)
+{
+ if (list->kind != CCL_TOK_EOL)
+ {
+ int len = list->len;
+ memcpy (info.account, list->name, len);
+ info.target[len] = '\0';
+ }
+ else
+ *info.account = '\0';
+ info.account_in_session = 1;
+ return 0;
+}
+
+void handle_target_list (const char *name, const char *value)
+{
+ GwRes res;
+ const char *p;
+
+ if (strlen(name) < 10)
+ return;
+ if (memcmp (name, "gw.target.", 10))
+ return;
+ fprintf (reply_fd, "%s\n", name+10);
+ res = gw_res_init ();
+ gw_res_merge (res, value);
+ p = gw_res_get (res, "gw.description", NULL);
+ if (p)
+ {
+ put_esc_str (p);
+ put_esc_str ("\\n");
+ }
+ p = gw_res_get (res, "gw.databases", NULL);
+ if (p)
+ fprintf (reply_fd, " Databases: %s\n", p);
+ fprintf (reply_fd, "\n");
+ gw_res_close (res);
+}
+
+static int exec_target_list (void)
+{
+ gw_res_trav (info.kernel_res, NULL, handle_target_list);
+ fprintf (reply_fd, "\n");
+ return 0;
+}
+
+static int exec_target (struct ccl_token *list)
+{
+ int len;
+ if (list->kind == CCL_TOK_EOL)
+ return exec_target_list ();
+ len = list->len;
+ memcpy (info.target, list->name, len);
+ info.target [len] = '\0';
+
+ if (!info.account_in_session)
+ *info.account = '\0';
+ info.account_in_session = 0;
+ read_kernel_res ();
+ info.connect_failed = 0;
+ return reopen_target ();
+}
+
+static void exec_status_r (struct gw_user_set *sp)
+{
+ if (!sp)
+ return;
+ exec_status_r (sp->prev);
+ fprintf (reply_fd, "%6s %7d %12.12s %.50s\n", sp->name, sp->hits,
+ sp->database, sp->search_str);
+}
+
+static int exec_status (struct ccl_token *list)
+{
+ fprintf (reply_fd, "%s\n",
+ gw_res_get (info.kernel_res,
+ "gw.msg.statusline",
+ " Name Hits Database Find"));
+ exec_status_r (info.sets);
+ return 0;
+}
+
+static int exec_base (struct ccl_token *list)
+{
+ struct ccl_token *li = list;
+ int len = 0;
+
+ assert (info.zass);
+ if (list->kind == CCL_TOK_EOL)
+ return -1;
+ free (info.database);
+ while (li->kind != CCL_TOK_EOL)
+ {
+ len += li->len + 1;
+ li = li->next;
+ if (li->kind == CCL_TOK_COMMA)
+ li = li->next;
+ }
+ info.database = malloc (len);
+ assert (info.database );
+ len = 0;
+ li = list;
+ while (li->kind != CCL_TOK_EOL)
+ {
+ memcpy (info.database+len, li->name, li->len);
+ len += li->len;
+ info.database[len++] = ',';
+ li = li->next;
+ if (li->kind == CCL_TOK_COMMA)
+ li = li->next;
+ }
+ info.database[len-1] = '\0';
+ return 0;
+}
+
+static void present (const char *set, int offset, int number,
+ struct ccl_token *format_token)
+{
+ const struct zass_presentent *zp;
+ int len;
+ int max_number;
+ char format_str[16];
+
+ max_number = gw_res_int (info.kernel_res, "gw.max.show", 100);
+ if (number > max_number)
+ number = max_number;
+ gw_log (GW_LOG_DEBUG, KERNEL_LOG, "present in set %s", set);
+ gw_log (GW_LOG_DEBUG, KERNEL_LOG, "present of %d records from offset %d",
+ number, offset);
+ zp = zass_p_present(info.zass, (char *) set, offset, number);
+ if (zp)
+ {
+ int i;
+ zass_record *pp;
+ int record_log_fd = -1;
+ const char *record_log_name;
+
+ record_log_name = gw_res_get (info.kernel_res, "gw.marc.log",
+ NULL);
+ if (record_log_name)
+ {
+ record_log_fd = open (record_log_name,
+ O_WRONLY|O_CREAT|O_APPEND, 0666);
+ if (record_log_fd == -1)
+ gw_log (GW_LOG_WARN|GW_LOG_ERRNO, "Cannot open %s",
+ record_log_name);
+ }
+ fprintf (reply_fd, gw_res_get (info.kernel_res,
+ "gw.msg.records",
+ "Got %d records from set %s"),
+ zp->num, set);
+ fprintf (reply_fd, "\n");
+ for (i = 0, pp = zp->records; pp; pp = pp->next, i++)
+ {
+ Iso2709Rec rec;
+#if USE_FML
+ const char *arg_ar[5];
+#endif
+ fprintf (reply_fd, "--- %d/%d ---\n",
+ i+offset, offset+zp->num-1);
+ if (!gw_res_get (info.kernel_res, "gw.ignore.which", NULL))
+ {
+ if (pp->which == ZASS_REC_DIAG)
+ {
+ display_diag_error (pp->errcode, pp->errstring);
+ continue;
+ }
+ else if (pp->which != ZASS_REC_USMARC)
+ {
+ fprintf (reply_fd, "Unknown record kind %d\n",
+ pp->which);
+ continue;
+ }
+ }
+ if (record_log_fd != -1)
+ write (record_log_fd, pp->record, strlen(pp->record));
+ rec = iso2709_cvt (pp->record);
+ if (rec)
+ {
+#if USE_FML
+ strcpy (format_str,
+ gw_res_get (info.kernel_res,
+ "gw.display.format", ""));
+ if (format_token)
+ {
+ len = format_token->len;
+ if (len >= sizeof(format_str))
+ len = sizeof(format_str)-1;
+ memcpy (format_str, format_token->name, len);
+ format_str[len] = '\0';
+ }
+ if (info.fml && *format_str &&
+ (!strcmp (format_str, "0") || !strcmp (format_str, "1")
+ || !strcmp(format_str, "2")))
+ {
+ arg_ar[0] = "\\f";
+ arg_ar[1] = format_str;
+ arg_ar[2] = " \\list";
+ arg_ar[3] = marc_to_str (info.fml, rec);
+ arg_ar[4] = NULL;
+ fml_exec_call_argv (info.fml, arg_ar);
+ }
+ else
+ iso2709_display (rec, reply_fd);
+#else
+ iso2709_display (rec, reply_fd);
+#endif
+ iso2709_rm (rec);
+ }
+ else
+ fprintf (reply_fd, "Not a MARC record\n");
+ }
+ if (record_log_fd != -1)
+ close (record_log_fd);
+ }
+}
+
+static int exec_show (struct ccl_token *list)
+{
+ static struct command_word show_tab [] =
+ {
+ { "f", "format"},
+ { "p", "position"},
+ { NULL, NULL }
+ };
+ char tmp_str[20];
+ struct ccl_token *set_token = NULL;
+ struct ccl_token *format_token = NULL;
+ struct ccl_token *li = list;
+ int no_of_present = 0;
+
+ assert (info.zass);
+ while (li->kind != CCL_TOK_EOL)
+ {
+ int modifier_no = 0;
+ if (li->next->kind == CCL_TOK_EQ)
+ {
+ if (li->kind == CCL_TOK_SET) /* set = <name> ? */
+ {
+ li = li->next->next;
+ set_token = li;
+ }
+ else
+ {
+ modifier_no = command_search (show_tab, li, "ccl.token.");
+ if (!modifier_no)
+ {
+ fprintf (reply_fd, "Unknown modifier in show\n");
+ return -1;
+ }
+ li = li->next->next;
+ if (modifier_no == 1) /* f = <name> ? */
+ format_token = li;
+ else if (modifier_no == 2) /* p = <name> ? */
+ {
+ if (li->kind != CCL_TOK_EOL /* p = <name> - <name> ? */
+ && li->next->kind == CCL_TOK_MINUS
+ && li->next->next != CCL_TOK_EOL)
+ li = li->next->next;
+ }
+ }
+ if (!li->next)
+ {
+ fprintf (reply_fd, "%s\n", "Missing token after '='");
+ return -2;
+ }
+ li = li->next;
+ }
+ else
+ {
+ int len = li->len;
+ memcpy (tmp_str, li->name, len);
+ tmp_str[len] = '\0';
+ if (atoi(tmp_str) <= 0)
+ {
+ fprintf (reply_fd, "%s\n",
+ gw_res_get (info.kernel_res, "gw.err.bad.show",
+ "Syntax error"));
+ return -3;
+ }
+ li = li->next;
+ }
+ }
+ if (set_token)
+ gw_log (GW_LOG_DEBUG, KERNEL_LOG, "Got set=%.*s", set_token->len,
+ set_token->name);
+ if (format_token)
+ gw_log (GW_LOG_DEBUG, KERNEL_LOG, "Got format=%.*s", format_token->len,
+ format_token->name);
+
+ li = list;
+ while (li->kind != CCL_TOK_EOL)
+ {
+ int modifier_no = 0;
+ int offset = 0;
+ int number = 0;
+ int len;
+ if (li->next->kind == CCL_TOK_EQ && li->kind != CCL_TOK_SET)
+ {
+ modifier_no = command_search (show_tab, li, "ccl.token.");
+ li = li->next->next;
+ if (modifier_no == 2) /* p = <name> ? */
+ {
+ if (li->kind != CCL_TOK_EOL /* p = <name> - <name> ? */
+ && li->next->kind == CCL_TOK_MINUS
+ && li->next->next != CCL_TOK_EOL)
+ {
+ len = li->len;
+ memcpy (tmp_str, li->name, len);
+ tmp_str [len] = '\0';
+ offset = atoi (tmp_str);
+ li = li->next->next;
+
+ len = li->len;
+ memcpy (tmp_str, li->name, len);
+ tmp_str [len] = '\0';
+ number = atoi (tmp_str) - offset + 1;
+ if (number <= 0)
+ {
+ fprintf (reply_fd, "%s\n",
+ gw_res_get (info.kernel_res,
+ "gw.err.pos.show",
+ "Starting position "
+ "greater than ending position"));
+ return -3;
+ }
+ }
+ else
+ {
+ len = li->len;
+ memcpy (tmp_str, li->name, len);
+ tmp_str [len] = '\0';
+ offset = atoi (tmp_str);
+ number = 1;
+ }
+ }
+ li = li->next;
+ }
+ else if (li->kind == CCL_TOK_TERM)
+ {
+ len = li->len;
+ memcpy (tmp_str, li->name, len);
+ tmp_str[len] = '\0';
+ number = atoi (tmp_str);
+ offset = 1;
+ li = li->next;
+ }
+ if (offset > 0 && number > 0)
+ {
+ struct gw_user_set *us;
+
+ if (set_token)
+ {
+ len = set_token->len;
+ memcpy (tmp_str, set_token->name, len);
+ tmp_str[len] = '\0';
+ us = user_set_search (tmp_str);
+ }
+ else
+ us = user_set_search (NULL);
+ if (us && us->hits != -1) /* proper result-set? */
+ {
+ if (offset <= us->hits)
+ {
+ if (offset+number-1 > us->hits)
+ number = us->hits - offset+1;
+ present (us->name, offset, number, format_token);
+ info.next_position = offset+number;
+ }
+ }
+ else if (!no_of_present) /* display error message once! */
+ {
+ fprintf (reply_fd, "%s\n",
+ gw_res_get (info.kernel_res, "gw.err.no.set",
+ "No result-set generated"));
+ }
+ no_of_present++;
+ }
+ }
+ if (!no_of_present) /* no records shown so far? */
+ {
+ struct gw_user_set *us;
+ int default_show;
+
+ us = user_set_search (NULL);
+ if (us && us->hits != -1) /* proper result-set? */
+ {
+ default_show = gw_res_int (info.kernel_res, "gw.default.show", 20);
+ if (us->hits >= info.next_position + default_show)
+ {
+ present (us->name, info.next_position, default_show,
+ format_token);
+ info.next_position += default_show;
+ }
+ else if (us->hits >= info.next_position)
+ {
+ present (us->name, info.next_position,
+ us->hits - info.next_position + 1,
+ format_token);
+ info.next_position = us->hits + 1;
+ }
+ }
+ else /* display error message */
+ {
+ fprintf (reply_fd, "%s\n",
+ gw_res_get (info.kernel_res, "gw.err.no.set",
+ "No result-set generated"));
+ return -3;
+ }
+ }