tests.
##
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 \
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 \
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
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:
-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)%>
--------
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 *);
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);
}
/*
+ * 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.
*/
{ NULL, 0 }
};
-/*
- * Add an item to a comma seperated list
- */
-
-static char *addlist(char *, char *);
-
int
main (int argc, char **argv)
{
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);
-}
#include <h/mh.h>
#include <fcntl.h>
-#include <h/fmt_scan.h>
#include <h/tws.h>
#include <h/utils.h>
{ "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 }
};
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
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;
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:
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 == '@') {
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)
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");
}
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;
-}
--- /dev/null
+
+/*
+ * 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 <h/mh.h>
+#include <fcntl.h>
+#include <h/fmt_scan.h>
+#include <h/tws.h>
+#include <h/utils.h>
+
+/*
+ * 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;
+}