xref: /csrg-svn/usr.bin/uucp/libuu/mailst.c (revision 23612)
113662Ssam #ifndef lint
2*23612Sbloom static char sccsid[] = "@(#)mailst.c	5.5 (Berkeley) 06/20/85";
313662Ssam #endif
413662Ssam 
5*23612Sbloom #include <signal.h>
613662Ssam #include "uucp.h"
7*23612Sbloom #ifdef USG
8*23612Sbloom #include <fcntl.h>
9*23612Sbloom #endif USG
1013662Ssam 
11*23612Sbloom /*LINTLIBRARY*/
12*23612Sbloom 
1317835Sralph /*
1413662Ssam  *	mailst  -  this routine will fork and execute
1513662Ssam  *	a mail command sending string (str) to user (user).
1613662Ssam  *	If file is non-null, the file is also sent.
1713662Ssam  *	(this is used for mail returned to sender.)
1813662Ssam  */
1913662Ssam 
2013662Ssam mailst(user, str, file)
2113662Ssam char *user, *str, *file;
2213662Ssam {
2313662Ssam 	register FILE *fp, *fi;
2417835Sralph 	char buf[BUFSIZ];
2517835Sralph 	register int c;
2613662Ssam 
2718620Sralph 	sprintf(buf, "%s '%s'", MAIL, user);
2817835Sralph 	if ((fp = rpopen(buf, "w")) != NULL) {
2917835Sralph 		fprintf(fp, "From: uucp\nTo: %s\nSubject: %s\n\n", user, str);
3017835Sralph 		if (file && *file != '\0' && (fi = fopen(subfile(file), "r")) != NULL) {
3117835Sralph 			while ((c = getc(fi)) != EOF)
3217835Sralph 				putc(c, fp);
3317835Sralph 			putc('\n', fp);
3417835Sralph 			fclose(fi);
3517835Sralph 		}
3617835Sralph 		rpclose(fp);
3713662Ssam 	}
3813662Ssam }
39*23612Sbloom 
40*23612Sbloom /*
41*23612Sbloom  * 'reverting' version of popen
42*23612Sbloom  * which runs process with permissions of real gid/uid
43*23612Sbloom  * rather than the effective gid/uid.
44*23612Sbloom  */
45*23612Sbloom #define	tst(a,b)	(*mode == 'r'? (b) : (a))
46*23612Sbloom #define	RDR	0
47*23612Sbloom #define	WTR	1
48*23612Sbloom static	int	popen_pid[20];
49*23612Sbloom 
50*23612Sbloom FILE *
51*23612Sbloom rpopen(cmd,mode)
52*23612Sbloom char	*cmd;
53*23612Sbloom char	*mode;
54*23612Sbloom {
55*23612Sbloom 	int p[2];
56*23612Sbloom 	register myside, hisside, pid;
57*23612Sbloom 
58*23612Sbloom 	if(pipe(p) < 0)
59*23612Sbloom 		return NULL;
60*23612Sbloom 	myside = tst(p[WTR], p[RDR]);
61*23612Sbloom 	hisside = tst(p[RDR], p[WTR]);
62*23612Sbloom 	if((pid = fork()) == 0) {
63*23612Sbloom 		/* myside and hisside reverse roles in child */
64*23612Sbloom 		close(myside);
65*23612Sbloom #ifdef USG
66*23612Sbloom 		close(tst(0, 1);
67*23612Sbloom 		fcntl(hisside, F_DUPFD, tst(0, 1));
68*23612Sbloom #else !USG
69*23612Sbloom 		dup2(hisside, tst(0, 1));
70*23612Sbloom #endif !USG
71*23612Sbloom 		close(hisside);
72*23612Sbloom 		/* revert permissions */
73*23612Sbloom 		setgid(getgid());
74*23612Sbloom 		setuid(getuid());
75*23612Sbloom 		execl("/bin/sh", "sh", "-c", cmd, (char *)0);
76*23612Sbloom 		_exit(1);
77*23612Sbloom 	}
78*23612Sbloom 	if(pid == -1)
79*23612Sbloom 		return NULL;
80*23612Sbloom 	popen_pid[myside] = pid;
81*23612Sbloom 	close(hisside);
82*23612Sbloom 	return(fdopen(myside, mode));
83*23612Sbloom }
84*23612Sbloom 
85*23612Sbloom rpclose(ptr)
86*23612Sbloom FILE *ptr;
87*23612Sbloom {
88*23612Sbloom 	register f, r, (*hstat)(), (*istat)(), (*qstat)();
89*23612Sbloom 	int status;
90*23612Sbloom 
91*23612Sbloom 	f = fileno(ptr);
92*23612Sbloom 	fclose(ptr);
93*23612Sbloom 	istat = signal(SIGINT, SIG_IGN);
94*23612Sbloom 	qstat = signal(SIGQUIT, SIG_IGN);
95*23612Sbloom 	hstat = signal(SIGHUP, SIG_IGN);
96*23612Sbloom 	while((r = wait(&status)) != popen_pid[f] && r != -1)
97*23612Sbloom 		;
98*23612Sbloom 	if(r == -1)
99*23612Sbloom 		status = -1;
100*23612Sbloom 	signal(SIGINT, istat);
101*23612Sbloom 	signal(SIGQUIT, qstat);
102*23612Sbloom 	signal(SIGHUP, hstat);
103*23612Sbloom 	return status;
104*23612Sbloom }
105