From: Paul Fox Date: Sun, 8 Feb 2015 20:22:07 +0000 (-0500) Subject: add new message separator header to mhshow X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/5b035a57c6f503870fa01242724c20ef907bc35c?ds=inline;hp=-c add new message separator header to mhshow new switches to mhshow (-headerform and -[no]header) control whether and what is displayed before the display of every message's content. the default separator looks like "[ Message folder:msg ]". the implementation parallels the -markform feature. since mhshow is often started by show, show now passes the -[no]header options through to mhshow. (also, show no longer attempts to pass such options through to cat (in the case of -noshowproc)). --- 5b035a57c6f503870fa01242724c20ef907bc35c diff --git a/etc/mhshow.header b/etc/mhshow.header new file mode 100644 index 00000000..2f9bafee --- /dev/null +++ b/etc/mhshow.header @@ -0,0 +1,5 @@ +%; +%; This is provided as reference only; it shows the default content marker +%; used by mhshow when it decides to not display content. +%; +[ Message %{folder}%<{folder}:%>%(msg) ] diff --git a/h/mhparse.h b/h/mhparse.h index d1c94420..3efec9cb 100644 --- a/h/mhparse.h +++ b/h/mhparse.h @@ -502,8 +502,7 @@ char *get_param_value(PM pm, char replace); * markerform - The name of a file containg mh-format(5) code used to * display markers about non-displayed MIME parts. */ -void show_all_messages(CT *cts, int concat, int textonly, int inlineonly, - char *markerform); +void show_all_messages(CT *cts, int concat, int textonly, int inlineonly); /* * Display (or store) a single MIME part using the specified command diff --git a/uip/mhn.c b/uip/mhn.c index be433d69..ea563791 100644 --- a/uip/mhn.c +++ b/uip/mhn.c @@ -554,7 +554,7 @@ do_cache: * Show the message content */ if (showsw) - show_all_messages (cts, 0, 0, 0, NULL); + show_all_messages (cts, 0, 0, 0); /* Now free all the structures for the content */ for (ctp = cts; *ctp; ctp++) diff --git a/uip/mhshow.c b/uip/mhshow.c index c8343763..b2a4c0da 100644 --- a/uip/mhshow.c +++ b/uip/mhshow.c @@ -31,6 +31,9 @@ X("noinlineonly", 0, NINLINESW) \ X("file file", 0, FILESW) \ X("form formfile", 0, FORMSW) \ + X("header", 0, HEADSW) \ + X("noheader", 0, NHEADSW) \ + X("headerform formfile", 0, HEADFORMSW) \ X("markform formfile", 0, MARKFORMSW) \ X("part number", 0, PARTSW) \ X("type content", 0, TYPESW) \ @@ -70,6 +73,10 @@ extern char *cache_private; extern char *progsw; extern int nomore; /* flags for moreproc/header display */ extern char *formsw; +extern char *folder; +extern char *headerform; +extern char *markerform; +extern int headersw; /* mhmisc.c */ extern int npart; @@ -110,7 +117,7 @@ int main (int argc, char **argv) { int msgnum, *icachesw, concatsw = -1, textonly = -1, inlineonly = -1; - char *cp, *file = NULL, *folder = NULL, *markform = NULL; + char *cp, *file = NULL; char *maildir, buf[100], **argp; char **arguments; struct msgs_array msgs = { 0, 0, NULL }; @@ -131,13 +138,13 @@ main (int argc, char **argv) while ((cp = *argp++)) { if (*cp == '-') { switch (smatch (++cp, switches)) { - case AMBIGSW: + case AMBIGSW: ambigsw (cp, switches); done (1); - case UNKWNSW: + case UNKWNSW: adios (NULL, "-%s unknown", cp); - case HELPSW: + case HELPSW: snprintf (buf, sizeof(buf), "%s [+folder] [msgs] [switches]", invo_name); print_help (buf, switches, 1); @@ -235,8 +242,20 @@ do_cache: formsw = getcpy (etcpath (cp)); continue; + case HEADSW: + headersw = 1; + continue; + case NHEADSW: + headersw = 0; + continue; + + case HEADFORMSW: + if (!(headerform = *argp++) || *headerform == '-') + adios (NULL, "missing argument to %s", argp[-2]); + continue; + case MARKFORMSW: - if (!(markform = *argp++) || *markform == '-') + if (!(markerform = *argp++) || *markerform == '-') adios (NULL, "missing argument to %s", argp[-2]); continue; @@ -257,10 +276,10 @@ do_cache: adios (NULL, "missing argument to %s", argp[-2]); continue; - case VERBSW: + case VERBSW: verbosw = 1; continue; - case NVERBSW: + case NVERBSW: verbosw = 0; continue; case DEBUGSW: @@ -338,6 +357,8 @@ do_cache: if ((ct = parse_mime (file))) *ctp++ = ct; + + headersw = 0; } else { /* * message(s) are coming from a folder @@ -430,7 +451,7 @@ do_cache: /* * Show the message content */ - show_all_messages (cts, concatsw, textonly, inlineonly, markform); + show_all_messages (cts, concatsw, textonly, inlineonly); /* Now free all the structures for the content */ for (ctp = cts; *ctp; ctp++) diff --git a/uip/mhshowsbr.c b/uip/mhshowsbr.c index 31d25eb1..4b11494e 100644 --- a/uip/mhshowsbr.c +++ b/uip/mhshowsbr.c @@ -33,6 +33,12 @@ char *progsw = NULL; int nomore = 0; char *formsw = NULL; +/* for output markerss and headers */ +char *folder = NULL; +char *markerform; +char *headerform; +int headersw = -1; + /* mhmisc.c */ int part_ok (CT); @@ -59,7 +65,9 @@ static int show_external (CT, int, int, int, int, struct format *); static int parse_display_string (CT, char *, int *, int *, char *, char *, size_t, int multipart); static int convert_content_charset (CT, char **); +static struct format *compile_header(char *); static struct format *compile_marker(char *); +static void output_header (CT, struct format *); static void output_marker (CT, struct format *, int); static void free_markercomps (void); static int pidcheck(int); @@ -69,6 +77,7 @@ static int pidcheck(int); * content marker display. */ +static struct comp *folder_comp = NULL; static struct comp *part_comp = NULL; static struct comp *ctype_comp = NULL; static struct comp *description_comp = NULL; @@ -89,11 +98,10 @@ static struct param_comp_list *dispo_pc_list = NULL; */ void -show_all_messages (CT *cts, int concatsw, int textonly, int inlineonly, - char *markerform) +show_all_messages (CT *cts, int concatsw, int textonly, int inlineonly) { CT ct, *ctp; - struct format *fmt; + struct format *hfmt, *mfmt; /* * If form is not specified, then get default form @@ -103,9 +111,10 @@ show_all_messages (CT *cts, int concatsw, int textonly, int inlineonly, formsw = getcpy (etcpath ("mhl.headers")); /* - * Compile the content marker format line + * Compile the content marker and header format lines */ - fmt = compile_marker(markerform); + mfmt = compile_marker(markerform); + hfmt = compile_header(headerform); /* * If form is "mhl.null", suppress display of header. @@ -118,12 +127,15 @@ show_all_messages (CT *cts, int concatsw, int textonly, int inlineonly, /* if top-level type is ok, then display message */ if (type_ok (ct, 1)) + if (headersw) output_header(ct, hfmt); + show_single_message (ct, formsw, concatsw, textonly, inlineonly, - fmt); + mfmt); } free_markercomps(); - fmt_free(fmt, 1); + fmt_free(hfmt, 1); + fmt_free(mfmt, 1); } @@ -1252,6 +1264,7 @@ convert_content_charset (CT ct, char **file) { * Compile our format string and save any parameters we care about. */ +#define DEFAULT_HEADER "[ Message %{folder}%<{folder}:%>%(msg) ]" #define DEFAULT_MARKER "[ part %{part} - %{content-type} - " \ "%<{description}%{description}" \ "%?{cdispo-filename}%{cdispo-filename}" \ @@ -1259,7 +1272,29 @@ convert_content_charset (CT ct, char **file) { "%(kilo(size))B %<(unseen)\\(suppressed\\)%> ]" static struct format * -compile_marker(char *markerform) +compile_header(char *form) +{ + struct format *fmt; + char *fmtstring; + struct comp *comp = NULL; + unsigned int bucket; + + fmtstring = new_fs(form, NULL, DEFAULT_HEADER); + + (void) fmt_compile(fmtstring, &fmt, 1); + free_fs(); + + while ((comp = fmt_nextcomp(comp, &bucket)) != NULL) { + if (strcasecmp(comp->c_name, "folder") == 0) { + folder_comp = comp; + } + } + + return fmt; +} + +static struct format * +compile_marker(char *form) { struct format *fmt; char *fmtstring; @@ -1267,10 +1302,10 @@ compile_marker(char *markerform) unsigned int bucket; struct param_comp_list *pc_entry; - fmtstring = new_fs(markerform, NULL, DEFAULT_MARKER); + fmtstring = new_fs(form, NULL, DEFAULT_MARKER); (void) fmt_compile(fmtstring, &fmt, 1); - free(fmtstring); + free_fs(); /* * Things we care about: @@ -1316,14 +1351,51 @@ compile_marker(char *markerform) * Output on stdout an appropriate marker for this content, using mh-format */ +static void +output_header(CT ct, struct format *fmt) +{ + charstring_t outbuf = charstring_create (BUFSIZ); + int dat[5]; + char *endp; + int message = 0; + + dat[0] = dat[1] = dat[2] = dat[3] = dat[4] = dat[5] = 0; + + if (folder_comp) + folder_comp->c_text = getcpy(folder); + + if (ct->c_file && *ct->c_file) { + message = strtol(ct->c_file, &endp, 10); + if (*endp) message = 0; + dat[0] = message; + } + + /* it would be nice to populate dat[2], for %(size) here, + * but it's not available. it might also be nice to know + * if the message originally had any mime parts or not -- but + * there's also no record of that. (except for MIME-version:) + */ + + fmt_scan(fmt, outbuf, BUFSIZ, dat, NULL); + + fputs(charstring_buffer (outbuf), stdout); + charstring_free (outbuf); + + fmt_freecomptext(); +} + static void output_marker(CT ct, struct format *fmt, int hidden) { charstring_t outbuf = charstring_create (BUFSIZ); struct param_comp_list *pcentry; int partsize; + int message = 0; + char *endp; int dat[5]; + dat[0] = dat[1] = dat[2] = dat[3] = dat[4] = dat[5] = 0; + /* * Grab any items we care about. */ @@ -1360,13 +1432,18 @@ output_marker(CT ct, struct format *fmt, int hidden) else partsize = ct->c_end - ct->c_begin; + if (ct->c_file && *ct->c_file) { + message = strtol(ct->c_file, &endp, 10); + if (*endp) message = 0; + dat[0] = message; + } + dat[2] = partsize; + /* make the part's hidden aspect available by overloading the * %(unseen) function. make the part's size available via %(size). * see comments in h/fmt_scan.h. */ - dat[2] = partsize; dat[4] = hidden; - dat[0] = dat[1] = dat[3] = 0; fmt_scan(fmt, outbuf, BUFSIZ, dat, NULL); @@ -1385,6 +1462,7 @@ free_markercomps(void) { struct param_comp_list *pc_entry, *pc2; + folder_comp = NULL; part_comp = NULL; ctype_comp = NULL; description_comp = NULL; diff --git a/uip/show.c b/uip/show.c index e5b71eff..f8910785 100644 --- a/uip/show.c +++ b/uip/show.c @@ -1,4 +1,3 @@ - /* * show.c -- show/list messages * @@ -79,23 +78,29 @@ main (int argc, char **argv) while ((cp = *argp++)) { if (*cp == '-') { switch (smatch (++cp, switches)) { - case AMBIGSW: + case AMBIGSW: ambigsw (cp, switches); done (1); + case HEADSW: + headersw = 1; + goto non_mhl_switches; + case NHEADSW: + headersw = 0; case CONCATSW: case NCONCATSW: +non_mhl_switches: /* mhl can't handle these, so keep them separate. */ app_msgarg(&non_mhl_vec, --cp); continue; - case UNKWNSW: + case UNKWNSW: case NPROGSW: case NFMTPROCSW: app_msgarg(&vec, --cp); continue; - case HELPSW: + case HELPSW: snprintf (buf, sizeof(buf), "%s [+folder] %s[switches] [switches for showproc]", invo_name, mode == SHOW ? "[msgs] ": ""); @@ -105,7 +110,7 @@ main (int argc, char **argv) print_version(invo_name); done (0); - case DRFTSW: + case DRFTSW: if (file) adios (NULL, "only one file at a time!"); draftsw++; @@ -115,7 +120,7 @@ usage: adios (NULL, "usage: %s [+folder] [switches] [switches for showproc]", invo_name); - case FILESW: + case FILESW: if (mode != SHOW) goto usage; if (draftsw || file) @@ -125,13 +130,6 @@ usage: file = path (cp, TFILE); continue; - case HEADSW: - headersw++; - continue; - case NHEADSW: - headersw = 0; - continue; - case FORMSW: app_msgarg(&vec, --cp); if (!(cp = *argp++) || *cp == '-') @@ -149,12 +147,12 @@ usage: app_msgarg(&vec, cp); continue; - case SHOWSW: + case SHOWSW: if (!(showproc = *argp++) || *showproc == '-') adios (NULL, "missing argument to %s", argp[-2]); nshow = 0; continue; - case NSHOWSW: + case NSHOWSW: nshow++; continue; @@ -194,6 +192,7 @@ usage: app_msgarg(&vec, getcpy (m_draft (folder, NULL, 1, &isdf))); else app_msgarg(&vec, file); + headersw = 0; goto go_to_it; } @@ -252,11 +251,7 @@ usage: context_replace (pfolder, folder); /* update current folder */ context_save (); /* save the context file */ - if (headersw && vec.size == 1) - printf ("(Message %s:%s)\n", folder, vec.msgs[0]); - go_to_it: ; - fflush (stdout); /* * Decide which "proc" to use @@ -290,12 +285,22 @@ go_to_it: ; if (folder && !draftsw && !file) m_putenv ("mhfolder", folder); - if (strcmp (r1bindex (proc, '/'), "mhl") == 0) { + if (strcmp (r1bindex (proc, '/'), "cat") == 0) { + + if (headersw && vec.size == 1) + printf ("(Message %s:%s)\n", folder, vec.msgs[0]); + + } else if (strcmp (r1bindex (proc, '/'), "mhl") == 0) { + + if (headersw && vec.size == 1) + printf ("(Message %s:%s)\n", folder, vec.msgs[0]); + /* If "mhl", then run it internally */ argsplit_insert(&vec, "mhl", &program); app_msgarg(&vec, NULL); mhl (vec.size, vec.msgs); done (0); + } else { int i; char **mp; @@ -324,9 +329,14 @@ go_to_it: ; app_msgarg(&vec, vec.msgs[vec.size - 1]); vec.msgs[vec.size - 2] = "-file"; } + } else { + if (headersw && vec.size == 1) + printf ("(Message %s:%s)\n", folder, vec.msgs[0]); } } + fflush (stdout); + argsplit_insert(&vec, proc, &program); app_msgarg(&vec, NULL); execvp (program, vec.msgs);