📄 rmail.c
字号:
#define MFDEBUG /* temporarily */#ifndef lintstatic char Id[] = "@(#)$Id: rmail.c,v 1.2 1993/08/25 17:32:49 jromine Exp $";#endif#include "util.h"#include "mmdf.h"#include <pwd.h>#include <signal.h>#include "mf.h"#include "tws.h"/* * R M A I L . C * * Developed from the Berkeley mail program of the same name * by Mike Obrien at RAND to run with the MMDF mail system. * Rewritten by Doug Kingston, US Army Ballistics Research Laboratory * Hacked a lot by Steve Bellovin (smb@unc) * * This program runs SETUID to root so that it can set effective and * real [ug]ids to mmdflogin. * * 27-Oct-82 Marshall T. Rose <mrose%uci@rand-relay> * Support proper munging by using the UCI mail filtering * routines (enabled by #ifdef MF) * Also use ll_log() package (enabled by #ifdef LOG) * * 17-Oct-83 Marshall T. Rose <mrose%uci@rand-relay> * New interfacing. Remove the #ifdef:s */#define NAMESZ 64 /* Limit on component name size */#define ADDROK 0#define UUCP 1#define RETURN 2int Syscpy = 1;int Tmpmode = 0600;char *Fromtmp = "/tmp/rml.f.XXXXXX";char *Msgtmp = "/tmp/rml.m.XXXXXX";char *Errtmp = "/tmp/rml.e.XXXXXX";char *Okhosts = "/usr/mmdf/table/rmail.ok";char *Okdests = "/usr/mmdf/table/rmail.okdests";extern char cmddfldir[];extern char logdfldir[];extern char mmdflogin[];extern char pathsubmit[];extern char sitesignature[];extern char supportaddr[];extern struct ll_struct chanlog;char *dupfpath (), *index(), *rindex();struct passwd *getpwnam(), *getpwuid();FILE *popen();/* */struct ll_struct *logptr = &chanlog;FILE *fromf; /* temporary out for colon-less UUCP "From" lines */FILE *msgf; /* temporary out for message text */FILE *mmdf; /* filtered mail file */FILE *pipef; /* output to "submit" or "uux" */char date[LINESIZE]; /* date of origination from uucp header */char from[LINESIZE]; /* accumulated path of sender */char origsys[NAMESZ]; /* originating system */char origpath[LINESIZE];/* path from us to originating system */char usrfrm[LINESIZE];char Mailsys[LINESIZE];int pbroke; /* broken-pipe flag */int rtnflag; /* note was sent back */int brpipe();/* */main(argc, argv)char **argv;{ char fromwhom[NAMESZ]; /* user on remote system */ char *fromptr; char linebuf[LINESIZE]; /* scratchpad */ char sys[NAMESZ]; /* an element in the uucp path */ char *cp; struct passwd *pw; int error; int cpyback; if (argc < 2) { fprintf(stderr, "Usage: rmail user [user ...]\n"); exit(1); } umask (0); ll_hdinit (logptr, "RM"); logptr -> ll_file = dupfpath (logptr -> ll_file, logdfldir); if ((pw = getpwnam (mmdflogin)) == NULL) { fprintf (stderr, "Cannot find mmdflogin\n"); exit (99); } setgid (pw->pw_gid); setuid (pw->pw_uid); sprintf (Mailsys, "%s <%s@%s>", sitesignature, mmdflogin, LocalName ());/* */ { /* BE VERY SURE... */ int i; for (i = fileno (stdout); i <= HIGHFD; i++) close (i); } /* create file to hold stderr output. We first open some */ /* null file to make sure stdout is taken. If stdin isn't */ /* open either, we've got so much trouble it isn't even worth */ /* worrying about a little more */ open("/dev/null", 0); mktemp(Errtmp); if (freopen(Errtmp, "w", stderr) == NULL) { fprintf(stderr, "Can't create %s\n", Errtmp); ll_log (logptr, LLOGFAT, "Unable to create '%s'", Errtmp); exit(1); } dup2 (fileno (stderr), fileno (stdout)); /* Create temp file for rest of message */ mktemp (Msgtmp); if ((msgf=fdopen(creat(Msgtmp, Tmpmode), "w")) == NULL) { fprintf(stderr, "Can't create %s\n", Msgtmp); ll_log (logptr, LLOGFAT, "Unable to create '%s'", Msgtmp); exit(1); } /* create temp file for colon-less UUCP "From" lines */ mktemp (Fromtmp); if ((fromf=fdopen(creat(Fromtmp, Tmpmode), "w")) == NULL) { fprintf(stderr, "Can't create %s\n", Fromtmp); ll_log (logptr, LLOGFAT, "Unable to create '%s'", Fromtmp); exit(1); }/* */ for (;;) { if( fgets(linebuf, sizeof linebuf, stdin) == NULL ) break; if( strncmp(linebuf, "From ", 5) && strncmp(linebuf, ">From ", 6) ) break; if (linebuf[0] != '>') fputs (">", fromf); fputs(linebuf, fromf); /* Save, we may forward via UUCP */ cp = index (linebuf, ' '); /* start of name */ fromptr = ++cp; cp = index (cp, ' '); /* cp at end of name */ *cp++ = 0; /* term. name, cp at date */ strcpy (fromwhom, fromptr); strncpy (date, cp, 24); /* Mon Nov 10 23:12:09 1981 */ for (;;) { cp = index(cp+1, 'r'); if (cp == NULL) { cp = rindex(fromwhom, '!'); if (cp != NULL) { char *p; *cp = '\0'; p = rindex(fromwhom, '!'); if (p != NULL) strcpy(origsys, p+1); else strcpy(origsys, fromwhom); strcat(from, fromwhom); strcat(from, "!"); strcpy(fromwhom, cp+1); goto out; } strcpy (sys, SystemName ()); strcat (from, sys); strcpy (origsys, sys); strcat (from, "!"); goto out; } if (strncmp(cp, "remote from ", 12) == 0) break; } sscanf(cp, "remote from %s", sys); strcat(from, sys); strcpy(origsys, sys); /* Save for quick ref. */ strcat(from, "!");out:; } if( fromwhom[0] == '\0' ) /* No from line, illegal */ exit(99);/* */ strcpy (origpath, from); strcat (from, fromwhom); mf_get_addr (from, usrfrm); if ((cp = rindex (usrfrm, '<')) != NULL) { strcpy (usrfrm, ++cp);/* sigh */ if ((cp = rindex (usrfrm, '>')) != NULL) *cp = NULL; } if (usrfrm[0] == NULL) sprintf (usrfrm, "%s!%s%%%s@%s", SystemName (), from, UucpChan (), LocalName ()); ll_log (logptr, LLOGGEN, "Rmail from '%s' (%s)", from, usrfrm); fputs (linebuf, msgf); if (rp_isbad (txtcpy (stdin, msgf))) fputs ("\n *** Problem during receipt from UUCP ***\n", msgf); freopen (Msgtmp, "r", msgf); freopen (Fromtmp, "r", fromf); unlink (Msgtmp); unlink (Fromtmp); mmdf = NULL; cpyback = 0; for (argv++; --argc > 0; ) { rewind (fromf); rewind (msgf); if (mmdf != NULL) rewind (mmdf); pbroke = 0; rtnflag = 0; signal(SIGPIPE, brpipe); if (rp_isbad(deliver(*argv++)) && !rtnflag) cpyback++; } /* Send back a copy if something nasty happened. For now, we use */ /* a real kludge -- we see if we noted some error, or if we find */ /* anything written to stderr.... */ fflush(stderr); fflush (stdout); if (cpyback) {rcpy();zcpy();} unlink(Errtmp); ll_close (logptr); exit (0);}/* *//* * deliver() -- Handle all deliveries be they returns, automatic * copies, or the real thing. Based on the address * the letter is accepted or returned with a copy * to the system administrators * * main() has set up the "from" string and the * "date" string. */char rtnend[] = " --------------- End of Returned Mail ---------------\n";deliver(to)char *to;{ int replyval; int i; char linebuf[LINESIZE]; char tmpbuf[LINESIZE]; switch (adrcheck (to)) { case ADDROK: ll_log (logptr, LLOGGEN, "Rmail to '%s' via MMDF", to); if (rp_isbad (replyval = xsubmit (NULL, usrfrm, NULL, NULL, to))) break; if (mmdf == NULL) if (mf_get_msg () == NOTOK) mmdf = msgf; replyval = txtcpy (mmdf, pipef);#ifndef RUNALON i = (pclose(pipef) >> 8 ) & 0xff; if (rp_isgood(replyval)) replyval = i;#endif break; case UUCP: ll_log (logptr, LLOGGEN, "Rmail to '%s' via UUCP", to); if (rp_isbad (replyval = xuucp(from, to))) break; replyval = txtcpy(msgf, pipef);#ifndef RUNALON i = (pclose(pipef) >> 8 ) & 0xff; if (rp_isgood(replyval)) replyval = (i == 0 ? RP_OK : RP_LIO);#endif break;/* */ case RETURN: rtnflag = 1; ll_log (logptr, LLOGGEN, "Illegal Rmail to '%s'", to); switch (adrcheck (from)) { case ADDROK: case RETURN: replyval = xsubmit (dtimenow (), Mailsys, from, supportaddr, from); rtnmesg(to); txtcpy(fromf, pipef); txtcpy(msgf, pipef); fputs (rtnend, pipef);#ifndef RUNALON i = (pclose(pipef) >> 8 ) & 0xff; if (rp_isgood(replyval)) replyval = i;#endif break; case UUCP: replyval = xuucp (mmdflogin, from); if (rp_isbad (replyval)) break; fprintf (pipef, "To: %s\n", from); fprintf (pipef, "Cc: %s\n", supportaddr); rtnmesg(to); txtcpy(fromf, pipef); txtcpy(msgf, pipef); fputs (rtnend, pipef);#ifndef RUNALON i = (pclose(pipef) >> 8 ) & 0xff; if (rp_isgood(replyval)) replyval = (i == 0 ? RP_OK : RP_LIO);#endif break; } /* And now for the mail overseer's copy */ if (Syscpy) { ll_log (logptr, LLOGGEN, "Notifying %s", supportaddr); rewind (fromf); rewind (msgf); replyval = xsubmit (dtimenow (), Mailsys, usrfrm, supportaddr, supportaddr); if (rp_isbad (replyval)) break; rtnmesg(to); txtcpy (fromf, pipef); txtcpy (msgf, pipef); fputs (rtnend, pipef);#ifndef RUNALON i = (pclose(pipef) >> 8 ) & 0xff; if (rp_isgood(replyval)) replyval = i;#endif } } return (replyval);}/* */adrcheck (adr) /* Gateway to Arpanet? */char *adr;{ char *cp, err[BUFSIZ], host[BUFSIZ], mbox[BUFSIZ]; struct adrx *adrxp; if ((adrxp = seekadrx (adr)) == NULL) return RETURN; strcpy (err, adrxp -> err ? adrxp -> err : ""); strcpy (host, adrxp -> host ? adrxp -> host : ""); strcpy (mbox, adrxp -> mbox ? adrxp -> mbox : ""); while (seekadrx (NULL))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -