Commit | Line | Data |
---|---|---|
c635088c | 1 | #ifndef lint |
103ae3d5 | 2 | static 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 | ||
20 | mailst(user, str, file) | |
21 | char *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 | |
48 | static int popen_pid[20]; | |
49 | ||
50 | FILE * | |
103ae3d5 | 51 | rpopen(cmd, mode) |
4edd6f7b JB |
52 | char *cmd; |
53 | char *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 | ||
85 | rpclose(ptr) | |
86 | FILE *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 | } |