V8/usr/src/cmd/upas/common/subrs.c

Compare this file to the similar file:
Show the results in this format:

/*
 *	subroutines that weren't worth their own files
 */
#include <stdio.h>
#include <signal.h>
#include <sys/param.h>
#include "mail.h"
#include "string.h"

/* configuration */
#define FRWRD	"Forward to "
#define PIPE	"Pipe to "
#define WHOAMI "/etc/whoami"		/* file containing system name */
#define MAILROOT "/usr/spool/mail/"	/* root of mail system */
#define UPASROOT "/usr/lib/upas/"	/* root of upas system */

/* imported */
int rmail;		/* true if started as rmail (init if undefined) */
int onatty;		/* true if on a tty (init if undefined) */
extern unsigned int alarm();

/* return a pointer to last element of a pathname */
extern char *
basename(file)
char *file;
{
	char *base;
	char *strrchr();

	if ((base = strrchr(file, '/')) != 0)
		base++;		/* past '/' */
	else
		base = file;
	return (base);
}

/* get the next whitespace delimited token from a string */
extern char *
getarg(s, p)      /* copy p... into s, update p */
register char *s, *p;
{
	while (*p == ' ' || *p == '\t')
		p++;
	if (*p == '\n' || *p == '\0')
		return(NULL);
	while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0')
		*s++ = *p++;
	*s = '\0';
	return(p);
}

/* a path to a mail file */
extern char *
mailpath(relp)
	char *relp;		/* relative path name */
{
	static char pathname[128];

	if (*relp == '/')
		*pathname = '\0';
	else
		(void)strcpy(pathname, MAILROOT);
	(void)strcat(pathname, relp);
	return pathname;
}

/* a path to a special upas file */
extern char *
upaspath(relp)
	char *relp;		/* relative path name */
{
	static char pathname[128];

	if (*relp == '/')
		*pathname = '\0';
	else
		(void)strcpy(pathname, UPASROOT);
	(void)strcat(pathname, relp);
	return pathname;
}

/* get the system's name */
extern char *
getsysname()
{
	int f;
	char *strchr();
	static char wsysname[33];

	f = open(WHOAMI, 0);
	if (f>=0) {
		wsysname[0] = '\0';
		read(f, wsysname, 32);
		if (strchr(wsysname, '\n')) {
			*strchr(wsysname, '\n') = '\0';
		}
		close(f);
	}
	return wsysname;
}

/*
 *	Return:
 *		0 if no special action is requested
 *		1 if fowarding (new address in param)
 *		2 if mail is to be piped to a comand (command in param)
 */
extern int
delivery_status(s, param)
	char *s, *param;
{
	FILE *fp;
	char fbuf[CMDSIZE], *p, *sp;
	int rv = MF_NORMAL;
	extern char *stringin();


	fp = fopen(s, "r");
	if(fp == NULL)
		return MF_NORMAL;
	fbuf[0] = '\0';
	fgets(fbuf, sizeof(fbuf), fp);
	if (p = stringin(FRWRD, fbuf))
		rv = MF_FORWARD;
	else if (p = stringin(PIPE, fbuf))
		rv = MF_PIPE;
	if (rv != 0) {
		while (*p == ' ')
			p++;
		sp = param;
		while (*p && *p!='\n')
			*sp++ = *p++;
		*sp = '\0';
		if (fgets(fbuf, sizeof(fbuf), fp) != NULL)
			rv |= MFEXTRA;
	}
	fclose(fp);
	return (*param != 0) ? rv : MF_NORMAL;
}

/*
 *	Find one string within another.
 *	Return:	 NULL if line doesn't contain str
 *		 a pointer to the first byte following str in line otherwise
 */
extern char *
stringin(str, line)
char *str, *line;
{
	register char *sp, *lp;

	while (*line) {
		sp = str;
		lp = line++;
		for (;;) {
			if (*sp != *lp) {
				if (*sp=='\0')
					return(lp);
				break;
			}
			sp++;
			lp++;
		}
	}
	return(NULL);
}

/* print error and core dump */
extern int
panic(s)
	char *s;
{
	fprintf(stderr, "mail: %s\n", s);
	signal(SIGQUIT, SIG_DFL);
	kill(getpid(), SIGQUIT);
	exit(-1);
}

/* global to from parsing */
static char rmtlist[ADDRSIZE];

/* output a unix header with remote from blurb */
extern void
putrfunix(sender, date, sys, fp)
	char *date, *sys, *sender;
	FILE *fp;
{
	fprintf(fp, "From %s %s%s%s\n", sender, date, REMFROM, sys);
}

/* output a unix header */
extern void
putunix(sender, date, fp)
	char *sender, *date;
	FILE *fp;
{
	fprintf(fp, "From %s %s\n", sender, date);
}

/* start the unix parse */
extern void
initgetunix()
{
	rmtlist[0] = '\0';
}

/* get/parse unix from line */
extern int
getunix(line, sender, date)
	char *line;	/* line to parse */
	char *sender;	/* filled by parseline */
	char *date;	/* filled by parseline */
{
	char *rp, *dp, *sp;

	/* look for a from */
	if ((sp = stringin(FROM, line))!=NULL
	    || (sp = stringin(ALTFROM, line))!=NULL) {

		/* do we have a remote from? */
		if ((rp = stringin(REMFROM, line))!=NULL) {

			/* add to remote list */
			line[strlen(line)-1] = '\0';
			*(rp - (sizeof(REMFROM)-1)) = '\0';
			if ((dp = strchr(sp, ' ')) != NULL) {
				strcpy(date, dp+1);
				*dp = '\0';
			}
			(void)strcpy(sender, sp);
			(void)strcat(rmtlist, rp);
			(void)strcat(rmtlist, "!");
			return -1;
		}
	}

	/* Not a from line */
	/* Use what we've found so far */
	(void)strcat(rmtlist, sender);
	(void)strcpy(sender, rmtlist);
	return 0;
}

/*
 *	a paranoid's version of popen 
 */
#define	RDR	0
#define	WTR	1

static int ppid;
static int perrfd;
static char *envp[] = {
	"IFS= 	\n",
	"PATH=/bin:/usr/bin:/usr/lib/upas",
	0
};

static char perrbuf[CMDSIZE];	/* where to put standard error */
static int forked;		/* true if we've already forked */

/* here if popen times out */
static
ptimeout()
{
	fprintf(stderr, "time out - possbile mail problem\n");
	exit(1);
}

extern FILE *
popen(cmd, uid, gid)
char	*cmd;
int	uid, gid;
{
	register i;
	int p[2], perr[2];

	/* do mail in background to keep user from getting bored */
	if (onatty && !rmail && !forked) {
		switch(fork()) {
		case 0:
			signal(SIGHUP, SIG_IGN);
			signal(SIGINT, SIG_IGN);
			signal(SIGQUIT, SIG_IGN);
			signal(SIGTERM, SIG_IGN);
			forked = 1;
			break;
		case -1:
			break;
		default:
			exit(0);
		}
	}

	if(pipe(p) < 0)
		return NULL;
	if(pipe(perr) < 0) {
		close(p[RDR]);
		close(p[WTR]);
		return NULL;
	}
	if((ppid = fork()) == 0) {
		(void)setgid(gid);
		(void)setuid(uid);
		(void)dup2(p[RDR], 0);
		(void)dup2(perr[WTR], 2);
		(void)close(1);
		for (i=3; i<NOFILE; i++)
			close(i);
		execle("/bin/sh", "sh", "-c", cmd, 0, envp);
		_exit(1);
	}
	if(ppid == -1)
		return NULL;

	signal(SIGALRM, ptimeout);
	signal(SIGPIPE, SIG_IGN);
	alarm(1200);	/* in case of deadly embrace twixt stdin and stderr */

	close(perr[WTR]);
	perrfd = perr[RDR];
	close(p[RDR]);
	return(fdopen(p[WTR], "w"));
}

extern int
pclose(ptr, perrbuf, perrlen)
FILE *ptr;
char *perrbuf;
unsigned int perrlen;
{
	register r, (*hstat)(), (*istat)(), (*qstat)();
	int status, len, i;

	fclose(ptr);
	istat = signal(SIGINT, SIG_IGN);
	qstat = signal(SIGQUIT, SIG_IGN);
	hstat = signal(SIGHUP, SIG_IGN);
	if (perrlen > 0) {
		for (i = 0; i < perrlen; i += len) {
			len = read(perrfd, perrbuf+i, perrlen-i);
			if (len <= 0)
				break;
		}
		perrbuf[i] = '\0';
	}
	close(perrfd);
	alarm(0);	/* see alarm in popen */
	signal(SIGALRM, SIG_IGN);
	while((r = wait(&status)) != ppid && r != -1)
		;
	if(r == -1)
		status = 0;
	signal(SIGINT, istat);
	signal(SIGQUIT, qstat);
	signal(SIGHUP, hstat);
	return(status);
}