First version of email gateway kernel. Email requests are read
authorAdam Dickmeiss <adam@indexdata.dk>
Wed, 15 Feb 1995 17:45:29 +0000 (17:45 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Wed, 15 Feb 1995 17:45:29 +0000 (17:45 +0000)
from stdin. The output is transferred to an MTA if 'From' is
found in the header - or stdout if absent. No Z39.50 client is used.

kernel/Makefile [new file with mode: 0644]
kernel/default.res [new file with mode: 0644]
kernel/kernel.h [new file with mode: 0644]
kernel/main.c [new file with mode: 0644]
kernel/urp.c [new file with mode: 0644]

diff --git a/kernel/Makefile b/kernel/Makefile
new file mode 100644 (file)
index 0000000..536fe6d
--- /dev/null
@@ -0,0 +1,47 @@
+# Makefile for Email gateway CCL
+# Europagate, 1995
+#
+# $Log: Makefile,v $
+# Revision 1.1  1995/02/15 17:45:29  adam
+# First version of email gateway kernel. Email requests are read
+# from stdin. The output is transferred to an MTA if 'From' is
+# found in the header - or stdout if absent. No Z39.50 client is used.
+#
+#
+SHELL=/bin/sh
+INCLUDE=-I../include
+CFLAGS=-g -Wall -pedantic -ansi
+CC=gcc
+TPROG1=kernel
+O=urp.o main.o
+CPP=cc -E
+USELIBS=../lib/ccl.a ../lib/fml.a ../lib/libres+log.a ../lib/util.a
+DEFS=$(INCLUDE)
+
+all: $(TPROG1)
+
+$(TPROG1):  $(O) $(USELIBS)
+       $(CC) $(CFLAGS) -o $(TPROG1) $(O) $(USELIBS)
+
+.c.o:
+       $(CC) -c $(DEFS) $(CFLAGS) $<
+
+clean:
+       rm -f *.log *.[oa] $(TPROG1) $(TPROG2) core mon.out gmon.out errlist *~
+
+depend: depend2
+
+depend1:
+       mv Makefile Makefile.tmp
+       sed '/^#Depend/q' <Makefile.tmp >Makefile
+       $(CPP) $(INCLUDE) -M *.c >>Makefile
+       -rm Makefile.tmp
+
+depend2:
+       $(CPP) $(INCLUDE) -M *.c >.depend       
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
+
+#Depend --- DOT NOT DELETE THIS LINE
diff --git a/kernel/default.res b/kernel/default.res
new file mode 100644 (file)
index 0000000..8d213f8
--- /dev/null
@@ -0,0 +1,21 @@
+# Email gateway - general kernel resources
+# $Id: default.res,v 1.1 1995/02/15 17:45:29 adam Exp $
+#
+gw.msg.greeting: Europagate email-Z39.50 gateway
+gw.err.nullbody: Empty body
+gw.reply.mta: /usr/bin/smail
+gw.reply.tmp.prefix: gwr
+gw.reply.tmp.dir: /tmp
+ccl.command.find: find f
+ccl.command.show: show s
+ccl.command.base: base b
+ccl.command.help: help h
+ccl.command.info: info i
+ccl.command.continue: continue
+ccl.command.status: status
+ccl.command.cancel: cancel
+ccl.token.and: and
+ccl.token.or: or
+ccl.token.not: not
+ccl.token.set: set
+
diff --git a/kernel/kernel.h b/kernel/kernel.h
new file mode 100644 (file)
index 0000000..185085e
--- /dev/null
@@ -0,0 +1,20 @@
+/* Gateway kernel
+ * Europagate, 1995
+ *
+ * $Log: kernel.h,v $
+ * Revision 1.1  1995/02/15 17:45:29  adam
+ * First version of email gateway kernel. Email requests are read
+ * from stdin. The output is transferred to an MTA if 'From' is
+ * found in the header - or stdout if absent. No Z39.50 client is used.
+ *
+ */
+
+#include <gw-res.h>
+#include <gw-log.h>
+#include <ccl.h>
+
+int urp (FILE *inf);
+
+extern CCL_bibset bibset;
+extern GwRes kernel_res;
+extern FILE *reply_fd;
diff --git a/kernel/main.c b/kernel/main.c
new file mode 100644 (file)
index 0000000..c3e4f65
--- /dev/null
@@ -0,0 +1,76 @@
+/* Gateway kernel
+ * Europagate, 1995
+ *
+ * $Log: main.c,v $
+ * Revision 1.1  1995/02/15 17:45:29  adam
+ * First version of email gateway kernel. Email requests are read
+ * from stdin. The output is transferred to an MTA if 'From' is
+ * found in the header - or stdout if absent. No Z39.50 client is used.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "kernel.h"
+
+GwRes kernel_res;
+CCL_bibset bibset;
+FILE *reply_fd = stdout;
+
+int main (int argc, char **argv)
+{
+    char *bib_fname;
+    FILE *bib_inf;
+
+    gw_log_init (*argv);
+    kernel_res = gw_res_init ();
+    bibset = ccl_qual_mk ();    
+    while (--argc > 0)
+    {
+        if (**++argv == '-')
+        {
+            switch (argv[0][1])
+            {
+            case 'b':
+                if (argv[0][2])
+                    bib_fname = argv[0]+2;
+                else if (argc > 0)
+                {
+                    --argc;
+                    bib_fname = *++argv;
+                }
+                else
+                {
+                    gw_log (GW_LOG_FATAL, "main", "missing bib filename");
+                    exit (1);
+                }
+                bib_inf = fopen (bib_fname, "r");
+                if (!bib_inf)
+                {
+                    gw_log (GW_LOG_FATAL, "main", "cannot open %s", bib_fname);
+                    exit (1);
+                }
+                ccl_qual_file (bibset, bib_inf);
+                fclose (bib_inf);
+                break;
+            default:
+                gw_log (GW_LOG_FATAL, "main", "unknown option %s", *argv);
+                exit (1);
+            }
+        }
+        else
+        {
+            int r;
+            r = gw_res_merge (kernel_res, *argv);
+            if (r)
+            {
+                gw_log (GW_LOG_FATAL, "main", "failed to read resource "
+                        "file %s", *argv);
+                exit (1);
+            }
+        }
+    }
+    urp (stdin);
+    return 0;
+}
diff --git a/kernel/urp.c b/kernel/urp.c
new file mode 100644 (file)
index 0000000..b8a27a8
--- /dev/null
@@ -0,0 +1,200 @@
+/* Gateway kernel
+ * Europagate, 1995
+ *
+ * $Log: urp.c,v $
+ * Revision 1.1  1995/02/15 17:45:30  adam
+ * First version of email gateway kernel. Email requests are read
+ * from stdin. The output is transferred to an MTA if 'From' is
+ * found in the header - or stdout if absent. No Z39.50 client is used.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "kernel.h"
+
+#define LINE_MAX 256
+
+static char line_buf[LINE_MAX+1];
+
+static struct command_word {
+    char *default_value;
+    char *resource_suffix;
+} command_tab [] = 
+{
+{   "find", "find"},
+{   "show", "show"},
+{   "base", "base" },
+{   "help", "help" },
+{   "info", "info" },
+{   "continue", "continue" },
+{   "status", "status" },
+{   "cancel", "cancel" },
+{   NULL, NULL }
+};
+
+static int command_search (struct command_word *tab, struct ccl_token *cmd,
+const char *resource_prefix)
+{
+    int no = 1;
+
+    assert (resource_prefix);
+    assert (tab);
+    assert (cmd);
+    while (tab->default_value)
+    {
+        char *cp, command_names[60];
+        char resource_name[60];
+        const char *v;
+
+        sprintf (resource_name, "%s%s", resource_prefix,
+                 tab->resource_suffix);
+        v = gw_res_get (kernel_res, resource_name, tab->default_value);
+        assert (v);
+        strcpy (command_names, v);
+        cp = command_names;
+        while (1)
+        {
+            char *split;
+
+            if ((split = strchr (cp, ' ')))
+                *split = '\0';
+            if (cmd->len == strlen(cp) &&
+                !memcmp (cmd->name, cp, cmd->len))
+                return no;
+            if (!split)
+                break;
+            cp = split+1;
+        }        
+        no++;
+        tab++;
+    }
+    return 0;
+}
+
+static int email_header (FILE *inf, char *from_str)
+{
+    *from_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);
+    }
+    return 1;
+}
+
+static int exec_find (struct ccl_token *list)
+{
+    struct ccl_rpn_node *rpn;
+    int error;
+    const char *pos;
+
+    rpn = ccl_find (bibset, list, &error, &pos);
+    if (!rpn)
+    {
+        fprintf (reply_fd, " %*s^ - ", pos - line_buf, " ");
+        fprintf (reply_fd, "%s\n", ccl_err_msg (error));
+        return -1;
+    }
+    ccl_pr_tree (rpn, reply_fd);
+    fprintf (reply_fd, "\n");
+    return 0;
+}
+
+static int exec_command (const char *str)
+{
+    struct ccl_token *cmd = ccl_tokenize (str);
+    int no;
+
+    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");
+    
+    fprintf (reply_fd, "> %s", str);
+    if (cmd->kind == CCL_TOK_TERM &&
+        (no = command_search (command_tab, cmd, "ccl.command.")))
+    {
+        switch (no)
+        {
+        case 1:
+            return exec_find (cmd->next);
+            break;
+        case 2:
+            fprintf (reply_fd, " show found\n");
+            break;
+        default:
+            fprintf (reply_fd, " unimplemented command\n");
+        }
+    }
+    else
+        fprintf (reply_fd, "  ^ unknown command\n");
+    return 0;
+}
+
+int urp (FILE *inf)
+{
+    char from_str[128];
+    int command_no = 0;
+    char *reply_fname = NULL;
+
+    if (email_header (inf, from_str))
+    {
+        gw_log (GW_LOG_WARN, "urp", "No message body");
+        return -1;
+    }
+    if (*from_str)
+    {
+        reply_fname = tempnam (gw_res_get (kernel_res,
+                                           "gw.reply.tmp.dir", NULL),
+                               gw_res_get (kernel_res,
+                                           "gw.reply.tmp.prefix", "gwr"));
+                                                 
+        reply_fd = fopen (reply_fname, "w");
+        if (!reply_fd)
+        {
+            gw_log (GW_LOG_FATAL, "urp", "Cannot create %s",
+                    reply_fname);
+            return -1;
+        }
+    }
+    fprintf (reply_fd, "%s\n", gw_res_get (kernel_res, "gw.msg.greeting",
+                                           "Email->Z39.50 gateway"));
+    while (fgets (line_buf, LINE_MAX, inf))
+    {
+        if (line_buf[0] == '\n')
+            break;
+        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",
+                                               "No body"));
+    if (*from_str)
+    {
+        const char *mta;
+        char cmd[256];
+        int mta_code;
+
+        assert (reply_fname);
+        fclose (reply_fd);
+        reply_fd = stdout;
+
+        mta = gw_res_get (kernel_res, "gw.reply.mta", "/usr/lib/sendmail");
+        sprintf (cmd, "%s %s < %s", mta, from_str, reply_fname);
+        
+        mta_code = system (cmd);
+        if (mta_code)
+            gw_log (GW_LOG_FATAL, "urp", "Reply '%s' got exit code %d",
+                    cmd, mta_code);
+        unlink (reply_fname);        
+    }
+    return 0;
+}