From 2d1f77125ffb16daf661a40710bb0fb48343d1f9 Mon Sep 17 00:00:00 2001 From: Ken Hornstein Date: Sun, 26 Feb 2012 00:09:52 -0500 Subject: [PATCH] Finally, some support for mh-format when using forw(1). Still needs some tests. --- Makefile.am | 6 +- etc/digestcomps | 2 +- etc/forwcomps | 9 +-- h/prototypes.h | 2 + h/utils.h | 1 + sbr/utils.c | 13 ++++ uip/comp.c | 19 ------ uip/forw.c | 138 +++++++++++++++++++++++------------------ uip/forwsbr.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 287 insertions(+), 85 deletions(-) create mode 100755 uip/forwsbr.c diff --git a/Makefile.am b/Makefile.am index 2d3342b..a219981 100644 --- a/Makefile.am +++ b/Makefile.am @@ -145,6 +145,9 @@ dist_sysconf_DATA = etc/MailAliases etc/components etc/digestcomps \ ## sysconf_DATA = etc/mhn.defaults etc/mts.conf +## +## Documentation that gets installed in docdir +## dist_doc_DATA = COPYRIGHT VERSION docs/COMPLETION-BASH docs/COMPLETION-TCSH \ docs/COMPLETION-ZSH docs/DIFFERENCES docs/FAQ \ docs/MAIL.FILTERING docs/MAILING-LISTS docs/README-ATTACHMENTS \ @@ -223,7 +226,7 @@ uip_flist_SOURCES = uip/flist.c uip_folder_SOURCES = uip/folder.c uip_forw_SOURCES = uip/forw.c uip/whatnowproc.c uip/whatnowsbr.c uip/sendsbr.c \ - uip/annosbr.c uip/distsbr.c + uip/annosbr.c uip/distsbr.c uip/forwsbr.c uip_forw_LDADD = $(LDADD) $(ICONVLIB) uip_inc_SOURCES = uip/inc.c uip/scansbr.c uip/dropsbr.c uip/termsbr.c \ @@ -547,6 +550,7 @@ rpm: dist cscope: echo "-I $(srcdir)/h -I $(srcdir)/sbr -I $(srcdir)/uip -I $(srcdir)/mts/smtp" > cscope.files find $(srcdir) \( -name \*.c -o -name \*.l \) -print | grep -v dtimep.c >> cscope.files +.PHONY: cscope ## ## Rules to upload the distribution to savannah diff --git a/etc/digestcomps b/etc/digestcomps index 7f5036d..fdb55f8 100644 --- a/etc/digestcomps +++ b/etc/digestcomps @@ -3,7 +3,7 @@ To: %{digest} Distribution: dist-%{digest}; Subject: %{digest} Digest V%(cur) #%(msg) Reply-To: %{digest} -------- -%{digest} Digest %(weekday{date}), %2(mday{date}) %(month{date}) %(year{date}) +%{digest} Digest %(weekday{nmh-date}), %2(mday{nmh-date}) %(month{nmh-date}) %(year{nmh-date}) Volume %(cur) : Issue %(msg) Today's Topics: diff --git a/etc/forwcomps b/etc/forwcomps index 7f255ea..fdfb23b 100644 --- a/etc/forwcomps +++ b/etc/forwcomps @@ -1,5 +1,6 @@ -To: -cc: -Fcc: +outbox -Subject: +%<{nmh-from}%|%(void(localmbox))%>%(void(width))%(putaddr From: ) +%<{nmh-to}%(void(width))%(putaddr To: )%|To:%> +%<{nmh-cc}%(void(width))%(putaddr cc: )%|cc:%> +Fcc: %<{fcc}%(putstr)%|+outbox%> +Subject:%<{nmh-subject} %(trim)%(putlit)%?{subject} %(trim)%(putlit) (fwd)%> -------- diff --git a/h/prototypes.h b/h/prototypes.h index 11db40d..ad9a87e 100644 --- a/h/prototypes.h +++ b/h/prototypes.h @@ -146,6 +146,8 @@ void annopreserve(int); int distout (char *, char *, char *); void replout (FILE *, char *, char *, struct msgs *, int, int, char *, char *, char *); +int build_form (char *, char *, int *, char *, char *, char *, char *, + char *, char *); int sendsbr (char **, int, char *, struct stat *, int, char *, int); int what_now (char *, int, int, char *, char *, int, struct msgs *, char *, int, char *); diff --git a/h/utils.h b/h/utils.h index b9660a5..8142b2c 100644 --- a/h/utils.h +++ b/h/utils.h @@ -7,6 +7,7 @@ void *mh_xmalloc(size_t); void *mh_xrealloc(void *, size_t); char *pwd(void); char *add(char *, char *); +char *addlist(char *, char *); int folder_exists(char *); void create_folder(char *, int, void (*)(int)); int num_digits(int); diff --git a/sbr/utils.c b/sbr/utils.c index 48969ab..cce7378 100644 --- a/sbr/utils.c +++ b/sbr/utils.c @@ -123,6 +123,19 @@ add (char *s2, char *s1) } /* + * addlist + * Append an item to a comma separated list + */ +char * +addlist (char *list, char *item) +{ + if (list) + list = add (", ", list); + + return add (item, list); +} + +/* * folder_exists * Check to see if a folder exists. */ diff --git a/uip/comp.c b/uip/comp.c index c8189d1..111a219 100644 --- a/uip/comp.c +++ b/uip/comp.c @@ -79,12 +79,6 @@ static struct swit aqrul[] = { { NULL, 0 } }; -/* - * Add an item to a comma seperated list - */ - -static char *addlist(char *, char *); - int main (int argc, char **argv) { @@ -416,16 +410,3 @@ edit_it: done (1); return 1; } - -/* - * Append an item to a comma separated list - */ - -static char * -addlist (char *list, char *item) -{ - if (list) - list = add (", ", list); - - return add (item, list); -} diff --git a/uip/forw.c b/uip/forw.c index 112b083..3c3e4f6 100644 --- a/uip/forw.c +++ b/uip/forw.c @@ -9,7 +9,6 @@ #include #include -#include #include #include @@ -70,7 +69,18 @@ static struct swit switches[] = { { "file file", 4 }, /* interface from msh */ #define BILDSW 25 { "build", 5 }, /* interface from mhe */ - +#define FROMSW 26 + { "from address", 0 }, +#define TOSW 27 + { "to address", 0 }, +#define CCSW 28 + { "cc address", 0 }, +#define SUBJECTSW 29 + { "subject text", 0 }, +#define FCCSW 30 + { "fcc mailbox", 0 }, +#define WIDTHSW 31 + { "width columns", 0 }, { NULL, 0 } }; @@ -112,7 +122,6 @@ static struct msgs *mp = NULL; /* used a lot */ static void mhl_draft (int, char *, int, int, char *, char *, int); static void copy_draft (int, char *, char *, int, int, int); static void copy_mime_draft (int); -static int build_form (char *, char *, int, int); int @@ -122,9 +131,12 @@ main (int argc, char **argv) int issue = 0, volume = 0, dashstuff = 0; int nedit = 0, nwhat = 0, i, in; int out, isdf = 0, msgnum; + int outputlinelen = OUTPUTLINELEN; + int dat[5]; char *cp, *cwd, *maildir, *dfolder = NULL; char *dmsg = NULL, *digest = NULL, *ed = NULL; - char *file = NULL, *filter = NULL, *folder = NULL; + char *file = NULL, *filter = NULL, *folder = NULL, *fwdmsg = NULL; + char *from = NULL, *to = NULL, *cc = NULL, *subject = NULL, *fcc = NULL; char *form = NULL, buf[BUFSIZ], value[10]; char **argp, **arguments, *msgs[MAXARGS]; struct stat st; @@ -228,8 +240,9 @@ main (int argc, char **argv) continue; case DGSTSW: - if (!(digest = *argp++) || *digest == '-') + if (!(cp = *argp++) || *cp == '-') adios (NULL, "missing argument to %s", argp[-2]); + digest = getcpy(cp); mime = 0; continue; case ISSUESW: @@ -270,6 +283,39 @@ main (int argc, char **argv) case NBITSTUFFSW: dashstuff = -1; /* trinary logic */ continue; + + case FROMSW: + if (!(cp = *argp++) || *cp == '-') + adios (NULL, "missing argument to %s", argp[-2]); + from = addlist(from, cp); + continue; + case TOSW: + if (!(cp = *argp++) || *cp == '-') + adios (NULL, "missing argument to %s", argp[-2]); + to = addlist(to, cp); + continue; + case CCSW: + if (!(cp = *argp++) || *cp == '-') + adios (NULL, "missing argument to %s", argp[-2]); + cc = addlist(cc, cp); + continue; + case FCCSW: + if (!(cp = *argp++) || *cp == '-') + adios (NULL, "missing argument to %s", argp[-2]); + fcc = addlist(fcc, cp); + continue; + case SUBJECTSW: + if (!(cp = *argp++) || *cp == '-') + adios (NULL, "missing argument to %s", argp[-2]); + subject = getcpy(cp); + continue; + + case WIDTHSW: + if (!(cp = *argp++) || *cp == '-') + adios (NULL, "missing argument to %s", argp[-2]); + if ((outputlinelen = atoi(cp)) < 10) + adios (NULL, "impossible width %d", outputlinelen); + continue; } } if (*cp == '+' || *cp == '@') { @@ -353,6 +399,20 @@ try_it_again: if (!m_convert (mp, msgs[msgnum])) done (1); seq_setprev (mp); /* set the previous sequence */ + + /* + * Find the first message in our set and use it as the input + * for the component scanner + */ + + for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) + if (is_selected (mp, msgnum)) { + fwdmsg = strdup(m_name(msgnum)); + break; + } + + if (! fwdmsg) + adios (NULL, "Unable to find input message"); } if (filter && access (filter, R_OK) == NOTOK) @@ -376,9 +436,19 @@ try_it_again: volume = 1; if (!form) form = digestcomps; - in = build_form (form, digest, volume, issue); - } else - in = open_form(&form, forwcomps); + } else { + form = forwcomps; + } + + dat[0] = issue; + dat[1] = volume; + dat[2] = 0; + dat[3] = outputlinelen; + dat[4] = 0; + + + in = build_form (form, digest, dat, from, to, cc, fcc, subject, + file ? file : fwdmsg); if ((out = creat (drft, m_gmprot ())) == NOTOK) adios (drft, "unable to create"); @@ -626,55 +696,3 @@ copy_mime_draft (int out) } write (out, "\n", 1); } - - -static int -build_form (char *form, char *digest, int volume, int issue) -{ - int in; - int fmtsize; - register char *nfs; - char *line, tmpfil[BUFSIZ]; - FILE *tmp; - register struct comp *cptr; - struct format *fmt; - int dat[5]; - char *cp = NULL; - - /* Get new format string */ - nfs = new_fs (form, NULL, NULL); - fmtsize = strlen (nfs) + 256; - - /* Compile format string */ - fmt_compile (nfs, &fmt); - - FINDCOMP (cptr, "digest"); - if (cptr) - cptr->c_text = digest; - FINDCOMP (cptr, "date"); - if (cptr) - cptr->c_text = getcpy(dtimenow (0)); - - dat[0] = issue; - dat[1] = volume; - dat[2] = 0; - dat[3] = fmtsize; - dat[4] = 0; - - cp = m_mktemp2(NULL, invo_name, NULL, &tmp); - if (cp == NULL) adios("forw", "unable to create temporary file"); - strncpy (tmpfil, cp, sizeof(tmpfil)); - unlink (tmpfil); - if ((in = dup (fileno (tmp))) == NOTOK) - adios ("dup", "unable to"); - - line = mh_xmalloc ((unsigned) fmtsize); - fmt_scan (fmt, line, fmtsize, dat); - fputs (line, tmp); - free (line); - if (fclose (tmp)) - adios (tmpfil, "error writing"); - - lseek (in, (off_t) 0, SEEK_SET); - return in; -} diff --git a/uip/forwsbr.c b/uip/forwsbr.c new file mode 100755 index 0000000..a3bc42e --- /dev/null +++ b/uip/forwsbr.c @@ -0,0 +1,182 @@ + +/* + * forwsbr.c -- subroutine to build a draft from a component file + * + * This code is Copyright (c) 2012, by the authors of nmh. See the + * COPYRIGHT file in the root directory of the nmh distribution for + * complete copyright information. + */ + +#include +#include +#include +#include +#include + +/* + * Take from replsbr.c - a buffer big enough to read in data header lines + * in reasonable chunks but not enough to slurp in the whole message + */ + +static char msgbuf[256]; +#define COMPFREE(c) if (c->c_text) free(c->c_text) + +int +build_form (char *form, char *digest, int *dat, char *from, char *to, + char *cc, char *fcc, char *subject, char *inputfile) +{ + int in; + int i, fmtsize, ncomps, state, char_read = 0; + register char *nfs; + char *line, tmpfil[BUFSIZ], name[NAMESZ]; + FILE *tmp; + register struct comp *cptr; + struct format *fmt; + char *cp = NULL; + + /* + * Open the message we'll be scanning for components + */ + + if ((tmp = fopen(inputfile, "r")) == NULL) + adios (inputfile, "Unable to open"); + + /* Get new format string */ + nfs = new_fs (form, NULL, NULL); + fmtsize = strlen (nfs) + 256; + + /* Compile format string */ + ncomps = fmt_compile (nfs, &fmt); + + /* + * Process our message and save all relevant components + * + * A lot of this is taken from replsbr.c; should we try to merge + * these routines? + */ + + for (state = FLD;;) { + state = m_getfld(state, name, msgbuf, sizeof(msgbuf), tmp); + switch (state) { + case FLD: + case FLDPLUS: + /* + * If we find a component that we're interested in, save + * a copy. We don't do all of that weird buffer switching + * that replout does. + */ + if ((cptr = wantcomp[CHASH(name)])) + do { + if (mh_strcasecmp(name, cptr->c_name) == 0) { + char_read += msg_count; + if (! cptr->c_text) { + i = strlen(cptr->c_text = strdup(msgbuf)) - 1; + if (cptr->c_text[i] == '\n') + cptr->c_text[i] = '\0'; + } else { + i = strlen(cptr->c_text) - 1; + if (cptr->c_text[i] == '\n') { + if (cptr->c_type & CT_ADDR) { + cptr->c_text[i] = '\0'; + cptr->c_text = add(",\n\t", + cptr->c_text); + } else { + cptr->c_text = add ("\t", cptr->c_text); + } + } + cptr->c_text = add(msgbuf, cptr->c_text); + } + while (state == FLDPLUS) { + state = m_getfld(state, name, msgbuf, + sizeof(msgbuf), tmp); + cptr->c_text = add(msgbuf, cptr->c_text); + char_read += msg_count; + } + break; + } + } while ((cptr = cptr->c_next)); + + while (state == FLDPLUS) + state = m_getfld(state, name, msgbuf, sizeof(msgbuf), tmp); + break; + + case LENERR: + case FMTERR: + case BODY: + case FILEEOF: + goto finished; + + default: + adios(NULL, "m_getfld() returned %d", state); + } + } + + /* + * Override any components just in case they were included in the + * input message. Also include command-line components given here + */ + +finished: + + FINDCOMP (cptr, "digest"); + if (cptr) { + COMPFREE(cptr); + cptr->c_text = digest; + } + FINDCOMP (cptr, "nmh-date"); + if (cptr) { + COMPFREE(cptr); + cptr->c_text = getcpy(dtimenow (0)); + } + FINDCOMP (cptr, "nmh-from"); + if (cptr) { + COMPFREE(cptr); + cptr->c_text = from; + } + FINDCOMP (cptr, "nmh-to"); + if (cptr) { + COMPFREE(cptr); + cptr->c_text = to; + } + FINDCOMP (cptr, "nmh-cc"); + if (cptr) { + COMPFREE(cptr); + cptr->c_text = cc; + } + FINDCOMP (cptr, "nmh-subject"); + if (cptr) { + COMPFREE(cptr); + cptr->c_text = subject; + } + FINDCOMP (cptr, "fcc"); + if (cptr) { + COMPFREE(cptr); + cptr->c_text = fcc; + } + + cp = m_mktemp2(NULL, invo_name, NULL, &tmp); + if (cp == NULL) adios("forw", "unable to create temporary file"); + strncpy (tmpfil, cp, sizeof(tmpfil)); + unlink (tmpfil); + if ((in = dup (fileno (tmp))) == NOTOK) + adios ("dup", "unable to"); + + line = mh_xmalloc ((unsigned) fmtsize); + fmt_scan (fmt, line, fmtsize, dat); + fputs (line, tmp); + free (line); + if (fclose (tmp)) + adios (tmpfil, "error writing"); + + lseek (in, (off_t) 0, SEEK_SET); + + /* + * Free any component buffers that we allocated + */ + + for (i = 0; i < (sizeof(wantcomp) / sizeof(struct comp)); i++) + for (cptr = wantcomp[i]; cptr != NULL; cptr = cptr->c_next) + COMPFREE(cptr); + + return in; +} -- 1.7.10.4