mts.c.old
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· OLD 代码 · 共 738 行
OLD
738 行
/* mts.c - definitions for the mail transport system *//* LINTLIBRARY */#undef NETWORK#if defined(BSD41A) || defined(BSD42) || defined(SOCKETS)#define NETWORK#endif not (defined(BSD41A) || defined(BSD42) || defined(SOCKETS))#include "../h/strings.h"#include <ctype.h>#include <stdio.h>#ifdef X400#include <sys/types.h>#include <sys/stat.h>#include <sys/file.h>#include "../../h/mh.h"#endif X400#include "mts.h"#ifdef NETWORK#if defined(BSD42) || defined(SOCKETS)#include <netdb.h>#endif BSD42 or SOCKETS#else not NETWORK#ifndef SYS5#include <whoami.h>#else SYS5#include <sys/utsname.h>#endif SYS5#endif not NETWORK#include <pwd.h>/* PJS: Included the conditional as for X.400 we include mh.h... */#ifndef X400#define NOTOK (-1)#define OK 0#define NULLCP ((char *) 0)#endifextern int errno;static char *tailor_value ();#ifdef SYS5#define index strchr#define rindex strrchr#endif SYS5char *index (), *malloc (), *mktemp (), *rindex (), *strcpy ();struct passwd *getpwuid ();/* *//* *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/lib/mh/mtstailor";static char *localname = "";static char *systemname = "";#ifdef MFstatic char *UUCPchan = "";#endif MFchar *mmdfldir = "/usr/spool/mail";char *mmdflfil = "";char *uucpldir = "/usr/spool/mail";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 MFchar *umincproc = "/usr/lib/mh/uminc";#else MFchar *umincproc = NULL;#endif MFint lockstyle = LOK_UNIX;static char *lkstyle = "0";char *lockldir = "";/* *//* MTS specific variables */#ifdef MHMTSchar *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/lib/mh/Rmail.OkHosts";char *Okdests = "/usr/lib/mh/Rmail.OkDests";#endif MHMTS#ifdef MMDFMTS#endif MMDFMTS#ifdef SENDMTSchar *hostable = "/usr/lib/mh/hosts";char *sendmail = "/usr/lib/sendmail";#endif SENDMTS/* SMTP/POP stuff */char *servers = "localhost \01localnet";char *pophost = "";char *x400host = "";/* BBoards-specific variables */char *bb_domain = "";/* POP BBoards-specific variables */#ifdef BPOPchar *popbbhost = "";char *popbbuser = "";char *popbblist = "/usr/lib/mh/hosts.popbb";#endif BPOP/* MailDelivery */char *maildelivery = "/usr/lib/mh/maildelivery";/* Aliasing Facility (doesn't belong here) */int Everyone = NOTOK;static char *everyone = "-1";char *NoShell = "";/* *//* customize the MTS settings for MH by reading /usr/lib/mh/mtstailor */static struct bind { char *keyword; char **value;} binds[] = { "localname", &localname, "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 "servers", &servers, "pophost", &pophost, "x400host", &x400host, "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, 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 = NULL; if (*buffer == '#' || *buffer == NULL) continue; if ((bp = index (buffer, ':')) == NULL) break; *bp++ = NULL; while (isspace (*bp)) *bp++ = NULL; 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);}/* */#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 NULL: 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 = NULL; bp = malloc ((unsigned) (strlen (buffer) + 1)); if (bp != NULL) (void) strcpy (bp, buffer); return bp;}/* */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) return strcpy (buffer, localname);#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 = 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 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 ALTOSgethostname (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 = NULL; (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] = "";/* PJS: added in this section: it contains a boolean which is set to indicate * if getusr() is supposed to return the x400 ORname or the local user name... * It also contains a statis char pointer pointing to the x400 ORname. */#ifdef X400char need_x400_me = 0;static char *x400_me = (char *)NULL;char *get_x400_orname();#endif X400char *getusr () { register char *cp, *np; register struct passwd *pw;#ifdef X400 if (need_x400_me != 0) { if (x400_me == (char *)NULL) x400_me = get_x400_orname(); if (x400_me == (char *)NULL) need_x400_me = 0; else return x400_me; }#endif X400 if (username[0]) return username; if ((pw = getpwuid (getuid ())) == NULL || pw -> pw_name == NULL || *pw -> pw_name == NULL) { (void) strcpy (username, "unknown"); (void) sprintf (fullname, "The Unknown User-ID (%d)", getuid ()); return username; } if (MMailids) { np = pw -> pw_gecos; for (cp = fullname; *np && *np != '<'; *cp++ = *np++) continue; *cp = NULL; if (*np) np++; for (cp = username; *np && *np != '>'; *cp++ = *np++) continue; *cp = NULL; } /* * If the fullname contains any .'s, quote it */ if (index(fullname, '.')) { char tmp[BUFSIZ]; sprintf (tmp, "\"%s\"", fullname); strcpy (fullname, tmp); } if (MMailids == 0 || *np == NULL) { (void) strcpy (username, pw -> pw_name); fullname[0] = NULL; } if ((cp = getenv ("SIGNATURE")) && *cp) (void) strcpy (fullname, cp); return username;}char *getfullname () { if (username[0] == NULL) (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 notdefint 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#ifdef X400set_which_mts(msg_fp)FILE *msg_fp;{ register int state; register char tmpbuf[BUFSIZ]; char name[NAMESZ]; char *mtsptr; extern char need_x400_me; for (state = FLD;state == FLD || state == FLDPLUS;) { state = m_getfld (state, name, tmpbuf, BUFSIZ, msg_fp); switch (state) { case FLD: case FLDPLUS: if (uleq(name, "X-mts")) { mtsptr = trimcpy(tmpbuf); if (uleq(mtsptr, "x400")) need_x400_me = 1; free(mtsptr); } while (state == FLDPLUS) state = m_getfld (state, name, tmpbuf, BUFSIZ, msg_fp); break; case LENERR: case FMTERR: case BODY: case FILEEOF: break; default: adios (NULLCP, "m_getfld() returned %d", state); } } rewind(msg_fp);}char *get_x400_orname(){int pid, fid, len;char *tfile, *ambx;char *ptr = NULL;struct stat sbuf;extern char *m_tmpfil();/* Replace stdout with a temporary file to grab the x400_whois output... */ close(1); tfile = m_tmpfil("x400repl");/* This 'open' replaces the closed stdout... */ if (open(tfile, O_WRONLY|O_CREAT, 0600) < 0) { fprintf(stderr,"Can't open temporary file for writing to...\n"); return((char *)NULL); } pid = fork(); if (pid == -1) return((char *)NULL); if (pid > 0) { /* Parent process. */ if (wait(NULL) != pid) fprintf(stderr,"Wait returned without pid\n"); } else { /* Child process. */ execl("/usr/bin/x400_whois", "x400_whois", (char *)NULL); execlp("x400_whois", "x400_whois", (char *)NULL); fprintf(stderr,"Can't find 'x400_whois'...\n"); exit(1); }/* Back to the main repl invocation again... *//* Replace the tempfile stdout with the stderr. */ close(1); dup(2); if (stat(tfile, &sbuf) < 0) fprintf(stderr,"Can't stat the temp file...\n"); else { if (sbuf.st_size <= 0) fprintf(stderr,"No X.400 address...\n"); else { ptr = malloc((unsigned)sbuf.st_size + 2); fid = open(tfile, O_RDONLY); if (fid < 0) fprintf(stderr,"Failed to open tempfile for reading from.\n"); else { len = read(fid, ptr, sbuf.st_size);/* If the output of x400_whois does not begin with a '/' then it is not an * ORaddress... */ if (*ptr == '/') {/* Terminate the string, and delete any trailing newline... */ ptr[sbuf.st_size] = '\0'; if (sbuf.st_size > 0 && ptr[sbuf.st_size - 1] == '\n') ptr[sbuf.st_size - 1] = '\0'; if (len != sbuf.st_size) { fprintf(stderr,"Read %d instead of %d\n",len,sbuf.st_size); ptr = (char *)NULL; }#ifdef NOTDEF/* PJS: Can't m_replcae the alternate-mailboxes entry, as it usually resides * in the mh_profile rather than the context: those entries in the profile * are not changeable in program code... */ else { ambx = m_find("Alternate-mailboxes"); if (ambx != (char *)NULL) { ptr = realloc(ptr,(unsigned)sbuf.st_size+strlen(ambx)+4); strcat(ptr, ","); strcat(ptr, ambx); } m_replace("Alternate-mailboxes",ptr); }#endif NOTDEF } close(fid); } } } unlink(tfile); return(ptr);}#endif X400
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?