Annotation of 43BSD/contrib/news/src/recmail.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.