[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Nmh-commits] [SCM] The nmh Mail Handling System branch, master, updated
From: |
Ken Hornstein |
Subject: |
[Nmh-commits] [SCM] The nmh Mail Handling System branch, master, updated. dd16d13e6e96a0ed6e7d7a23d6e45fd628420ae4 |
Date: |
Tue, 20 Mar 2012 23:15:52 +0000 |
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The nmh Mail Handling System".
The branch, master has been updated
via dd16d13e6e96a0ed6e7d7a23d6e45fd628420ae4 (commit)
from 4079495fc819851b2506fc0017ffcfce61f2305f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/nmh.git/commit/?id=dd16d13e6e96a0ed6e7d7a23d6e45fd628420ae4
commit dd16d13e6e96a0ed6e7d7a23d6e45fd628420ae4
Author: Ken Hornstein <address@hidden>
Date: Tue Mar 20 19:15:18 2012 -0400
Basic work to add arguments to formatproc calls.
diff --git a/h/fmt_scan.h b/h/fmt_scan.h
index 394b01e..dbe955f 100644
--- a/h/fmt_scan.h
+++ b/h/fmt_scan.h
@@ -93,3 +93,4 @@ char *new_fs (char *, char *, char *);
int fmt_compile (char *, struct format **);
char *formataddr(char *, char *);
char *concataddr(char *, char *);
+extern char *format_string;
diff --git a/sbr/fmt_compile.c b/sbr/fmt_compile.c
index 0b739cf..ee495f1 100644
--- a/sbr/fmt_compile.c
+++ b/sbr/fmt_compile.c
@@ -246,7 +246,7 @@ static struct ftable functable[] = {
#define PUTLIT(str) do { NEW(FT_LIT,0,0); fp->f_text = (str); }
while (0)
#define PUTC(c) do { NEW(FT_CHAR,0,0); fp->f_char =
(c); } while (0)
-static char *format_string;
+char *format_string;
static unsigned char *usr_fstring; /* for CERROR */
#define CERROR(str) compile_error (str, cp)
diff --git a/uip/mhlsbr.c b/uip/mhlsbr.c
index e961b9b..ae1fb5d 100644
--- a/uip/mhlsbr.c
+++ b/uip/mhlsbr.c
@@ -91,6 +91,10 @@ static struct swit mhlswitches[] = {
{ "issue number", -5 },
#define NBODYSW 22
{ "nobody", -6 },
+#define FMTPROCSW 23
+ { "fmtproc program", 0 },
+#define NFMTPROCSW 24
+ { "nofmtproc", 0 },
{ NULL, 0 }
};
@@ -117,6 +121,16 @@ static struct swit mhlswitches[] = {
#define LBITS
"\020\01NOCOMPONENT\02UPPERCASE\03CENTER\04CLEARTEXT\05EXTRA\06HDROUTPUT\07CLEARSCR\010LEFTADJUST\011COMPRESS\012ADDRFMT\013BELL\014DATEFMT\015FORMAT\016INIT\017FACEFMT\020FACEDFLT\021SPLIT\022NONEWLINE\023NOWRAP\024FMTFILTER"
#define GFLAGS (NOCOMPONENT | UPPERCASE | CENTER | LEFTADJUST |
COMPRESS | SPLIT | NOWRAP)
+/*
+ * A list of format arguments
+ */
+
+struct arglist {
+ struct format *a_fmt;
+ char *a_nfs;
+ struct arglist *a_next;
+};
+
struct mcomp {
char *c_name; /* component name */
char *c_text; /* component text */
@@ -130,6 +144,9 @@ struct mcomp {
int c_cwidth; /* width of component */
int c_length; /* length in lines */
long c_flags;
+ struct arglist *c_f_args; /* Argument list for filter*/
+ struct arglist *c_f_tail; /* Pointer to tail of list */
+ int c_nargs; /* Number of arguments */
struct mcomp *c_next;
};
@@ -253,6 +270,7 @@ static char delim4[] =
"\n------------------------------\n\n";
static FILE *(*mhl_action) () = (FILE *(*) ()) 0;
+static struct comp *mhlcomp[128];
/*
* Redefine a couple of functions.
@@ -289,6 +307,11 @@ static void mhladios (char *, char *, ...);
static void mhldone (int);
static void m_popen (char *);
static void filterbody (struct mcomp *, char *, int, int, FILE *);
+static int compileargs (struct mcomp *, char *);
+static int checkcomp (char *, char *);
+static void addcomp (int, char *, char *);
+static void freecomps (void);
+static void freecomptext (void);
int
@@ -375,6 +398,14 @@ mhl (int argc, char **argv)
nomore++;
continue;
+ case FMTPROCSW:
+ if (!(formatproc = *argp++) || *formatproc == '-')
+ adios (NULL, "missing argument to %s", argp[-2]);
+ continue;
+ case NFMTPROCSW:
+ formatproc = NULL;
+ continue;
+
case LENSW:
if (!(cp = *argp++) || *cp == '-')
adios (NULL, "missing argument to %s", argp[-2]);
@@ -448,6 +479,9 @@ mhl (int argc, char **argv)
ontty = NOTTY;
}
+ for (i = 0; i < sizeof(mhlcomp)/sizeof(mhlcomp[0]); i++)
+ mhlcomp[i] = NULL;
+
mhl_format (form ? form : mhlformat, length, width);
if (vecp == 0) {
@@ -457,6 +491,8 @@ mhl (int argc, char **argv)
process (folder, files[i], i + 1, vecp);
}
+ freecomps();
+
if (forwall) {
if (digest) {
printf ("%s", delim4);
@@ -715,6 +751,20 @@ evalvar (struct mcomp *c1)
return 0;
}
+ if (!mh_strcasecmp (name, "formatarg")) {
+ char *nfs;
+ int rc;
+
+ if (ptos (name, &cp))
+ return 1;
+ nfs = new_fs (NULL, NULL, cp);
+
+ rc = compileargs(c1, nfs);
+
+ return rc;
+ }
+
+
return 1;
}
@@ -829,13 +879,15 @@ process (char *folder, char *fname, int ofilen, int
ofilec)
c1->c_flags &= ~HDROUTPUT;
break;
}
+
+ freecomptext();
}
static void
mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
{
- int state;
+ int state, bucket;
struct mcomp *c1, *c2, *c3;
char **ip, name[NAMESZ], buf[BUFSIZ];
@@ -901,10 +953,13 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
switch (state = m_getfld (state, name, buf, sizeof(buf), fp)) {
case FLD:
case FLDPLUS:
+ bucket = checkcomp(name, buf);
for (ip = ignores; *ip; ip++)
if (!mh_strcasecmp (name, *ip)) {
- while (state == FLDPLUS)
+ while (state == FLDPLUS) {
state = m_getfld (state, name, buf, sizeof(buf),
fp);
+ addcomp(bucket, name, buf);
+ }
break;
}
if (*ip)
@@ -926,6 +981,7 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
while (state == FLDPLUS) {
state = m_getfld (state, name, buf, sizeof(buf), fp);
c1->c_text = add (buf, c1->c_text);
+ addcomp(bucket, name, buf);
}
if (c2 == NULL)
c1->c_flags |= EXTRA;
@@ -1177,6 +1233,17 @@ free_queue (struct mcomp **head, struct mcomp **tail)
free ((char *) c1->c_fmt);
if (c1->c_face)
free (c1->c_face);
+ if (c1->c_f_args) {
+ struct arglist *a1, *a2;
+ for (a1 = c1->c_f_args; a1; a1 = a2) {
+ a2 = a1->a_next;
+ if (a1->a_fmt)
+ free(a1->a_fmt);
+ if (a1->a_nfs)
+ free(a1->a_nfs);
+ }
+ free(a1);
+ }
free ((char *) c1);
}
@@ -1818,10 +1885,177 @@ m_pclose (void)
/*
+ * Compile a format string and add it to the list of arguments used by
+ * the formatproc.
+ *
+ * This deserves some explanation. Here's the deal:
+ *
+ * We want to keep track of components used as arguments by formatproc,
+ * but the hash table is reset every time fmt_compile is called. So we
+ * iterate through the function list looking for things that use components
+ * and save the name. And because we might get the same components used
+ * by different arguments we need to keep track to every reference of
+ * every component so we can add them when the message is processed. So
+ * we compile the argument string now (to get the components we use) and
+ * save them for later.
+ */
+
+static int
+compileargs (struct mcomp *c1, char *nfs)
+{
+ struct format *fmt;
+ struct arglist *args;
+ int i;
+
+ i = fmt_compile(nfs, &fmt);
+
+ args = (struct arglist *) mh_xmalloc(sizeof(struct arglist));
+
+ if (! args)
+ adios (NULL, "Unable to allocate formatproc args storage");
+
+ args->a_fmt = fmt;
+ args->a_nfs = format_string;
+ args->a_next = NULL;
+ c1->c_nargs++;
+ format_string = NULL;
+
+ if (c1->c_f_tail)
+ c1->c_f_tail->a_next = args;
+
+ c1->c_f_tail = args;
+
+ if (! c1->c_f_args)
+ c1->c_f_args = args;
+
+ if (i == 0)
+ return 0;
+
+ /*
+ * If wantcomp ever changes size, we need to change the size
+ * of mhlcomp as well
+ */
+
+ for (i = 0; i < sizeof(wantcomp)/sizeof(wantcomp[0]); i++) {
+ if (wantcomp[i]) {
+ if (mhlcomp[i]) {
+ struct comp *c;
+ for (c = mhlcomp[i]; c->c_next != NULL; c = c->c_next)
+ ;
+ c->c_next = wantcomp[i];
+ } else
+ mhlcomp[i] = wantcomp[i];
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Check to see if we are interested in a component. If we are, save
+ * the text.
+ */
+
+static int
+checkcomp(char *name, char *buf)
+{
+ int found = 0, i;
+ struct comp *c;
+ int bucket = CHASH(name);
+ char *cp;
+
+ if ((c = mhlcomp[bucket])) {
+ do {
+ if (mh_strcasecmp(name, c->c_name) == 0) {
+ found++;
+ if (! c->c_text) {
+ i = strlen(c->c_text = strdup(buf)) - 1;
+ if (c->c_text[i] == '\n')
+ c->c_text[i] = '\0';
+ } else {
+ i = strlen(cp = c->c_text) - 1;
+ if (cp[i] == '\n') {
+ if (c->c_type & CT_ADDR) {
+ cp[i] = '\0';
+ cp = add (",\n\t", cp);
+ } else {
+ cp = add ("\t", cp);
+ }
+ }
+ c->c_text = add (buf, cp);
+ }
+ }
+ } while ((c = c->c_next));
+ }
+
+ return found ? bucket : -1;
+}
+
+/*
+ * Add text to an existing component
+ */
+
+static void
+addcomp(int bucket, char *name, char *buf)
+{
+ struct comp *c;
+
+ if (bucket != -1) {
+ c = mhlcomp[bucket];
+ do {
+ if (mh_strcasecmp(name, c->c_name) == 0)
+ c->c_text = add (buf, c->c_text);
+ } while ((c = c->c_next));
+ }
+}
+
+/*
+ * Free up saved component structures
+ */
+
+static void
+freecomps(void)
+{
+ struct comp *c1, *c2;
+ int i;
+
+ for (i = 0; i < sizeof(mhlcomp)/sizeof(mhlcomp[0]); i++) {
+ if ((c1 = mhlcomp[i]))
+ for (; c1; c1 = c2) {
+ c2 = c1->c_next;
+ if (c1->c_text)
+ free(c1->c_text);
+ free(c1);
+ }
+ }
+}
+
+/*
+ * Just free up the component text.
+ */
+
+static void
+freecomptext(void)
+{
+ struct comp *c1;
+ int i;
+
+ for (i = 0; i < sizeof(mhlcomp)/sizeof(mhlcomp[0]); i++) {
+ if ((c1 = mhlcomp[i]))
+ for (; c1; c1 = c1->c_next) {
+ if (c1->c_text) {
+ free(c1->c_text);
+ c1->c_text = NULL;
+ }
+ }
+ }
+}
+
+/*
* Filter the body of a message through a specified format program
*/
-void
+static void
filterbody (struct mcomp *c1, char *buf, int bufsz, int state, FILE *fp)
{
struct mcomp holder;
@@ -1898,7 +2132,40 @@ filterbody (struct mcomp *c1, char *buf, int bufsz, int
state, FILE *fp)
*/
switch (filterpid = fork()) {
+ char **args;
+ struct arglist *a;
+ int i, dat[5], s;
+
case 0:
+ /*
+ * Allocate an argument array for us
+ */
+
+ args = (char **) mh_xmalloc((c1->c_nargs + 2) * sizeof(char *));
+ args[0] = formatproc;
+ args[c1->c_nargs + 1] = NULL;
+ dat[0] = 0;
+ dat[1] = 0;
+ dat[2] = 0;
+ dat[3] = BUFSIZ;
+ dat[4] = 0;
+
+ /*
+ * Pull out each argument and scan them.
+ */
+
+ for (a = c1->c_f_args, i = 1; a != NULL; a = a->a_next, i++) {
+ args[i] = mh_xmalloc(BUFSIZ);
+ fmt_scan(a->a_fmt, args[i], BUFSIZ, dat);
+ /*
+ * fmt_scan likes to put a trailing newline at the end of the
+ * format string. If we have one, get rid of it.
+ */
+ s = strlen(args[i]);
+ if (args[i][s - 1] == '\n')
+ args[i][s - 1] = '\0';
+ }
+
if (dup2(fdinput[0], STDIN_FILENO) < 0) {
adios("formatproc", "Unable to dup2() standard input");
}
@@ -1917,7 +2184,7 @@ filterbody (struct mcomp *c1, char *buf, int bufsz, int
state, FILE *fp)
close(fdoutput[0]);
close(fdoutput[1]);
- execlp(formatproc, formatproc, (char *) NULL);
+ execvp(formatproc, args);
adios(formatproc, "Unable to execute filter");
-----------------------------------------------------------------------
Summary of changes:
h/fmt_scan.h | 1 +
sbr/fmt_compile.c | 2 +-
uip/mhlsbr.c | 275 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 273 insertions(+), 5 deletions(-)
hooks/post-receive
--
The nmh Mail Handling System
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Nmh-commits] [SCM] The nmh Mail Handling System branch, master, updated. dd16d13e6e96a0ed6e7d7a23d6e45fd628420ae4,
Ken Hornstein <=