grammar
[unix-history] / usr / src / usr.bin / uucp / libuu / mailst.c
CommitLineData
c635088c 1#ifndef lint
103ae3d5 2static char sccsid[] = "@(#)mailst.c 5.6 (Berkeley) %G%";
c635088c
SL
3#endif
4
4edd6f7b 5#include <signal.h>
c635088c 6#include "uucp.h"
4edd6f7b
JB
7#ifdef USG
8#include <fcntl.h>
9#endif USG
10
11/*LINTLIBRARY*/
c635088c 12
46b15d8a 13/*
c635088c
SL
14 * mailst - this routine will fork and execute
15 * a mail command sending string (str) to user (user).
16 * If file is non-null, the file is also sent.
17 * (this is used for mail returned to sender.)
18 */
19
20mailst(user, str, file)
21char *user, *str, *file;
22{
23 register FILE *fp, *fi;
46b15d8a
RC
24 char buf[BUFSIZ];
25 register int c;
c635088c 26
1a85e9d2 27 sprintf(buf, "%s '%s'", MAIL, user);
46b15d8a
RC
28 if ((fp = rpopen(buf, "w")) != NULL) {
29 fprintf(fp, "From: uucp\nTo: %s\nSubject: %s\n\n", user, str);
30 if (file && *file != '\0' && (fi = fopen(subfile(file), "r")) != NULL) {
31 while ((c = getc(fi)) != EOF)
32 putc(c, fp);
33 putc('\n', fp);
34 fclose(fi);
35 }
36 rpclose(fp);
c635088c 37 }
c635088c 38}
4edd6f7b
JB
39
40/*
41 * 'reverting' version of popen
42 * which runs process with permissions of real gid/uid
43 * rather than the effective gid/uid.
44 */
45#define tst(a,b) (*mode == 'r'? (b) : (a))
46#define RDR 0
47#define WTR 1
48static int popen_pid[20];
49
50FILE *
103ae3d5 51rpopen(cmd, mode)
4edd6f7b
JB
52char *cmd;
53char *mode;
54{
55 int p[2];
56 register myside, hisside, pid;
57
58 if(pipe(p) < 0)
59 return NULL;
60 myside = tst(p[WTR], p[RDR]);
61 hisside = tst(p[RDR], p[WTR]);
62 if((pid = fork()) == 0) {
63 /* myside and hisside reverse roles in child */
64 close(myside);
65#ifdef USG
103ae3d5 66 close(tst(0, 1));
4edd6f7b
JB
67 fcntl(hisside, F_DUPFD, tst(0, 1));
68#else !USG
69 dup2(hisside, tst(0, 1));
70#endif !USG
71 close(hisside);
72 /* revert permissions */
73 setgid(getgid());
74 setuid(getuid());
75 execl("/bin/sh", "sh", "-c", cmd, (char *)0);
76 _exit(1);
77 }
78 if(pid == -1)
79 return NULL;
80 popen_pid[myside] = pid;
81 close(hisside);
82 return(fdopen(myside, mode));
83}
84
85rpclose(ptr)
86FILE *ptr;
87{
88 register f, r, (*hstat)(), (*istat)(), (*qstat)();
89 int status;
90
91 f = fileno(ptr);
92 fclose(ptr);
93 istat = signal(SIGINT, SIG_IGN);
94 qstat = signal(SIGQUIT, SIG_IGN);
95 hstat = signal(SIGHUP, SIG_IGN);
96 while((r = wait(&status)) != popen_pid[f] && r != -1)
97 ;
98 if(r == -1)
99 status = -1;
100 signal(SIGINT, istat);
101 signal(SIGQUIT, qstat);
102 signal(SIGHUP, hstat);
103 return status;
104}