First steps of CCL show command. Not finished yet.
[egate.git] / kernel / urp.c
index dce2ba8..308b93b 100644 (file)
@@ -2,7 +2,17 @@
  * Europagate, 1995
  *
  * $Log: urp.c,v $
- * Revision 1.2  1995/02/16 13:21:00  adam
+ * Revision 1.5  1995/02/17 14:22:13  adam
+ * First steps of CCL show command. Not finished yet.
+ *
+ * Revision 1.4  1995/02/17  09:08:36  adam
+ * Reply with subject. CCL base command implemented.
+ *
+ * Revision 1.3  1995/02/16  18:35:09  adam
+ * First use of Zdist library. Search requests are supported.
+ * Present requests are not supported yet.
+ *
+ * Revision 1.2  1995/02/16  13:21:00  adam
  * Organization of resource files for targets and conversion
  * language implemented.
  *
 #include <assert.h>
 #include <ctype.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "kernel.h"
 
 #define LINE_MAX 256
 
+static int reopen_target (void)
+{
+    const char *v;
+    if (info.zass)
+        gw_log (GW_LOG_WARN, "urp", "Zass free...");
+    info.zass = zass_open (info.hostname, info.port);
+    if (!info.zass)
+    {
+        fprintf (reply_fd, "%s %s:%d\n", 
+                 gw_res_get (info.kernel_res, "gw.err.connect",
+                             "Cannot connect to target"),
+                 info.hostname, info.port);
+        return -1;
+    }
+    v = gw_res_get (info.kernel_res, "gw.description", NULL);
+    if (v)
+        fprintf (reply_fd, "%s\n", v);
+    fprintf (reply_fd, "%s %s:%d\n %s\n",
+             gw_res_get (info.kernel_res, "gw.msg.databases",
+                         "Available databases on"),
+             info.hostname, info.port, info.databases);
+    return 0;
+}
+
 static char line_buf[LINE_MAX+1];
 
 static struct command_word {
@@ -58,7 +93,7 @@ const char *resource_prefix)
 
         sprintf (resource_name, "%s%s", resource_prefix,
                  tab->resource_suffix);
-        v = gw_res_get (kernel_res, resource_name, tab->default_value);
+        v = gw_res_get (info.kernel_res, resource_name, tab->default_value);
         assert (v);
         strcpy (command_names, v);
         cp = command_names;
@@ -113,26 +148,32 @@ static char *error_no_search (struct error_no_struct *tab, int no)
     return NULL;
 }
 
-static int email_header (FILE *inf, char *from_str)
+static int email_header (FILE *inf, char *from_str, char *subject_str)
 {
     *from_str = '\0';
+    *subject_str = '\0';
     while (fgets (line_buf, LINE_MAX, inf))
     {
         if (line_buf[0] == '\n')
             return 0;
         if (strncmp (line_buf, "From ", 5) == 0)
             sscanf (line_buf+4, "%s", from_str);
+        if (strncmp (line_buf, "Subject: ", 9) == 0 &&
+            sscanf (line_buf+9, "%s", subject_str+1) == 1)
+            strcpy (subject_str, line_buf+9);
     }
     return 1;
 }
 
 static int exec_find (struct ccl_token *list)
 {
+    const struct zass_searchent *p;
+
     struct ccl_rpn_node *rpn;
     int error;
     const char *pos;
 
-    rpn = ccl_find (bibset, list, &error, &pos);
+    rpn = ccl_find (info.bibset, list, &error, &pos);
     if (!rpn)
     {
         const char *v = NULL, *n;
@@ -144,7 +185,7 @@ static int exec_find (struct ccl_token *list)
         if (n)
         {
             sprintf (name, "gw.err.%s", n);
-            v = gw_res_get (kernel_res, name, NULL);
+            v = gw_res_get (info.kernel_res, name, NULL);
         }
         if (!v)
             v = ccl_err_msg (error);
@@ -153,6 +194,86 @@ static int exec_find (struct ccl_token *list)
     }
     ccl_pr_tree (rpn, reply_fd);
     fprintf (reply_fd, "\n");
+
+    if (!info.zass)
+        return -2;
+    p = zass_search (info.zass, rpn, "Default", info.databases);
+    if (!p)
+        return -1;
+    fprintf (reply_fd, "%d %s\n", p->num,
+             gw_res_get (info.kernel_res, "gw.msg.hits", "hit(s)"));
+    if (p->errcode != -1)
+        fprintf (reply_fd, "%s %d: %s\n",
+                 gw_res_get (info.kernel_res, "gw.msg.z39errcode",
+                             "Z39.50 error code"),
+                 p->errcode, p->errstring);
+    return 0;
+}
+
+static int exec_target (struct ccl_token *list)
+{
+    int len;
+    if (list->kind == CCL_TOK_EOL)
+        return -1;
+    len = list->len;
+    memcpy (info.target, list->name, len);
+    info.target [len] = '\0';
+
+    read_kernel_res ();
+    return reopen_target ();
+}
+
+static int exec_base (struct ccl_token *list)
+{
+    struct ccl_token *li = list;
+    int len = 0;
+
+    if (list->kind == CCL_TOK_EOL)
+        return -1;
+    free (info.databases);
+    while (li->kind != CCL_TOK_EOL)
+    {
+        len += li->len + 1;
+        li = li->next;
+        if (li->kind == CCL_TOK_COMMA)
+            li = li->next;
+    }
+    info.databases = malloc (len);
+    assert (info.databases);
+    len = 0;
+    li = list;
+    while (li->kind != CCL_TOK_EOL)
+    {
+        memcpy (info.databases+len, li->name, li->len);
+        len += li->len;
+        info.databases[len++] = ',';
+        li = li->next;
+        if (li->kind == CCL_TOK_COMMA)
+            li = li->next;
+    }
+    info.databases[len-1] = '\0';
+    return 0;
+}
+
+static int exec_show (struct ccl_token *list)
+{
+    const struct zass_presentent *zp;
+    char num_str[20];
+    int num;
+
+    if (list->kind == CCL_TOK_EOL)
+        return -1;
+    if (!info.zass)
+        return -2;
+    
+    memcpy (num_str, list->name, list->len);
+    num_str[list->len] = '\0';
+
+    num = atoi (num_str);
+    if (!num)
+        return -3;
+    gw_log (GW_LOG_DEBUG, "urp", "zass_present of %d records", num);
+    zp = zass_present(info.zass, "Default", 1, num);
     return 0;
 }
 
@@ -161,25 +282,33 @@ static int exec_command (const char *str)
     struct ccl_token *cmd = ccl_tokenize (str);
     int no;
 
-    fprintf (reply_fd, "> %s", str);
     if (cmd->kind != CCL_TOK_EOL &&
         (no = command_search (command_tab, cmd, "ccl.command.")))
     {
+        if (!info.zass && no != 9)
+            reopen_target ();
+        fprintf (reply_fd, "\n> %s", str);
         switch (no)
         {
         case 1:
             return exec_find (cmd->next);
-            break;
+        case 2:
+            return exec_show (cmd->next);
+        case 3:
+            return exec_base (cmd->next);
+        case 9:
+            return exec_target (cmd->next);
         default:
-            fprintf (reply_fd, " %s\n",
-                     gw_res_get (kernel_res, "gw.err.unimplemented",
+            fprintf (reply_fd, "%s\n",
+                     gw_res_get (info.kernel_res, "gw.err.unimplemented",
                                  "Not implemented yet"));
         }
     }
     else
     {
+        fprintf (reply_fd, "\n> %s", str);
         fprintf (reply_fd, "  ^ %s\n", 
-                 gw_res_get (kernel_res, "gw.err.unknown.command",
+                 gw_res_get (info.kernel_res, "gw.err.unknown.command",
                              "unknown command"));
     }
     return 0;
@@ -188,19 +317,20 @@ static int exec_command (const char *str)
 int urp (FILE *inf)
 {
     char from_str[128];
+    char subject_str[128];
     int command_no = 0;
     char *reply_fname = NULL;
 
-    if (email_header (inf, from_str))
+    if (email_header (inf, from_str, subject_str))
     {
         gw_log (GW_LOG_WARN, "urp", "No message body");
         return -1;
     }
     if (*from_str)
     {
-        reply_fname = tempnam (gw_res_get (kernel_res,
+        reply_fname = tempnam (gw_res_get (info.kernel_res,
                                            "gw.reply.tmp.dir", NULL),
-                               gw_res_get (kernel_res,
+                               gw_res_get (info.kernel_res,
                                            "gw.reply.tmp.prefix", "gwr"));
                                                  
         reply_fd = fopen (reply_fname, "w");
@@ -210,25 +340,34 @@ int urp (FILE *inf)
                     reply_fname);
             return -1;
         }
+        fprintf (reply_fd, "Subject: ");
+        if (*subject_str)
+            fprintf (reply_fd, "Z39.50 Re: %s", subject_str);
+        else
+            fprintf (reply_fd, "%s\n", gw_res_get (info.kernel_res,
+                                                   "gw.msg.subject",
+                                                   "Your Z39.50 Query"));
+        fprintf (reply_fd, "\n");
     }
     else
         gw_log (GW_LOG_WARN, "urp", "No From in email header");
-    fprintf (reply_fd, "%s\n", gw_res_get (kernel_res, "gw.msg.greeting",
+    fprintf (reply_fd, "%s\n", gw_res_get (info.kernel_res, "gw.msg.greeting",
                                            "Email->Z39.50 gateway"));
     while (fgets (line_buf, LINE_MAX, inf))
     {
         if (line_buf[0] == '\n')
             break;
-        ccl_token_and = gw_res_get (kernel_res, "ccl.token.and", "and");
-        ccl_token_or = gw_res_get (kernel_res, "ccl.token.or", "or");
-        ccl_token_not = gw_res_get (kernel_res, "ccl.token.not", "not");
-        ccl_token_set = gw_res_get (kernel_res, "ccl.token.set", "set");       
+        ccl_token_and = gw_res_get (info.kernel_res, "ccl.token.and", "and");
+        ccl_token_or = gw_res_get (info.kernel_res, "ccl.token.or", "or");
+        ccl_token_not = gw_res_get (info.kernel_res, "ccl.token.not", "not");
+        ccl_token_set = gw_res_get (info.kernel_res, "ccl.token.set", "set");       
         if (isalpha (line_buf[0]))
             exec_command (line_buf);
         command_no++;
     }
     if (!command_no)
-        fprintf (reply_fd, "%s\n", gw_res_get (kernel_res, "gw.err.nullbody",
+        fprintf (reply_fd, "%s\n", gw_res_get (info.kernel_res,
+                                               "gw.err.nullbody",
                                                "No body"));
     if (*from_str)
     {
@@ -240,7 +379,8 @@ int urp (FILE *inf)
         fclose (reply_fd);
         reply_fd = stdout;
 
-        mta = gw_res_get (kernel_res, "gw.reply.mta", "/usr/lib/sendmail");
+        mta = gw_res_get (info.kernel_res, "gw.reply.mta",
+                          "/usr/lib/sendmail");
         sprintf (cmd, "%s %s < %s", mta, from_str, reply_fname);
         
         mta_code = system (cmd);