xref: /csrg-svn/usr.bin/uucp/uuxqt/uuxqt.c (revision 13702)
113697Ssam #ifndef lint
2*13702Ssam static char sccsid[] = "@(#)uuxqt.c	5.2 (Berkeley) 07/02/83";
313697Ssam #endif
413697Ssam 
513697Ssam #include "uucp.h"
613697Ssam #include <sys/types.h>
713697Ssam #include <sys/stat.h>
813697Ssam #ifdef	NDIR
913697Ssam #include "ndir.h"
1013697Ssam #else
11*13702Ssam #include <sys/dir.h>
1213697Ssam #endif
1313697Ssam 
1413697Ssam #define APPCMD(d) {\
1513697Ssam char *p;\
1613697Ssam for (p = d; *p != '\0';) *cmdp++ = *p++;\
1713697Ssam *cmdp++ = ' ';\
1813697Ssam *cmdp = '\0';}
1913697Ssam 
2013697Ssam /*
2113697Ssam  *	uuxqt will execute commands set up by a uux command,
2213697Ssam  *	usually from a remote machine - set by uucp.
2313697Ssam  */
2413697Ssam 
2513697Ssam #define	NCMDS	50
2613697Ssam char *Cmds[NCMDS];
2713697Ssam 
2813697Ssam int notiok = 1;
2913697Ssam int nonzero = 0;
3013697Ssam 
3113697Ssam char PATH[MAXFULLNAME] = "PATH=/bin:/usr/bin";
3213697Ssam /*  to remove restrictions from uuxqt
3313697Ssam  *  define ALLOK 1
3413697Ssam  *
3513697Ssam  *  to add allowable commands, add to the file CMDFILE
3613697Ssam  *  A line of form "PATH=..." changes the search path
3713697Ssam  */
3813697Ssam 
3913697Ssam 
4013697Ssam main(argc, argv)
4113697Ssam char *argv[];
4213697Ssam {
4313697Ssam 	char xcmd[MAXFULLNAME];
4413697Ssam 	int argnok;
4513697Ssam 	char xfile[MAXFULLNAME], user[32], buf[BUFSIZ];
4613697Ssam 	char lbuf[30];
4713697Ssam 	char cfile[NAMESIZE], dfile[MAXFULLNAME];
4813697Ssam 	char file[NAMESIZE];
4913697Ssam 	char fin[MAXFULLNAME], sysout[NAMESIZE], fout[MAXFULLNAME];
5013697Ssam 	register FILE *xfp, *fp;
5113697Ssam 	FILE *dfp;
5213697Ssam 	char path[MAXFULLNAME];
5313697Ssam 	char cmd[BUFSIZ];
5413697Ssam 	/* set size of prm to something large -- cmcl2!salkind */
5513697Ssam 	char *cmdp, prm[1000], *ptr;
5613697Ssam 	char *getprm(), *lastpart();
5713697Ssam 	int uid, ret, badfiles;
5813697Ssam 	register int i;
5913697Ssam 	int stcico = 0;
6013697Ssam 	char retstat[30];
6113697Ssam 	int orig_uid = getuid();
6213697Ssam 
6313697Ssam 	strcpy(Progname, "uuxqt");
6413697Ssam 	uucpname(Myname);
6513697Ssam 
6613697Ssam 	/* Try to run as uucp -- rti!trt */
6713697Ssam 	setgid(getegid());
6813697Ssam 	setuid(geteuid());
6913697Ssam 
7013697Ssam 	umask(WFMASK);
7113697Ssam 	Ofn = 1;
7213697Ssam 	Ifn = 0;
7313697Ssam 	while (argc>1 && argv[1][0] == '-') {
7413697Ssam 		switch(argv[1][1]){
7513697Ssam 		case 'x':
7613697Ssam 			chkdebug(orig_uid);
7713697Ssam 			Debug = atoi(&argv[1][2]);
7813697Ssam 			if (Debug <= 0)
7913697Ssam 				Debug = 1;
8013697Ssam 			break;
8113697Ssam 		default:
8213697Ssam 			fprintf(stderr, "unknown flag %s\n", argv[1]);
8313697Ssam 				break;
8413697Ssam 		}
8513697Ssam 		--argc;  argv++;
8613697Ssam 	}
8713697Ssam 
8813697Ssam 	DEBUG(4, "\n\n** %s **\n", "START");
8913697Ssam 	subchdir(Spool);
9013697Ssam 	strcpy(Wrkdir, Spool);
9113697Ssam 	uid = getuid();
9213697Ssam 	guinfo(uid, User, path);
9313697Ssam 	DEBUG(4, "User - %s\n", User);
9413697Ssam 	if (ulockf(X_LOCK, (time_t)  X_LOCKTIME) != 0)
9513697Ssam 		exit(0);
9613697Ssam 
9713697Ssam 	fp = fopen(CMDFILE, "r");
9813697Ssam 	if (fp == NULL) {
9913697Ssam 		/* Fall-back if CMDFILE missing. Sept 1982, rti!trt */
10013697Ssam 		logent("CAN'T OPEN", CMDFILE);
10113697Ssam 		Cmds[0] = "rmail";
10213697Ssam 		Cmds[1] = "rnews";
10313697Ssam 		Cmds[2] = "ruusend";
10413697Ssam 		Cmds[3] = NULL;
10513697Ssam 		goto doprocess;
10613697Ssam 	}
10713697Ssam 	DEBUG(5, "%s opened\n", CMDFILE);
10813697Ssam 	for (i=0; i<NCMDS-1 && cfgets(xcmd, sizeof(xcmd), fp) != NULL; i++) {
10913697Ssam 		xcmd[strlen(xcmd)-1] = '\0';
11013697Ssam 		if (strncmp(xcmd, "PATH=", 5) == 0) {
11113697Ssam 			strcpy(PATH, xcmd);
11213697Ssam 			i--; /* kludge */
11313697Ssam 			continue;
11413697Ssam 		}
11513697Ssam 		DEBUG(5, "xcmd = %s\n", xcmd);
11613697Ssam 		Cmds[i] = malloc((unsigned)(strlen(xcmd)+1));
11713697Ssam 		strcpy(Cmds[i], xcmd);
11813697Ssam 	}
11913697Ssam 	Cmds[i] = 0;
12013697Ssam 	fclose(fp);
12113697Ssam 
12213697Ssam doprocess:
12313697Ssam 	DEBUG(4, "process %s\n", "");
12413697Ssam 	while (gtxfile(xfile) > 0) {
12513697Ssam 		ultouch();	/* rti!trt */
12613697Ssam 		DEBUG(4, "xfile - %s\n", xfile);
12713697Ssam 
12813697Ssam 		xfp = fopen(subfile(xfile), "r");
12913697Ssam 		ASSERT(xfp != NULL, "CAN'T OPEN", xfile, 0);
13013697Ssam 
13113697Ssam 		/*  initialize to default  */
13213697Ssam 		strcpy(user, User);
13313697Ssam 		strcpy(fin, "/dev/null");
13413697Ssam 		strcpy(fout, "/dev/null");
13513697Ssam 		sprintf(sysout, "%.7s", Myname);
13613697Ssam 		badfiles = 0;	/* this was missing -- rti!trt */
13713697Ssam 		while (fgets(buf, BUFSIZ, xfp) != NULL) {
13813697Ssam 			switch (buf[0]) {
13913697Ssam 			case X_USER:
14013697Ssam 				sscanf(&buf[1], "%s%s", user, Rmtname);
14113697Ssam 				break;
14213697Ssam 			case X_STDIN:
14313697Ssam 				sscanf(&buf[1], "%s", fin);
14413697Ssam 				i = expfile(fin);
14513697Ssam 				/* rti!trt: do not check permissions of
14613697Ssam 				 * vanilla spool file */
14713697Ssam 				if (i != 0
14813697Ssam 				 && (chkpth("", "", fin) || anyread(fin) != 0))
14913697Ssam 					badfiles = 1;
15013697Ssam 				break;
15113697Ssam 			case X_STDOUT:
15213697Ssam 				sscanf(&buf[1], "%s%s", fout, sysout);
15313697Ssam 				sysout[7] = '\0';
15413697Ssam 				/* rti!trt: do not check permissions of
15513697Ssam 				 * vanilla spool file.  DO check permissions
15613697Ssam 				 * of writing on a non-vanilla file */
15713697Ssam 				i = 1;
15813697Ssam 				if (fout[0] != '~' || prefix(sysout, Myname))
15913697Ssam 					i = expfile(fout);
16013697Ssam 				if (i != 0
16113697Ssam 				 && (chkpth("", "", fout)
16213697Ssam 					|| chkperm(fout, (char *)1)))
16313697Ssam 					badfiles = 1;
16413697Ssam 				break;
16513697Ssam 			case X_CMD:
16613697Ssam 				strcpy(cmd, &buf[2]);
16713697Ssam 				if (*(cmd + strlen(cmd) - 1) == '\n')
16813697Ssam 					*(cmd + strlen(cmd) - 1) = '\0';
16913697Ssam 				break;
17013697Ssam 			case X_NONOTI:
17113697Ssam 				notiok = 0;
17213697Ssam 				break;
17313697Ssam 			case X_NONZERO:
17413697Ssam 				nonzero = 1;
17513697Ssam 				break;
17613697Ssam 			default:
17713697Ssam 				break;
17813697Ssam 			}
17913697Ssam 		}
18013697Ssam 
18113697Ssam 		fclose(xfp);
18213697Ssam 		DEBUG(4, "fin - %s, ", fin);
18313697Ssam 		DEBUG(4, "fout - %s, ", fout);
18413697Ssam 		DEBUG(4, "sysout - %s, ", sysout);
18513697Ssam 		DEBUG(4, "user - %s\n", user);
18613697Ssam 		DEBUG(4, "cmd - %s\n", cmd);
18713697Ssam 
18813697Ssam 		/*  command execution  */
18913697Ssam 		if (strcmp(fout, "/dev/null") == SAME)
19013697Ssam 			strcpy(dfile,"/dev/null");
19113697Ssam 		else
19213697Ssam 			gename(DATAPRE, sysout, 'O', dfile);
19313697Ssam 
19413697Ssam 		/* expand file names where necessary */
19513697Ssam 		expfile(dfile);
19613697Ssam 		strcpy(buf, PATH);
19713697Ssam 		strcat(buf, ";export PATH;");
19813697Ssam 		cmdp = buf + strlen(buf);
19913697Ssam 		ptr = cmd;
20013697Ssam 		xcmd[0] = '\0';
20113697Ssam 		argnok = 0;
20213697Ssam 		while ((ptr = getprm(ptr, prm)) != NULL) {
20313697Ssam 			if (prm[0] == ';' || prm[0] == '^'
20413697Ssam 			  || prm[0] == '&'  || prm[0] == '|') {
20513697Ssam 				xcmd[0] = '\0';
20613697Ssam 				APPCMD(prm);
20713697Ssam 				continue;
20813697Ssam 			}
20913697Ssam 
21013697Ssam 			if ((argnok = argok(xcmd, prm)) != 0)
21113697Ssam 				/*  command not valid  */
21213697Ssam 				break;
21313697Ssam 
21413697Ssam 			if (prm[0] == '~')
21513697Ssam 				expfile(prm);
21613697Ssam 			APPCMD(prm);
21713697Ssam 		}
21813697Ssam 		if (argnok || badfiles) {
21913697Ssam 			sprintf(lbuf, "%s XQT DENIED", user);
22013697Ssam 			logent(cmd, lbuf);
22113697Ssam 			DEBUG(4, "bad command %s\n", prm);
22213697Ssam 			notify(user, Rmtname, cmd, "DENIED");
22313697Ssam 			goto rmfiles;
22413697Ssam 		}
22513697Ssam 		sprintf(lbuf, "%s XQT", user);
22613697Ssam 		logent(buf, lbuf);
22713697Ssam 		DEBUG(4, "cmd %s\n", buf);
22813697Ssam 
22913697Ssam 		mvxfiles(xfile);
23013697Ssam 		subchdir(XQTDIR);
23113697Ssam 		ret = shio(buf, fin, dfile, (char *)NULL);
23213697Ssam /* watcgl.11, dmmartindale, signal and exit values were reversed */
23313697Ssam 		sprintf(retstat, "signal %d, exit %d", ret & 0377,
23413697Ssam 		  (ret>>8) & 0377);
23513697Ssam 		if (strcmp(xcmd, "rmail") == SAME)
23613697Ssam 			notiok = 0;
23713697Ssam 		if (strcmp(xcmd, "rnews") == SAME)
23813697Ssam 			nonzero = 1;
23913697Ssam 		 if (notiok && (!nonzero || (nonzero && ret != 0)))
24013697Ssam 			notify(user, Rmtname, cmd, retstat);
24113697Ssam 		else if (ret != 0 && strcmp(xcmd, "rmail") == SAME) {
24213697Ssam 			/* mail failed - return letter to sender  */
24313697Ssam 			retosndr(user, Rmtname, fin);
24413697Ssam 			sprintf(buf, "ret (%o) from %s!%s", ret, Rmtname, user);
24513697Ssam 			logent("MAIL FAIL", buf);
24613697Ssam 		}
24713697Ssam 		DEBUG(4, "exit cmd - %d\n", ret);
24813697Ssam 		subchdir(Spool);
24913697Ssam 		rmxfiles(xfile);
25013697Ssam 		if (ret != 0) {
25113697Ssam 			/*  exit status not zero */
25213697Ssam 			dfp = fopen(subfile(dfile), "a");
25313697Ssam 			ASSERT(dfp != NULL, "CAN'T OPEN", dfile, 0);
25413697Ssam 			fprintf(dfp, "exit status %d", ret);
25513697Ssam 			fclose(dfp);
25613697Ssam 		}
25713697Ssam 		if (strcmp(fout, "/dev/null") != SAME) {
25813697Ssam 			if (prefix(sysout, Myname)) {
25913697Ssam 				xmv(dfile, fout);
26013697Ssam 				chmod(fout, BASEMODE);
26113697Ssam 			}
26213697Ssam 			else {
26313697Ssam 				gename(CMDPRE, sysout, 'O', cfile);
26413697Ssam 				fp = fopen(subfile(cfile), "w");
26513697Ssam 				ASSERT(fp != NULL, "OPEN", cfile, 0);
26613697Ssam 				fprintf(fp, "S %s %s %s - %s 0666\n",
26713697Ssam 				dfile, fout, user, lastpart(dfile));
26813697Ssam 				fclose(fp);
26913697Ssam 			}
27013697Ssam 		}
27113697Ssam 	rmfiles:
27213697Ssam 		xfp = fopen(subfile(xfile), "r");
27313697Ssam 		ASSERT(xfp != NULL, "CAN'T OPEN", xfile, 0);
27413697Ssam 		while (fgets(buf, BUFSIZ, xfp) != NULL) {
27513697Ssam 			if (buf[0] != X_RQDFILE)
27613697Ssam 				continue;
27713697Ssam 			sscanf(&buf[1], "%s", file);
27813697Ssam 			unlink(subfile(file));
27913697Ssam 		}
28013697Ssam 		unlink(subfile(xfile));
28113697Ssam 		fclose(xfp);
28213697Ssam 	}
28313697Ssam 
28413697Ssam 	if (stcico)
28513697Ssam 		xuucico("");
28613697Ssam 	cleanup(0);
28713697Ssam }
28813697Ssam 
28913697Ssam 
29013697Ssam cleanup(code)
29113697Ssam int code;
29213697Ssam {
29313697Ssam 	logcls();
29413697Ssam 	rmlock(CNULL);
29513697Ssam 	exit(code);
29613697Ssam }
29713697Ssam 
29813697Ssam 
29913697Ssam /*******
30013697Ssam  *	gtxfile(file)	get a file to execute
30113697Ssam  *	char *file;
30213697Ssam  *
30313697Ssam  *	return codes:  0 - no file  |  1 - file to execute
30413697Ssam  * Mod to recheck for X-able files. Sept 1982, rti!trt.
30513697Ssam  * Suggested by utzoo.2458 (utzoo!henry)
30613697Ssam  * Uses iswrk/gtwrkf to keep files in sequence, May 1983.
30713697Ssam  */
30813697Ssam 
30913697Ssam gtxfile(file)
31013697Ssam register char *file;
31113697Ssam {
31213697Ssam 	char pre[3];
31313697Ssam 	register int rechecked;
31413697Ssam 
31513697Ssam 	pre[0] = XQTPRE;
31613697Ssam 	pre[1] = '.';
31713697Ssam 	pre[2] = '\0';
31813697Ssam 	rechecked = 0;
31913697Ssam retry:
32013697Ssam 	if (!gtwrkf(Spool, file)) {
32113697Ssam 		if (rechecked)
32213697Ssam 			return(0);
32313697Ssam 		rechecked = 1;
32413697Ssam 		DEBUG(4, "iswrk\n", "");
32513697Ssam 		if (!iswrk(file, "get", Spool, pre))
32613697Ssam 			return(0);
32713697Ssam 	}
32813697Ssam 	DEBUG(4, "file - %s\n", file);
32913697Ssam #ifndef UUDIR
33013697Ssam 	/* skip spurious subdirectories */
33113697Ssam 	if (strcmp(pre, file) == SAME)
33213697Ssam 		goto retry;
33313697Ssam #endif
33413697Ssam 	if (gotfiles(file))
33513697Ssam 		return(1);
33613697Ssam 	goto retry;
33713697Ssam }
33813697Ssam 
33913697Ssam 
34013697Ssam /***
34113697Ssam  *	gotfiles(file)		check for needed files
34213697Ssam  *	char *file;
34313697Ssam  *
34413697Ssam  *	return codes:  0 - not ready  |  1 - all files ready
34513697Ssam  */
34613697Ssam 
34713697Ssam gotfiles(file)
34813697Ssam register char *file;
34913697Ssam {
35013697Ssam 	struct stat stbuf;
35113697Ssam 	register FILE *fp;
35213697Ssam 	char buf[BUFSIZ], rqfile[MAXFULLNAME];
35313697Ssam 
35413697Ssam 	fp = fopen(subfile(file), "r");
35513697Ssam 	if (fp == NULL)
35613697Ssam 		return(0);
35713697Ssam 
35813697Ssam 	while (fgets(buf, BUFSIZ, fp) != NULL) {
35913697Ssam 		DEBUG(4, "%s\n", buf);
36013697Ssam 		if (buf[0] != X_RQDFILE)
36113697Ssam 			continue;
36213697Ssam 		sscanf(&buf[1], "%s", rqfile);
36313697Ssam 		expfile(rqfile);
36413697Ssam 		if (stat(subfile(rqfile), &stbuf) == -1) {
36513697Ssam 			fclose(fp);
36613697Ssam 			return(0);
36713697Ssam 		}
36813697Ssam 	}
36913697Ssam 
37013697Ssam 	fclose(fp);
37113697Ssam 	return(1);
37213697Ssam }
37313697Ssam 
37413697Ssam 
37513697Ssam /***
37613697Ssam  *	rmxfiles(xfile)		remove execute files to x-directory
37713697Ssam  *	char *xfile;
37813697Ssam  *
37913697Ssam  *	return codes - none
38013697Ssam  */
38113697Ssam 
38213697Ssam rmxfiles(xfile)
38313697Ssam register char *xfile;
38413697Ssam {
38513697Ssam 	register FILE *fp;
38613697Ssam 	char buf[BUFSIZ], file[NAMESIZE], tfile[NAMESIZE];
38713697Ssam 	char tfull[MAXFULLNAME];
38813697Ssam 
38913697Ssam 	if((fp = fopen(subfile(xfile), "r")) == NULL)
39013697Ssam 		return;
39113697Ssam 
39213697Ssam 	while (fgets(buf, BUFSIZ, fp) != NULL) {
39313697Ssam 		if (buf[0] != X_RQDFILE)
39413697Ssam 			continue;
39513697Ssam 		if (sscanf(&buf[1], "%s%s", file, tfile) < 2)
39613697Ssam 			continue;
39713697Ssam 		sprintf(tfull, "%s/%s", XQTDIR, tfile);
39813697Ssam 		unlink(subfile(tfull));
39913697Ssam 	}
40013697Ssam 	fclose(fp);
40113697Ssam 	return;
40213697Ssam }
40313697Ssam 
40413697Ssam 
40513697Ssam /***
40613697Ssam  *	mvxfiles(xfile)		move execute files to x-directory
40713697Ssam  *	char *xfile;
40813697Ssam  *
40913697Ssam  *	return codes - none
41013697Ssam  */
41113697Ssam 
41213697Ssam mvxfiles(xfile)
41313697Ssam char *xfile;
41413697Ssam {
41513697Ssam 	register FILE *fp;
41613697Ssam 	char buf[BUFSIZ], ffile[MAXFULLNAME], tfile[NAMESIZE];
41713697Ssam 	char tfull[MAXFULLNAME];
41813697Ssam 	int ret;
41913697Ssam 
42013697Ssam 	if((fp = fopen(subfile(xfile), "r")) == NULL)
42113697Ssam 		return;
42213697Ssam 
42313697Ssam 	while (fgets(buf, BUFSIZ, fp) != NULL) {
42413697Ssam 		if (buf[0] != X_RQDFILE)
42513697Ssam 			continue;
42613697Ssam 		if (sscanf(&buf[1], "%s%s", ffile, tfile) < 2)
42713697Ssam 			continue;
42813697Ssam 		expfile(ffile);
42913697Ssam 		sprintf(tfull, "%s/%s", XQTDIR, tfile);
43013697Ssam 		/* duke!rti, ncsu!mcm: use xmv, not link(II) */
43113697Ssam 		unlink(subfile(tfull));
43213697Ssam 		ret = xmv(ffile, tfull);
43313697Ssam 		ASSERT(ret == 0, "XQTDIR ERROR", "", ret);
43413697Ssam 	}
43513697Ssam 	fclose(fp);
43613697Ssam 	return;
43713697Ssam }
43813697Ssam 
43913697Ssam 
44013697Ssam /***
44113697Ssam  *	argok(xc, cmd)		check for valid command/argumanet
44213697Ssam  *			*NOTE - side effect is to set xc to the
44313697Ssam  *				command to be executed.
44413697Ssam  *	char *xc, *cmd;
44513697Ssam  *
44613697Ssam  *	return 0 - ok | 1 nok
44713697Ssam  */
44813697Ssam 
44913697Ssam argok(xc, cmd)
45013697Ssam register char *xc, *cmd;
45113697Ssam {
45213697Ssam 	register char **ptr;
45313697Ssam 
45413697Ssam #ifndef ALLOK
45513697Ssam 	/* don't allow sh command strings `....` */
45613697Ssam 	/* don't allow redirection of standard in or out  */
45713697Ssam 	/* don't allow other funny stuff */
45813697Ssam 	/* but there are probably total holes here */
45913697Ssam 	/* post-script.  ittvax!swatt has a uuxqt that solves this. */
46013697Ssam 	/* This version of uuxqt will shortly disappear */
46113697Ssam 	if (index(cmd, '`') != NULL
46213697Ssam 	  || index(cmd, '>') != NULL
46313697Ssam 	  || index(cmd, ';') != NULL
46413697Ssam 	  || index(cmd, '^') != NULL
46513697Ssam 	  || index(cmd, '&') != NULL
46613697Ssam 	  || index(cmd, '|') != NULL
46713697Ssam 	  || index(cmd, '<') != NULL)
46813697Ssam 		return(1);
46913697Ssam #endif
47013697Ssam 
47113697Ssam 	if (xc[0] != '\0')
47213697Ssam 		return(0);
47313697Ssam 
47413697Ssam #ifndef ALLOK
47513697Ssam 	ptr = Cmds;
47613697Ssam 	while(*ptr != NULL) {
47713697Ssam 		if (strcmp(cmd, *ptr) == SAME)
47813697Ssam 			break;
47913697Ssam 	ptr++;
48013697Ssam 	}
48113697Ssam 	if (*ptr == NULL)
48213697Ssam 		return(1);
48313697Ssam #endif
48413697Ssam 	strcpy(xc, cmd);
48513697Ssam 	return(0);
48613697Ssam }
48713697Ssam 
48813697Ssam 
48913697Ssam /***
49013697Ssam  *	notify	send mail to user giving execution results
49113697Ssam  *	return code - none
49213697Ssam  *	This program assumes new mail command - send remote mail
49313697Ssam  */
49413697Ssam 
49513697Ssam notify(user, rmt, cmd, str)
49613697Ssam char *user, *rmt, *cmd, *str;
49713697Ssam {
49813697Ssam 	char text[MAXFULLNAME];
49913697Ssam 	char ruser[MAXFULLNAME];
50013697Ssam 
50113697Ssam 	sprintf(text, "uuxqt cmd (%.50s) status (%s)", cmd, str);
50213697Ssam 	if (prefix(rmt, Myname))
50313697Ssam 		strcpy(ruser, user);
50413697Ssam 	else
50513697Ssam 		sprintf(ruser, "%s!%s", rmt, user);
50613697Ssam 	mailst(ruser, text, "");
50713697Ssam 	return;
50813697Ssam }
50913697Ssam 
51013697Ssam /***
51113697Ssam  *	retosndr - return mail to sender
51213697Ssam  *
51313697Ssam  *	return code - none
51413697Ssam  */
51513697Ssam 
51613697Ssam retosndr(user, rmt, file)
51713697Ssam char *user, *rmt, *file;
51813697Ssam {
51913697Ssam 	char ruser[100];
52013697Ssam 
52113697Ssam 	if (strcmp(rmt, Myname) == SAME)
52213697Ssam 		strcpy(ruser, user);
52313697Ssam 	else
52413697Ssam 		sprintf(ruser, "%s!%s", rmt, user);
52513697Ssam 
52613697Ssam 	if (anyread(file) == 0)
52713697Ssam 		mailst(ruser, "Mail failed.  Letter returned to sender.\n", file);
52813697Ssam 	else
52913697Ssam 		mailst(ruser, "Mail failed.  Letter returned to sender.\n", "");
53013697Ssam 	return;
53113697Ssam }
532