]> diplodocus.org Git - nmh/commitdiff
add new message separator header to mhshow
authorPaul Fox <pgf@foxharp.boston.ma.us>
Sun, 8 Feb 2015 20:22:07 +0000 (15:22 -0500)
committerPaul Fox <pgf@foxharp.boston.ma.us>
Sun, 8 Feb 2015 22:01:58 +0000 (17:01 -0500)
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)).

etc/mhshow.header [new file with mode: 0644]
h/mhparse.h
uip/mhn.c
uip/mhshow.c
uip/mhshowsbr.c
uip/show.c

diff --git a/etc/mhshow.header b/etc/mhshow.header
new file mode 100644 (file)
index 0000000..2f9bafe
--- /dev/null
@@ -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) ]
index d1c94420ff984ada9efe3e85d4b5a1c02ceff47d..3efec9cb62dff37b2d8ab1aa364313f6c9365dab 100644 (file)
@@ -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
index be433d69b5e9be79c8dcdc423906089ced84fce0..ea56379150618ae9b5945f0c60e96f2181f616c8 100644 (file)
--- 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++)
index c83437630e4b01425093984887b67863eff38671..b2a4c0da5736b7153c2cc9f692b753b932031383 100644 (file)
@@ -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++)
index 31d25eb109d31dfa943d5f3044219377eeefc51f..4b11494e50063ac29937dcb975c403cc3da8ad58 100644 (file)
@@ -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;
index e5b71eff0a24a7246bfb0d58ca778b563a50fd00..f89107855c0214bc766f1cc4c64312c9fc055c54 100644 (file)
@@ -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);