X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/042f5bed7ff3e5b34ff3166951a7b98bf6bbf105..9a87f2bf9289ef232ec8c267fd7be76120c87ca2:/uip/post.c diff --git a/uip/post.c b/uip/post.c index 3c9a61e8..6dc18d10 100644 --- a/uip/post.c +++ b/uip/post.c @@ -15,6 +15,8 @@ #include #include #include +#include "../sbr/m_mktemp.h" +#include "../sbr/message_id.h" #ifdef HAVE_SYS_TIME_H # include @@ -288,8 +290,9 @@ static char *partno = NULL; static void putfmt (char *, char *, int *, FILE *); static void start_headers (void); static void finish_headers (FILE *); -static int get_header (char *, struct headers *); -static int putadr (char *, char *, struct mailname *, FILE *, unsigned int); +static int get_header (char *, struct headers *) PURE; +static int putadr (char *, char *, struct mailname *, FILE *, unsigned int, + char *, unsigned int); static void putgrp (char *, char *, FILE *, unsigned int); static int insert (struct mailname *); static void pl (void); @@ -298,12 +301,12 @@ static int annoaux (struct mailname *); static void insert_fcc (struct headers *, char *); static void make_bcc_file (int); static void verify_all_addresses (int, int, char *, int, char *); -static void chkadr (void); +static void chkadr (void) PURE; static void sigon (void); static void sigoff (void); static void p_refile (char *); static void fcc (char *, char *); -static void die (char *, char *, ...); +static void fatal (char *, char *, ...) CHECK_PRINTF(2, 3); static void post (char *, int, int, int, char *, int, char *); static void do_text (char *file, int fd); static void do_an_address (struct mailname *, int); @@ -320,7 +323,7 @@ main (int argc, char **argv) char *cp, *msg = NULL, **argp, **arguments, *envelope; char buf[NMH_BUFSIZ], name[NAMESZ], *auth_svc = NULL; FILE *in, *out; - m_getfld_state_t gstate = 0; + m_getfld_state_t gstate; if (nmh_init(argv[0], 0 /* use context_foil() */)) { return 1; } @@ -581,8 +584,7 @@ main (int argc, char **argv) } if (msg) adios (NULL, "only one message at a time!"); - else - msg = cp; + msg = cp; } alias (AliasFile); @@ -616,16 +618,17 @@ main (int argc, char **argv) hdrtab = msgstate == NORMAL ? NHeaders : RHeaders; + gstate = m_getfld_state_init(in); for (compnum = 1;;) { int bufsz = sizeof buf; - switch (state = m_getfld (&gstate, name, buf, &bufsz, in)) { + switch (state = m_getfld2(&gstate, name, buf, &bufsz)) { case FLD: case FLDPLUS: compnum++; cp = mh_xstrdup(buf); while (state == FLDPLUS) { bufsz = sizeof buf; - state = m_getfld (&gstate, name, buf, &bufsz, in); + state = m_getfld2(&gstate, name, buf, &bufsz); cp = add (buf, cp); } putfmt (name, cp, &eai, out); @@ -639,7 +642,7 @@ main (int argc, char **argv) fprintf (out, "\n%s", buf); while (state == BODY) { bufsz = sizeof buf; - state = m_getfld (&gstate, name, buf, &bufsz, in); + state = m_getfld2(&gstate, name, buf, &bufsz); fputs (buf, out); } break; @@ -666,9 +669,8 @@ main (int argc, char **argv) if (debug) { pl (); done (0); - } else { - fclose (out); } + fclose (out); /* * Here's how we decide which address to use as the envelope-from @@ -788,6 +790,8 @@ putfmt (char *name, char *str, int *eai, FILE *out) int count, grp, i, keep; char *cp, *pp, *qp; char namep[BUFSIZ], error[BUFSIZ]; + char *savehdr = NULL; + unsigned int savehdrlen = 0; struct mailname *mp = NULL, *np = NULL; struct headers *hdr; @@ -871,6 +875,19 @@ putfmt (char *name, char *str, int *eai, FILE *out) return; } + /* + * If this is a From:/Resent-From: header, save the full thing for + * later in case we need it for use when constructing a Bcc draft message. + * Because we want to capture the results of alias expansion, save + * the output from putadr(). + */ + + if ((msgstate == RESENT) ? (hdr->set & MRFM) : (hdr->set & MFRM)) { + savehdr = fullfrom; + savehdr[0] = '\0'; + savehdrlen = sizeof(fullfrom); + } + tmpaddrs.m_next = NULL; for (count = 0; (cp = getname (str)); count++) { @@ -971,9 +988,8 @@ putfmt (char *name, char *str, int *eai, FILE *out) mp->m_bcc++; if (np->m_ingrp) mp->m_ingrp = np->m_ingrp; - else - if (mp->m_gname) - putgrp (namep, mp->m_gname, out, hdr->flags); + else if (mp->m_gname) + putgrp (namep, mp->m_gname, out, hdr->flags); if (mp->m_ingrp) { if (sm_mts == MTS_SENDMAIL_PIPE) { /* Catch this before sendmail chokes with: @@ -990,7 +1006,8 @@ putfmt (char *name, char *str, int *eai, FILE *out) grp++; } - if (putadr (namep, qp, mp, out, hdr->flags)) + if (putadr (namep, qp, mp, out, hdr->flags, savehdr, + savehdrlen)) msgflags |= (hdr->set & (MVIS | MINV)); else mnfree (mp); @@ -1039,7 +1056,7 @@ putfmt (char *name, char *str, int *eai, FILE *out) putgrp (namep, mp->m_gname, out, hdr->flags); if (mp->m_ingrp) grp++; - keep = putadr (namep, "", mp, out, hdr->flags); + keep = putadr (namep, "", mp, out, hdr->flags, savehdr, savehdrlen); np = mp->m_next; if (keep) { mp->m_next = NULL; @@ -1050,17 +1067,11 @@ putfmt (char *name, char *str, int *eai, FILE *out) } /* - * If this is a From:/Resent-From: header, save the full thing for - * later in case we need it for use when constructing a Bcc draft message + * If it was a From header, strip off any trailing newlines from + * the alias-expanded From line. */ if ((msgstate == RESENT) ? (hdr->set & MRFM) : (hdr->set & MFRM)) { - strncpy(fullfrom, str, sizeof(fullfrom)); - fullfrom[sizeof(fullfrom) - 1] = 0; - /* - * Strip off any trailing newlines - */ - while (*fullfrom && fullfrom[strlen(fullfrom) - 1] == '\n') { fullfrom[strlen(fullfrom) - 1] = '\0'; } @@ -1219,9 +1230,11 @@ get_header (char *header, struct headers *table) static int -putadr (char *name, char *aka, struct mailname *mp, FILE *out, unsigned int flags) +putadr (char *name, char *aka, struct mailname *mp, FILE *out, + unsigned int flags, char *savehdr, unsigned int savehdrsize) { - int len; + int len, saveappend = 0; + unsigned int shlen; char *cp; char buffer[BUFSIZ]; @@ -1236,6 +1249,11 @@ putadr (char *name, char *aka, struct mailname *mp, FILE *out, unsigned int flag linepos += (nameoutput = strlen (name) + 2); } + if (savehdr) { + shlen = strlen(savehdr); + saveappend = 1; + } + if (*aka && mp->m_type != UUCPHOST && !mp->m_pers) mp->m_pers = mh_xstrdup(aka); if (format) { @@ -1251,15 +1269,34 @@ putadr (char *name, char *aka, struct mailname *mp, FILE *out, unsigned int flag len = strlen (cp); if (linepos != nameoutput) { - if (len + linepos + 2 > outputlinelen) + if (len + linepos + 2 > outputlinelen) { fprintf (out, ",\n%*s", linepos = nameoutput, ""); - else { + if (saveappend) { + if (shlen + 2 + nameoutput + len >= savehdrsize) { + saveappend = 0; + } else { + snprintf(savehdr + shlen, savehdrsize - shlen, ",\n%*s", + linepos, ""); + } + } + } else { fputs (", ", out); linepos += 2; + if (saveappend) { + if (shlen + 2 + len >= savehdrsize) { + saveappend = 0; + } else { + strncat(savehdr, ", ", savehdrsize - shlen); + } + } } } fputs (cp, out); + + if (saveappend && shlen + len < savehdrsize) + strncat(savehdr, cp, savehdrsize - shlen + len); + linepos += len; return (flags & HTRY); @@ -1455,11 +1492,10 @@ make_bcc_file (int dashstuff) while (find_prefix () == NOTOK) { if (*cp < 'z') (*cp)++; - else - if (*++cp == 0) - adios (NULL, "can't find a unique delimiter string"); - else - (*cp)++; + else if (*++cp == 0) + adios (NULL, "can't find a unique delimiter string"); + else + (*cp)++; } fprintf (out, "%s: %s\n%s: multipart/digest; boundary=\"", @@ -1566,18 +1602,16 @@ find_prefix (void) } -#define plural(x) (x == 1 ? "" : "s") - static void chkadr (void) { if (badadr && unkadr) - die (NULL, "%d address%s unparsable, %d addressee%s undeliverable", - badadr, plural (badadr), unkadr, plural (badadr)); + fatal (NULL, "%d address%s unparsable, %d addressee%s undeliverable", + badadr, PLURALS(badadr), unkadr, PLURALS(badadr)); if (badadr) - die (NULL, "%d address%s unparsable", badadr, plural (badadr)); + fatal (NULL, "%d address%s unparsable", badadr, PLURALS(badadr)); if (unkadr) - die (NULL, "%d addressee%s undeliverable", unkadr, plural (unkadr)); + fatal (NULL, "%d addressee%s undeliverable", unkadr, PLURALS(unkadr)); } @@ -1618,7 +1652,7 @@ do_addresses (int bccque, int talk) chkadr (); if (rp_isbad (retval = sm_waend ())) - die (NULL, "problem ending addresses; %s", rp_string (retval)); + fatal (NULL, "problem ending addresses; %s", rp_string (retval)); } @@ -1684,7 +1718,7 @@ post (char *file, int bccque, int talk, int eai, char *envelope, int eightbit = 0; if (fd == NOTOK) { - die (file, "unable to re-open"); + fatal (file, "unable to re-open"); } if (msgflags & MMIM && cte != UNKNOWN) { @@ -1694,7 +1728,7 @@ post (char *file, int bccque, int talk, int eai, char *envelope, } else { if (scan_input (fd, &eightbit) == NOTOK) { close (fd); - die (file, "problem reading from"); + fatal (file, "problem reading from"); } } @@ -1703,7 +1737,7 @@ post (char *file, int bccque, int talk, int eai, char *envelope, oauth_flag ? auth_svc : NULL, tlsflag)) || rp_isbad (retval = sm_winit (envelope, eai, eightbit))) { close (fd); - die (NULL, "problem initializing server; %s", rp_string (retval)); + fatal (NULL, "problem initializing server; %s", rp_string (retval)); } do_addresses (bccque, talk && verbose); @@ -1746,7 +1780,7 @@ verify_all_addresses (int talk, int eai, char *envelope, int oauth_flag, verbose, snoop, sasl, saslmech, user, oauth_flag ? auth_svc : NULL, tlsflag)) || rp_isbad (retval = sm_winit (envelope, eai, eightbit))) { - die (NULL, "problem initializing server; %s", rp_string (retval)); + fatal (NULL, "problem initializing server; %s", rp_string (retval)); } } @@ -1836,7 +1870,7 @@ do_an_address (struct mailname *lp, int talk) default: if (!talk) fprintf (stderr, " %s: ", addr); - die (NULL, "unexpected response; %s", rp_string (retval)); + fatal (NULL, "unexpected response; %s", rp_string (retval)); } fflush (stdout); @@ -1849,15 +1883,15 @@ do_text (char *file, int fd) int retval, state; char buf[BUFSIZ]; - lseek (fd, (off_t) 0, SEEK_SET); + lseek(fd, 0, SEEK_SET); while ((state = read (fd, buf, sizeof(buf))) > 0) { if (rp_isbad (retval = sm_wtxt (buf, state))) - die (NULL, "problem writing text; %s\n", rp_string (retval)); + fatal (NULL, "problem writing text; %s\n", rp_string (retval)); } if (state == NOTOK) - die (file, "problem reading from"); + fatal (file, "problem reading from"); switch (retval = sm_wtend ()) { case RP_OK: @@ -1865,11 +1899,11 @@ do_text (char *file, int fd) case RP_NO: case RP_NDEL: - die (NULL, "posting failed; %s", rp_string (retval)); - /* FALLTHRU */ + fatal (NULL, "posting failed; %s", rp_string (retval)); + break; default: - die (NULL, "unexpected response; %s", rp_string (retval)); + fatal (NULL, "unexpected response; %s", rp_string (retval)); } } @@ -1988,7 +2022,7 @@ fcc (char *file, char *folder) if (!verbose) fprintf (stderr, " %sFcc %s: ", msgstate == RESENT ? "Resent-" : "", folder); - pidstatus (status, verbose ? stdout : stderr, NULL); + pidstatus (status, verbose ? stdout : stderr, fileproc); } else { if (verbose) puts("folder ok"); @@ -2003,7 +2037,7 @@ fcc (char *file, char *folder) */ static void -die (char *what, char *fmt, ...) +fatal (char *what, char *fmt, ...) { int err; va_list ap;