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: }

Defined functions

addrecips defined in line 158; used 2 times
mailback defined in line 219; used 2 times
mailto defined in line 187; used 2 times
main defined in line 37; never used

Defined variables

SccsId defined in line 23; never used
mailer defined in line 31; used 3 times
nrecips defined in line 35; used 5 times
recips defined in line 34; used 3 times

Defined macros

MAILER defined in line 29; used 2 times
MAXRECIPS defined in line 33; used 2 times
isok defined in line 157; used 2 times
Last modified: 1986-03-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1654
Valid CSS Valid XHTML 1.0 Strict