1: #ifndef lint 2: static char sccsid[] = "@(#)mailst.c 5.6 (Berkeley) 10/9/85"; 3: #endif 4: 5: #include <signal.h> 6: #include "uucp.h" 7: #ifdef USG 8: #include <fcntl.h> 9: #endif USG 10: 11: /*LINTLIBRARY*/ 12: 13: /* 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; 24: char buf[BUFSIZ]; 25: register int c; 26: 27: sprintf(buf, "%s '%s'", MAIL, user); 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); 37: } 38: } 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 * 51: rpopen(cmd, mode) 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 66: close(tst(0, 1)); 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: }