X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/3184019bcb217265d1caa25c1cd3be1ba6abb32e..ca8907b2bb768fe1112070406459914c8335dd35:/usr/src/usr.bin/mail/send.c diff --git a/usr/src/usr.bin/mail/send.c b/usr/src/usr.bin/mail/send.c index 51f71fec5b..7cfae0ee07 100644 --- a/usr/src/usr.bin/mail/send.c +++ b/usr/src/usr.bin/mail/send.c @@ -4,6 +4,8 @@ #ifdef VMUNIX #include #endif +#include +#include /* * Mail -- a mail program @@ -11,38 +13,162 @@ * Mail to others. */ -static char *SccsId = "@(#)send.c 1.1 %G%"; +static char *SccsId = "@(#)send.c 2.11 %G%"; /* * Send message described by the passed pointer to the * passed output buffer. Return -1 on error, but normally - * the number of lines written. + * the number of lines written. Adjust the status: field + * if need be. If doign is set, suppress ignored header fields. */ - -send(mailp, obuf) +send(mailp, obuf, doign) struct message *mailp; FILE *obuf; { register struct message *mp; register int t; - unsigned int c; + long c; FILE *ibuf; - int lc; + char line[LINESIZE], field[BUFSIZ]; + int lc, ishead, infld, fline, dostat; + char *cp, *cp2; mp = mailp; ibuf = setinput(mp); - c = msize(mp); + c = mp->m_size; + ishead = 1; + dostat = 1; + infld = 0; + fline = 1; lc = 0; - while (c-- > 0) { - putc(t = getc(ibuf), obuf); - if (t == '\n') - lc++; + while (c > 0L) { + fgets(line, LINESIZE, ibuf); + c -= (long) strlen(line); + lc++; + if (ishead) { + /* + * First line is the From line, so no headers + * there to worry about + */ + if (fline) { + fline = 0; + goto writeit; + } + /* + * If line is blank, we've reached end of + * headers, so force out status: field + * and note that we are no longer in header + * fields + */ + if (line[0] == '\n') { + if (dostat) { + statusput(mailp, obuf, doign); + dostat = 0; + } + ishead = 0; + goto writeit; + } + /* + * If this line is a continuation (via space or tab) + * of a previous header field, just echo it + * (unless the field should be ignored). + */ + if (infld && (isspace(line[0]) || line[0] == '\t')) { + if (doign && isign(field)) continue; + goto writeit; + } + infld = 0; + /* + * If we are no longer looking at real + * header lines, force out status: + * This happens in uucp style mail where + * there are no headers at all. + */ + if (!headerp(line)) { + if (dostat) { + statusput(mailp, obuf, doign); + dostat = 0; + } + putc('\n', obuf); + ishead = 0; + goto writeit; + } + infld++; + /* + * Pick up the header field. + * If it is an ignored field and + * we care about such things, skip it. + */ + cp = line; + cp2 = field; + while (*cp && *cp != ':' && !isspace(*cp)) + *cp2++ = *cp++; + *cp2 = 0; + if (doign && isign(field)) + continue; + /* + * If the field is "status," go compute and print the + * real Status: field + */ + if (icequal(field, "status")) { + if (dostat) { + statusput(mailp, obuf, doign); + dostat = 0; + } + continue; + } + } +writeit: + fputs(line, obuf); if (ferror(obuf)) return(-1); } + if (ferror(obuf)) + return(-1); + if (ishead && (mailp->m_flag & MSTATUS)) + printf("failed to fix up status field\n"); return(lc); } +/* + * Test if the passed line is a header line, RFC 733 style. + */ +headerp(line) + register char *line; +{ + register char *cp = line; + + while (*cp && !isspace(*cp) && *cp != ':') + cp++; + while (*cp && isspace(*cp)) + cp++; + return(*cp == ':'); +} + +/* + * Output a reasonable looking status field. + * But if "status" is ignored and doign, forget it. + */ +statusput(mp, obuf, doign) + register struct message *mp; + register FILE *obuf; +{ + char statout[3]; + + if (doign && isign("status")) + return; + if ((mp->m_flag & (MNEW|MREAD)) == MNEW) + return; + if (mp->m_flag & MREAD) + strcpy(statout, "R"); + else + strcpy(statout, ""); + if ((mp->m_flag & MNEW) == 0) + strcat(statout, "O"); + fprintf(obuf, "Status: %s\n", statout); +} + + /* * Interface between the argument list and the mail1 routine * which does all the dirty work. @@ -112,8 +238,9 @@ mail1(hp) { register char *cp; int pid, i, s, p, gotcha; - char **namelist; + char **namelist, *deliver; struct name *to, *np; + struct stat sbuf; FILE *mtf, *postage; int remote = rflag != NOSTR || rmail; char **t; @@ -129,10 +256,6 @@ mail1(hp) hp->h_seq = 1; if (hp->h_subject == NOSTR) hp->h_subject = sflag; - if (fsize(mtf) == 0 && hp->h_subject == NOSTR) { - printf("No message !?!\n"); - goto out; - } if (intty && value("askcc") != NOSTR) grabh(hp, GCC); else if (intty) { @@ -185,6 +308,9 @@ topdog: if (hp->h_seq > 0 && !remote) { fixhead(hp, to); if (fsize(mtf) == 0) + if (hp->h_subject == NOSTR) + printf("No message, no subject; hope that's ok\n"); + else printf("Null message body; hope that's ok\n"); if ((mtf = infix(hp, mtf)) == NULL) { fprintf(stderr, ". . . message lost, sorry.\n"); @@ -212,7 +338,12 @@ topdog: */ #ifdef VMUNIX +#ifdef pdp11 + while (wait2(&s, WNOHANG) > 0) +#endif +#if defined(vax) || defined(sun) while (wait3(&s, WNOHANG, 0) > 0) +#endif ; #else wait(&s); @@ -226,20 +357,22 @@ topdog: goto out; } if (pid == 0) { + sigchild(); #ifdef SIGTSTP if (remote == 0) { - signal(SIGTSTP, SIG_IGN); - signal(SIGTTIN, SIG_IGN); - signal(SIGTTOU, SIG_IGN); + sigset(SIGTSTP, SIG_IGN); + sigset(SIGTTIN, SIG_IGN); + sigset(SIGTTOU, SIG_IGN); } #endif for (i = SIGHUP; i <= SIGQUIT; i++) - signal(i, SIG_IGN); - if ((postage = fopen("/crp/kurt/postage", "a")) != NULL) { - fprintf(postage, "%s %d %d\n", myname, - count(to), fsize(mtf)); - fclose(postage); - } + sigset(i, SIG_IGN); + if (!stat(POSTAGE, &sbuf)) + if ((postage = fopen(POSTAGE, "a")) != NULL) { + fprintf(postage, "%s %d %d\n", myname, + count(to), fsize(mtf)); + fclose(postage); + } s = fileno(mtf); for (i = 3; i < 15; i++) if (i != s) @@ -250,16 +383,18 @@ topdog: #ifdef CC submit(getpid()); #endif CC -#ifdef DELIVERMAIL - execv(DELIVERMAIL, namelist); -#endif DELIVERMAIL +#ifdef SENDMAIL + if ((deliver = value("sendmail")) == NOSTR) + deliver = SENDMAIL; + execv(deliver, namelist); +#endif SENDMAIL execv(MAIL, namelist); perror(MAIL); exit(1); } out: - if (remote) { + if (remote || (value("verbose") != NOSTR)) { while ((p = wait(&s)) != pid && p != -1) ; if (s != 0) @@ -311,6 +446,7 @@ infix(hp, fi) register FILE *nfo, *nfi; register int c; + rewind(fi); if ((nfo = fopen(tempMail, "w")) == NULL) { perror(tempMail); return(fi); @@ -322,7 +458,6 @@ infix(hp, fi) } remove(tempMail); puthead(hp, nfo, GTO|GSUBJECT|GCC|GNL); - rewind(fi); c = getc(fi); while (c != EOF) { putc(c, nfo); @@ -330,7 +465,6 @@ infix(hp, fi) } if (ferror(fi)) { perror("read"); - fprintf(stderr, "Please notify Kurt Shoens\n"); return(fi); } fflush(nfo); @@ -359,13 +493,13 @@ puthead(hp, fo, w) gotcha = 0; if (hp->h_to != NOSTR && w & GTO) - fprintf(fo, "To: "), fmt(hp->h_to, fo), gotcha++; + fmt("To: ", hp->h_to, fo), gotcha++; if (hp->h_subject != NOSTR && w & GSUBJECT) fprintf(fo, "Subject: %s\n", hp->h_subject), gotcha++; if (hp->h_cc != NOSTR && w & GCC) - fprintf(fo, "Cc: "), fmt(hp->h_cc, fo), gotcha++; + fmt("Cc: ", hp->h_cc, fo), gotcha++; if (hp->h_bcc != NOSTR && w & GBCC) - fprintf(fo, "Bcc: "), fmt(hp->h_bcc, fo), gotcha++; + fmt("Bcc: ", hp->h_bcc, fo), gotcha++; if (gotcha && w & GNL) putc('\n', fo); return(0); @@ -375,26 +509,44 @@ puthead(hp, fo, w) * Format the given text to not exceed 72 characters. */ -fmt(str, fo) - register char *str; +fmt(str, txt, fo) + register char *str, *txt; register FILE *fo; { register int col; - register char *cp; - - cp = str; - col = 0; - while (*cp) { - if (*cp == ' ' && col > 65) { - fprintf(fo, "\n "); + register char *bg, *bl, *pt, ch; + + col = strlen(str); + if (col) + fprintf(fo, "%s", str); + pt = bg = txt; + bl = 0; + while (*bg) { + pt++; + if (++col >72) { + if (!bl) { + bl = bg; + while (*bl && !isspace(*bl)) + bl++; + } + if (!*bl) + goto finish; + ch = *bl; + *bl = '\0'; + fprintf(fo, "%s\n ", bg); col = 4; - cp++; - continue; + *bl = ch; + pt = bg = ++bl; + bl = 0; + } + if (!*pt) { +finish: + fprintf(fo, "%s\n", bg); + return; } - putc(*cp++, fo); - col++; + if (isspace(*pt)) + bl = pt; } - putc('\n', fo); } /*