Annotation of 3BSD/cmd/ucbmail/send.c, revision 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.