Moved code from zotnet/mts to mts/generic. Also, unified generic
authorShantonu Sen <ssen@mit.edu>
Fri, 8 Sep 2000 00:30:58 +0000 (00:30 +0000)
committerShantonu Sen <ssen@mit.edu>
Fri, 8 Sep 2000 00:30:58 +0000 (00:30 +0000)
mts code and smtp/sendmail into libmts.a as an intermediate, instead
of having two static libs.

mts/Makefile.in
mts/generic/Makefile.in [new file with mode: 0644]
mts/generic/client.c [new file with mode: 0644]
mts/generic/mts.c [new file with mode: 0644]
mts/generic/mts.h [new file with mode: 0644]
mts/mmdf/hosts.c
mts/sendmail/hosts.c
mts/sendmail/sendmail.c
mts/smtp/Makefile.in
mts/smtp/hosts.c
mts/smtp/smtp.c

index a8c5ee5..08b4754 100644 (file)
@@ -17,6 +17,15 @@ etcdir='$(etcdir)' libdir='$(libdir)' mandir='$(mandir)' \
 mailspool='$(mailspool)' sendmailpath='$(sendmailpath)' \
 default_editor='$(default_editor)' default_pager='$(default_pager)'
 
+LORDER = @LORDER@
+TSORT  = @TSORT@
+RANLIB = @RANLIB@
+LIBTOOL = @LIBTOOL@
+GNU_LIBTOOL = @GNU_LIBTOOL@
+
+# object files that go into libmts.a
+OBJS =  generic/client.o generic/mts.o smtp/hosts.o smtp/smtp.o
+
 # auxiliary files
 AUX = Makefile.in
 
@@ -24,18 +33,32 @@ AUX = Makefile.in
 DIST = $(AUX)
 
 # subdirectories
-SUBDIRS = smtp sendmail mmdf
+SUBDIRS = smtp generic
 
 # mail transport agent we are using (currently always smtp)
-MTS = smtp
+# MTS = smtp
+# DEPRECATED: smtp/sendmail functionality handled by mts.conf
 
 # ========= DEPENDENCIES FOR BUILDING AND INSTALLING ==========
 
-all install uninstall:
-       for subdir in $(MTS); do \
-         (cd $$subdir && $(MAKE) $(MAKEDEFS) $@) || exit 1; \
+all: all-recursive libmts.a
+
+all-recursive:
+       for subdir in $(SUBDIRS); do \
+         (cd $$subdir && $(MAKE) $(MAKEDEFS) all) || exit 1; \
        done
 
+libmts.a: $(OBJS)
+       rm -f $@
+       if test x$(LIBTOOL) != x -a x$(GNU_LIBTOOL) = x ; then \
+         $(LIBTOOL) -static -c $(OBJS) -o $@  ; \
+       else \
+         ar cr $@ `$(LORDER) $(OBJS) | $(TSORT)`  ; \
+         $(RANLIB) $@  ; \
+       fi 
+
+install uninstall:
+
 # ========== DEPENDENCIES FOR CLEANUP ==========
 
 mostlyclean: mostlyclean-recursive mostlyclean-local
@@ -48,7 +71,7 @@ mostlyclean-local:
        rm -f *~
 
 clean-local: mostlyclean-local
-
+       rm -f libmts.a
 distclean-local: clean-local
        rm -f Makefile
 
diff --git a/mts/generic/Makefile.in b/mts/generic/Makefile.in
new file mode 100644 (file)
index 0000000..97dca02
--- /dev/null
@@ -0,0 +1,101 @@
+#
+# Makefile for mts/generic subdirectory
+#
+# $Id$
+#
+
+SHELL = /bin/sh
+
+top_srcdir = @top_srcdir@
+srcdir     = @srcdir@
+VPATH      = @srcdir@
+
+prefix      = @prefix@
+exec_prefix = @exec_prefix@
+bindir      = @bindir@
+libdir      = @libdir@
+etcdir      = @sysconfdir@
+
+mailspool    = @mailspool@
+sendmailpath = @sendmailpath@
+
+CC         = @CC@
+CFLAGS     = @CFLAGS@
+DEFS       = @DEFS@
+KRB4_INCLUDES = @KRB4_INCLUDES@
+HESIOD_INCLUDES = @HESIOD_INCLUDES@
+INCLUDES   = -I../.. -I$(srcdir) -I$(top_srcdir) $(KRB4_INCLUDES) $(HESIOD_INCLUDES)
+CONFIGDEFS = -DNMHETCDIR='"$(etcdir)"' -DMAILSPOOL='"$(mailspool)"' -DSENDMAILPATH='"$(sendmailpath)"'
+LINT      = @LINT@
+LINTFLAGS  = @LINTFLAGS@
+
+COMPILE  = $(CC) -c $(DEFS) $(INCLUDES) $(CFLAGS)
+COMPILE2 = $(CC) -c $(DEFS) $(CONFIGDEFS) $(INCLUDES) $(CFLAGS)
+
+SED = sed
+
+.SUFFIXES:
+.SUFFIXES: .c .o
+
+.c.o:
+       $(COMPILE) $<
+
+# header files
+HDRS = mts.h
+
+# source files
+SRCS = mts.c client.c
+
+# object files
+OBJS = mts.o client.o
+
+# auxiliary files
+AUX = Makefile.in
+
+# all files in this directory included in the distribution
+DIST = $(HDRS) $(SRCS) $(AUX)
+
+# ========= DEPENDENCIES FOR BUILDING AND INSTALLING ==========
+
+all: $(OBJS)
+
+mts.o: mts.c
+       $(COMPILE2) $<
+
+install:
+
+uninstall:
+
+# ========== DEPENDENCIES FOR CLEANUP ==========
+
+mostlyclean:
+       rm -f *.o *~
+
+clean: mostlyclean
+
+distclean: clean
+       rm -f Makefile
+
+realclean: distclean
+
+superclean: realclean
+
+# ========== DEPENDENCIES FOR LINT ================
+
+lint: 
+       $(LINT) $(LINTFLAGS) $(INCLUDES) $(DEFS) $(SRCS)
+
+# ========== DEPENDENCIES FOR MAINTENANCE ==========
+
+subdir = mts/generic
+
+Makefile: Makefile.in ../../config.status
+       cd ../.. && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
+distdir = ../../`cat ../../distname`/$(subdir)
+nmhdist: $(DIST)
+       @echo "Copying distribution files in $(subdir)"
+       @for file in $(DIST); do \
+         cp -p $(srcdir)/$$file $(distdir); \
+       done
+
diff --git a/mts/generic/client.c b/mts/generic/client.c
new file mode 100644 (file)
index 0000000..0095959
--- /dev/null
@@ -0,0 +1,479 @@
+
+/*
+ * client.c -- connect to a server
+ *
+ * $Id$
+ */
+
+#include <h/mh.h>
+#include <mts.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#ifdef HESIOD
+# include <hesiod.h>
+#endif
+
+#ifdef KPOP
+# include <krb.h>
+# include <ctype.h>
+#endif /* KPOP */
+
+#define        TRUE         1
+#define        FALSE        0
+
+#define        OOPS1      (-2)
+#define        OOPS2      (-3)
+
+#define        MAXARGS   1000
+#define        MAXNETS      5
+#define        MAXHOSTS    25
+
+struct addrent {
+    int a_addrtype;            /* assumes AF_INET for inet_netof () */
+    union {
+       int un_net;
+       char un_addr[14];
+    } un;
+};
+
+#define        a_net  un.un_net
+#define        a_addr un.un_addr
+
+static struct addrent *n1, *n2;
+static struct addrent nets[MAXNETS];
+static struct addrent *h1, *h2;
+static struct addrent hosts[MAXHOSTS];
+
+#ifdef KPOP
+static CREDENTIALS cred;
+static MSG_DAT msg_data;
+static KTEXT ticket = (KTEXT) NULL;
+static Key_schedule schedule;
+static char *kservice;                 /* "pop" if using kpop */
+char krb_realm[REALM_SZ];
+char *PrincipalHostname();
+#endif /* KPOP */
+
+#if !defined(h_addr)
+# define h_addr h_addr_list[0]
+#endif
+
+#define        inaddr_copy(hp,sin) \
+    memcpy(&((sin)->sin_addr), (hp)->h_addr, (hp)->h_length)
+
+/*
+ * static prototypes
+ */
+static int rcaux (struct servent *, struct hostent *, int, char *, int);
+static int getport (int, int, char *, int);
+static int inet (struct hostent *, int);
+struct hostent *gethostbystring (char *s);
+
+/* client's own static version of several nmh subroutines */
+static char **client_brkstring (char *, char *, char *);
+static int client_brkany (char, char *);
+static char **client_copyip (char **, char **, int);
+static char *client_getcpy (char *);
+
+
+int
+client (char *args, char *protocol, char *service, int rproto,
+               char *response, int len_response)
+{
+    int sd;
+    register char **ap;
+    char *arguments[MAXARGS];
+    register struct hostent *hp;
+    register struct servent *sp;
+#ifndef        HAVE_GETHOSTBYNAME
+    register struct netent *np;
+#endif
+
+#ifdef KPOP
+    char *cp;
+
+    kservice = service;
+    if (cp = strchr (service, '/')) {  /* "pop/kpop" */
+       *cp++ = '\0';           /* kservice = "pop" */
+       service = cp;           /* service  = "kpop" */
+    } else {
+       kservice = NULL;        /* not using KERBEROS */
+    }
+#endif /* KPOP */
+    
+
+    if ((sp = getservbyname (service, protocol)) == NULL) {
+#ifdef HESIOD
+       if ((sp = hes_getservbyname (service, protocol)) == NULL) {
+           snprintf (response, len_response, "%s/%s: unknown service", protocol, service);
+           return NOTOK;
+       }
+#else
+       snprintf (response, len_response, "%s/%s: unknown service", protocol, service);
+       return NOTOK;
+#endif
+    }
+
+    ap = arguments;
+    if (args != NULL && *args != 0) {
+       ap = client_copyip (client_brkstring (client_getcpy (args), " ", "\n"),
+               ap, MAXARGS);
+    } else {
+       if (servers != NULL && *servers != 0)
+           ap = client_copyip (client_brkstring (client_getcpy (servers), " ", "\n"),
+               ap, MAXARGS);
+    }
+    if (ap == arguments) {
+       *ap++ = client_getcpy ("localhost");
+       *ap = NULL;
+    }
+
+    n1 = nets;
+    n2 = nets + sizeof(nets) / sizeof(nets[0]);
+
+    h1 = hosts;
+    h2 = hosts + sizeof(hosts) / sizeof(hosts[0]);
+
+    for (ap = arguments; *ap; ap++) {
+       if (**ap == '\01') {
+/*
+ * the assumption here is that if the system doesn't have a
+ * gethostbyname() function, it must not use DNS. So we need to look
+ * into the /etc/hosts using gethostent(). There probablly aren't any
+ * systems still like this, but you never know. On every system I have
+ * access to, this section is ignored.
+ */
+#ifndef        HAVE_GETHOSTBYNAME
+           if ((np = getnetbyname (*ap + 1))) {
+#ifdef HAVE_SETHOSTENT
+               sethostent (1);
+#endif /* HAVE_SETHOSTENT */
+               while ((hp = gethostent()))
+                   if (np->n_addrtype == hp->h_addrtype
+                           && inet (hp, np->n_net)) {
+                       switch (sd = rcaux (sp, hp, rproto, response, len_response)) {
+                           case NOTOK: 
+                               continue;
+                           case OOPS1: 
+                               break;
+                           case OOPS2: 
+                               return NOTOK;
+
+                           default: 
+                               return sd;
+                       }
+                       break;
+                   }
+           }
+#endif /* don't HAVE_GETHOSTBYNAME */
+           continue;
+       }
+
+       if ((hp = gethostbystring (*ap))) {
+           switch (sd = rcaux (sp, hp, rproto, response, len_response)) {
+               case NOTOK: 
+               case OOPS1: 
+                   break;
+               case OOPS2: 
+                   return NOTOK;
+
+               default: 
+                   return sd;
+           }
+           continue;
+       }
+    }
+
+    strncpy (response, "no servers available", len_response);
+    return NOTOK;
+}
+
+
+static int
+rcaux (struct servent *sp, struct hostent *hp, int rproto,
+               char *response, int len_response)
+{
+    int sd;
+    struct in_addr in;
+    register struct addrent *ap;
+    struct sockaddr_in in_socket;
+    register struct sockaddr_in *isock = &in_socket;
+
+#ifdef KPOP
+    int rem;
+    struct hostent *hp2;
+#endif /* KPOP */
+
+    for (ap = nets; ap < n1; ap++)
+       if (ap->a_addrtype == hp->h_addrtype && inet (hp, ap->a_net))
+           return NOTOK;
+
+    for (ap = hosts; ap < h1; ap++)
+       if (ap->a_addrtype == hp->h_addrtype
+               && memcmp(ap->a_addr, hp->h_addr, hp->h_length) == 0)
+           return NOTOK;
+
+    if ((sd = getport (rproto, hp->h_addrtype, response, len_response)) == NOTOK)
+       return OOPS2;
+
+    memset (isock, 0, sizeof(*isock));
+    isock->sin_family = hp->h_addrtype;
+    inaddr_copy (hp, isock);
+    isock->sin_port = sp->s_port;
+
+    if (connect (sd, (struct sockaddr *) isock, sizeof(*isock)) == NOTOK)
+       switch (errno) {
+           case ENETDOWN: 
+           case ENETUNREACH: 
+               close (sd);
+               if (n1 < n2) {
+                   n1->a_addrtype = hp->h_addrtype;
+                   memcpy(&in, hp->h_addr, sizeof(in));
+                   n1->a_net = inet_netof (in);
+                   n1++;
+               }
+               return OOPS1;
+
+           case ETIMEDOUT: 
+           case ECONNREFUSED: 
+           default: 
+               close (sd);
+               if (h1 < h2) {
+                   h1->a_addrtype = hp->h_addrtype;
+                   memcpy(h1->a_addr, hp->h_addr, hp->h_length);
+                   h1++;
+               }
+               return NOTOK;
+       }
+
+#ifdef KPOP
+    if (kservice) {    /* "pop" */
+       char *instance;
+
+       if (( hp2 = gethostbyaddr( hp->h_addr, hp->h_length, hp->h_addrtype ))
+               == NULL ) {
+           return NOTOK;
+       }
+       if ((instance = strdup (hp2->h_name)) == NULL) {
+           close (sd);
+           strncpy (response, "Out of memory.", len_response);
+           return OOPS2;
+       }
+       ticket = (KTEXT) malloc (sizeof(KTEXT_ST));
+       rem = krb_sendauth (0L, sd, ticket, kservice, instance,
+                          (char *) krb_realmofhost (instance),
+                          (unsigned long) 0, &msg_data, &cred, schedule,
+                          (struct sockaddr_in *) NULL,
+                          (struct sockaddr_in *) NULL,
+                          "KPOPV0.1");
+       free (instance);
+       if (rem != KSUCCESS) {
+           close (sd);
+           strncpy (response, "Post office refused connection: ", len_response);
+           strncat (response, krb_err_txt[rem], len_response - strlen(response));
+           return OOPS2;
+       }
+    }
+#endif /* KPOP */
+
+    return sd;
+}
+
+
+static int
+getport (int rproto, int addrtype, char *response, int len_response)
+{
+    int sd, port;
+    struct sockaddr_in in_socket, *isock;
+
+    isock = &in_socket;
+    if (rproto && addrtype != AF_INET) {
+       snprintf (response, len_response, "reserved ports not supported for af=%d", addrtype);
+       errno = ENOPROTOOPT;
+       return NOTOK;
+    }
+
+    if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == NOTOK) {
+       char *s;
+
+       if ((s = strerror (errno)))
+           snprintf (response, len_response, "unable to create socket: %s", s);
+       else
+           snprintf (response, len_response, "unable to create socket: unknown error");
+       return NOTOK;
+    }
+#ifdef KPOP
+    if (kservice)      /* "pop" */
+       return(sd);
+#endif /* KPOP */
+    if (!rproto)
+       return sd;
+
+    memset(isock, 0, sizeof(*isock));
+    isock->sin_family = addrtype;
+    for (port = IPPORT_RESERVED - 1;;) {
+       isock->sin_port = htons ((unsigned short) port);
+       if (bind (sd, (struct sockaddr *) isock, sizeof(*isock)) != NOTOK)
+           return sd;
+
+       switch (errno) {
+           char *s;
+
+           case EADDRINUSE: 
+           case EADDRNOTAVAIL: 
+               if (--port <= IPPORT_RESERVED / 2) {
+                   strncpy (response, "ports available", len_response);
+                   return NOTOK;
+               }
+               break;
+
+           default: 
+               if ((s = strerror (errno)))
+                   snprintf (response, len_response, "unable to bind socket: %s", s);
+               else
+                   snprintf (response, len_response, "unable to bind socket: unknown error");
+               return NOTOK;
+       }
+    }
+}
+
+
+static int
+inet (struct hostent *hp, int net)
+{
+    struct in_addr in;
+
+    memcpy(&in, hp->h_addr, sizeof(in));
+    return (inet_netof (in) == net);
+}
+
+
+/*
+ * taken from ISODE's compat/internet.c
+ */
+
+static char *empty = NULL;
+
+#ifdef h_addr
+static char *addrs[2] = { NULL };
+#endif
+
+struct hostent *
+gethostbystring (char *s)
+{
+    register struct hostent *h;
+    static struct hostent hs;
+#ifdef DG
+    static struct in_addr iaddr;
+#else
+    static unsigned long iaddr;
+#endif
+
+    iaddr = inet_addr (s);
+#ifdef DG
+    if (iaddr.s_addr == NOTOK && strcmp (s, "255.255.255.255"))
+#else
+    if (((int) iaddr == NOTOK) && strcmp (s, "255.255.255.255"))
+#endif
+       return gethostbyname (s);
+
+    h = &hs;
+    h->h_name = s;
+    h->h_aliases = &empty;
+    h->h_addrtype = AF_INET;
+    h->h_length = sizeof(iaddr);
+#ifdef h_addr
+    h->h_addr_list = addrs;
+    memset(addrs, 0, sizeof(addrs));
+#endif
+    h->h_addr = (char *) &iaddr;
+
+    return h;
+}
+
+
+/*
+ * static copies of three nmh subroutines
+ */
+
+static char *broken[MAXARGS + 1];
+
+static char **
+client_brkstring (char *strg, char *brksep, char *brkterm)
+{
+    register int bi;
+    register char c, *sp;
+
+    sp = strg;
+
+    for (bi = 0; bi < MAXARGS; bi++) {
+       while (client_brkany (c = *sp, brksep))
+           *sp++ = 0;
+       if (!c || client_brkany (c, brkterm)) {
+           *sp = 0;
+           broken[bi] = 0;
+           return broken;
+       }
+
+       broken[bi] = sp;
+       while ((c = *++sp) && !client_brkany (c, brksep) && !client_brkany (c, brkterm))
+           continue;
+    }
+    broken[MAXARGS] = 0;
+
+    return broken;
+}
+
+
+/*
+ * returns 1 if chr in strg, 0 otherwise
+ */
+static int
+client_brkany (char chr, char *strg)
+{
+    register char *sp;
+    if (strg)
+       for (sp = strg; *sp; sp++)
+           if (chr == *sp)
+               return 1;
+    return 0;
+}
+
+
+/*
+ * copy a string array and return pointer to end
+ */
+static char **
+client_copyip (char **p, char **q, int len_q)
+{
+    while (*p && --len_q > 0)
+       *q++ = *p++;
+
+    *q = NULL;
+
+    return q;
+}
+
+
+static char *
+client_getcpy (char *str)
+{
+    char *cp;
+    size_t len;
+
+    len = strlen(str) + 1;
+    if (!(cp = malloc(len)))
+       return NULL;
+
+    memcpy (cp, str, len);
+    return cp;
+}
+
diff --git a/mts/generic/mts.c b/mts/generic/mts.c
new file mode 100644 (file)
index 0000000..7d9b718
--- /dev/null
@@ -0,0 +1,523 @@
+
+/*
+ * mts.c -- definitions for the mail transport system
+ *
+ * $Id$
+ */
+
+#include "h/mh.h"   /* for snprintf() */
+#include <h/nmh.h>
+
+#define nmhetcdir(file) NMHETCDIR#file
+
+#include <ctype.h>
+#include <stdio.h>
+#include <mts.h>
+#include <pwd.h>
+#include <netdb.h>
+
+#ifdef HAVE_SYS_UTSNAME_H
+# include <sys/utsname.h>
+#endif
+
+#define        NOTOK   (-1)
+#define        OK        0
+
+extern int errno;
+
+/*
+ * static prototypes
+ */
+static char *tailor_value (char *);
+static void getuserinfo (void);
+
+/*
+ * *mmdfldir and *uucpldir are the maildrop directories.  If maildrops
+ * are kept in the user's home directory, then these should be empty
+ * strings.  In this case, the appropriate ...lfil array should contain
+ * the name of the file in the user's home directory.  Usually, this is
+ * something like ".mail".
+ */
+
+/*
+ * nmh mail transport interface customization file
+ */
+static char *mtsconf = nmhetcdir(/mts.conf);
+
+static char *localname   = "";
+static char *localdomain = "";
+static char *systemname  = "";
+
+char *mmdfldir = MAILSPOOL;
+char *mmdflfil = "";
+char *uucpldir = "/usr/spool/mail";
+char *uucplfil = "";
+
+char *mmdlm1 = "\001\001\001\001\n";
+char *mmdlm2 = "\001\001\001\001\n";
+
+/* Cache the username and fullname of the user */
+static char username[BUFSIZ];
+static char fullname[BUFSIZ];
+
+/* Variables for username masquerading: */
+       boolean  draft_from_masquerading = FALSE;  /* also used from post.c */
+static boolean  mmailid_masquerading = FALSE;
+       boolean  username_extension_masquerading = FALSE;  /* " from addrsbr.c */
+static char*    masquerade = "";
+
+/*
+ * MTS specific variables
+ */
+#if defined(SMTPMTS)
+static char *sm_method = "smtp";
+int  sm_mts    = MTS_SMTP;
+char *hostable = nmhetcdir(/hosts);
+char *sendmail = SENDMAILPATH;
+#endif
+
+/*
+ * SMTP/POP stuff
+ */
+char *clientname = NULL;
+char *servers    = "localhost \01localnet";
+char *pophost    = "";
+
+/*
+ * BBoards-specific variables
+ */
+char *bb_domain = "";
+
+
+/*
+ * POP BBoards-specific variables
+ */
+#ifdef BPOP
+char *popbbhost = "";
+char *popbbuser = "";
+char *popbblist = nmhetcdir(/hosts.popbb);
+#endif /* BPOP */
+
+/*
+ * Global MailDelivery file
+ */
+char *maildelivery = nmhetcdir(/maildelivery);
+
+
+/*
+ * Aliasing Facility (doesn't belong here)
+ */
+int Everyone = NOTOK;
+static char *everyone = "-1";
+char *NoShell = "";
+
+/*
+ * Customize the MTS settings for nmh by adjusting
+ * the file mts.conf in the nmh etc directory.
+ */
+
+struct bind {
+    char *keyword;
+    char **value;
+};
+
+static struct bind binds[] = {
+    { "localname", &localname },
+    { "localdomain", &localdomain },
+    { "systemname", &systemname },
+    { "mmdfldir", &mmdfldir },
+    { "mmdflfil", &mmdflfil },
+    { "uucpldir", &uucpldir },
+    { "uucplfil", &uucplfil },
+    { "mmdelim1", &mmdlm1 },
+    { "mmdelim2", &mmdlm2 },
+    { "masquerade", &masquerade },
+
+#if defined(SMTPMTS)
+    { "mts",      &sm_method },
+    { "hostable", &hostable  },
+    { "sendmail", &sendmail  },
+#endif
+
+    { "clientname",  &clientname },
+    { "servers", &servers },
+    { "pophost", &pophost },
+    { "bbdomain", &bb_domain },
+
+#ifdef BPOP
+    { "popbbhost", &popbbhost },
+    { "popbbuser", &popbbuser },
+    { "popbblist", &popbblist },
+#endif
+
+#ifdef NNTP
+    { "nntphost", &popbbhost },
+#endif
+
+    { "maildelivery", &maildelivery },
+    { "everyone", &everyone },
+    { "noshell", &NoShell },
+    { NULL, NULL }
+};
+
+
+/*
+ * Read the configuration file for the nmh interface
+ * to the mail transport system (MTS).
+ */
+
+void
+mts_init (char *name)
+{
+    char *bp, *cp, buffer[BUFSIZ];
+    struct bind *b;
+    FILE *fp;
+    static int inited = 0;
+
+    if (inited++ || (fp = fopen (mtsconf, "r")) == NULL)
+       return;
+
+    while (fgets (buffer, sizeof(buffer), fp)) {
+       if (!(cp = strchr(buffer, '\n')))
+           break;
+       *cp = 0;
+       if (*buffer == '#' || *buffer == '\0')
+           continue;
+       if (!(bp = strchr(buffer, ':')))
+           break;
+       *bp++ = 0;
+       while (isspace (*bp))
+           *bp++ = 0;
+
+       for (b = binds; b->keyword; b++)
+           if (!strcmp (buffer, b->keyword))
+               break;
+       if (b->keyword && (cp = tailor_value (bp)))
+           *b->value = cp;
+    }
+
+    fclose (fp);
+
+    Everyone = atoi (everyone);
+
+    if (strstr(masquerade, "draft_from") != NULL)
+       draft_from_masquerading = TRUE;
+
+    if (strstr(masquerade, "mmailid") != NULL)
+       mmailid_masquerading = TRUE;
+
+    if (strstr(masquerade, "username_extension") != NULL)
+       username_extension_masquerading = TRUE;
+
+#ifdef SMTPMTS
+    if (strcmp(sm_method, "smtp") == 0)
+        sm_mts = MTS_SMTP;
+    else if (strcmp(sm_method, "sendmail") == 0)
+        sm_mts = MTS_SENDMAIL;
+    else {
+        advise(NULL, "unsupported \"mts\" value in mts.conf: %s", sm_method);
+        sm_mts = MTS_SMTP;
+    }
+#endif
+}
+
+
+#define        QUOTE   '\\'
+
+/*
+ * Convert escaped values, malloc some new space,
+ * and copy string to malloc'ed memory.
+ */
+
+static char *
+tailor_value (char *s)
+{
+    int i, r;
+    char *bp;
+    char buffer[BUFSIZ];
+    size_t len;
+
+    for (bp = buffer; *s; bp++, s++) {
+       if (*s != QUOTE) {
+           *bp = *s;
+       } else {
+           switch (*++s) {
+               case 'b': *bp = '\b'; break;
+               case 'f': *bp = '\f'; break;
+               case 'n': *bp = '\n'; break;
+               case 't': *bp = '\t'; break;
+
+               case 0: s--;
+               case QUOTE: 
+                   *bp = QUOTE;
+                   break;
+
+               default: 
+                   if (!isdigit (*s)) {
+                       *bp++ = QUOTE;
+                       *bp = *s;
+                   }
+                   r = *s != '0' ? 10 : 8;
+                   for (i = 0; isdigit (*s); s++)
+                       i = i * r + *s - '0';
+                   s--;
+                   *bp = toascii (i);
+                   break;
+           }
+       }
+    }
+    *bp = 0;
+
+    len = strlen (buffer) + 1;
+    if ((bp = malloc (len)))
+       memcpy (bp, buffer, len);
+
+    return bp;
+}
+
+/*
+ * Get the fully qualified name of the local host.
+ */
+
+char *
+LocalName (void)
+{
+    static char buffer[BUFSIZ] = "";
+    struct hostent *hp;
+
+#ifdef HAVE_UNAME
+    struct utsname name;
+#endif
+
+    /* check if we have cached the local name */
+    if (buffer[0])
+       return buffer;
+
+    mts_init ("mts");
+
+    /* check if the mts.conf file specifies a "localname" */
+    if (*localname) {
+       strncpy (buffer, localname, sizeof(buffer));
+    } else {
+#ifdef HAVE_UNAME
+       /* first get our local name */
+       uname (&name);
+       strncpy (buffer, name.nodename, sizeof(buffer));
+#else
+       /* first get our local name */
+       gethostname (buffer, sizeof(buffer));
+#endif
+#ifdef HAVE_SETHOSTENT
+       sethostent (1);
+#endif 
+       /* now fully qualify our name */
+       if ((hp = gethostbyname (buffer)))
+           strncpy (buffer, hp->h_name, sizeof(buffer));
+    }
+
+    /*
+     * If the mts.conf file specifies a "localdomain",
+     * we append that now.  This should rarely be needed.
+     */
+    if (*localdomain) {
+       strcat (buffer, ".");
+       strcat (buffer, localdomain);
+    }
+
+    return buffer;
+}
+
+
+/*
+ * This is only for UUCP mail.  It gets the hostname
+ * as part of the UUCP "domain".
+ */
+
+char *
+SystemName (void)
+{
+    static char buffer[BUFSIZ] = "";
+
+#ifdef HAVE_UNAME
+    struct utsname name;
+#endif
+
+    /* check if we have cached the system name */
+    if (buffer[0])
+       return buffer;
+
+    mts_init ("mts");
+
+    /* check if mts.conf file specifies a "systemname" */
+    if (*systemname) {
+       strncpy (buffer, systemname, sizeof(buffer));
+       return buffer;
+    }
+
+#ifdef HAVE_UNAME
+    uname (&name);
+    strncpy (buffer, name.nodename, sizeof(buffer));
+#else
+    gethostname (buffer, sizeof(buffer));
+#endif
+
+    return buffer;
+}
+
+
+/*
+ * Get the username of current user
+ */
+
+char *
+getusername (void)
+{
+    if (username[0] == '\0')
+       getuserinfo();
+
+    return username;
+}
+
+
+/*
+ * Get full name of current user (typically from GECOS
+ * field of password file).
+ */
+
+char *
+getfullname (void)
+{
+    if (username[0] == '\0')
+       getuserinfo();
+
+    return fullname;
+}
+
+
+/*
+ * Find the user's username and full name, and cache them.
+ * Also, handle "mmailid" username masquerading controlled from the GECOS field
+ * of the passwd file. 
+ */
+
+static void
+getuserinfo (void)
+{
+    register char *cp, *np;
+    register struct passwd *pw;
+
+#ifdef KPOP
+    uid_t uid;
+
+    uid = getuid ();
+    if (uid == geteuid () && (cp = getenv ("USER")) != NULL
+       && (pw = getpwnam (cp)) != NULL)
+      strncpy (username, cp, sizeof(username));
+    else if ((pw = getpwuid (uid)) == NULL
+            || pw->pw_name == NULL
+            || *pw->pw_name == '\0') {
+#else /* KPOP */
+    if ((pw = getpwuid (getuid ())) == NULL
+           || pw->pw_name == NULL
+           || *pw->pw_name == '\0') {
+#endif /* KPOP */
+       strncpy (username, "unknown", sizeof(username));
+       snprintf (fullname, sizeof(fullname), "The Unknown User-ID (%d)",
+               (int) getuid ());
+       return;
+    }
+
+    np = pw->pw_gecos;
+
+    /* Get the user's real name from the GECOS field.  Stop once we hit a ',',
+       which some OSes use to separate other 'finger' information in the GECOS
+       field, like phone number.  Also, if mmailid masquerading is turned on due
+       to "mmailid" appearing on the "masquerade:" line of mts.conf, stop if we
+       hit a '<' (which should precede any ','s). */
+#ifndef BSD42
+    if (mmailid_masquerading)
+       /* Stop at ',' or '<'. */
+       for (cp = fullname; *np != '\0' && *np != ',' && *np != '<';
+            *cp++ = *np++)
+           continue;
+    else
+       /* Allow '<' as a legal character of the user's name.  This code is
+          basically a duplicate of the code above the "else" -- we don't
+          collapse it down to one copy and put the mmailid_masquerading check
+          inside the loop with "(x ? y : z)" because that's inefficient and the
+          value'll never change while it's in there. */
+       for (cp = fullname; *np != '\0' && *np != ',';
+            *cp++ = *np++)
+           continue;
+#else /* BSD42 */
+    /* On BSD(-derived) systems, the system utilities that deal with the GECOS
+       field (finger, mail, sendmail, etc.) translate any '&' character in it to
+       the login name, with the first letter capitalized.  So, for instance,
+       fingering a user "bob" with the GECOS field "& Jones" would reveal him to
+       be "In real life: Bob Jones".  Surprisingly, though, the OS doesn't do
+       the translation for you, so we have to do it manually here. */
+    if (mmailid_masquerading)
+       /* Stop at ',' or '<'. */
+       for (cp = fullname;
+            *np != '\0' && *np != ',' && *np != '<';) {
+           if (*np == '&')     {       /* blech! */
+               strcpy (cp, pw->pw_name);
+               *cp = toupper(*cp);
+               while (*cp)
+                   cp++;
+               np++;
+           } else {
+               *cp++ = *np++;
+           }
+       }
+    else
+       /* Allow '<' as a legal character of the user's name.  This code is
+          basically a duplicate of the code above the "else" -- we don't
+          collapse it down to one copy and put the mmailid_masquerading check
+          inside the loop with "(x ? y : z)" because that's inefficient and the
+          value'll never change while it's in there. */
+       for (cp = fullname;
+            *np != '\0' && *np != ',';) {
+           if (*np == '&')     {       /* blech! */
+               strcpy (cp, pw->pw_name);
+               *cp = toupper(*cp);
+               while (*cp)
+                   cp++;
+               np++;
+           } else {
+               *cp++ = *np++;
+           }
+       }
+#endif /* BSD42 */
+    *cp = '\0';
+
+    if (mmailid_masquerading) {
+       /* Do mmailid processing.  The GECOS field should have the form
+          "Full Name <fakeusername>".  For instance,
+          "Dan Harkless <Dan.Harkless>".  Naturally, you'll want your MTA to
+          have an alias (e.g. in /etc/aliases) from "fakeusername" to your
+          account name.  */ 
+       if (*np)
+           np++;
+       for (cp = username; *np && *np != '>'; *cp++ = *np++)
+           continue;
+       *cp = '\0';
+    }
+    if (!mmailid_masquerading || *np == '\0')
+       strncpy (username, pw->pw_name, sizeof(username));
+
+    /* The $SIGNATURE environment variable overrides the GECOS field's idea of
+       your real name. */
+    if ((cp = getenv ("SIGNATURE")) && *cp)
+       strncpy (fullname, cp, sizeof(fullname));
+
+    if (strchr(fullname, '.')) {               /*  quote any .'s */
+       char tmp[BUFSIZ];
+
+       /* should quote "'s too */
+       snprintf (tmp, sizeof(tmp), "\"%s\"", fullname);
+       strncpy (fullname, tmp, sizeof(fullname));
+    }
+
+    return;
+}
diff --git a/mts/generic/mts.h b/mts/generic/mts.h
new file mode 100644 (file)
index 0000000..ce063d9
--- /dev/null
@@ -0,0 +1,88 @@
+
+/*
+ * mts.h -- definitions for the mail system
+ *
+ * $Id$
+ */
+
+/*
+ * Local and UUCP Host Name
+ */
+char *LocalName(void);
+char *SystemName(void);
+
+/*
+ * Mailboxes
+ */
+extern char *mmdfldir;
+extern char *mmdflfil;
+extern char *uucpldir;
+extern char *uucplfil;
+
+#define        MAILDIR (mmdfldir && *mmdfldir ? mmdfldir : getenv ("HOME"))
+#define        MAILFIL (mmdflfil && *mmdflfil ? mmdflfil : getusername ())
+#define        UUCPDIR (uucpldir && *uucpldir ? uucpldir : getenv ("HOME"))
+#define        UUCPFIL (uucplfil && *uucplfil ? uucplfil : getusername ())
+
+char *getusername(void);
+char *getfullname(void);
+
+/*
+ * Separators
+ */
+extern char *mmdlm1;
+extern char *mmdlm2;
+
+#define        isdlm1(s) (strcmp (s, mmdlm1) == 0)
+#define        isdlm2(s) (strcmp (s, mmdlm2) == 0)
+
+/*
+ * Read mts.conf file
+ */
+void mts_init (char *);
+
+/*
+ * MTS specific variables
+ */
+#if defined (SMTPMTS)
+
+/* whether to speak SMTP to localhost:25 or to /usr/sbin/sendmail */
+#define MTS_SMTP     0
+#define MTS_SENDMAIL 1
+extern int sm_mts;
+
+extern char *hostable;
+extern char *sendmail;
+#endif
+
+/*
+ * SMTP/POP stuff
+ */
+extern char *clientname;
+extern char *servers;
+extern char *pophost;
+
+/*
+ * BBoards-specific variables
+ */
+extern char *bb_domain;
+
+/*
+ * POP BBoards-specific variables
+ */
+#ifdef BPOP
+extern char *popbbhost;
+extern char *popbbuser;
+extern char *popbblist;
+#endif /* BPOP */
+
+/*
+ * Global MailDelivery File
+ */
+extern char *maildelivery;
+
+/*
+ * Aliasing Facility (doesn't belong here)
+ */
+extern int Everyone;
+extern char *NoShell;
index 748d8d6..a6d3139 100644 (file)
@@ -14,7 +14,7 @@
 # include "dm.h"
 #endif /* MMDFII */
 
-#include "../../zotnet/mts.h"
+#include <mts/generic/mts.h>
 
 /* 
  * We really should be careful with the number of fd's that this routine
index 83727d5..40697ce 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 #include <h/mh.h>
-#include <zotnet/mts/mts.h>
+#include <mts/generic/mts.h>
 #include <netdb.h>
 
 static struct host {
index 9a9c725..00fe825 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <h/mh.h>
 #include <mts/smtp/smtp.h>
-#include <zotnet/mts/mts.h>
+#include <mts/generic/mts.h>
 #include <signal.h>
 #include "h/signals.h"  /* for SIGNAL() */
 #ifdef MPOP
index 4a726b9..341f0b1 100644 (file)
@@ -21,12 +21,6 @@ CFLAGS   = @CFLAGS@
 DEFS     = @DEFS@
 SASL_INCLUDES = @SASL_INCLUDES@
 INCLUDES = -I../.. -I$(srcdir) -I$(top_srcdir) $(SASL_INCLUDES)
-
-LORDER  = @LORDER@
-TSORT   = @TSORT@
-RANLIB  = @RANLIB@
-LIBTOOL = @LIBTOOL@
-GNU_LIBTOOL = @GNU_LIBTOOL@
 LINT   = @LINT@
 LINTFLAGS = @LINTFLAGS@
 
@@ -55,16 +49,7 @@ DIST = $(HDRS) $(SRCS) $(AUX)
 
 # ========= DEPENDENCIES FOR BUILDING AND INSTALLING ==========
 
-all: libsmtp.a
-
-libsmtp.a: $(OBJS)
-       rm -f $@
-       if test x$(LIBTOOL) != x -a x$(GNU_LIBTOOL) = x ; then \
-         $(LIBTOOL) -static -c $(OBJS) -o $@  ; \
-       else \
-         ar cr $@ `$(LORDER) $(OBJS) | $(TSORT)`  ; \
-         $(RANLIB) $@  ; \
-       fi 
+all: $(OBJS)
 
 install:
 
@@ -76,7 +61,6 @@ mostlyclean:
        rm -f *.o *~
 
 clean: mostlyclean
-       rm -f libsmtp.a
 
 distclean: clean
        rm -f Makefile
index 83727d5..40697ce 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 #include <h/mh.h>
-#include <zotnet/mts/mts.h>
+#include <mts/generic/mts.h>
 #include <netdb.h>
 
 static struct host {
index f2390b8..e596680 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <h/mh.h>
 #include "smtp.h"
-#include <zotnet/mts/mts.h>
+#include <mts/generic/mts.h>
 #include <signal.h>
 #include <h/signals.h>
 #ifdef MPOP
@@ -150,7 +150,7 @@ char **smail_copyip (char **, char **, int);
 static int sm_auth_sasl(char *, char *, char *);
 #endif /* CYRUS_SASL */
 
-/* from zotnet/mts/client.c */
+/* from mts/generic/client.c */
 int client (char *, char *, char *, int, char *, int);
 
 int