X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=uip%2Fspost.c;h=8b4b8300dacc80edce7eae329d2d661d24c7fec5;hp=4d23fe5f5fc5348e47941b842da798966a73e83f;hb=fcde9624e6832e0dcdc6f21996b69b7e58745e3d;hpb=a485ed478abbd599d8c9aab48934e7a26733ecb1 diff --git a/uip/spost.c b/uip/spost.c index 4d23fe5..8b4b830 100644 --- a/uip/spost.c +++ b/uip/spost.c @@ -1,13 +1,13 @@ /* - * spost.c -- feed messages to sendmail - * - * This is a simpler, faster, replacement for "post" for use - * when "sendmail" is the transport system. - * - * This code is Copyright (c) 2002, by the authors of nmh. See the - * COPYRIGHT file in the root directory of the nmh distribution for - * complete copyright information. - */ +** spost.c -- feed messages to sendmail +** +** This is a simpler, faster, replacement for "post" for use +** when "sendmail" is the transport system. +** +** This code is Copyright (c) 2002, by the authors of nmh. See the +** COPYRIGHT file in the root directory of the nmh distribution for +** complete copyright information. +*/ #include #include @@ -15,65 +15,38 @@ #include #include #include -#include #include #define MAX_SM_FIELD 1476 /* < largest hdr field sendmail will accept */ #define FCCS 10 /* max number of fccs allowed */ struct swit switches[] = { -#define FILTSW 0 - { "filter filterfile", 0 }, -#define NFILTSW 1 - { "nofilter", 0 }, -#define FRMTSW 2 - { "format", 0 }, -#define NFRMTSW 3 - { "noformat", 0 }, -#define REMVSW 4 - { "remove", 0 }, -#define NREMVSW 5 - { "noremove", 0 }, -#define VERBSW 6 +#define VERBSW 0 { "verbose", 0 }, -#define NVERBSW 7 +#define NVERBSW 1 { "noverbose", 0 }, -#define WATCSW 8 +#define WATCSW 2 { "watch", 0 }, -#define NWATCSW 9 +#define NWATCSW 3 { "nowatch", 0 }, -#define BACKSW 10 - { "backup", 0 }, -#define NBACKSW 11 - { "nobackup", 0 }, -#define ALIASW 12 +#define ALIASW 4 { "alias aliasfile", 0 }, -#define NALIASW 13 +#define NALIASW 5 { "noalias", 0 }, -#define WIDTHSW 14 - { "width columns", 0 }, -#define VERSIONSW 15 +#define VERSIONSW 6 { "version", 0 }, -#define HELPSW 16 +#define HELPSW 7 { "help", 0 }, -#define DEBUGSW 17 +#define DEBUGSW 8 { "debug", -5 }, -#define DISTSW 18 +#define DISTSW 9 { "dist", -4 }, /* interface from dist */ -#define CHKSW 19 - { "check", -5 }, /* interface from whom */ -#define NCHKSW 20 - { "nocheck", -7 }, /* interface from whom */ -#define WHOMSW 21 - { "whom", -4 }, /* interface from whom */ -#define PUSHSW 22 /* fork to sendmail then exit */ +#define PUSHSW 10 /* fork to sendmail then exit */ { "push", -4 }, -#define NPUSHSW 23 /* exec sendmail */ +#define NPUSHSW 11 /* exec sendmail */ { "nopush", -6 }, -#define LIBSW 24 +#define LIBSW 12 { "library directory", -7 }, -#define ANNOSW 25 - { "idanno number", -6 }, { NULL, 0 } }; @@ -85,11 +58,10 @@ struct swit switches[] = { #define HSUB 0x0004 /* Subject: header */ #define HTRY 0x0008 /* try to send to addrs on header */ #define HBCC 0x0010 /* don't output this header */ -#define HMNG 0x0020 /* mung this header */ -#define HNGR 0x0040 /* no groups allowed in this header */ -#define HFCC 0x0080 /* FCC: type header */ -#define HNIL 0x0100 /* okay for this header not to have addrs */ -#define HIGN 0x0200 /* ignore this header */ +#define HNGR 0x0020 /* no groups allowed in this header */ +#define HFCC 0x0040 /* FCC: type header */ +#define HNIL 0x0080 /* okay for this header not to have addrs */ +#define HIGN 0x0100 /* ignore this header */ /* flags for headers->set */ #define MFRM 0x0001 /* we've seen a From: */ @@ -115,7 +87,7 @@ static struct headers NHeaders[] = { { "Date", HNOP, MDAT }, { "Subject", HSUB, 0 }, { "To", HADR|HTRY, MVIS }, - { "cc", HADR|HTRY, MVIS }, + { "Cc", HADR|HTRY, MVIS }, { "Bcc", HADR|HTRY|HBCC|HNIL, MINV }, { "Message-Id", HBAD, 0 }, { "Fcc", HFCC, 0 }, @@ -129,7 +101,7 @@ static struct headers RHeaders[] = { { "Resent-Date", HNOP, MRDT }, { "Resent-Subject", HSUB, 0 }, { "Resent-To", HADR|HTRY, MVIS }, - { "Resent-cc", HADR|HTRY, MVIS }, + { "Resent-Cc", HADR|HTRY, MVIS }, { "Resent-Bcc", HADR|HTRY|HBCC, MINV }, { "Resent-Message-Id", HBAD, 0 }, { "Resent-Fcc", HFCC, 0 }, @@ -139,18 +111,12 @@ static struct headers RHeaders[] = { }; -static short fccind = 0; /* index into fccfold[] */ - static int badmsg = 0; /* message has bad semantics */ static int verbose = 0; /* spell it out */ static int debug = 0; /* debugging post */ -static int rmflg = 1; /* remove temporary file when done */ static int watch = 0; /* watch the delivery process */ -static int backflg = 0; /* rename input file as *.bak when done */ -static int whomflg = 0; /* if just checking addresses */ static int pushflg = 0; /* if going to fork to sendmail */ -static int aliasflg = -1; /* if going to process aliases */ -static int outputlinelen=72; +static int aliasflg = 0; /* if going to process aliases */ static unsigned msgflags = 0; /* what we've seen */ @@ -158,13 +124,13 @@ static enum { normal, resent } msgstate = normal; -static char tmpfil[] = "/tmp/pstXXXXXX"; +static char tmpfil[] = "/tmp/spost-XXXXXX"; +static char bccfil[] = "/tmp/spost-bcc-XXXXXX"; -static char from[BUFSIZ]; /* my network address */ -static char signature[BUFSIZ]; /* my signature */ -static char *filter = NULL; /* the filter for BCC'ing */ static char *subject = NULL; /* the subject field for BCC'ing */ static char *fccfold[FCCS]; /* foldernames for FCC'ing */ +static short fccind = 0; /* index into fccfold[] */ +struct mailname *bccs = NULL; static struct headers *hdrtab; /* table for the message we're doing */ static FILE *out; /* output (temp) file */ @@ -172,34 +138,20 @@ static FILE *out; /* output (temp) file */ extern char *sendmail; /* - * external prototypes - */ -extern char *getfullname (void); -extern char *getusername (void); - -extern boolean draft_from_masquerading; /* defined in mts.c */ - -/* - * static prototypes - */ -static void putfmt (char *, char *, FILE *); -static void start_headers (void); -static void finish_headers (FILE *); -static int get_header (char *, struct headers *); -static void putadr (char *, struct mailname *); -static int putone (char *, int, int); -static void insert_fcc (struct headers *, unsigned char *); -static void file (char *); -static void fcc (char *, char *); - -#if 0 -static void die (char *, char *, ...); -static void make_bcc_file (void); -#endif +** static prototypes +*/ +static void putfmt(char *, char *, FILE *); +static void finish_headers(FILE *); +static int get_header(char *, struct headers *); +static void putadr(char *, struct mailname *); +static int putone(char *, int, int); +static void insert_fcc(char *, unsigned char *); +static void fcc(char *, char *); +static void make_bcc_draft(char *); int -main (int argc, char **argv) +main(int argc, char **argv) { int state, i, pid, compnum; char *cp, *msg = NULL, **argp, **arguments; @@ -209,262 +161,241 @@ main (int argc, char **argv) #ifdef LOCALE setlocale(LC_ALL, ""); #endif - invo_name = r1bindex (argv[0], '/'); + invo_name = mhbasename(argv[0]); /* foil search of user profile/context */ - if (context_foil (NULL) == -1) - done (1); + if (context_foil(NULL) == -1) + done(1); - mts_init (invo_name); - arguments = getarguments (invo_name, argc, argv, 0); + arguments = getarguments(invo_name, argc, argv, 0); argp = arguments; while ((cp = *argp++)) { if (*cp == '-') { - switch (smatch (++cp, switches)) { - case AMBIGSW: - ambigsw (cp, switches); - done (1); - case UNKWNSW: - adios (NULL, "-%s unknown", cp); - - case HELPSW: - snprintf (buf, sizeof(buf), "%s [switches] file", invo_name); - print_help (buf, switches, 1); - done (1); - case VERSIONSW: - print_version(invo_name); - done (1); - - case DEBUGSW: - debug++; - continue; - - case DISTSW: - msgstate = resent; - continue; - - case WHOMSW: - whomflg++; - continue; - - case FILTSW: - if (!(filter = *argp++) || *filter == '-') - adios (NULL, "missing argument to %s", argp[-2]); - continue; - case NFILTSW: - filter = NULL; - continue; - - case REMVSW: - rmflg++; - continue; - case NREMVSW: - rmflg = 0; - continue; - - case BACKSW: - backflg++; - continue; - case NBACKSW: - backflg = 0; - continue; - - case VERBSW: - verbose++; - continue; - case NVERBSW: - verbose = 0; - continue; - - case WATCSW: - watch++; - continue; - case NWATCSW: - watch = 0; - continue; - - case PUSHSW: - pushflg++; - continue; - case NPUSHSW: - pushflg = 0; - continue; - - case ALIASW: - if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - if (aliasflg < 0) - alias (AliasFile);/* load default aka's */ - aliasflg = 1; - if ((state = alias(cp)) != AK_OK) - adios (NULL, "aliasing error in file %s - %s", - cp, akerror(state) ); - continue; - case NALIASW: - aliasflg = 0; - continue; - - case WIDTHSW: - if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - outputlinelen = atoi (cp); - if (outputlinelen <= 10) - outputlinelen = 72; - continue; - - case LIBSW: - if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - /* create a minimal context */ - if (context_foil (cp) == -1) - done(1); - continue; - - case ANNOSW: - /* -idanno switch ignored */ - if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - continue; + switch (smatch(++cp, switches)) { + case AMBIGSW: + ambigsw(cp, switches); + done(1); + case UNKWNSW: + adios(NULL, "-%s unknown", cp); + + case HELPSW: + snprintf(buf, sizeof(buf), + "%s [switches] file", + invo_name); + print_help(buf, switches, 1); + done(1); + case VERSIONSW: + print_version(invo_name); + done(1); + + case DEBUGSW: + debug++; + continue; + + case DISTSW: + msgstate = resent; + continue; + + case VERBSW: + verbose++; + continue; + case NVERBSW: + verbose = 0; + continue; + + case WATCSW: + watch++; + continue; + case NWATCSW: + watch = 0; + continue; + + case PUSHSW: + pushflg++; + continue; + case NPUSHSW: + pushflg = 0; + continue; + + case ALIASW: + if (!(cp = *argp++) || *cp == '-') + adios(NULL, "missing argument to %s", + argp[-2]); + aliasflg = 1; + if ((state = alias(cp)) != AK_OK) + adios(NULL, "aliasing error in file %s - %s", cp, akerror(state)); + continue; + case NALIASW: + aliasflg = 0; + continue; + + case LIBSW: + if (!(cp = *argp++) || *cp == '-') + adios(NULL, "missing argument to %s", + argp[-2]); + /* create a minimal context */ + if (context_foil(cp) == -1) + done(1); + continue; } } if (msg) - adios (NULL, "only one message at a time!"); + adios(NULL, "only one message at a time!"); else msg = cp; } - if (aliasflg < 0) - alias (AliasFile); /* load default aka's */ - if (!msg) - adios (NULL, "usage: %s [switches] file", invo_name); + adios(NULL, "usage: %s [switches] file", invo_name); - if ((in = fopen (msg, "r")) == NULL) - adios (msg, "unable to open"); + if ((in = fopen(msg, "r")) == NULL) + adios(msg, "unable to open"); - start_headers (); if (debug) { verbose++; out = stdout; - } - else { + } else { #ifdef HAVE_MKSTEMP - if ((out = fdopen( mkstemp (tmpfil), "w" )) == NULL ) - adios (tmpfil, "unable to create"); + if ((out = fdopen(mkstemp(tmpfil), "w")) == NULL) + adios(tmpfil, "unable to create"); #else - mktemp (tmpfil); - if ((out = fopen (tmpfil, "w")) == NULL) - adios (tmpfil, "unable to create"); - chmod (tmpfil, 0600); + mktemp(tmpfil); + if ((out = fopen(tmpfil, "w")) == NULL) + adios(tmpfil, "unable to create"); + chmod(tmpfil, 0600); #endif - } + } hdrtab = (msgstate == normal) ? NHeaders : RHeaders; for (compnum = 1, state = FLD;;) { - switch (state = m_getfld (state, name, buf, sizeof(buf), in)) { - case FLD: - compnum++; - putfmt (name, buf, out); - continue; - - case FLDPLUS: - compnum++; - cp = add (buf, cp); - while (state == FLDPLUS) { - state = m_getfld (state, name, buf, sizeof(buf), in); - cp = add (buf, cp); - } - putfmt (name, cp, out); - free (cp); - continue; - - case BODY: - finish_headers (out); - fprintf (out, "\n%s", buf); - if(whomflg == 0) - while (state == BODY) { - state = m_getfld (state, name, buf, sizeof(buf), in); - fputs (buf, out); - } - break; + switch (state = m_getfld(state, name, buf, sizeof(buf), in)) { + case FLD: + compnum++; + putfmt(name, buf, out); + continue; + + case FLDPLUS: + compnum++; + cp = add(buf, cp); + while (state == FLDPLUS) { + state = m_getfld(state, name, buf, + sizeof(buf), in); + cp = add(buf, cp); + } + putfmt(name, cp, out); + free(cp); + continue; + + case BODY: + finish_headers(out); + fprintf(out, "\n%s", buf); + while (state == BODY) { + state = m_getfld(state, name, buf, + sizeof(buf), in); + fputs(buf, out); + } + break; - case FILEEOF: - finish_headers (out); - break; + case FILEEOF: + finish_headers(out); + break; - case LENERR: - case FMTERR: - adios (NULL, "message format error in component #%d", - compnum); + case LENERR: + case FMTERR: + adios(NULL, "message format error in component #%d", + compnum); - default: - adios (NULL, "getfld() returned %d", state); + default: + adios(NULL, "getfld() returned %d", state); } break; } + fclose(in); - fclose (in); - if (backflg && !whomflg) { - strncpy (buf, m_backup (msg), sizeof(buf)); - if (rename (msg, buf) == NOTOK) - advise (buf, "unable to rename %s to", msg); + if (debug) { + /* stop here */ + done(0); } - if (debug) { - done (0); + fclose(out); + + /* process Fcc */ + for (i=0; iflags & HIGN) + + if (hdr->flags & HIGN) { return; + } if (hdr->flags & HBAD) { - advise (NULL, "illegal header line -- %s:", name); + advise(NULL, "illegal header line -- %s:", name); badmsg++; return; } msgflags |= hdr->set; - if (hdr->flags & HSUB) - subject = subject ? add (str, add ("\t", subject)) : getcpy (str); + if (hdr->flags & HSUB) { + if (subject) { + /* concatenate mupliple subject */ + char *cp = concat(subject, "\t", str, NULL); + free(subject); + subject = cp; + } else { + subject = getcpy(str); + } + } if (hdr->flags & HFCC) { - if ((cp = strrchr(str, '\n'))) - *cp = 0; + if ((cp = strrchr(str, '\n'))) { + *cp = '\0'; + } for (cp = pp = str; (cp = strchr(pp, ',')); pp = cp) { - *cp++ = 0; - insert_fcc (hdr, pp); + *cp++ = '\0'; + insert_fcc(hdr->value, pp); } - insert_fcc (hdr, pp); - return; - } - -#ifdef notdef - if (hdr->flags & HBCC) { - insert_bcc(str); + insert_fcc(hdr->value, pp); return; } -#endif /* notdef */ if (*str != '\n' && *str != '\0') { - if (aliasflg && hdr->flags & HTRY) { - /* this header contains address(es) that we have to do - * alias expansion on. Because of the saved state in - * getname we have to put all the addresses into a list. - * We then let putadr munch on that list, possibly - * expanding aliases. - */ + if (hdr->flags & HBCC) { + struct mailname *mp = NULL; + + /* Create list of Bcc adds. */ + while ((cp = getname(str))) { + mp = getm(cp, NULL, 0, AD_HOST, NULL); + mp->m_next = bccs; /* push */ + bccs = mp; + } + } else if (aliasflg && hdr->flags & HTRY) { + /* + ** this header contains address(es) that we have to do + ** alias expansion on. Because of the saved state in + ** getname we have to put all the addresses into a + ** list. We then let putadr munch on that list, + ** possibly expanding aliases. + **/ register struct mailname *f = 0; register struct mailname *mp = 0; while ((cp = getname(str))) { - mp = getm( cp, NULL, 0, AD_HOST, NULL); + mp = getm(cp, NULL, 0, AD_HOST, NULL); if (f == 0) { f = mp; mp->m_next = mp; @@ -532,379 +478,268 @@ putfmt (char *name, char *str, FILE *out) } } f = mp->m_next; mp->m_next = 0; - putadr( name, f ); + putadr(name, f); } else { /* - * The author(s) of spost decided that alias - * substitution wasn't necessary for the non-HTRY - * headers. Unfortunately, one of those headers - * is "From:", and having alias substitution - * work on that is extremely useful for someone - * with a lot of POP3 email accounts or aliases. - * post supports aliasing of "From:"... - * - * Since "From:"-processing is incompletely - * implemented in this unsupported and - * undocumented spost backend, I'm not - * going to take the time to implement my new - * draft-From:-based email address masquerading. - * If I do ever implement it here, I'd almost - * certainly want to implement "From:" line - * alias processing as well. - * -- Dan Harkless - */ - fprintf (out, "%s: %s", name, str ); + ** The author(s) of spost decided that alias + ** substitution wasn't necessary for the non-HTRY + ** headers. Unfortunately, one of those headers + ** is "From:", and having alias substitution + ** work on that is extremely useful for someone + ** with a lot of POP3 email accounts or aliases. + ** post supports aliasing of "From:"... + ** + ** Since "From:"-processing is incompletely + ** implemented in this unsupported and + ** undocumented spost backend, I'm not + ** going to take the time to implement my new + ** draft-From:-based email address masquerading. + ** If I do ever implement it here, I'd almost + ** certainly want to implement "From:" line + ** alias processing as well. + ** -- Dan Harkless + */ + fprintf(out, "%s: %s", name, str); } } } +/* +** Add yet missing headers. +*/ static void -start_headers (void) +finish_headers(FILE *out) { char *cp; - char sigbuf[BUFSIZ]; - - strncpy(from, getusername(), sizeof(from)); - - if ((cp = getfullname ()) && *cp) { - strncpy (sigbuf, cp, sizeof(sigbuf)); - snprintf (signature, sizeof(signature), "%s <%s>", sigbuf, from); - } else - snprintf (signature, sizeof(signature), "%s", from); -} - - -static void -finish_headers (FILE *out) -{ - switch (msgstate) { - case normal: - if (!(msgflags & MDAT)) - fprintf (out, "Date: %s\n", dtimenow (0)); - - if (msgflags & MFRM) { - /* There was already a From: in the draft. Don't add one. */ - if (!draft_from_masquerading) - /* - * mts.conf didn't contain - * "masquerade:[...]draft_from[...]" - * so we'll reveal the user's - * actual account@thismachine - * address in a Sender: header - * (and use it as the envelope - * From: later). - */ - fprintf (out, "Sender: %s\n", from); - } else - fprintf (out, "From: %s\n", signature); - -#ifdef notdef - if (!(msgflags & MVIS)) - fprintf (out, "Bcc: Blind Distribution List: ;\n"); -#endif /* notdef */ - break; + char from[BUFSIZ]; /* my network address */ + char signature[BUFSIZ]; /* my signature */ + char *resentstr = (msgstate == resent) ? "Resent-" : ""; - case resent: - if (!(msgflags & MRDT)) - fprintf (out, "Resent-Date: %s\n", dtimenow(0)); - if (msgflags & MRFM) { - /* There was already a Resent-From: in draft. Don't add one. */ - if (!draft_from_masquerading) - /* - * mts.conf didn't contain - * "masquerade:[...]draft_from[...]" - * so we'll reveal the user's - * actual account@thismachine - * address in a Sender: header - * (and use it as the envelope - * From: later). - */ - fprintf (out, "Resent-Sender: %s\n", from); - } else - /* Construct a Resent-From: header. */ - fprintf (out, "Resent-From: %s\n", signature); -#ifdef notdef - if (!(msgflags & MVIS)) - fprintf (out, "Resent-Bcc: Blind Re-Distribution List: ;\n"); -#endif /* notdef */ - break; + if (!(msgflags & MDAT)) { + fprintf(out, "%sDate: %s\n", resentstr, dtimenow(0)); } - if (badmsg) - adios (NULL, "re-format message and try again"); + strncpy(from, getusername(), sizeof(from)); + if ((cp = getfullname()) && *cp) { + snprintf(signature, sizeof(signature), "%s <%s>", cp, from); + } else { + snprintf(signature, sizeof(signature), "%s", from); + } + if (!(msgflags & MFRM)) { + fprintf(out, "%sFrom: %s\n", resentstr, signature); + } else { + /* In case the From: header contains multiple addresses. */ + fprintf(out, "%sSender: %s\n", resentstr, from); + } + if (!(msgflags & MVIS)) { + fprintf(out, "%sBcc: Blind Distribution List: ;\n", resentstr); + } + if (badmsg) { + adios(NULL, "re-format message and try again"); + } } +/* +** Return index of the requested header in the table, or NOTOK if missing. +*/ static int -get_header (char *header, struct headers *table) +get_header(char *header, struct headers *table) { struct headers *h; - for (h = table; h->value; h++) - if (!mh_strcasecmp (header, h->value)) + for (h=table; h->value; h++) { + if (mh_strcasecmp(header, h->value)==0) { return (h - table); + } + } return NOTOK; } /* - * output the address list for header "name". The address list - * is a linked list of mailname structs. "nl" points to the head - * of the list. Alias substitution should be done on nl. - */ +** output the address list for header "name". The address list +** is a linked list of mailname structs. "nl" points to the head +** of the list. Alias substitution should be done on nl. +*/ static void -putadr (char *name, struct mailname *nl) +putadr(char *name, struct mailname *nl) { - register struct mailname *mp, *mp2; - register int linepos; - register char *cp; + struct mailname *mp, *mp2; + int linepos; + char *cp; int namelen; - fprintf (out, "%s: ", name); + fprintf(out, "%s: ", name); namelen = strlen(name) + 2; linepos = namelen; for (mp = nl; mp; ) { if (linepos > MAX_SM_FIELD) { - fprintf (out, "\n%s: ", name); - linepos = namelen; + fprintf(out, "\n%s: ", name); + linepos = namelen; } if (mp->m_nohost) { /* a local name - see if it's an alias */ cp = akvalue(mp->m_mbox); - if (cp == mp->m_mbox) + if (cp == mp->m_mbox) { /* wasn't an alias - use what the user typed */ - linepos = putone( mp->m_text, linepos, namelen ); - else + linepos = putone(mp->m_text, linepos, namelen); + } else { /* an alias - expand it */ while ((cp = getname(cp))) { if (linepos > MAX_SM_FIELD) { - fprintf (out, "\n%s: ", name); - linepos = namelen; + fprintf(out, "\n%s: ", name); + linepos = namelen; } - mp2 = getm( cp, NULL, 0, AD_HOST, NULL); + mp2 = getm(cp, NULL, 0, AD_HOST, NULL); if (akvisible()) { mp2->m_pers = getcpy(mp->m_mbox); - linepos = putone( adrformat(mp2), linepos, namelen ); + linepos = putone(adrformat(mp2), linepos, namelen); } else { - linepos = putone( mp2->m_text, linepos, namelen ); + linepos = putone(mp2->m_text, + linepos, + namelen); } - mnfree( mp2 ); + mnfree(mp2); } + } } else { /* not a local name - use what the user typed */ - linepos = putone( mp->m_text, linepos, namelen ); + linepos = putone(mp->m_text, linepos, namelen); } mp2 = mp; mp = mp->m_next; - mnfree( mp2 ); + mnfree(mp2); } - putc( '\n', out ); + putc('\n', out); } static int -putone (char *adr, int pos, int indent) +putone(char *adr, int pos, int indent) { register int len; static int linepos; - len = strlen( adr ); + len = strlen(adr); if (pos == indent) linepos = pos; - else if ( linepos+len > outputlinelen ) { - fprintf ( out, ",\n%*s", indent, ""); + else if (linepos+len > OUTPUTLINELEN) { + fprintf(out, ",\n%*s", indent, ""); linepos = indent; pos += indent + 2; - } - else { - fputs( ", ", out ); + } else { + fputs(", ", out); linepos += 2; pos += 2; } - fputs( adr, out ); + fputs(adr, out); linepos += len; return (pos+len); } +/* +** Insert the normalized value from pp into fccfold[]. +*/ static void -insert_fcc (struct headers *hdr, unsigned char *pp) +insert_fcc(char *name, unsigned char *pp) { - unsigned char *cp; + unsigned char *cp; - for (cp = pp; isspace (*cp); cp++) + for (cp = pp; isspace(*cp); cp++) continue; - for (pp += strlen (pp) - 1; pp > cp && isspace (*pp); pp--) + for (pp += strlen(pp) - 1; pp > cp && isspace(*pp); pp--) continue; if (pp >= cp) - *++pp = 0; - if (*cp == 0) + *++pp = '\0'; + if (!*cp) return; if (fccind >= FCCS) - adios (NULL, "too many %ss", hdr->value); - fccfold[fccind++] = getcpy (cp); + adios(NULL, "too many %ss", name); + fccfold[fccind++] = getcpy(cp); } -#if 0 -/* BCC GENERATION */ static void -make_bcc_file (void) -{ - pid_t child_id; - int fd, i, status; - char *vec[6]; - FILE * in, *out; - -#ifdef HAVE_MKSTEMP - fd = mkstemp(bccfil); - if (fd == -1 || (out = fdopen(fd, "w")) == NULL) - adios (bccfil, "unable to create"); -#else - mktemp (bccfil); - if ((out = fopen (bccfil, "w")) == NULL) - adios (bccfil, "unable to create"); -#endif - chmod (bccfil, 0600); - - fprintf (out, "Date: %s\n", dtimenow (0)); - if (msgflags & MFRM) { - /* There was already a From: in the draft. Don't add one. */ - if (!draft_from_masquerading) - /* - * mts.conf didn't contain "masquerade:[...]draft_from[...]" - * so we'll reveal the user's actual account@thismachine - * address in a Sender: header (and use it as the envelope - * From: later). - */ - fprintf (out, "Sender: %s\n", from); - } else - /* Construct a From: header. */ - fprintf (out, "From: %s\n", signature); - if (subject) - fprintf (out, "Subject: %s", subject); - fprintf (out, "BCC:\n\n------- Blind-Carbon-Copy\n\n"); - fflush (out); - - if (filter == NULL) { - if ((fd = open (tmpfil, O_RDONLY)) == NOTOK) - adios (NULL, "unable to re-open"); - cpydgst (fd, fileno (out), tmpfil, bccfil); - close (fd); - } else { - vec[0] = r1bindex (mhlproc, '/'); - - for (i = 0; (child_id = vfork()) == NOTOK && i < 5; i++) - sleep (5); - switch (child_id) { - case NOTOK: - adios ("vfork", "unable to"); - - case OK: - dup2 (fileno (out), 1); - - i = 1; - vec[i++] = "-forward"; - vec[i++] = "-form"; - vec[i++] = filter; - vec[i++] = tmpfil; - vec[i] = NULL; - - execvp (mhlproc, vec); - adios (mhlproc, "unable to exec"); - - default: - if (status = pidwait(child_id, OK)) - admonish (NULL, "%s lost (status=0%o)", vec[0], status); - break; - } - } - - fseek (out, 0L, SEEK_END); - fprintf (out, "\n------- End of Blind-Carbon-Copy\n"); - fclose (out); -} -#endif /* if 0 */ - -/* FCC INTERACTION */ - -static void -file (char *path) -{ - int i; - - if (fccind == 0) - return; - - for (i = 0; i < fccind; i++) - if (whomflg) - printf ("Fcc: %s\n", fccfold[i]); - else - fcc (path, fccfold[i]); -} - - -static void -fcc (char *file, char *folder) +fcc(char *file, char *folder) { pid_t child_id; int i, status; char fold[BUFSIZ]; if (verbose) - printf ("%sFcc: %s\n", msgstate == resent ? "Resent-" : "", folder); - fflush (stdout); + printf("%sFcc: %s\n", msgstate == resent ? "Resent-" : "", + folder); + fflush(stdout); - for (i = 0; (child_id = vfork()) == NOTOK && i < 5; i++) - sleep (5); + for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++) + sleep(5); switch (child_id) { - case NOTOK: - if (!verbose) - fprintf (stderr, " %sFcc %s: ", - msgstate == resent ? "Resent-" : "", folder); - fprintf (verbose ? stdout : stderr, "no forks, so not ok\n"); - break; + case NOTOK: + if (verbose) { + printf("Sorry man, but we had no more forks.\n"); + } else { + fprintf(stderr, "Skipped %sFcc %s: unable to fork.\n", + msgstate == resent ? "Resent-" : "", + folder); + } + break; - case OK: - snprintf (fold, sizeof(fold), "%s%s", - *folder == '+' || *folder == '@' ? "" : "+", folder); - execlp (fileproc, r1bindex (fileproc, '/'), + case OK: + snprintf(fold, sizeof(fold), "%s%s", + *folder == '+' || *folder == '@' ? "" : "+", + folder); + execlp(fileproc, mhbasename(fileproc), "-link", "-file", file, fold, NULL); - _exit (-1); - - default: - if ((status = pidwait(child_id, OK))) { - if (!verbose) - fprintf (stderr, " %sFcc %s: ", - msgstate == resent ? "Resent-" : "", folder); - fprintf (verbose ? stdout : stderr, - " errored (0%o)\n", status); + _exit(-1); + + default: + if ((status = pidwait(child_id, OK))) { + if (verbose) { + printf(" errored (0%o)\n", status); + } else { + fprintf(stderr, " %sFcc %s: errored (0%o)\n", + msgstate == resent ? + "Resent-" : "", folder, + status); } + } } - fflush (stdout); + fflush(stdout); } -#if 0 - -/* - * TERMINATION - */ +/* BCC GENERATION */ static void -die (char *what, char *fmt, ...) +make_bcc_draft(char *draft) { - va_list ap; + int fd; + FILE *out; - va_start(ap, fmt); - advertise (what, NULL, fmt, ap); - va_end(ap); +#ifdef HAVE_MKSTEMP + fd = mkstemp(bccfil); + if (fd == -1 || (out = fdopen(fd, "w")) == NULL) + adios(bccfil, "unable to create"); +#else + mktemp(bccfil); + if ((out = fopen(bccfil, "w")) == NULL) + adios(bccfil, "unable to create"); +#endif + chmod(bccfil, 0600); - done (1); + if (subject) { + fprintf(out, "Subject: BCC: %s", subject); + } else { + fprintf(out, "Subject: BCC: message without subject"); + } + fprintf(out, "%s: %s\n", attach_hdr, draft); + fprintf(out, "------------\n"); + fclose(out); } -#endif