Mercurial > hg > Applications > mh
diff zotnet/mts/mts.c @ 0:bce86c4163a3
Initial revision
author | kono |
---|---|
date | Mon, 18 Apr 2005 23:46:02 +0900 |
parents | |
children | a6481689f99c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zotnet/mts/mts.c Mon Apr 18 23:46:02 2005 +0900 @@ -0,0 +1,687 @@ +/* mts.c - definitions for the mail transport system */ +#ifndef lint +static char ident[] = "@(#)$Id$"; +#endif /* lint */ + +/* LINTLIBRARY */ + +#undef NETWORK +#if defined(BSD41A) || defined(BSD42) || defined(SOCKETS) +#define NETWORK +#endif + +#include "../h/strings.h" +#include <ctype.h> +#include <stdio.h> +#include "mts.h" +#ifdef NETWORK +#if defined(BSD42) || defined(SOCKETS) +#include <netdb.h> +#endif +#else /* NETWORK */ +#ifndef SYS5 +#include <whoami.h> +#else +#include <sys/utsname.h> +#endif /* SYS5 */ +#endif /* NETWORK */ +#include <pwd.h> + + +#define NOTOK (-1) +#define OK 0 + +#define NULLCP ((char *) 0) + +#ifdef __CYGWIN32__ +#include <errno.h> +#endif +extern int errno; + +static char *tailor_value (); + + +#if defined(SYS5) && !defined(_AIX) +#define index strchr +#define rindex strrchr +#endif /* SYS5 */ + +#if !defined(__STDC__) && !defined(_AIX) && !defined(_POSIX_SOURCE) +char *index (), *malloc (), *mktemp (), *rindex (), *strcpy (); + +#ifdef SYS5 +struct passwd *getpwuid (); +#endif +#endif /* !__STDC__ */ + +/* */ + +/* + *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". + */ + +static char *mtstailor = "/usr/local/mh/lib/mtstailor"; + +static char *localname = ""; +static char *localdomain = ""; +static char *systemname = ""; +#ifdef MF +static char *UUCPchan = ""; +#endif /* MF */ +char *mmdfldir = "/var/mail"; +char *mmdflfil = ""; +#ifdef MF +char *uucpldir = "/usr/spool/mail"; +#else /* MF */ +char *uucpldir = ""; +#endif /* MF */ +char *uucplfil = ""; + + +char *mmdlm1 = "\001\001\001\001\n"; +char *mmdlm2 = "\001\001\001\001\n"; + + +static int MMailids = 0; +static char *mmailid = "0"; + + +#ifdef MF +char *umincproc = "/usr/local/mh/lib/uminc"; +#else /* MF */ +char *umincproc = NULL; +#endif /* MF */ + + +int lockstyle = LOK_UNIX; +static char *lkstyle = "0"; +char *lockldir = ""; + +/* */ + +/* MTS specific variables */ + +#ifdef MHMTS +char *Mailqdir = "/usr/spool/netmail"; +char *TMailqdir = "/usr/tmp"; +int Syscpy = 1; +static char *syscpy = "1"; +char *Overseer = "root"; +char *Mailer = "root"; +char *Fromtmp = "/tmp/rml.f.XXXXXX"; +char *Msgtmp = "/tmp/rml.m.XXXXXX"; +char *Errtmp = "/tmp/rml.e.XXXXXX"; +int Tmpmode = 0600; +static char *tmpmode = "0600"; +char *Okhosts = "/usr/local/mh/lib/Rmail.OkHosts"; +char *Okdests = "/usr/local/mh/lib/Rmail.OkDests"; +#endif /* MHMTS */ + +#ifdef MMDFMTS +#endif /* MMDFMTS */ + +#ifdef SENDMTS +char *hostable = "/usr/local/mh/lib/hosts"; +char *sendmail = "/usr/sbin/sendmail"; +#endif /* SENDMTS */ + + +/* SMTP/POP stuff */ + +char *clientname = (char *)0; +char *servers = "localhost \01localnet"; +char *pophost = ""; +#ifdef MH_PLUS +char *rpop_default = ""; +#endif /* MH_PLUS */ + + +/* BBoards-specific variables */ + +char *bb_domain = ""; + + +/* POP BBoards-specific variables */ + +#if defined(BPOP) || defined(NNTP) +char *popbbhost = ""; +#endif /* BPOP || NNTP */ +#ifdef BPOP +char *popbbuser = ""; +char *popbblist = "/usr/local/mh/lib/hosts.popbb"; +#endif /* BPOP */ + + +/* MailDelivery */ + +char *maildelivery = "/usr/local/mh/lib/maildelivery"; + + +/* Aliasing Facility (doesn't belong here) */ + +int Everyone = NOTOK; +static char *everyone = "-1"; +char *NoShell = ""; + +#ifdef MH_PLUS +int LocalUser = 0; +static char *localuser = "0"; +#endif /* MH_PLUS */ + +/* */ + +/* customize the MTS settings for MH by reading /usr/local/mh/lib/mtstailor */ + +static struct bind { + char *keyword; + char **value; +} binds[] = { + "localname", &localname, + "localdomain", &localdomain, + "systemname", &systemname, +#ifdef MF + "uucpchan", &UUCPchan, +#endif /* MF */ + "mmdfldir", &mmdfldir, + "mmdflfil", &mmdflfil, + "uucpldir", &uucpldir, + "uucplfil", &uucplfil, + "mmdelim1", &mmdlm1, + "mmdelim2", &mmdlm2, + "mmailid", &mmailid, + "umincproc", &umincproc, + "lockstyle", &lkstyle, + "lockldir", &lockldir, + +#ifdef MHMTS + "mailqdir", &Mailqdir, + "tmailqdir", &TMailqdir, + "syscpy", &syscpy, + "overseer", &Overseer, + "mailer", &Mailer, + "fromtmp", &Fromtmp, + "msgtmp", &Msgtmp, + "errtmp", &Errtmp, + "tmpmode", &tmpmode, + "okhosts", &Okhosts, + "okdests", &Okdests, +#endif /* MHMTS */ + +#ifdef MMDFMTS +#endif /* MMDFMTS */ + +#ifdef SENDMTS + "hostable", &hostable, + "sendmail", &sendmail, +#endif /* SENDMTS */ + + "clientname", &clientname, + "servers", &servers, + "pophost", &pophost, +#ifdef MH_PLUS + "rpop", &rpop_default, +#endif /* MH_PLUS */ + + "bbdomain", &bb_domain, + +#ifdef BPOP + "popbbhost", &popbbhost, + "popbbuser", &popbbuser, + "popbblist", &popbblist, +#endif /* BPOP */ +#ifdef NNTP + "nntphost", &popbbhost, +#endif /* NNTP */ + + "maildelivery", &maildelivery, + + "everyone", &everyone, + "noshell", &NoShell, + +#ifdef MH_PLUS + "localuser", &localuser, +#endif /* MH_PLUS */ + + NULL +}; + +/* */ + +/* I'd like to use m_getfld() here, but not all programs loading mts.o may be + MH-style programs... */ + +/* ARGSUSED */ + +mts_init (name) +char *name; +{ + register char *bp, + *cp; + char buffer[BUFSIZ]; + register struct bind *b; + register FILE *fp; + static int inited = 0; + + if (inited++ || (fp = fopen (mtstailor, "r")) == NULL) + return; + + while (fgets (buffer, sizeof buffer, fp)) { + if ((cp = index (buffer, '\n')) == NULL) + break; + *cp = 0; + if (*buffer == '#' || *buffer == '\0') + continue; + if ((bp = index (buffer, ':')) == NULL) + break; + *bp++ = 0; + while (isspace (*bp)) + *bp++ = 0; + + for (b = binds; b -> keyword; b++) + if (strcmp (buffer, b -> keyword) == 0) + break; + if (b -> keyword && (cp = tailor_value (bp))) + *b -> value = cp; + } + + (void) fclose (fp); + + MMailids = atoi (mmailid); + if ((lockstyle = atoi (lkstyle)) < LOK_UNIX || lockstyle > LOK_MMDF) + lockstyle = LOK_UNIX; +#ifdef MHMTS + Syscpy = atoi (syscpy); + (void) sscanf (tmpmode, "0%o", &Tmpmode); +#endif /* MHMTS */ + Everyone = atoi (everyone); +#ifdef MH_PLUS + LocalUser = atoi (localuser); +#endif /* MH_PLUS */ +} + +/* */ + +#define QUOTE '\\' + +static char *tailor_value (s) +register char *s; +{ + register int i, + r; + register char *bp; + char buffer[BUFSIZ]; + + for (bp = buffer; *s; bp++, s++) + if (*s != QUOTE) + *bp = *s; + else + switch (*++s) { +#define grot(y,z) case y: *bp = z; break; + grot ('b', '\b'); + grot ('f', '\f'); + grot ('n', '\n'); + grot ('t', '\t'); +#undef grot + + 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; + + bp = malloc ((unsigned) (strlen (buffer) + 1)); + if (bp != NULL) + (void) strcpy (bp, buffer); + + return bp; +} + +/* */ + +struct hostent *mh_gethostbyname(); + +char *LocalName () { +#ifdef BSD41A + char *myname; +#endif /* BSD41A */ +#if defined(BSD42) || defined(SOCKETS) + register struct hostent *hp; +#endif /* BSD42 or SOCKETS */ +#if defined(SYS5) && !defined(NETWORK) + struct utsname name; +#endif /* SYS5 and not NETWORK */ + static char buffer[BUFSIZ] = ""; + + if (buffer[0]) + return buffer; + + mts_init ("mts"); + if (*localname) + strcpy (buffer, localname); + else { + +#ifdef locname + (void) strcpy (buffer, locname); +#else /* not locname */ +#ifdef NETWORK +#ifdef BSD41A + myname = "myname"; + if (rhost (&myname) == -1) + (void) gethostname (buffer, sizeof buffer); + else { + (void) strcpy (buffer, myname); + free (myname); + } +#endif /* BSD41A */ +#if defined(BSD42) || defined(SOCKETS) + (void) gethostname (buffer, sizeof buffer); +#ifndef BIND + sethostent (1); +#endif + if (hp = mh_gethostbyname (buffer)) + (void) strcpy (buffer, hp -> h_name); +#endif /* BSD42 or SOCKETS */ +#else /* not NETWORK */ +#ifndef SYS5 + (void) strcpy (buffer, SystemName ()); +#else /* SYS5 */ + (void) uname (&name); + (void) strcpy (buffer, name.nodename); +#endif /* SYS5 */ +#endif /* not NETWORK */ +#endif /* not locname */ + } + if (*localdomain) { + strcat (buffer, "."); + strcat (buffer, localdomain); + } + return buffer; +} + +/* */ + +char *SystemName () { +#if defined(SYS5) && !defined(NETWORK) + struct utsname name; +#endif /* SYS5 and not NETWORK */ + static char buffer[BUFSIZ] = ""; + + if (buffer[0]) + return buffer; + + mts_init ("mts"); + if (*systemname) + return strcpy (buffer, systemname); + +#ifdef sysname + (void) strcpy (buffer, sysname); +#else /* sysname */ +#if !defined(SYS5) || defined(NETWORK) + (void) gethostname (buffer, sizeof buffer); +#else /* SYS5 and not NETWORK */ +#ifdef SYS5 + (void) uname (&name); + (void) strcpy (buffer, name.nodename); +#endif /* SYS5 */ +#endif /* SYS5 and not NETWORK */ +#endif /* sysname */ + + return buffer; +} + +/* */ + +char *UucpChan () { +#ifdef MF + static char buffer[BUFSIZ] = ""; +#endif /* MF */ + +#ifndef MF + return NULL; +#else /* MF */ + if (buffer[0]) + return buffer; + + mts_init ("mts"); + if (*UUCPchan) + return strcpy (buffer, UUCPchan); + +#ifdef uucpchan + (void) strcpy (buffer, uucpchan); +#else /* uucpchan */ + (void) strcpy (buffer, "uucp"); +#endif /* uucpchan */ + return buffer; +#endif /* MF */ +} + +/* */ + +#ifdef ALTOS +gethostname (name, len) +register char *name; +register int len; +{ + register char *cp; + register FILE *fp; + + if (fp = fopen ("/etc/systemid", "r")) { + if (fgets (name, len, fp)) { + if (cp = index (name, '\n')) + *cp = 0; + (void) fclose (fp); + return OK; + } + (void) fclose (fp); + } + (void) strncpy (name, "altos", len); + + return OK; +} +#endif /* ALTOS */ + +/* */ + +static char username[BUFSIZ]; +static char fullname[BUFSIZ]; + + +char *getusr () { + register char *cp, + *np; +#ifdef KPOP + int uid; +#endif /* KPOP */ + register struct passwd *pw; + + if (username[0]) + return username; + +#ifndef KPOP +#ifdef __CYGWIN32__ + if ((cp = getenv ("USERNAME")) != NULL + && (pw = getpwnam (cp)) != NULL) + strcpy (username, cp); + else if ((pw = getpwuid (getuid ())) == NULL + || pw -> pw_name == NULL + || *pw -> pw_name == '\0') { +#else /* __CYGWIN32__ */ + if ((pw = getpwuid (getuid ())) == NULL + || pw -> pw_name == NULL + || *pw -> pw_name == '\0') { +#endif /* __CYGWIN32__ */ +#else /* KPOP */ + uid = getuid (); + if (uid == geteuid () && (cp = getenv ("USER")) != NULL + && (pw = getpwnam (cp)) != NULL) + strcpy (username, cp); + else if ((pw = getpwuid (uid)) == NULL + || pw -> pw_name == NULL + || *pw -> pw_name == '\0') { +#endif /* KPOP */ + (void) strcpy (username, "unknown"); + (void) sprintf (fullname, "The Unknown User-ID (%d)", getuid ()); + return username; + } + + np = pw -> pw_gecos; +#ifndef GCOS_HACK + for (cp = fullname; *np && *np != (MMailids ? '<' : ','); *cp++ = *np++) + continue; +#else + for (cp = fullname; *np && *np != (MMailids ? '<' : ','); ) + if (*np == '&') { /* blech! */ + (void) strcpy(cp, pw -> pw_name); + *cp = toupper(*cp); + while (*cp) + cp++; + np++; + } + else + *cp++ = *np++; +#endif + *cp = '\0'; + if (MMailids) { + if (*np) + np++; + for (cp = username; *np && *np != '>'; *cp++ = *np++) + continue; + *cp = '\0'; + } + if (MMailids == 0 || *np == '\0') + (void) strcpy (username, pw -> pw_name); + + if ((cp = getenv ("SIGNATURE")) && *cp) { + if (strlen(cp) > BUFSIZ / 4) { + fprintf(stderr, "SIGNATURE envariable too long\n"); + exit(1); + } + (void) strcpy (fullname, cp); + } + if (index(fullname, '.')) { /* quote any .'s */ + char tmp[BUFSIZ]; + sprintf (tmp, "\"%s\"", fullname);/* should quote "'s too */ + strcpy (fullname, tmp); + } + + return username; +} + + +char *getfullname () { + if (username[0] == '\0') + (void) getusr (); + + return fullname; +} + +/* */ + +#ifdef SYS5 +#ifndef notdef /* Supposedly this works, I prefer the + recursive solution... */ + +#include <fcntl.h> + +int dup2 (d1, d2) +register int d1, + d2; +{ + int d; + + if (d1 == d2) + return OK; + + (void) close (d2); + if ((d = fcntl (d1, F_DUPFD, d2)) == NOTOK) + return NOTOK; + if (d == d2) + return OK; + + errno = 0; + return NOTOK; +} + +#else /* notdef */ +int dup2 (d1, d2) +register int d1, + d2; +{ + if (d1 == d2) + return OK; + + (void) close (d2); + return dup2aux (d1, d2); +} + + +static int dup2aux (d1, d2) +register int d1, + d2; +{ + int d, + i, + eindex; + + if ((d = dup (d1)) == NOTOK) + return NOTOK; + if (d == d2) + return OK; + + i = dup2aux (d1, d2); + eindex = errno; + (void) close (d); + errno = eindex; + return i; +} +#endif /* notdef */ +#endif /* SYS5 */ + +struct hostent * +mh_gethostbyname(name) + char *name; +{ + struct hostent *xx; +#if (defined(SOLARIS) && SOLARIS < 20400) || (defined(sony_news) && defined(__svr4)) +# if SOLARIS == 20300 + static struct hostent hp; + static char buf[1000]; + extern struct hostent *_switch_gethostbyname_r(); + + xx = _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno); +# else + extern struct hostent *__switch_gethostbyname(); + + xx = __switch_gethostbyname(name); +# endif /* Solaris 2.3 */ +#else /* SOLARIS */ + + xx = gethostbyname(name); +#endif /* SOLARIS */ + + return xx; +} + +#ifdef __CYGWIN32__ +void sethostent(x) +int x; +{ +} +#endif