From f6a107777079379b767452dc6ade3f56272af49e Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 15 Feb 1995 17:45:29 +0000 Subject: [PATCH] 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. --- kernel/Makefile | 47 ++++++++++++ kernel/default.res | 21 ++++++ kernel/kernel.h | 20 ++++++ kernel/main.c | 76 ++++++++++++++++++++ kernel/urp.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 364 insertions(+) create mode 100644 kernel/Makefile create mode 100644 kernel/default.res create mode 100644 kernel/kernel.h create mode 100644 kernel/main.c create mode 100644 kernel/urp.c diff --git a/kernel/Makefile b/kernel/Makefile new file mode 100644 index 0000000..536fe6d --- /dev/null +++ b/kernel/Makefile @@ -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 + $(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 index 0000000..8d213f8 --- /dev/null +++ b/kernel/default.res @@ -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 index 0000000..185085e --- /dev/null +++ b/kernel/kernel.h @@ -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 +#include +#include + +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 index 0000000..c3e4f65 --- /dev/null +++ b/kernel/main.c @@ -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 +#include + +#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 index 0000000..b8a27a8 --- /dev/null +++ b/kernel/urp.c @@ -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 +#include +#include +#include +#include + +#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; +} -- 1.7.10.4