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