⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slocal.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
/* slocal.c - MH style mailer to write to a local user's mailbox */#ifndef	lintstatic char ident[] = "@(#)$Id: slocal.c,v 1.2 90/11/25 19:05:52 sharpe Exp $";#endif	lint/* This program implements mail delivery in the MH/MMDF style.   Under SendMail, users should add the line	"| /usr/local/lib/mh/slocal"   to their $HOME/.forward file.   Under MMDF-I, users should (symbolically) link /usr/local/lib/mh/slocal   to $HOME/bin/rcvmail.   Under stand-alone MH, post will automatically run this during local   delivery.   This program should be used ONLY if you have "mts sendmail" or "mts mh"   or "mts mmdf1" set in your MH configuration. *//*  */#include "../h/mh.h"#include "../h/dropsbr.h"#include "../h/rcvmail.h"#include "../zotnet/tws.h"#include "../zotnet/mts.h"#include <pwd.h>#include <signal.h>#ifndef	V7#ifndef	NOIOCTLH#include <sys/ioctl.h>#endif	NOIOCTLH#endif	not V7#include <sys/stat.h>#include <utmp.h>#define	NVEC	100/*  */static struct swit switches[] = {#define	ADDRSW	0    "addr address", 0,#define	USERSW	1    "user name", 0,#define	FILESW	2    "file file", 0,#define	SENDSW	3    "sender address", 0,#define	MBOXSW	4    "mailbox file", 0,#define	HOMESW	5    "home directory", 0,#define	MAILSW	6    "maildelivery file", 0,#define	VERBSW	7    "verbose", 0,#define	NVERBSW	8    "noverbose", 0,#define	DEBUGSW	9    "debug", 0,#define	HELPSW	10    "help", 4,    NULL, NULL};/*  */static int  debug = 0;static int  globbed = 0;static int  parsed = 0;static int  utmped = 0;static int  verbose = 0;static char *addr = NULLCP;static char *user = NULLCP;static char *info = NULLCP;static char *file = NULLCP;static char *sender = NULLCP;static char *unixfrom = NULLCP;static char *mbox = NULLCP;static char *home = NULLCP;static struct passwd *pw;static char ddate[BUFSIZ];struct tws *now;static jmp_buf myctx;/*  */static struct pair {    char   *p_name;    char   *p_value;    char    p_flags;#define	P_NIL	0x00#define	P_ADR	0x01#define	P_HID	0x02#define	P_CHK	0x04};static struct pair *lookup ();static struct pair  hdrs[NVEC + 1] = {    "source", NULL, P_HID,    "addr", NULL, P_HID,    "Return-Path", NULL, P_ADR,    "Reply-To", NULL, P_ADR,    "From", NULL, P_ADR,    "Sender", NULL, P_ADR,    "To", NULL, P_ADR,    "cc", NULL, P_ADR,    "Resent-Reply-To", NULL, P_ADR,    "Resent-From", NULL, P_ADR,    "Resent-Sender", NULL, P_ADR,    "Resent-To", NULL, P_ADR,    "Resent-cc", NULL, P_ADR,    NULL};static struct pair  vars[] = {    "sender", NULL, P_NIL,    "address", NULL, P_NIL,    "size", NULL, P_NIL,    "reply-to", NULL, P_CHK,    "info", NULL, P_NIL,    NULL};/*  */extern char **environ;static void	adorn ();static int	alrmser ();long    lseek ();#ifdef	SYS5struct passwd *getpwnam ();#endif	SYS5static int	localmail(), usr_delivery(), split(), parse(), logged_in();static int	timely(), usr_file(), usr_pipe(), copyfile();static expand(), glob(), copyinfo();/*  *//* ARGSUSED */main (argc, argv, envp)int     argc;char  **argv,      **envp;{    int     fd;    FILE   *fp    = stdin;    char   *cp,	   *mdlvr = NULL,            buf[100],            from[BUFSIZ],            mailbox[BUFSIZ],            tmpfil[BUFSIZ],          **argp = argv + 1;    invo_name = r1bindex (*argv, '/');    m_foil (NULLCP);    mts_init (invo_name);/*  */    while (cp = *argp++) {	if (*cp == '-')	    switch (smatch (++cp, switches)) {		case AMBIGSW: 		    ambigsw (cp, switches);		    done (1);		case UNKWNSW: 		    adios (NULLCP, "-%s unknown", cp);		case HELPSW: 		    (void) sprintf (buf, "%s [switches] [address info sender]",			    invo_name);		    help (buf, switches);		    done (1);		case ADDRSW: 		    if (!(addr = *argp++))/* allow -xyz arguments */			adios (NULLCP, "missing argument to %s", argp[-2]);		    continue;		case USERSW: 		    if (!(user = *argp++))/* allow -xyz arguments */			adios (NULLCP, "missing argument to %s", argp[-2]);		    continue;		case FILESW: 		    if (!(file = *argp++) || *file == '-')			adios (NULLCP, "missing argument to %s", argp[-2]);		    continue;		case SENDSW: 		    if (!(sender = *argp++))/* allow -xyz arguments */			adios (NULLCP, "missing argument to %s", argp[-2]);		    continue;		case MBOXSW: 		    if (!(mbox = *argp++) || *mbox == '-')			adios (NULLCP, "missing argument to %s", argp[-2]);		    continue;		case HOMESW: 		    if (!(home = *argp++) || *home == '-')			adios (NULLCP, "missing argument to %s", argp[-2]);		    continue;		case MAILSW: 		    if (!(cp = *argp++) || *cp == '-')			adios (NULLCP, "missing argument to %s", argp[-2]);		    if (mdlvr)			adios (NULLCP, "only one maildelivery file at a time!");		    mdlvr = cp;		    continue;		case VERBSW: 		    verbose++;		    continue;		case NVERBSW: 		    verbose = 0;		    continue;		case DEBUGSW: 		    debug++;		    continue;	    }	switch (argp - (argv + 1)) {	    case 1: 		addr = cp;		break;	    case 2: 		info = cp;		break;	    case 3: 		sender = cp;		break;	}    }/*  */    if (addr == NULL)	addr = getusr ();    if (user == NULL)	user = (cp = index (addr, '.')) ? ++cp : addr;    if ((pw = getpwnam (user)) == NULL)	adios (NULLCP, "no such local user as %s", user);    if (chdir (pw -> pw_dir) == NOTOK)	(void) chdir ("/");    (void) umask (0077);    if (geteuid () == 0) {#ifdef	BSD41A	(void) inigrp (pw -> pw_name, pw -> pw_gid);#endif	BSD41A	(void) setgid (pw -> pw_gid);#ifdef	BSD42	(void) initgroups (pw -> pw_name, pw -> pw_gid);#endif	BSD42	(void) setuid (pw -> pw_uid);    }        if (info == NULL)	info = "";    setbuf (stdin, NULLCP);    if (file == NULL) {	if ((fd = copyfile (fileno (stdin), file = tmpfil, 1)) == NOTOK)	    adios (NULLCP, "unable to create temporary file");	if (debug)	    fprintf (stderr, "temporary file \"%s\" selected\n", tmpfil);	else	    (void) unlink (tmpfil);   	if ((fp = fdopen (fd, "r+")) == NULL)	    adios (NULLCP, "unable to access temporary file");    }    else	fd = fileno (stdin);    from[0] = NULL;    if (sender == NULL)	copyinfo (fp, from);    if (mbox == NULL) {	(void) sprintf (mailbox, "%s/%s",		mmdfldir[0] ? mmdfldir : pw -> pw_dir,		mmdflfil[0] ? mmdflfil : pw -> pw_name);	mbox = mailbox;    }    if (home == NULL)	home = pw -> pw_dir;    if ((now = dtwstime ()) == NULL)	adios (NULLCP, "unable to ascertain local time");    (void) sprintf (ddate, "Delivery-Date: %s\n", dtimenow ());    if (debug) {	fprintf (stderr, "addr=\"%s\" user=\"%s\" info=\"%s\" file=\"%s\"\n",		addr, user, info, file);	fprintf (stderr, "sender=\"%s\" mbox=\"%s\" home=\"%s\" from=\"%s\"\n",		sender, mbox, home, from);	fprintf (stderr, "ddate=\"%s\" now=%02d:%02d\n",		ddate, now -> tw_hour, now -> tw_min);    }    done (localmail (fd, from, mdlvr) != NOTOK ? RCV_MOK : RCV_MBX);}/*  */static int  localmail (fd, from, mdlvr)int     fd;char   *from,       *mdlvr;{    if (usr_delivery (fd, mdlvr ? mdlvr : ".maildelivery", 0, from) != NOTOK)	return OK;    if (usr_delivery (fd, maildelivery, 1, from) != NOTOK)	return OK;#ifdef	notdef    if (verbose)	printf ("(invoking hook)\n");    if (usr_hook (fd, mbox) != NOTOK)	return OK;#endif	notdef    if (verbose)	printf ("(trying normal delivery)\n");    return usr_file (fd, mbox, from);}/*  */#define	matches(a,b)	(stringdex (b, a) >= 0)static int  usr_delivery (fd, delivery, su, from)int     fd,	su;char   *delivery,       *from;{    int     i,	    accept,            status,            won,	    vecp,            next;    register char  *cp,                   *action,                   *field,                   *pattern,		   *string;    char    buffer[BUFSIZ],	    tmpbuf[BUFSIZ],           *vec[NVEC];    struct stat st;    register struct pair   *p;    register FILE  *fp;    if ((fp = fopen (delivery, "r")) == NULL)	return NOTOK;    if (fstat (fileno (fp), &st) == NOTOK	    || (st.st_uid != 0 && (su || st.st_uid != pw -> pw_uid))	    || st.st_mode & 0022) {	if (verbose) {	    printf ("%s: ownership/modes bad (%d, %d,%d,0%o)\n",		    delivery, su, pw -> pw_uid, st.st_uid, st.st_mode);	    (void) fflush (stdout);	}	return NOTOK;    }    won = 0;    next = 1;    while (fgets (buffer, sizeof buffer, fp) != NULL) {	if (*buffer == '#')	    continue;	if (cp = index (buffer, '\n'))	    *cp = NULL;	if ((vecp = split (buffer, vec)) < 5)	    continue;	if (debug)	    for (i = 0; vec[i]; i++)		fprintf (stderr, "vec[%d]: \"%s\"\n", i, vec[i]);	field = vec[0];	pattern = vec[1];	action = vec[2];	switch (vec[3][0]) {	    case 'N':	    case 'n': 		if (! next)			continue;  /* if previous condition failed, don't				      do this - else fall through */	    case '?': 		if (won)		    continue;	/* else fall */	    case 'A': 	    case 'a': 		accept = 1;		break;	    case 'R': 	    case 'r': 	    default: 		accept = 0;		break;	}	string = vec[4];	if (vecp > 5) {	    if (uleq (vec[5], "select")) {		if (logged_in () != NOTOK)		    continue;		if (vecp > 7 && timely (vec[6], vec[7]) == NOTOK)		    continue;	    }	}	switch (*field) {	    case '*': 		break;	    case 'd': 		if (uleq (field, "default")) {		    if (won)			continue;		    break;		}		/* else fall */	    default: 		if (!parsed && parse (fd) == NOTOK) {		    (void) fclose (fp);		    return NOTOK;		}		if ((p = lookup (hdrs, field)) == NULL			|| (p->p_value == NULL)			/* XXX */			|| !matches (p -> p_value, pattern)) {			next = 0;			continue;		}		else		    next = 1;		break;	}	switch (*action) {	    case 'q':		if (!uleq (action, "qpipe"))		    continue;	/* else fall */	    case '^':		expand (tmpbuf, string, fd);		if (split (tmpbuf, vec) < 1)		    continue;		status = usr_pipe (fd, tmpbuf, vec[0], vec);		break;	    case 'p': 		if (!uleq (action, "pipe"))		    continue;	/* else fall */	    case '|': 		vec[2] = "sh";		vec[3] = "-c";		expand (tmpbuf, string, fd);		vec[4] = tmpbuf;		vec[5] = NULL;		status = usr_pipe (fd, tmpbuf, "/bin/sh", vec + 2);		break;	    case 'f': 		if (!uleq (action, "file"))		    continue;	/* else fall */	    case '>': 		status = usr_file (fd, string,  from);	/* UUCP format? */		break;	    case 'd': 		if (!uleq (action, "destroy"))		    continue;		status = OK;		break;	}	if (accept) {	    if (status == NOTOK) {		won = 0;		break;	    }	    won++;	}    }    (void) fclose (fp);    return (won ? OK : NOTOK);}/*  */#define	QUOTE	'\\'static int  split (cp, vec)char   *cp,      **vec;{    register int    i;    register char  *s;    for (i = 0, s = cp; i <= NVEC;) {	vec[i] = NULL;	while (isspace (*s) || *s == ',')	    *s++ = NULL;	if (*s == NULL)	    break;	if (*s == '"') {	    for (vec[i++] = ++s; *s != NULL && *s != '"'; s++)		if (*s == QUOTE) {		    if (*++s == '"')			(void) strcpy (s - 1, s);		    s--;		}	    if (*s == '"')		*s++ = NULL;	    continue;	}	if (*s == QUOTE && *++s != '"')	    s--;	vec[i++] = s++;	while (*s != NULL && !isspace (*s) && *s != ',')	    s++;    }    vec[i] = NULL;    return i;}/*  */static int  parse (fd)register int    fd;{    register int    i,                    state;    int     fd1;    register char  *cp,                   *dp,                   *lp;    char    name[NAMESZ],            field[BUFSIZ];    register struct pair   *p,			   *q;    register FILE  *in;    if (parsed++)	return OK;    if ((fd1 = dup (fd)) == NOTOK)	return NOTOK;    if ((in = fdopen (fd1, "r")) == NULL) {	(void) close (fd1);	return NOTOK;    }    rewind (in);    if (p = lookup (hdrs, "source"))	p -> p_value = getcpy (sender);    if (p = lookup (hdrs, "addr"))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -