xref: /csrg-svn/usr.bin/uucp/uuxqt/uuxqt.c (revision 17846)
113697Ssam #ifndef lint
2*17846Sralph static char sccsid[] = "@(#)uuxqt.c	5.3 (Berkeley) 01/22/85";
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
1113702Ssam #include <sys/dir.h>
1213697Ssam #endif
13*17846Sralph #include <signal.h>
1413697Ssam 
1513697Ssam #define APPCMD(d) {\
1613697Ssam char *p;\
17*17846Sralph for (p = d; *p != '\0';) *cmdp++ = *p++; *cmdp++ = ' '; *cmdp = '\0';}
1813697Ssam 
1913697Ssam /*
2013697Ssam  *	uuxqt will execute commands set up by a uux command,
2113697Ssam  *	usually from a remote machine - set by uucp.
2213697Ssam  */
2313697Ssam 
2413697Ssam #define	NCMDS	50
25*17846Sralph char *Cmds[NCMDS+1];
26*17846Sralph int Notify[NCMDS+1];
27*17846Sralph #define	NT_YES	0	/* if should notify on execution */
28*17846Sralph #define	NT_ERR	1	/* if should notify if non-zero exit status (-z equivalent) */
29*17846Sralph #define	NT_NO	2	/* if should not notify ever (-n equivalent) */
3013697Ssam 
31*17846Sralph extern int Nfiles;
32*17846Sralph 
3313697Ssam int notiok = 1;
3413697Ssam int nonzero = 0;
3513697Ssam 
36*17846Sralph #ifdef SIGCHLD
37*17846Sralph #include <sys/wait.h>
38*17846Sralph reapchild()
39*17846Sralph {
40*17846Sralph 	union wait status;
41*17846Sralph 
42*17846Sralph 	while (wait3(&status,WNOHANG,0) > 0)
43*17846Sralph 		;
44*17846Sralph }
45*17846Sralph #endif SIGCHLD
46*17846Sralph 
47*17846Sralph char PATH[MAXFULLNAME] = "PATH=/bin:/usr/bin:/usr/ucb";
4813697Ssam /*  to remove restrictions from uuxqt
4913697Ssam  *  define ALLOK 1
5013697Ssam  *
5113697Ssam  *  to add allowable commands, add to the file CMDFILE
5213697Ssam  *  A line of form "PATH=..." changes the search path
5313697Ssam  */
5413697Ssam main(argc, argv)
5513697Ssam char *argv[];
5613697Ssam {
5713697Ssam 	char xcmd[MAXFULLNAME];
5813697Ssam 	int argnok;
59*17846Sralph 	int notiflg;
60*17846Sralph 	char xfile[MAXFULLNAME], user[MAXFULLNAME], buf[BUFSIZ];
61*17846Sralph 	char lbuf[MAXFULLNAME];
6213697Ssam 	char cfile[NAMESIZE], dfile[MAXFULLNAME];
6313697Ssam 	char file[NAMESIZE];
6413697Ssam 	char fin[MAXFULLNAME], sysout[NAMESIZE], fout[MAXFULLNAME];
6513697Ssam 	register FILE *xfp, *fp;
6613697Ssam 	FILE *dfp;
6713697Ssam 	char path[MAXFULLNAME];
6813697Ssam 	char cmd[BUFSIZ];
6913697Ssam 	char *cmdp, prm[1000], *ptr;
7013697Ssam 	char *getprm(), *lastpart();
71*17846Sralph 	int uid, ret, ret2, badfiles;
7213697Ssam 	register int i;
7313697Ssam 	int stcico = 0;
7413697Ssam 	char retstat[30];
7513697Ssam 
7613697Ssam 	strcpy(Progname, "uuxqt");
7713697Ssam 	uucpname(Myname);
7813697Ssam 
79*17846Sralph #ifdef SIGCHLD
80*17846Sralph 	signal(SIGCHLD, reapchild);
81*17846Sralph #endif SIGCHLD
8213697Ssam 
8313697Ssam 	umask(WFMASK);
8413697Ssam 	Ofn = 1;
8513697Ssam 	Ifn = 0;
8613697Ssam 	while (argc>1 && argv[1][0] == '-') {
8713697Ssam 		switch(argv[1][1]){
8813697Ssam 		case 'x':
89*17846Sralph 			chkdebug();
9013697Ssam 			Debug = atoi(&argv[1][2]);
9113697Ssam 			if (Debug <= 0)
9213697Ssam 				Debug = 1;
9313697Ssam 			break;
9413697Ssam 		default:
9513697Ssam 			fprintf(stderr, "unknown flag %s\n", argv[1]);
9613697Ssam 				break;
9713697Ssam 		}
9813697Ssam 		--argc;  argv++;
9913697Ssam 	}
10013697Ssam 
10113697Ssam 	DEBUG(4, "\n\n** %s **\n", "START");
102*17846Sralph 	ret = subchdir(Spool);
103*17846Sralph 	ASSERT(ret >= 0, "CHDIR FAILED", Spool, ret);
10413697Ssam 	strcpy(Wrkdir, Spool);
10513697Ssam 	uid = getuid();
10613697Ssam 	guinfo(uid, User, path);
107*17846Sralph 	/* Try to run as uucp -- rti!trt */
108*17846Sralph 	setgid(getegid());
109*17846Sralph 	setuid(geteuid());
110*17846Sralph 
11113697Ssam 	DEBUG(4, "User - %s\n", User);
11213697Ssam 	if (ulockf(X_LOCK, (time_t)  X_LOCKTIME) != 0)
11313697Ssam 		exit(0);
11413697Ssam 
11513697Ssam 	fp = fopen(CMDFILE, "r");
11613697Ssam 	if (fp == NULL) {
117*17846Sralph 		logent(CANTOPEN, CMDFILE);
11813697Ssam 		Cmds[0] = "rmail";
11913697Ssam 		Cmds[1] = "rnews";
12013697Ssam 		Cmds[2] = "ruusend";
12113697Ssam 		Cmds[3] = NULL;
12213697Ssam 		goto doprocess;
12313697Ssam 	}
12413697Ssam 	DEBUG(5, "%s opened\n", CMDFILE);
125*17846Sralph 	for (i=0; i<NCMDS && cfgets(xcmd, sizeof(xcmd), fp) != NULL; i++) {
126*17846Sralph 		int j;
127*17846Sralph 		/* strip trailing whitespace */
128*17846Sralph 		for (j = strlen(xcmd)-1; j >= 0; --j)
129*17846Sralph 			if (xcmd[j] == '\n' || xcmd[j] == ' ' || xcmd[j] == '\t')
130*17846Sralph 				xcmd[j] = '\0';
131*17846Sralph 			else
132*17846Sralph 				break;
133*17846Sralph 		/* look for imbedded whitespace */
134*17846Sralph 		for (; j >= 0; --j)
135*17846Sralph 			if (xcmd[j] == '\n' || xcmd[j] == ' ' || xcmd[j] == '\t')
136*17846Sralph 				break;
137*17846Sralph 		/* skip this entry if it has embedded whitespace */
138*17846Sralph 		/* This defends against a bad PATH=, for example */
139*17846Sralph 		if (j >= 0) {
140*17846Sralph 			logent(xcmd, "BAD WHITESPACE");
141*17846Sralph 			continue;
142*17846Sralph 		}
14313697Ssam 		if (strncmp(xcmd, "PATH=", 5) == 0) {
14413697Ssam 			strcpy(PATH, xcmd);
145*17846Sralph 			i--;	/*kludge */
14613697Ssam 			continue;
14713697Ssam 		}
14813697Ssam 		DEBUG(5, "xcmd = %s\n", xcmd);
149*17846Sralph 
150*17846Sralph 		if ((ptr = index(xcmd, ',')) != NULL) {
151*17846Sralph 			*ptr++ = '\0';
152*17846Sralph 			if (strncmp(ptr, "Err", 3) == SAME)
153*17846Sralph 				Notify[i] = NT_ERR;
154*17846Sralph 			else if (strcmp(ptr, "No") == SAME)
155*17846Sralph 				Notify[i] = NT_NO;
156*17846Sralph 			else
157*17846Sralph 				Notify[i] = NT_YES;
158*17846Sralph 		} else
159*17846Sralph 			Notify[i] = NT_YES;
160*17846Sralph 		if ((Cmds[i] = malloc((unsigned)(strlen(xcmd)+1))) == NULL) {
161*17846Sralph 			DEBUG(1, "MALLOC FAILED", CNULL);
162*17846Sralph 			break;
163*17846Sralph 		}
16413697Ssam 		strcpy(Cmds[i], xcmd);
16513697Ssam 	}
166*17846Sralph 	Cmds[i] = CNULL;
16713697Ssam 	fclose(fp);
16813697Ssam 
16913697Ssam doprocess:
170*17846Sralph 	DEBUG(4, "process %s\n", CNULL);
17113697Ssam 	while (gtxfile(xfile) > 0) {
172*17846Sralph 		ultouch();
173*17846Sralph 		/* if /etc/nologin exists, exit cleanly */
174*17846Sralph 		if (nologinflag) {
175*17846Sralph 			logent(NOLOGIN, "UUXQT SHUTDOWN");
176*17846Sralph 			if (Debug)
177*17846Sralph 				logent("debugging", "continuing anyway");
178*17846Sralph 			else
179*17846Sralph 				break;
180*17846Sralph 		}
18113697Ssam 		DEBUG(4, "xfile - %s\n", xfile);
18213697Ssam 
18313697Ssam 		xfp = fopen(subfile(xfile), "r");
184*17846Sralph 		ASSERT(xfp != NULL, CANTOPEN, xfile, 0);
18513697Ssam 
18613697Ssam 		/*  initialize to default  */
18713697Ssam 		strcpy(user, User);
188*17846Sralph 		strcpy(fin, DEVNULL);
189*17846Sralph 		strcpy(fout, DEVNULL);
19013697Ssam 		sprintf(sysout, "%.7s", Myname);
191*17846Sralph 		badfiles = 0;
19213697Ssam 		while (fgets(buf, BUFSIZ, xfp) != NULL) {
19313697Ssam 			switch (buf[0]) {
19413697Ssam 			case X_USER:
195*17846Sralph 				sscanf(&buf[1], "%s %s", user, Rmtname);
19613697Ssam 				break;
197*17846Sralph 			case X_RETURNTO:
198*17846Sralph 				sscanf(&buf[1], "%s", user);
199*17846Sralph 				break;
20013697Ssam 			case X_STDIN:
20113697Ssam 				sscanf(&buf[1], "%s", fin);
20213697Ssam 				i = expfile(fin);
20313697Ssam 				/* rti!trt: do not check permissions of
20413697Ssam 				 * vanilla spool file */
20513697Ssam 				if (i != 0
20613697Ssam 				 && (chkpth("", "", fin) || anyread(fin) != 0))
20713697Ssam 					badfiles = 1;
20813697Ssam 				break;
20913697Ssam 			case X_STDOUT:
21013697Ssam 				sscanf(&buf[1], "%s%s", fout, sysout);
21113697Ssam 				sysout[7] = '\0';
21213697Ssam 				/* rti!trt: do not check permissions of
21313697Ssam 				 * vanilla spool file.  DO check permissions
21413697Ssam 				 * of writing on a non-vanilla file */
21513697Ssam 				i = 1;
21613697Ssam 				if (fout[0] != '~' || prefix(sysout, Myname))
21713697Ssam 					i = expfile(fout);
21813697Ssam 				if (i != 0
21913697Ssam 				 && (chkpth("", "", fout)
22013697Ssam 					|| chkperm(fout, (char *)1)))
22113697Ssam 					badfiles = 1;
22213697Ssam 				break;
22313697Ssam 			case X_CMD:
22413697Ssam 				strcpy(cmd, &buf[2]);
22513697Ssam 				if (*(cmd + strlen(cmd) - 1) == '\n')
22613697Ssam 					*(cmd + strlen(cmd) - 1) = '\0';
22713697Ssam 				break;
22813697Ssam 			case X_NONOTI:
22913697Ssam 				notiok = 0;
23013697Ssam 				break;
23113697Ssam 			case X_NONZERO:
23213697Ssam 				nonzero = 1;
23313697Ssam 				break;
23413697Ssam 			default:
23513697Ssam 				break;
23613697Ssam 			}
23713697Ssam 		}
23813697Ssam 
23913697Ssam 		fclose(xfp);
24013697Ssam 		DEBUG(4, "fin - %s, ", fin);
24113697Ssam 		DEBUG(4, "fout - %s, ", fout);
24213697Ssam 		DEBUG(4, "sysout - %s, ", sysout);
24313697Ssam 		DEBUG(4, "user - %s\n", user);
24413697Ssam 		DEBUG(4, "cmd - %s\n", cmd);
24513697Ssam 
24613697Ssam 		/*  command execution  */
247*17846Sralph 		if (strcmp(fout, DEVNULL) == SAME)
248*17846Sralph 			strcpy(dfile,DEVNULL);
24913697Ssam 		else
25013697Ssam 			gename(DATAPRE, sysout, 'O', dfile);
25113697Ssam 
25213697Ssam 		/* expand file names where necessary */
25313697Ssam 		expfile(dfile);
25413697Ssam 		strcpy(buf, PATH);
255*17846Sralph 		strcat(buf, " ");
25613697Ssam 		cmdp = buf + strlen(buf);
25713697Ssam 		ptr = cmd;
25813697Ssam 		xcmd[0] = '\0';
25913697Ssam 		argnok = 0;
26013697Ssam 		while ((ptr = getprm(ptr, prm)) != NULL) {
26113697Ssam 			if (prm[0] == ';' || prm[0] == '^'
26213697Ssam 			  || prm[0] == '&'  || prm[0] == '|') {
26313697Ssam 				xcmd[0] = '\0';
26413697Ssam 				APPCMD(prm);
26513697Ssam 				continue;
26613697Ssam 			}
26713697Ssam 
268*17846Sralph 			if ((argnok = argok(xcmd, prm)) != SUCCESS)
26913697Ssam 				/*  command not valid  */
27013697Ssam 				break;
27113697Ssam 
27213697Ssam 			if (prm[0] == '~')
27313697Ssam 				expfile(prm);
27413697Ssam 			APPCMD(prm);
27513697Ssam 		}
276*17846Sralph 		/*
277*17846Sralph 		 * clean up trailing ' ' in command.
278*17846Sralph 		 */
279*17846Sralph 		if (cmdp > buf && cmdp[0] == '\0' && cmdp[-1] == ' ')
280*17846Sralph 			*--cmdp = '\0';
28113697Ssam 		if (argnok || badfiles) {
28213697Ssam 			sprintf(lbuf, "%s XQT DENIED", user);
28313697Ssam 			logent(cmd, lbuf);
28413697Ssam 			DEBUG(4, "bad command %s\n", prm);
28513697Ssam 			notify(user, Rmtname, cmd, "DENIED");
28613697Ssam 			goto rmfiles;
28713697Ssam 		}
28813697Ssam 		sprintf(lbuf, "%s XQT", user);
28913697Ssam 		logent(buf, lbuf);
29013697Ssam 		DEBUG(4, "cmd %s\n", buf);
29113697Ssam 
29213697Ssam 		mvxfiles(xfile);
293*17846Sralph 		ret = subchdir(XQTDIR);
294*17846Sralph 		ASSERT(ret >= 0, "CHDIR FAILED", XQTDIR, ret);
295*17846Sralph 		ret = shio(buf, fin, dfile, CNULL);
29613697Ssam 		sprintf(retstat, "signal %d, exit %d", ret & 0377,
29713697Ssam 		  (ret>>8) & 0377);
29813697Ssam 		if (strcmp(xcmd, "rmail") == SAME)
29913697Ssam 			notiok = 0;
30013697Ssam 		if (strcmp(xcmd, "rnews") == SAME)
30113697Ssam 			nonzero = 1;
302*17846Sralph 		notiflg = chknotify(xcmd);
303*17846Sralph 		if (notiok && notiflg != NT_NO &&
304*17846Sralph 		   (ret != 0 || (!nonzero && notiflg == NT_YES)))
30513697Ssam 			notify(user, Rmtname, cmd, retstat);
30613697Ssam 		else if (ret != 0 && strcmp(xcmd, "rmail") == SAME) {
30713697Ssam 			/* mail failed - return letter to sender  */
308*17846Sralph #ifdef	DANGEROUS
309*17846Sralph 			/* NOT GUARANTEED SAFE!!! */
310*17846Sralph 			if (!nonzero)
311*17846Sralph 				retosndr(user, Rmtname, fin);
312*17846Sralph #else
313*17846Sralph 			notify(user, Rmtname, cmd, retstat);
314*17846Sralph #endif
315*17846Sralph 			sprintf(buf, "%s (%s) from %s!%s", buf, retstat, Rmtname, user);
31613697Ssam 			logent("MAIL FAIL", buf);
31713697Ssam 		}
31813697Ssam 		DEBUG(4, "exit cmd - %d\n", ret);
319*17846Sralph 		ret2 = subchdir(Spool);
320*17846Sralph 		ASSERT(ret2 >= 0, "CHDIR FAILED", Spool, ret);
32113697Ssam 		rmxfiles(xfile);
32213697Ssam 		if (ret != 0) {
32313697Ssam 			/*  exit status not zero */
32413697Ssam 			dfp = fopen(subfile(dfile), "a");
325*17846Sralph 			ASSERT(dfp != NULL, CANTOPEN, dfile, 0);
32613697Ssam 			fprintf(dfp, "exit status %d", ret);
32713697Ssam 			fclose(dfp);
32813697Ssam 		}
329*17846Sralph 		if (strcmp(fout, DEVNULL) != SAME) {
33013697Ssam 			if (prefix(sysout, Myname)) {
33113697Ssam 				xmv(dfile, fout);
33213697Ssam 				chmod(fout, BASEMODE);
33313697Ssam 			}
33413697Ssam 			else {
335*17846Sralph 				char *cp = rindex(user, '!');
33613697Ssam 				gename(CMDPRE, sysout, 'O', cfile);
33713697Ssam 				fp = fopen(subfile(cfile), "w");
33813697Ssam 				ASSERT(fp != NULL, "OPEN", cfile, 0);
339*17846Sralph 				fprintf(fp, "S %s %s %s - %s 0666\n", dfile,
340*17846Sralph 					fout, cp ? cp : user, lastpart(dfile));
34113697Ssam 				fclose(fp);
34213697Ssam 			}
34313697Ssam 		}
34413697Ssam 	rmfiles:
34513697Ssam 		xfp = fopen(subfile(xfile), "r");
346*17846Sralph 		ASSERT(xfp != NULL, CANTOPEN, xfile, 0);
34713697Ssam 		while (fgets(buf, BUFSIZ, xfp) != NULL) {
34813697Ssam 			if (buf[0] != X_RQDFILE)
34913697Ssam 				continue;
35013697Ssam 			sscanf(&buf[1], "%s", file);
35113697Ssam 			unlink(subfile(file));
35213697Ssam 		}
35313697Ssam 		unlink(subfile(xfile));
35413697Ssam 		fclose(xfp);
35513697Ssam 	}
35613697Ssam 
35713697Ssam 	if (stcico)
35813697Ssam 		xuucico("");
35913697Ssam 	cleanup(0);
36013697Ssam }
36113697Ssam 
36213697Ssam 
36313697Ssam cleanup(code)
36413697Ssam int code;
36513697Ssam {
36613697Ssam 	logcls();
36713697Ssam 	rmlock(CNULL);
368*17846Sralph #ifdef	VMS
369*17846Sralph 	/*
370*17846Sralph 	 *	Since we run as a BATCH job we must wait for all processes to
371*17846Sralph 	 *	to finish
372*17846Sralph 	 */
373*17846Sralph 	while(wait(0) != -1);
374*17846Sralph #endif VMS
37513697Ssam 	exit(code);
37613697Ssam }
37713697Ssam 
37813697Ssam 
37913697Ssam /*******
38013697Ssam  *	gtxfile(file)	get a file to execute
38113697Ssam  *	char *file;
38213697Ssam  *
38313697Ssam  *	return codes:  0 - no file  |  1 - file to execute
38413697Ssam  */
38513697Ssam 
38613697Ssam gtxfile(file)
38713697Ssam register char *file;
38813697Ssam {
38913697Ssam 	char pre[3];
390*17846Sralph 	int rechecked;
391*17846Sralph 	time_t ystrdy;		/* yesterday */
392*17846Sralph 	extern time_t time();
393*17846Sralph 	struct stat stbuf;	/* for X file age */
39413697Ssam 
39513697Ssam 	pre[0] = XQTPRE;
39613697Ssam 	pre[1] = '.';
39713697Ssam 	pre[2] = '\0';
39813697Ssam 	rechecked = 0;
39913697Ssam retry:
40013697Ssam 	if (!gtwrkf(Spool, file)) {
40113697Ssam 		if (rechecked)
402*17846Sralph 			return 0;
40313697Ssam 		rechecked = 1;
404*17846Sralph 		DEBUG(4, "iswrk\n", CNULL);
40513697Ssam 		if (!iswrk(file, "get", Spool, pre))
406*17846Sralph 			return 0;
40713697Ssam 	}
40813697Ssam 	DEBUG(4, "file - %s\n", file);
40913697Ssam 	/* skip spurious subdirectories */
41013697Ssam 	if (strcmp(pre, file) == SAME)
41113697Ssam 		goto retry;
41213697Ssam 	if (gotfiles(file))
413*17846Sralph 		return 1;
414*17846Sralph 	/* check for old X. file with no work files and remove them. */
415*17846Sralph 	if (Nfiles > LLEN/2) {
416*17846Sralph 	    time(&ystrdy);
417*17846Sralph 	    ystrdy -= (4 * 3600L);		/* 4 hours ago */
418*17846Sralph 	    DEBUG(4, "gtxfile: Nfiles > LLEN/2\n", CNULL);
419*17846Sralph 	    while (gtwrkf(Spool, file) && !gotfiles(file)) {
420*17846Sralph 		if (stat(subfile(file), &stbuf) == 0)
421*17846Sralph 		    if (stbuf.st_mtime <= ystrdy) {
422*17846Sralph 			char *bnp, cfilename[NAMESIZE];
423*17846Sralph 			DEBUG(4, "gtxfile: move %s to CORRUPT \n", file);
424*17846Sralph 			unlink(subfile(file));
425*17846Sralph 			bnp = rindex(subfile(file), '/');
426*17846Sralph 			sprintf(cfilename, "%s/%s", CORRUPT,
427*17846Sralph 				bnp ? bnp + 1 : subfile(file));
428*17846Sralph 			xmv(subfile(file), cfilename);
429*17846Sralph 			logent(file, "X. FILE CORRUPTED");
430*17846Sralph 		    }
431*17846Sralph 	    }
432*17846Sralph 	    DEBUG(4, "iswrk\n", CNULL);
433*17846Sralph 	    if (!iswrk(file, "get", Spool, pre))
434*17846Sralph 		return 0;
435*17846Sralph 	}
43613697Ssam 	goto retry;
43713697Ssam }
43813697Ssam 
43913697Ssam 
44013697Ssam /***
44113697Ssam  *	gotfiles(file)		check for needed files
44213697Ssam  *	char *file;
44313697Ssam  *
44413697Ssam  *	return codes:  0 - not ready  |  1 - all files ready
44513697Ssam  */
44613697Ssam 
44713697Ssam gotfiles(file)
44813697Ssam register char *file;
44913697Ssam {
45013697Ssam 	struct stat stbuf;
45113697Ssam 	register FILE *fp;
45213697Ssam 	char buf[BUFSIZ], rqfile[MAXFULLNAME];
45313697Ssam 
45413697Ssam 	fp = fopen(subfile(file), "r");
45513697Ssam 	if (fp == NULL)
456*17846Sralph 		return 0;
45713697Ssam 
45813697Ssam 	while (fgets(buf, BUFSIZ, fp) != NULL) {
45913697Ssam 		DEBUG(4, "%s\n", buf);
46013697Ssam 		if (buf[0] != X_RQDFILE)
46113697Ssam 			continue;
46213697Ssam 		sscanf(&buf[1], "%s", rqfile);
46313697Ssam 		expfile(rqfile);
46413697Ssam 		if (stat(subfile(rqfile), &stbuf) == -1) {
46513697Ssam 			fclose(fp);
466*17846Sralph 			return 0;
46713697Ssam 		}
46813697Ssam 	}
46913697Ssam 
47013697Ssam 	fclose(fp);
471*17846Sralph 	return 1;
47213697Ssam }
47313697Ssam 
47413697Ssam 
47513697Ssam /***
47613697Ssam  *	rmxfiles(xfile)		remove execute files to x-directory
47713697Ssam  *	char *xfile;
47813697Ssam  *
47913697Ssam  *	return codes - none
48013697Ssam  */
48113697Ssam 
48213697Ssam rmxfiles(xfile)
48313697Ssam register char *xfile;
48413697Ssam {
48513697Ssam 	register FILE *fp;
48613697Ssam 	char buf[BUFSIZ], file[NAMESIZE], tfile[NAMESIZE];
48713697Ssam 	char tfull[MAXFULLNAME];
48813697Ssam 
48913697Ssam 	if((fp = fopen(subfile(xfile), "r")) == NULL)
49013697Ssam 		return;
49113697Ssam 
49213697Ssam 	while (fgets(buf, BUFSIZ, fp) != NULL) {
49313697Ssam 		if (buf[0] != X_RQDFILE)
49413697Ssam 			continue;
49513697Ssam 		if (sscanf(&buf[1], "%s%s", file, tfile) < 2)
49613697Ssam 			continue;
49713697Ssam 		sprintf(tfull, "%s/%s", XQTDIR, tfile);
49813697Ssam 		unlink(subfile(tfull));
49913697Ssam 	}
50013697Ssam 	fclose(fp);
50113697Ssam 	return;
50213697Ssam }
50313697Ssam 
50413697Ssam 
50513697Ssam /***
50613697Ssam  *	mvxfiles(xfile)		move execute files to x-directory
50713697Ssam  *	char *xfile;
50813697Ssam  *
50913697Ssam  *	return codes - none
51013697Ssam  */
51113697Ssam 
51213697Ssam mvxfiles(xfile)
51313697Ssam char *xfile;
51413697Ssam {
51513697Ssam 	register FILE *fp;
51613697Ssam 	char buf[BUFSIZ], ffile[MAXFULLNAME], tfile[NAMESIZE];
51713697Ssam 	char tfull[MAXFULLNAME];
51813697Ssam 	int ret;
51913697Ssam 
52013697Ssam 	if((fp = fopen(subfile(xfile), "r")) == NULL)
52113697Ssam 		return;
52213697Ssam 
52313697Ssam 	while (fgets(buf, BUFSIZ, fp) != NULL) {
52413697Ssam 		if (buf[0] != X_RQDFILE)
52513697Ssam 			continue;
52613697Ssam 		if (sscanf(&buf[1], "%s%s", ffile, tfile) < 2)
52713697Ssam 			continue;
52813697Ssam 		expfile(ffile);
52913697Ssam 		sprintf(tfull, "%s/%s", XQTDIR, tfile);
53013697Ssam 		unlink(subfile(tfull));
53113697Ssam 		ret = xmv(ffile, tfull);
532*17846Sralph 		ASSERT(ret == 0, "XQTDIR ERROR", CNULL, ret);
53313697Ssam 	}
53413697Ssam 	fclose(fp);
53513697Ssam 	return;
53613697Ssam }
53713697Ssam 
53813697Ssam 
53913697Ssam /***
54013697Ssam  *	argok(xc, cmd)		check for valid command/argumanet
54113697Ssam  *			*NOTE - side effect is to set xc to the
54213697Ssam  *				command to be executed.
54313697Ssam  *	char *xc, *cmd;
54413697Ssam  *
54513697Ssam  *	return 0 - ok | 1 nok
54613697Ssam  */
54713697Ssam 
54813697Ssam argok(xc, cmd)
54913697Ssam register char *xc, *cmd;
55013697Ssam {
55113697Ssam 	register char **ptr;
55213697Ssam 
55313697Ssam #ifndef ALLOK
55413697Ssam 	/* don't allow sh command strings `....` */
55513697Ssam 	/* don't allow redirection of standard in or out  */
55613697Ssam 	/* don't allow other funny stuff */
55713697Ssam 	/* but there are probably total holes here */
55813697Ssam 	/* post-script.  ittvax!swatt has a uuxqt that solves this. */
55913697Ssam 	/* This version of uuxqt will shortly disappear */
56013697Ssam 	if (index(cmd, '`') != NULL
56113697Ssam 	  || index(cmd, '>') != NULL
56213697Ssam 	  || index(cmd, ';') != NULL
56313697Ssam 	  || index(cmd, '^') != NULL
56413697Ssam 	  || index(cmd, '&') != NULL
56513697Ssam 	  || index(cmd, '|') != NULL
566*17846Sralph 	  || index(cmd, '<') != NULL) {
567*17846Sralph 		DEBUG(1,"MAGIC CHARACTER FOUND\n", CNULL);
568*17846Sralph 		return FAIL;
569*17846Sralph 	}
570*17846Sralph #endif !ALLOK
57113697Ssam 
57213697Ssam 	if (xc[0] != '\0')
573*17846Sralph 		return SUCCESS;
57413697Ssam 
57513697Ssam #ifndef ALLOK
57613697Ssam 	ptr = Cmds;
577*17846Sralph 	DEBUG(9, "Compare %s and\n", cmd);
57813697Ssam 	while(*ptr != NULL) {
579*17846Sralph 		DEBUG(9, "\t%s\n", *ptr);
58013697Ssam 		if (strcmp(cmd, *ptr) == SAME)
58113697Ssam 			break;
582*17846Sralph 		ptr++;
58313697Ssam 	}
584*17846Sralph 	if (*ptr == NULL) {
585*17846Sralph 		DEBUG(1,"COMMAND NOT FOUND\n", CNULL);
586*17846Sralph 		return FAIL;
587*17846Sralph 	}
58813697Ssam #endif
58913697Ssam 	strcpy(xc, cmd);
590*17846Sralph 	DEBUG(9, "MATCHED %s\n", xc);
591*17846Sralph 	return SUCCESS;
59213697Ssam }
59313697Ssam 
59413697Ssam 
59513697Ssam /***
596*17846Sralph  *	chknotify(cmd)	check if notification should be sent for
597*17846Sralph  *			successful execution of cmd
598*17846Sralph  *	char *cmd;
599*17846Sralph  *
600*17846Sralph  *	return NT_YES - do notification
601*17846Sralph  *	       NT_ERR - do notification if exit status != 0
602*17846Sralph  *	       NT_NO  - don't do notification ever
603*17846Sralph  */
604*17846Sralph 
605*17846Sralph chknotify(cmd)
606*17846Sralph char *cmd;
607*17846Sralph {
608*17846Sralph 	register char **ptr;
609*17846Sralph 	register int *nptr;
610*17846Sralph 
611*17846Sralph 	ptr = Cmds;
612*17846Sralph 	nptr = Notify;
613*17846Sralph 	while (*ptr != NULL) {
614*17846Sralph 		if (strcmp(cmd, *ptr) == SAME)
615*17846Sralph 			return *nptr;
616*17846Sralph 		ptr++;
617*17846Sralph 		nptr++;
618*17846Sralph 	}
619*17846Sralph 	return NT_YES;		/* "shouldn't happen" */
620*17846Sralph }
621*17846Sralph 
622*17846Sralph 
623*17846Sralph 
624*17846Sralph /***
62513697Ssam  *	notify	send mail to user giving execution results
62613697Ssam  *	return code - none
62713697Ssam  *	This program assumes new mail command - send remote mail
62813697Ssam  */
62913697Ssam 
63013697Ssam notify(user, rmt, cmd, str)
63113697Ssam char *user, *rmt, *cmd, *str;
63213697Ssam {
63313697Ssam 	char text[MAXFULLNAME];
63413697Ssam 	char ruser[MAXFULLNAME];
63513697Ssam 
636*17846Sralph 	sprintf(text, "uuxqt cmd (%s) status (%s)", cmd, str);
63713697Ssam 	if (prefix(rmt, Myname))
63813697Ssam 		strcpy(ruser, user);
63913697Ssam 	else
64013697Ssam 		sprintf(ruser, "%s!%s", rmt, user);
641*17846Sralph 	mailst(ruser, text, CNULL);
64213697Ssam 	return;
64313697Ssam }
64413697Ssam 
64513697Ssam /***
64613697Ssam  *	retosndr - return mail to sender
64713697Ssam  *
64813697Ssam  *	return code - none
64913697Ssam  */
65013697Ssam 
65113697Ssam retosndr(user, rmt, file)
65213697Ssam char *user, *rmt, *file;
65313697Ssam {
654*17846Sralph 	char ruser[MAXFULLNAME];
65513697Ssam 
65613697Ssam 	if (strcmp(rmt, Myname) == SAME)
65713697Ssam 		strcpy(ruser, user);
65813697Ssam 	else
65913697Ssam 		sprintf(ruser, "%s!%s", rmt, user);
66013697Ssam 
66113697Ssam 	if (anyread(file) == 0)
66213697Ssam 		mailst(ruser, "Mail failed.  Letter returned to sender.\n", file);
66313697Ssam 	else
664*17846Sralph 		mailst(ruser, "Mail failed.  Letter returned to sender.\n", CNULL);
66513697Ssam 	return;
66613697Ssam }
667