Annotation of 3BSD/cmd/ucbmail/send.c, revision 1.1.1.1

1.1       root        1: #
                      2: 
                      3: #include "rcv.h"
                      4: 
                      5: /*
                      6:  * Mail -- a mail program
                      7:  *
                      8:  * Mail to others.
                      9:  */
                     10: 
                     11: /*
                     12:  * Send message described by the passed pointer to the
                     13:  * passed output buffer.  Return -1 on error, but normally
                     14:  * the number of lines written.
                     15:  */
                     16: 
                     17: send(mailp, obuf)
                     18:        struct message *mailp;
                     19:        FILE *obuf;
                     20: {
                     21:        register struct message *mp;
                     22:        register int t;
                     23:        unsigned int c;
                     24:        FILE *ibuf;
                     25:        int lc;
                     26: 
                     27:        mp = mailp;
                     28:        ibuf = setinput(mp);
                     29:        c = msize(mp);
                     30:        lc = 0;
                     31:        while (c-- > 0) {
                     32:                putc(t = getc(ibuf), obuf);
                     33:                if (t == '\n')
                     34:                        lc++;
                     35:                if (ferror(obuf))
                     36:                        return(-1);
                     37:        }
                     38:        return(lc);
                     39: }
                     40: 
                     41: /*
                     42:  * Interface between the argument list and the mail1 routine
                     43:  * which does all the dirty work.
                     44:  */
                     45: 
                     46: mail(people)
                     47:        char **people;
                     48: {
                     49:        register char *cp2;
                     50:        register int s;
                     51:        char *buf, **ap;
                     52:        struct header head;
                     53: 
                     54:        for (s = 0, ap = people; *ap != (char *) -1; ap++)
                     55:                s += strlen(*ap) + 1;
                     56:        buf = salloc(s+1);
                     57:        cp2 = buf;
                     58:        for (ap = people; *ap != (char *) -1; ap++) {
                     59:                cp2 = copy(*ap, cp2);
                     60:                *cp2++ = ' ';
                     61:        }
                     62:        if (cp2 != buf)
                     63:                cp2--;
                     64:        *cp2 = '\0';
                     65:        head.h_to = buf;
                     66:        head.h_subject = NOSTR;
                     67:        head.h_cc = NOSTR;
                     68:        head.h_bcc = NOSTR;
                     69:        head.h_seq = 0;
                     70:        mail1(&head);
                     71:        return(0);
                     72: }
                     73: 
                     74: 
                     75: /*
                     76:  * Send mail to a bunch of user names.  The interface is through
                     77:  * the mail routine below.
                     78:  */
                     79: 
                     80: sendmail(str)
                     81:        char *str;
                     82: {
                     83:        register char **ap;
                     84:        char *bufp;
                     85:        register int t;
                     86:        struct header head;
                     87: 
                     88:        if (blankline(str))
                     89:                head.h_to = NOSTR;
                     90:        else
                     91:                head.h_to = str;
                     92:        head.h_subject = NOSTR;
                     93:        head.h_cc = NOSTR;
                     94:        head.h_bcc = NOSTR;
                     95:        head.h_seq = 0;
                     96:        mail1(&head);
                     97:        return(0);
                     98: }
                     99: 
                    100: /*
                    101:  * Mail a message on standard input to the people indicated
                    102:  * in the passed header.  (Internal interface).
                    103:  */
                    104: 
                    105: mail1(hp)
                    106:        struct header *hp;
                    107: {
                    108:        register char *cp;
                    109:        int pid, i, s;
                    110:        char **namelist;
                    111:        struct name *to;
                    112:        FILE *mtf;
                    113: 
                    114:        /*
                    115:         * Collect user's mail from standard input.
                    116:         * Get the result as mtf.
                    117:         */
                    118: 
                    119:        pid = -1;
                    120:        if (hp->h_subject == NOSTR)
                    121:                hp->h_seq = 0;
                    122:        else
                    123:                hp->h_seq = 1;
                    124:        if ((mtf = collect(hp)) == NULL)
                    125:                return(-1);
                    126:        if (fsize(mtf) == 0 && hp->h_subject == NOSTR) {
                    127:                printf("No message !?!\n");
                    128:                goto out;
                    129:        }
                    130:        if (intty && value("askcc") != NOSTR)
                    131:                grabh(hp, GCC);
                    132:        else if (intty) {
                    133:                printf("EOT\n");
                    134:                flush();
                    135:        }
                    136: 
                    137:        /*
                    138:         * Now, take the user names from the combined
                    139:         * to and cc lists and do all the alias
                    140:         * processing.
                    141:         */
                    142: 
                    143:        senderr = 0;
                    144:        to = usermap(cat(extract(hp->h_bcc),
                    145:            cat(extract(hp->h_to), extract(hp->h_cc))));
                    146:        if (to == NIL) {
                    147:                printf("No recipients specified\n");
                    148:                goto topdog;
                    149:        }
                    150: 
                    151:        /*
                    152:         * Look through the recipient list for names with /'s
                    153:         * in them which we write to as files directly.
                    154:         */
                    155: 
                    156:        to = outof(to, mtf, hp);
                    157:        rewind(mtf);
                    158:        to = verify(to);
                    159:        if (senderr) {
                    160: topdog:
                    161:                remove(deadletter);
                    162:                exwrite(deadletter, mtf, 1);
                    163:                rewind(mtf);
                    164:        }
                    165:        if (to == NIL)
                    166:                goto out;
                    167:        to = elide(to);
                    168:        mechk(to);
                    169:        if (count(to) > 1)
                    170:                hp->h_seq++;
                    171:        if (hp->h_seq > 0)
                    172:                if ((mtf = infix(hp, mtf)) == NULL) {
                    173:                        fprintf(stderr, ". . . message lost, sorry.\n");
                    174:                        return(-1);
                    175:                }
                    176:        namelist = unpack(to);
                    177:        if (value("record") != NOSTR)
                    178:                savemail(value("record"), hp, mtf, namelist);
                    179: 
                    180:        /*
                    181:         * Wait, to absorb a potential zombie, then
                    182:         * fork, set up the temporary mail file as standard
                    183:         * input for "mail" and exec with the user list we generated
                    184:         * far above. Return the process id to caller in case he
                    185:         * wants to await the completion of mail.
                    186:         */
                    187: 
                    188:        wait(&s);
                    189:        rewind(mtf);
                    190:        pid = fork();
                    191:        if (pid == -1) {
                    192:                perror("fork");
                    193:                remove(deadletter);
                    194:                exwrite(deadletter, mtf, 1);
                    195:                goto out;
                    196:        }
                    197:        if (pid == 0) {
                    198:                for (i = SIGHUP; i <= SIGQUIT; i++)
                    199:                        signal(i, SIG_IGN);
                    200:                s = fileno(mtf);
                    201:                for (i = 3; i < 15; i++)
                    202:                        if (i != s)
                    203:                                close(i);
                    204:                close(0);
                    205:                dup(s);
                    206:                close(s);
                    207: #ifdef CC
                    208:                submit(getpid());
                    209: #endif
                    210:                execv(MAIL, namelist);
                    211:                perror(MAIL);
                    212:                exit(1);
                    213:        }
                    214: 
                    215: out:
                    216:        fclose(mtf);
                    217:        return(pid);
                    218: }
                    219: 
                    220: /*
                    221:  * Prepend a header in front of the collected stuff
                    222:  * and return the new file.
                    223:  */
                    224: 
                    225: FILE *
                    226: infix(hp, fi)
                    227:        struct header *hp;
                    228:        FILE *fi;
                    229: {
                    230:        extern char tempMail[];
                    231:        register FILE *nfo, *nfi;
                    232:        register int c;
                    233: 
                    234:        if ((nfo = fopen(tempMail, "w")) == NULL) {
                    235:                perror(tempMail);
                    236:                return(fi);
                    237:        }
                    238:        if ((nfi = fopen(tempMail, "r")) == NULL) {
                    239:                perror(tempMail);
                    240:                fclose(nfo);
                    241:                return(fi);
                    242:        }
                    243:        remove(tempMail);
                    244:        puthead(hp, nfo, GTO|GSUBJECT|GCC);
                    245:        c = getc(fi);
                    246:        while (c != EOF) {
                    247:                putc(c, nfo);
                    248:                c = getc(fi);
                    249:        }
                    250:        fflush(nfo);
                    251:        if (ferror(nfo)) {
                    252:                perror(tempMail);
                    253:                fclose(nfo);
                    254:                fclose(nfi);
                    255:                return(fi);
                    256:        }
                    257:        fclose(nfo);
                    258:        fclose(fi);
                    259:        rewind(nfi);
                    260:        return(nfi);
                    261: }
                    262: 
                    263: /*
                    264:  * Dump the to, subject, cc header on the
                    265:  * passed file buffer.
                    266:  */
                    267: 
                    268: puthead(hp, fo, w)
                    269:        struct header *hp;
                    270:        FILE *fo;
                    271: {
                    272:        register int gotcha;
                    273: 
                    274:        gotcha = 0;
                    275:        if (hp->h_to != NOSTR && w & GTO)
                    276:                fprintf(fo, "To: %s\n", hp->h_to), gotcha++;
                    277:        if (hp->h_subject != NOSTR && w & GSUBJECT)
                    278:                fprintf(fo, "Subject: %s\n", hp->h_subject), gotcha++;
                    279:        if (hp->h_cc != NOSTR && w & GCC)
                    280:                fprintf(fo, "Cc: %s\n", hp->h_cc), gotcha++;
                    281:        if (hp->h_bcc != NOSTR && w & GBCC)
                    282:                fprintf(fo, "Bcc: %s\n", hp->h_bcc), gotcha++;
                    283:        if (gotcha)
                    284:                putc('\n', fo);
                    285:        return(0);
                    286: }
                    287: 
                    288: /*
                    289:  * Save the outgoing mail on the passed file.
                    290:  */
                    291: 
                    292: savemail(name, hp, fi, tolist)
                    293:        char name[], **tolist;
                    294:        struct header *hp;
                    295:        FILE *fi;
                    296: {
                    297:        register FILE *fo;
                    298:        register int c;
                    299:        long now;
                    300: 
                    301:        if ((fo = fopen(name, "a")) == NULL) {
                    302:                perror(name);
                    303:                return(-1);
                    304:        }
                    305:        time(&now);
                    306:        fprintf(fo, "From %s %s", *(tolist+1), ctime(&now));
                    307:        rewind(fi);
                    308:        for (c = getc(fi); c != EOF; c = getc(fi))
                    309:                putc(c, fo);
                    310:        fprintf(fo, "\n");
                    311:        fflush(fo);
                    312:        if (ferror(fo))
                    313:                perror(name);
                    314:        fclose(fo);
                    315:        return(0);
                    316: }

unix.superglobalmegacorp.com

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