X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=uip%2Fspost.c;h=046f3403a66ed6ad758ff85bf563d61f3cf509e1;hp=e3cf211df24678c167ba4afd7341d4ee4ddeb7f8;hb=3eaeef7c3cf27aa9d715e20ebb72982406ab1d53;hpb=6a7760a0fa8ccb36a056a7600aab31f3656f7cfa diff --git a/uip/spost.c b/uip/spost.c index e3cf211..046f340 100644 --- a/uip/spost.c +++ b/uip/spost.c @@ -15,46 +15,36 @@ #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 VERBSW 2 +#define VERBSW 0 { "verbose", 0 }, -#define NVERBSW 3 +#define NVERBSW 1 { "noverbose", 0 }, -#define WATCSW 4 +#define WATCSW 2 { "watch", 0 }, -#define NWATCSW 5 +#define NWATCSW 3 { "nowatch", 0 }, -#define BACKSW 6 - { "backup", 0 }, -#define NBACKSW 7 - { "nobackup", 0 }, -#define ALIASW 8 +#define ALIASW 4 { "alias aliasfile", 0 }, -#define NALIASW 9 +#define NALIASW 5 { "noalias", 0 }, -#define VERSIONSW 10 +#define VERSIONSW 6 { "version", 0 }, -#define HELPSW 11 +#define HELPSW 7 { "help", 0 }, -#define DEBUGSW 12 +#define DEBUGSW 8 { "debug", -5 }, -#define DISTSW 13 +#define DISTSW 9 { "dist", -4 }, /* interface from dist */ -#define PUSHSW 14 /* fork to sendmail then exit */ +#define PUSHSW 10 /* fork to sendmail then exit */ { "push", -4 }, -#define NPUSHSW 15 /* exec sendmail */ +#define NPUSHSW 11 /* exec sendmail */ { "nopush", -6 }, -#define LIBSW 16 +#define LIBSW 12 { "library directory", -7 }, { NULL, 0 } }; @@ -67,11 +57,8 @@ 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 HFCC 0x0020 /* FCC: type header */ +#define HIGN 0x0040 /* ignore this header */ /* flags for headers->set */ #define MFRM 0x0001 /* we've seen a From: */ @@ -87,26 +74,25 @@ struct headers { unsigned int set; }; - static struct headers NHeaders[] = { { "Return-Path", HBAD, 0 }, { "Received", HBAD, 0 }, - { "Reply-To", HADR|HNGR, 0 }, - { "From", HADR|HNGR, MFRM }, + { "Reply-To", HADR, 0 }, + { "From", HADR, MFRM }, { "Sender", HADR|HBAD, 0 }, { "Date", HNOP, MDAT }, { "Subject", HSUB, 0 }, { "To", HADR|HTRY, MVIS }, { "Cc", HADR|HTRY, MVIS }, - { "Bcc", HADR|HTRY|HBCC|HNIL, MINV }, + { "Bcc", HADR|HTRY|HBCC, MINV }, { "Message-Id", HBAD, 0 }, { "Fcc", HFCC, 0 }, { NULL, 0, 0 } }; static struct headers RHeaders[] = { - { "Resent-Reply-To", HADR|HNGR, 0 }, - { "Resent-From", HADR|HNGR, MRFM }, + { "Resent-Reply-To", HADR, 0 }, + { "Resent-From", HADR, MRFM }, { "Resent-Sender", HADR|HBAD, 0 }, { "Resent-Date", HNOP, MRDT }, { "Resent-Subject", HSUB, 0 }, @@ -125,7 +111,6 @@ static int badmsg = 0; /* message has bad semantics */ static int verbose = 0; /* spell it out */ static int debug = 0; /* debugging post */ static int watch = 0; /* watch the delivery process */ -static int backflg = 0; /* prepend backup prefix to input file when done */ static int pushflg = 0; /* if going to fork to sendmail */ static int aliasflg = 0; /* if going to process aliases */ @@ -135,24 +120,15 @@ static enum { normal, resent } msgstate = normal; -static char tmpfil[] = "/tmp/pstXXXXXX"; +static char *tmpfil; -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[] */ +static char fccs[BUFSIZ] = ""; +struct mailname *bccs = NULL; /* list of the bcc recipients */ static struct headers *hdrtab; /* table for the message we're doing */ static FILE *out; /* output (temp) file */ -extern char *sendmail; - -/* -** external prototypes -*/ -extern char *getfullname(void); -extern char *getusername(void); - /* ** static prototypes */ @@ -161,18 +137,15 @@ 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 process_fcc(char *); static void fcc(char *, char *); - -#if 0 -static void make_bcc_file(void); -#endif +static void process_bccs(char *); int main(int argc, char **argv) { - int state, i, pid, compnum; + int state, compnum; char *cp, *msg = NULL, **argp, **arguments; char *sargv[16], buf[BUFSIZ], name[NAMESZ]; FILE *in; @@ -186,7 +159,6 @@ main(int argc, char **argv) if (context_foil(NULL) == -1) done(1); - mts_init(invo_name); arguments = getarguments(invo_name, argc, argv, 0); argp = arguments; @@ -217,22 +189,6 @@ main(int argc, char **argv) msgstate = resent; continue; - case FILTSW: - if (!(filter = *argp++) || *filter == '-') - adios(NULL, "missing argument to %s", - argp[-2]); - continue; - case NFILTSW: - filter = NULL; - continue; - - case BACKSW: - backflg++; - continue; - case NBACKSW: - backflg = 0; - continue; - case VERBSW: verbose++; continue; @@ -292,15 +248,7 @@ main(int argc, char **argv) verbose++; out = stdout; } else { -#ifdef HAVE_MKSTEMP - 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); -#endif + tmpfil = getcpy(m_mktemp2("/tmp/", invo_name, NULL, &out)); } hdrtab = (msgstate == normal) ? NHeaders : RHeaders; @@ -350,12 +298,6 @@ main(int argc, char **argv) } fclose(in); - if (backflg) { - 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); @@ -364,8 +306,28 @@ main(int argc, char **argv) fclose(out); /* process Fcc */ - for (i=0; iflags & HIGN) { + + if (hdr->flags & HIGN || !*str) { return; } + if (hdr->flags & HBAD) { advise(NULL, "illegal header line -- %s:", name); badmsg++; return; } - msgflags |= hdr->set; - if (hdr->flags & HSUB) { - if (subject) { - /* append mupliple subject */ - char *cp = concat(subject, "\t", str, NULL); - free(subject); - subject = cp; - } else { - subject = getcpy(str); - } - } + msgflags |= hdr->set; if (hdr->flags & HFCC) { - if ((cp = strrchr(str, '\n'))) { - *cp = '\0'; - } - for (cp = pp = str; (cp = strchr(pp, ',')); pp = cp) { - *cp++ = '\0'; - insert_fcc(hdr->value, pp); - } - insert_fcc(hdr->value, pp); + process_fcc(str); return; } -#ifdef notdef if (hdr->flags & HBCC) { - insert_bcc(str); + struct mailname *mp = NULL; + + /* Create list of Bcc addrs. */ + while ((cp = getname(str))) { + mp = getm(cp, NULL, 0, AD_HOST, NULL); + mp->m_next = bccs; /* push */ + bccs = mp; + } 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. - **/ - register struct mailname *f = 0; - register struct mailname *mp = 0; - - while ((cp = getname(str))) { - mp = getm(cp, NULL, 0, AD_HOST, NULL); - if (f == 0) { - f = mp; - mp->m_next = mp; - } else { - mp->m_next = f->m_next; - f->m_next = mp; - f = mp; - } + + 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. + **/ + struct mailname *f = NULL; + struct mailname *mp = NULL; + + while ((cp = getname(str))) { + mp = getm(cp, NULL, 0, AD_HOST, NULL); + if (!f) { + f = mp; + mp->m_next = mp; + } else { + mp->m_next = f->m_next; + f->m_next = mp; + f = mp; } - f = mp->m_next; mp->m_next = 0; - 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); } + f = mp->m_next; + mp->m_next = NULL; + /* Now munch on the list, possibly expanding aliases */ + putadr(name, f); + return; } + + /* + ** 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 + */ + /* + ** Although there is no masquerading anymore in mmh, we might want + ** to have aliasing of From: addresses. Think about it. + ** -- meillo@marmaro.de 2012-02 + */ + + if (hdr->flags & HSUB) { + subject = getcpy(str); + } + fprintf(out, "%s: %s", name, str); } @@ -546,12 +492,11 @@ finish_headers(FILE *out) /* In case the From: header contains multiple addresses. */ fprintf(out, "%sSender: %s\n", resentstr, from); } -#ifdef notdef - if (!(msgflags & MVIS)) + if (!(msgflags & MVIS)) { fprintf(out, "%sBcc: Blind Distribution List: ;\n", resentstr); -#endif /* notdef */ - + } if (badmsg) { + unlink(tmpfil); adios(NULL, "re-format message and try again"); } } @@ -583,9 +528,9 @@ get_header(char *header, struct headers *table) static void 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); @@ -658,152 +603,102 @@ putone(char *adr, int pos, int indent) } -/* -** Insert the normalized value from pp into fccfold[]. -*/ static void -insert_fcc(char *name, unsigned char *pp) +process_fcc(char *str) { - unsigned char *cp; - - for (cp = pp; isspace(*cp); cp++) - continue; - for (pp += strlen(pp) - 1; pp > cp && isspace(*pp); pp--) - continue; - if (pp >= cp) - *++pp = '\0'; - if (!*cp) - return; + char *cp, *pp; + int state = 0; - if (fccind >= FCCS) - adios(NULL, "too many %ss", name); - fccfold[fccind++] = getcpy(cp); + if (strlen(str)+strlen(fccs) > sizeof fccs /2) { + adios(NULL, "Too much Fcc data"); + } + /* todo: better have three states: SEPARATOR, PLUS, WORD */ + for (cp=pp=str; *cp; cp++) { + switch (*cp) { + case ' ': + case '\t': + case '\n': + case ',': + if (state != 0) { + state = 0; + *cp = '\0'; + if (*pp=='+' || *pp=='@') { + strcat(fccs, " "); + } else { + strcat(fccs, " +"); + } + strcat(fccs, pp); + } + break; + default: + if (state == 0) { + state = 1; + pp = cp; + } + break; + } + } } -#if 0 -/* BCC GENERATION */ static void -make_bcc_file(void) +fcc(char *file, char *folders) { - 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); + int status; + char cmd[BUFSIZ]; - fprintf(out, "Date: %s\n", dtimenow(0)); - if (!(msgflags & MFRM)) { - /* Construct a From: header. */ - fprintf(out, "From: %s\n", signature); - } else { - /* Add a Sender: header in case the From: header is fake. */ - fprintf(out, "Sender: %s\n", from); + if (verbose) { + printf("%sFcc: %s\n", msgstate == resent ? "Resent-" : "", + folders); + fflush(stdout); } - if (subject) - fprintf(out, "Subject: %s", subject); - fprintf(out, "BCC:\n\n------- Blind-Carbon-Copy\n\n"); - fflush(out); - - if (!filter) { - if ((fd = open(tmpfil, O_RDONLY)) == NOTOK) - adios(NULL, "unable to re-open"); - cpydgst(fd, fileno(out), tmpfil, bccfil); - close(fd); - } else { - vec[0] = mhbasename(mhlproc); - - for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++) - sleep(5); - switch (child_id) { - case NOTOK: - adios("fork", "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; - } + if (strlen(fileproc)+strlen(file)+strlen(folders)+100 > sizeof cmd) { + adios(NULL, "Too much Fcc data"); + } + /* hack: read from /dev/null and refile(1) won't question us */ + snprintf(cmd, sizeof cmd, "m_next) { + /* + ** Note: This draft file will be left existing by send(1), + ** although renamed with backup prefix. + ** TODO: We should have it removed eventually. + */ + bccdraft = getcpy(m_mktemp2("/tmp/", invo_name, NULL, &out)); + fprintf(out, "To: %s\n", mp->m_text); + fprintf(out, "Subject: [BCC] %s", subject ? subject : ""); + fprintf(out, "%s: %s\n", attach_hdr, origmsg); + fprintf(out, "------------\n"); + fclose(out); + + snprintf(buf, sizeof buf, "%s%s %s", sendproc, + pushflg ? " -push" : "", bccdraft); + if (system(buf) != 0) { + admonish(invo_name, "Problems to send Bcc to %s", + mp->m_text); + unlink(bccdraft); } + /* TODO: unlink renamed bcc draft after send(1) */ } - - fflush(stdout); }