From dee387b53ab0d42922f857b60d6f980c9e79d16f Mon Sep 17 00:00:00 2001 From: Shantonu Sen Date: Thu, 14 Dec 2000 01:30:43 +0000 Subject: [PATCH] Resolve the circular dependency of libmh on libmts on libmh. The files mts/generic/client.c and mts.c are moved to sbr/, and mts/generic/mts.h is moved to h/mts.h. Thus, libmh is self-contained. All header includes have been appropriately updated, and the Makefiles and configure script no longer build mts/generic. --- configure | 4 +- configure.in | 2 +- h/Makefile.in | 8 +- h/mts.h | 88 +++++++++ mts/Makefile.in | 4 +- mts/smtp/hosts.c | 2 +- mts/smtp/smtp.c | 2 +- sbr/Makefile.in | 24 ++- sbr/client.c | 479 +++++++++++++++++++++++++++++++++++++++++++++++++ sbr/m_getfld.c | 2 +- sbr/mts.c | 523 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ stamp-h.in | 2 +- uip/ali.c | 2 +- uip/ap.c | 2 +- uip/conflict.c | 2 +- uip/dropsbr.c | 2 +- uip/inc.c | 2 +- uip/mhbuild.c | 2 +- uip/mhbuildsbr.c | 2 +- uip/mhcachesbr.c | 2 +- uip/mhlist.c | 2 +- uip/mhlistsbr.c | 2 +- uip/mhn.c | 2 +- uip/mhoutsbr.c | 2 +- uip/mhparse.c | 2 +- uip/mhshow.c | 2 +- uip/mhshowsbr.c | 2 +- uip/mhstore.c | 2 +- uip/mhstoresbr.c | 2 +- uip/mhtest.c | 2 +- uip/msgchk.c | 2 +- uip/msh.c | 2 +- uip/mshcmds.c | 2 +- uip/popi.c | 4 +- uip/post.c | 2 +- uip/rcvdist.c | 2 +- uip/rcvpack.c | 2 +- uip/rcvstore.c | 2 +- uip/rcvtty.c | 2 +- uip/scan.c | 2 +- uip/slocal.c | 2 +- uip/spost.c | 2 +- uip/viamail.c | 2 +- 43 files changed, 1157 insertions(+), 47 deletions(-) create mode 100644 h/mts.h create mode 100644 sbr/client.c create mode 100644 sbr/mts.c diff --git a/configure b/configure index 757e8d1..b74bba2 100755 --- a/configure +++ b/configure @@ -4763,7 +4763,7 @@ ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "Makefile config/Makefile h/Makefile sbr/Makefile uip/Makefile \ - mts/generic/Makefile mts/Makefile mts/smtp/Makefile \ + mts/Makefile mts/smtp/Makefile \ etc/Makefile docs/Makefile man/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF diff --git a/configure.in b/configure.in index 2958b79..8c43c76 100644 --- a/configure.in +++ b/configure.in @@ -779,7 +779,7 @@ dnl ---------------- dnl OUTPUT MAKEFILES dnl ---------------- AC_OUTPUT(Makefile config/Makefile h/Makefile sbr/Makefile uip/Makefile \ - mts/generic/Makefile mts/Makefile mts/smtp/Makefile \ + mts/Makefile mts/smtp/Makefile \ etc/Makefile docs/Makefile man/Makefile, \ [test -z "$CONFIG_HEADERS" || echo > stamp-h]) diff --git a/h/Makefile.in b/h/Makefile.in index 6a5844f..6cf88b6 100644 --- a/h/Makefile.in +++ b/h/Makefile.in @@ -10,10 +10,10 @@ srcdir = @srcdir@ VPATH = @srcdir@ # header files included in distribution -HDRS = addrsbr.h aliasbr.h dropsbr.h fmt_compile.h fmt_scan.h \ - md5.h mf.h mh.h mhcachesbr.h mhparse.h mime.h msh.h netdb.h nmh.h \ - nntp.h picksbr.h popsbr.h prototypes.h rcvmail.h scansbr.h \ - signals.h tws.h vmhsbr.h +HDRS = addrsbr.h aliasbr.h dropsbr.h fmt_compile.h fmt_scan.h \ + md5.h mf.h mh.h mhcachesbr.h mhparse.h mime.h msh.h mts.h \ + netdb.h nmh.h nntp.h picksbr.h popsbr.h prototypes.h rcvmail.h \ + scansbr.h signals.h tws.h vmhsbr.h # auxiliary files AUX = Makefile.in diff --git a/h/mts.h b/h/mts.h new file mode 100644 index 0000000..ce063d9 --- /dev/null +++ b/h/mts.h @@ -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; diff --git a/mts/Makefile.in b/mts/Makefile.in index 08b4754..c72f350 100644 --- a/mts/Makefile.in +++ b/mts/Makefile.in @@ -24,7 +24,7 @@ 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 +OBJS = smtp/hosts.o smtp/smtp.o # auxiliary files AUX = Makefile.in @@ -33,7 +33,7 @@ AUX = Makefile.in DIST = $(AUX) # subdirectories -SUBDIRS = smtp generic +SUBDIRS = smtp # mail transport agent we are using (currently always smtp) # MTS = smtp diff --git a/mts/smtp/hosts.c b/mts/smtp/hosts.c index 40697ce..4b3d606 100644 --- a/mts/smtp/hosts.c +++ b/mts/smtp/hosts.c @@ -13,7 +13,7 @@ */ #include -#include +#include #include static struct host { diff --git a/mts/smtp/smtp.c b/mts/smtp/smtp.c index e596680..6de440f 100644 --- a/mts/smtp/smtp.c +++ b/mts/smtp/smtp.c @@ -6,7 +6,7 @@ #include #include "smtp.h" -#include +#include #include #include #ifdef MPOP diff --git a/sbr/Makefile.in b/sbr/Makefile.in index 7ca5554..882094e 100644 --- a/sbr/Makefile.in +++ b/sbr/Makefile.in @@ -10,9 +10,18 @@ top_srcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +libdir = @libdir@ +etcdir = @sysconfdir@ + CC = @CC@ CFLAGS = @CFLAGS@ DEFS = @DEFS@ +KRB4_INCLUDES = @KRB4_INCLUDES@ # for mts +HESIOD_INCLUDES = @HESIOD_INCLUDES@ # for mts +CONFIGDEFS = -DNMHETCDIR='"$(etcdir)"' -DMAILSPOOL='"$(mailspool)"' -DSENDMAILPATH='"$(sendmailpath)"' INCLUDES = -I.. -I. -I$(top_srcdir) LEX = @LEX@ @@ -25,8 +34,13 @@ GNU_LIBTOOL = @GNU_LIBTOOL@ LINT = @LINT@ LINTFLAGS = @LINTFLAGS@ +mailspool = @mailspool@ +sendmailpath = @sendmailpath@ COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CFLAGS) +COMPILE2 = $(CC) -c $(DEFS) $(CONFIGDEFS) $(INCLUDES) $(KRB4_INCLUDES) $(HESIOD_INCLUDES) $(CFLAGS) + + .SUFFIXES: .SUFFIXES: .c .o @@ -39,7 +53,7 @@ SIGNAL_H = @SIGNAL_H@ # source for library functions SRCS = add.c addrsbr.c ambigsw.c atooi.c brkstring.c \ - check_charset.c closefds.c concat.c context_del.c \ + check_charset.c client.c closefds.c concat.c context_del.c \ context_find.c context_foil.c context_read.c \ context_replace.c context_save.c copy.c \ copyip.c cpydata.c cpydgst.c discard.c done.c dtime.c dtimep.c \ @@ -51,7 +65,7 @@ SRCS = add.c addrsbr.c ambigsw.c atooi.c brkstring.c \ fmt_scan.c lock_file.c m_atoi.c m_backup.c \ m_convert.c m_draft.c m_getfld.c m_gmprot.c \ m_maildir.c m_name.c m_scratch.c m_tmpfil.c \ - makedir.c path.c peekc.c pidwait.c pidstatus.c \ + makedir.c mts.c path.c peekc.c pidwait.c pidstatus.c \ print_help.c print_sw.c print_version.c push.c \ putenv.c pwd.c refile.c remdir.c r1bindex.c \ readconfig.c ruserpass.c seq_add.c seq_bits.c \ @@ -87,6 +101,12 @@ lint: sigmsg.h dtimep.c: dtimep.lex $(LEX) -nt $< > $@ +client.o: client.c + $(COMPILE2) $< + +mts.o: mts.c + $(COMPILE2) $< + pidstatus.o: sigmsg.h libmh.a: $(OBJS) diff --git a/sbr/client.c b/sbr/client.c new file mode 100644 index 0000000..eb2ffd5 --- /dev/null +++ b/sbr/client.c @@ -0,0 +1,479 @@ + +/* + * client.c -- connect to a server + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_ARPA_INET_H +# include +#endif + +#ifdef HESIOD +# include +#endif + +#ifdef KPOP +# include +# include +#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 = ∅ + 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/sbr/m_getfld.c b/sbr/m_getfld.c index f62d0e8..8a18e78 100644 --- a/sbr/m_getfld.c +++ b/sbr/m_getfld.c @@ -6,7 +6,7 @@ */ #include -#include +#include /* This module has a long and checkered history. First, it didn't burst maildrops correctly because it considered two CTRL-A:s in a row to be diff --git a/sbr/mts.c b/sbr/mts.c new file mode 100644 index 0000000..551fd1f --- /dev/null +++ b/sbr/mts.c @@ -0,0 +1,523 @@ + +/* + * mts.c -- definitions for the mail transport system + * + * $Id$ + */ + +#include /* for snprintf() */ +#include + +#define nmhetcdir(file) NMHETCDIR#file + +#include +#include +#include +#include +#include + +#ifdef HAVE_SYS_UTSNAME_H +# include +#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 ". For instance, + "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/stamp-h.in b/stamp-h.in index ef8e1b4..511d101 100644 --- a/stamp-h.in +++ b/stamp-h.in @@ -1 +1 @@ -Thu Sep 7 20:37:09 EDT 2000 +Wed Dec 13 20:00:24 EST 2000 diff --git a/uip/ali.c b/uip/ali.c index 67e7aee..7cffc50 100644 --- a/uip/ali.c +++ b/uip/ali.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include /* * maximum number of names diff --git a/uip/ap.c b/uip/ap.c index 5184baf..843ece4 100644 --- a/uip/ap.c +++ b/uip/ap.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #define NADDRS 100 diff --git a/uip/conflict.c b/uip/conflict.c index c0ba63b..dde0602 100644 --- a/uip/conflict.c +++ b/uip/conflict.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include diff --git a/uip/dropsbr.c b/uip/dropsbr.c index 3c5fdd5..45d5c28 100644 --- a/uip/dropsbr.c +++ b/uip/dropsbr.c @@ -10,7 +10,7 @@ #ifndef MMDFONLY # include # include -# include +# include # include #else # include "dropsbr.h" diff --git a/uip/inc.c b/uip/inc.c index 3ea3b9e..7475d5e 100644 --- a/uip/inc.c +++ b/uip/inc.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include diff --git a/uip/mhbuild.c b/uip/mhbuild.c index 63204a5..0822788 100644 --- a/uip/mhbuild.c +++ b/uip/mhbuild.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/uip/mhbuildsbr.c b/uip/mhbuildsbr.c index 4a6a986..ed330e3 100644 --- a/uip/mhbuildsbr.c +++ b/uip/mhbuildsbr.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/uip/mhcachesbr.c b/uip/mhcachesbr.c index 0be30c0..712ec04 100644 --- a/uip/mhcachesbr.c +++ b/uip/mhcachesbr.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/uip/mhlist.c b/uip/mhlist.c index 57b18b2..856bfc5 100644 --- a/uip/mhlist.c +++ b/uip/mhlist.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/uip/mhlistsbr.c b/uip/mhlistsbr.c index 42e0b05..2a91eac 100644 --- a/uip/mhlistsbr.c +++ b/uip/mhlistsbr.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/uip/mhn.c b/uip/mhn.c index 11c0276..601ce5f 100644 --- a/uip/mhn.c +++ b/uip/mhn.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/uip/mhoutsbr.c b/uip/mhoutsbr.c index f292ddc..5ed9b97 100644 --- a/uip/mhoutsbr.c +++ b/uip/mhoutsbr.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/uip/mhparse.c b/uip/mhparse.c index 8f4d574..2511f85 100644 --- a/uip/mhparse.c +++ b/uip/mhparse.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/uip/mhshow.c b/uip/mhshow.c index 74a8f54..abb399c 100644 --- a/uip/mhshow.c +++ b/uip/mhshow.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/uip/mhshowsbr.c b/uip/mhshowsbr.c index 83616a2..4899939 100644 --- a/uip/mhshowsbr.c +++ b/uip/mhshowsbr.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/uip/mhstore.c b/uip/mhstore.c index b56a505..2de12bc 100644 --- a/uip/mhstore.c +++ b/uip/mhstore.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/uip/mhstoresbr.c b/uip/mhstoresbr.c index f1b0162..9f840dd 100644 --- a/uip/mhstoresbr.c +++ b/uip/mhstoresbr.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/uip/mhtest.c b/uip/mhtest.c index 90f7337..f10216f 100644 --- a/uip/mhtest.c +++ b/uip/mhtest.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/uip/msgchk.c b/uip/msgchk.c index 9489ef0..3616ea8 100644 --- a/uip/msgchk.c +++ b/uip/msgchk.c @@ -6,7 +6,7 @@ */ #include -#include +#include #include #include diff --git a/uip/msh.c b/uip/msh.c index 0db7905..2eda3b2 100644 --- a/uip/msh.c +++ b/uip/msh.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #ifdef HAVE_TERMIOS_H # include diff --git a/uip/mshcmds.c b/uip/mshcmds.c index b8c7d92..d2d0ad7 100644 --- a/uip/mshcmds.c +++ b/uip/mshcmds.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/uip/popi.c b/uip/popi.c index 2fae381..1dc74a3 100644 --- a/uip/popi.c +++ b/uip/popi.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #ifndef RPOP @@ -515,7 +515,7 @@ msh (void) #ifdef SMTPMTS -#include +#include #include static int diff --git a/uip/post.c b/uip/post.c index d91e003..37db5f9 100644 --- a/uip/post.c +++ b/uip/post.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include diff --git a/uip/rcvdist.c b/uip/rcvdist.c index 9eb9916..867104a 100644 --- a/uip/rcvdist.c +++ b/uip/rcvdist.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include static struct swit switches[] = { #define FORMSW 0 diff --git a/uip/rcvpack.c b/uip/rcvpack.c index a760177..1e85f80 100644 --- a/uip/rcvpack.c +++ b/uip/rcvpack.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include static struct swit switches[] = { #define MBOXSW 0 diff --git a/uip/rcvstore.c b/uip/rcvstore.c index 8734ebc..726ff9e 100644 --- a/uip/rcvstore.c +++ b/uip/rcvstore.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include static struct swit switches[] = { #define CRETSW 0 diff --git a/uip/rcvtty.c b/uip/rcvtty.c index 32d78d2..cf54134 100644 --- a/uip/rcvtty.c +++ b/uip/rcvtty.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/uip/scan.c b/uip/scan.c index d85d80e..56980e9 100644 --- a/uip/scan.c +++ b/uip/scan.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include /* diff --git a/uip/slocal.c b/uip/slocal.c index 8a3f5f7..ce806dc 100644 --- a/uip/slocal.c +++ b/uip/slocal.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include diff --git a/uip/spost.c b/uip/spost.c index 18d1152..78c300c 100644 --- a/uip/spost.c +++ b/uip/spost.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #define uptolow(c) ((isalpha(c) && isupper (c)) ? tolower (c) : c) diff --git a/uip/viamail.c b/uip/viamail.c index 2168f71..9f79a2e 100644 --- a/uip/viamail.c +++ b/uip/viamail.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include -- 1.7.10.4