1: /* 2: * This software is Copyright (c) 1986 by Rick Adams. 3: * 4: * Permission is hereby granted to copy, reproduce, redistribute or 5: * otherwise use this software as long as: there is no monetary 6: * profit gained specifically from the use or reproduction or this 7: * software, it is not sold, rented, traded or otherwise marketed, and 8: * this copyright notice is included prominently in any copy 9: * made. 10: * 11: * The author make no claims as to the fitness or correctness of 12: * this software for any use whatsoever, and it is provided as is. 13: * Any use of this software is at the user's own risk. 14: * 15: * recmail: read a mail message on stdin, grab all addresses in To and Cc 16: * lines, and pass the full message to all addressees. This is useful to 17: * send the output of a recently edited mail message (with headers edited too). 18: * It is similar to sendmail -t, but only assumes /bin/mail. 19: * To use your own mailer, e. g. nmail, compile with -DMAILER=my_mailer. 20: */ 21: 22: #ifdef SCCSID 23: static char *SccsId = "@(#)recmail.c 1.13 3/19/86"; 24: #endif /* SCCSID */ 25: 26: #include "params.h" 27: 28: #ifndef MAILER 29: #define MAILER "/bin/mail" 30: #endif 31: char mailer[] = MAILER; 32: 33: #define MAXRECIPS 100 34: char *recips[MAXRECIPS]; 35: int nrecips = 0; 36: 37: main() 38: { 39: FILE *fd; 40: char *tmpf; 41: FILE *errfd; 42: char *errf; 43: char linebuf[1024]; 44: int i, pid, wpid; 45: int exstat; 46: char *mypath; 47: int goodcnt, badcnt; 48: char *mktemp(), *getenv(); 49: 50: tmpf = mktemp("/tmp/rmXXXXXX"); 51: (void) close(creat(tmpf,0666)); 52: fd = fopen(tmpf, "w"); 53: errf = mktemp("/tmp/rmXXXXXX"); 54: (void) close(creat(errf,0666)); 55: errfd = fopen(errf, "w"); 56: fprintf(errfd, "Subject: Returned mail\n"); 57: fprintf(errfd, "\n ----- Transcript of session follows -----\n"); 58: (void) fflush(errfd); 59: goodcnt = badcnt = 0; 60: 61: while (fgets(linebuf, sizeof linebuf, stdin) != NULL) { 62: if ((strncmp(linebuf, "Bcc: ", 5) == 0 || 63: strncmp(linebuf, "bcc: ", 5) == 0 || 64: strncmp(linebuf, "BCC: ", 5) == 0)) { 65: if (linebuf[5] != '\n') 66: addrecips(linebuf+5); 67: } 68: else if (fputs(linebuf, fd) == EOF) 69: goto werror; 70: if (linebuf[0] == '\n') 71: break; 72: if ((strncmp(linebuf, "To: ", 4) == 0 || 73: strncmp(linebuf, "to: ", 4) == 0 || 74: strncmp(linebuf, "TO: ", 4) == 0 || 75: strncmp(linebuf, "Cc: ", 4) == 0 || 76: strncmp(linebuf, "cc: ", 4) == 0 || 77: strncmp(linebuf, "CC: ", 4) == 0) && 78: linebuf[4] != '\n') 79: addrecips(linebuf+4); 80: } 81: if (!feof(stdin)) { 82: while (fgets(linebuf, sizeof linebuf, stdin) != NULL) { 83: if (fputs(linebuf, fd) == EOF) { 84: werror: 85: printf("write error on temp file\n"); 86: exit(2); 87: } 88: } 89: } 90: /* 91: * Append the contents of the .signature file (if it exists) to 92: * the end of the mail message 93: */ 94: { 95: char sigbuf[BUFSIZ]; 96: register c; 97: register char *p = getenv("HOME"); 98: FILE *infp; 99: 100: if (p) { 101: (void) sprintf(sigbuf, "%s/%s", p, ".signature"); 102: if (infp = fopen(sigbuf, "r")) { 103: fprintf(fd,"---\n"); 104: while ((c = getc(infp)) != EOF) 105: putc(c,fd); 106: (void) fclose(infp); 107: } 108: } 109: } 110: (void) fclose(fd); 111: 112: /* 113: * Force the path to only consider /bin and /usr/bin, since 114: * that's the version of mail we want (not /usr/ucb/mail) 115: * This code will probably cause a core dump some day. 116: */ 117: mypath = getenv("PATH"); 118: if (mypath) 119: strcpy(mypath, "/bin:/usr/bin"); 120: 121: /* 122: * We send the copies out separately, because of a bug in 123: * USG's /bin/mail which will generate ANOTHER To: line, 124: * even though we already have one, if there are at least 125: * two recipients. 126: */ 127: for (i=0; i<nrecips; i++) { 128: /* 129: * mail recips[i] < tmpf 130: */ 131: pid = mailto(tmpf, errfd, recips[i]); 132: exstat = -1; 133: while ((wpid = wait(&exstat)) >= 0 && wpid != pid) 134: ; 135: if (exstat == 0) 136: goodcnt++; 137: else 138: badcnt++; 139: } 140: if (badcnt) { 141: mailback(errfd, tmpf, errf); 142: (void) unlink(tmpf); 143: (void) unlink(errf); 144: exit(1); 145: } else if (goodcnt == 0) { 146: fprintf(errfd, "recmail: no 'To:' line\n"); 147: mailback(errfd, tmpf, errf); 148: (void) unlink(tmpf); 149: (void) unlink(errf); 150: exit (1); 151: } 152: (void) unlink(tmpf); 153: (void) unlink(errf); 154: exit (0); 155: } 156: 157: #define isok(c) (isprint(c) && (c) != ' ' && c != ',') 158: addrecips(line) 159: char *line; 160: { 161: char *front, *back, *tail; 162: char *malloc(); 163: 164: tail = line + strlen(line); 165: for (front=line; front < tail; ) { 166: while (!isok(*front) && front < tail) 167: front++; 168: if (front >= tail) 169: break; /* skip end of line garbage */ 170: for (back=front; isok(*back); back++) 171: ; 172: *back=0; 173: if (nrecips >= MAXRECIPS) { 174: printf("Too many destinations\n"); 175: exit(2); 176: } 177: if ((recips[nrecips] = malloc(strlen(front) + 1)) == NULL) { 178: printf("Out of space\n"); 179: exit(2); 180: } 181: (void) strcpy(recips[nrecips], front); 182: nrecips++; 183: front = back+1; 184: } 185: } 186: 187: int 188: mailto(tmpf, errfd, recip) 189: char *tmpf; 190: FILE *errfd; 191: char *recip; 192: { 193: register int pid; 194: 195: /* 196: * mail recips < tmpf 197: */ 198: while ((pid = fork()) == -1) { 199: fprintf(stderr, "fork failed, waiting...\r\n"); 200: sleep(60); 201: } 202: if (pid == 0) { 203: (void) close(0); 204: (void) open(tmpf, 0); 205: if (errfd != NULL) { 206: (void) close(1); 207: (void) dup(fileno(errfd)); 208: (void) fclose(errfd); 209: (void) close(2); 210: (void) dup(1); 211: } 212: execlp(mailer, mailer, recip, (char *)0); 213: perror(mailer); 214: exit(1); 215: } 216: return pid; 217: } 218: 219: mailback(errfd, tmpf, errf) 220: register FILE *errfd; 221: char *tmpf; 222: char *errf; 223: { 224: register FILE *fd; 225: register int c; 226: int exstat; 227: register int pid, wpid; 228: char *logn; 229: char *getlogin(), *getenv(); 230: register struct passwd *pwd; 231: 232: if ((fd = fopen(tmpf, "r")) != NULL) { 233: fprintf(errfd, "\n ----- Unsent message follows -----\n"); 234: while ((c = getc(fd)) != EOF) 235: putc(c, errfd); 236: (void) fclose(fd); 237: } 238: (void) fclose(errfd); 239: if ((logn = getlogin()) == NULL && (logn = getenv("USER")) == NULL) { 240: if ((pwd = getpwent(getuid())) == NULL) 241: return; 242: logn = pwd->pw_name; 243: } 244: pid = mailto(errf, (FILE *)NULL, logn); 245: while ((wpid = wait(&exstat)) >= 0 && wpid != pid) 246: ; 247: }