|
|
1.1 ! root 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.16 9/24/87"; ! 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: */ ! 116: if (mailer[0] != '/') { ! 117: register int e; ! 118: extern char **environ; ! 119: for (e = 0; environ[e] != NULL; ++e) ! 120: if (strncmp(environ[e], "PATH=", 5) == 0) { ! 121: environ[e] = "PATH=/bin:/usr/bin"; ! 122: break; ! 123: } ! 124: } ! 125: mypath = getenv("PATH"); ! 126: if (mypath) ! 127: strcpy(mypath, "/bin:/usr/bin"); ! 128: ! 129: /* ! 130: * We send the copies out separately, because of a bug in ! 131: * USG's /bin/mail which will generate ANOTHER To: line, ! 132: * even though we already have one, if there are at least ! 133: * two recipients. ! 134: */ ! 135: for (i=0; i<nrecips; i++) { ! 136: /* ! 137: * mail recips[i] < tmpf ! 138: */ ! 139: pid = mailto(tmpf, errfd, recips[i]); ! 140: exstat = -1; ! 141: while ((wpid = wait(&exstat)) >= 0 && wpid != pid) ! 142: ; ! 143: if (exstat == 0) ! 144: goodcnt++; ! 145: else ! 146: badcnt++; ! 147: } ! 148: if (badcnt) { ! 149: mailback(errfd, tmpf, errf); ! 150: (void) unlink(tmpf); ! 151: (void) unlink(errf); ! 152: exit(1); ! 153: } else if (goodcnt == 0) { ! 154: fprintf(errfd, "recmail: no 'To:' line\n"); ! 155: mailback(errfd, tmpf, errf); ! 156: (void) unlink(tmpf); ! 157: (void) unlink(errf); ! 158: exit (1); ! 159: } ! 160: (void) unlink(tmpf); ! 161: (void) unlink(errf); ! 162: exit (0); ! 163: } ! 164: ! 165: #define isok(c) (isprint(c) && (c) != ' ' && c != ',') ! 166: addrecips(line) ! 167: char *line; ! 168: { ! 169: char *front, *back, *tail; ! 170: char *malloc(); ! 171: ! 172: tail = line + strlen(line); ! 173: for (front=line; front < tail; ) { ! 174: while (!isok(*front) && front < tail) ! 175: front++; ! 176: if (front >= tail) ! 177: break; /* skip end of line garbage */ ! 178: for (back=front; isok(*back); back++) ! 179: ; ! 180: *back=0; ! 181: if (nrecips >= MAXRECIPS) { ! 182: printf("Too many destinations\n"); ! 183: exit(2); ! 184: } ! 185: if ((recips[nrecips] = malloc(strlen(front) + 1)) == NULL) { ! 186: printf("Out of space\n"); ! 187: exit(2); ! 188: } ! 189: (void) strcpy(recips[nrecips], front); ! 190: nrecips++; ! 191: front = back+1; ! 192: } ! 193: } ! 194: ! 195: int ! 196: mailto(tmpf, errfd, recip) ! 197: char *tmpf; ! 198: FILE *errfd; ! 199: char *recip; ! 200: { ! 201: register int pid; ! 202: ! 203: /* ! 204: * mail recips < tmpf ! 205: */ ! 206: while ((pid = vfork()) == -1) { ! 207: fprintf(stderr, "fork failed, waiting...\r\n"); ! 208: sleep(60); ! 209: } ! 210: if (pid == 0) { ! 211: (void) close(0); ! 212: (void) open(tmpf, 0); ! 213: if (errfd != NULL) { ! 214: (void) close(1); ! 215: (void) dup(fileno(errfd)); ! 216: (void) fclose(errfd); ! 217: (void) close(2); ! 218: (void) dup(1); ! 219: } ! 220: execlp(mailer, mailer, recip, (char *)0); ! 221: perror(mailer); ! 222: exit(1); ! 223: } ! 224: return pid; ! 225: } ! 226: ! 227: mailback(errfd, tmpf, errf) ! 228: register FILE *errfd; ! 229: char *tmpf; ! 230: char *errf; ! 231: { ! 232: register FILE *fd; ! 233: register int c; ! 234: int exstat; ! 235: register int pid, wpid; ! 236: char *logn; ! 237: char *getlogin(), *getenv(); ! 238: register struct passwd *pwd; ! 239: ! 240: if ((fd = fopen(tmpf, "r")) != NULL) { ! 241: fprintf(errfd, "\n ----- Unsent message follows -----\n"); ! 242: while ((c = getc(fd)) != EOF) ! 243: putc(c, errfd); ! 244: (void) fclose(fd); ! 245: } ! 246: (void) fclose(errfd); ! 247: if ((logn = getlogin()) == NULL && (logn = getenv("USER")) == NULL) { ! 248: if ((pwd = getpwuid(getuid())) == NULL) ! 249: return; ! 250: logn = pwd->pw_name; ! 251: } ! 252: pid = mailto(errf, (FILE *)NULL, logn); ! 253: while ((wpid = wait(&exstat)) >= 0 && wpid != pid) ! 254: ; ! 255: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.