X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/397deef44d1f8d92b781e7d9af6f0f256eccbe73..0b7286788a95dd854d1826b8493eda431d8e8aac:/uip/show.c diff --git a/uip/show.c b/uip/show.c index 5a912f6b..9d387f63 100644 --- a/uip/show.c +++ b/uip/show.c @@ -1,15 +1,25 @@ - -/* - * show.c -- show/list messages +/* show.c -- show/list messages * * This code is Copyright (c) 2002, 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 "h/mh.h" +#include "sbr/folder_read.h" +#include "sbr/context_save.h" +#include "sbr/context_replace.h" +#include "sbr/context_find.h" +#include "sbr/ambigsw.h" +#include "sbr/path.h" +#include "sbr/print_version.h" +#include "sbr/print_help.h" +#include "sbr/arglist.h" +#include "sbr/error.h" +#include "h/mime.h" +#include "h/done.h" +#include "h/utils.h" +#include "sbr/m_maildir.h" #define SHOW_SWITCHES \ X("checkmime", 0, CHECKMIMESW) \ @@ -30,6 +40,20 @@ X("nofmtproc", 0, NFMTPROCSW) \ X("version", 0, VERSIONSW) \ X("help", 0, HELPSW) \ + /* \ + * switches for mhlproc \ + */ \ + X("concat", 0, CONCATSW) \ + X("noconcat", 0, NCONCATSW) \ + /* \ + * switches for mhshow \ + */ \ + X("part number", 0, PARTSW) \ + X("type content", 0, TYPESW) \ + X("prefer content", 0, PREFERSW) \ + X("markform file", 0, MARKFORMSW) \ + X("rcache policy", 0, RCACHESW) \ + X("wcache policy", 0, WCACHESW) \ #define X(sw, minchars, id) id, DEFINE_SWITCH_ENUM(SHOW); @@ -52,22 +76,19 @@ static int is_nontext(char *); int main (int argc, char **argv) { - int draftsw = 0, headersw = 1; - int nshow = 0, checkmime = 1, mime; + bool draftsw = false; + bool headersw = true; + bool nshow = false; + bool checkmime = true; + bool mime = false; int isdf = 0, mode = SHOW, msgnum; char *cp, *maildir, *file = NULL, *folder = NULL, *proc, *program; char buf[BUFSIZ], **argp, **arguments; struct msgs *mp = NULL; struct msgs_array msgs = { 0, 0, NULL }; - struct msgs_array vec = { 0, 0, NULL }; + struct msgs_array vec = { 0, 0, NULL }, non_mhl_vec = { 0, 0, NULL }; -#ifdef LOCALE - setlocale(LC_ALL, ""); -#endif - invo_name = r1bindex (argv[0], '/'); - - /* read user profile/context */ - context_read(); + if (nmh_init(argv[0], true, true)) { return 1; } if (!strcasecmp (invo_name, "next")) { mode = NEXT; @@ -80,16 +101,30 @@ 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 HEADSW: + headersw = true; + goto non_mhl_switches; + case NHEADSW: + headersw = false; + /* FALLTHRU */ + 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 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] ": ""); @@ -99,82 +134,78 @@ 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++; + die("only one file at a time!"); + draftsw = true; if (mode == SHOW) continue; usage: - adios (NULL, - "usage: %s [+folder] [switches] [switches for showproc]", + die( "usage: %s [+folder] [switches] [switches for showproc]", invo_name); - case FILESW: + case FILESW: if (mode != SHOW) goto usage; if (draftsw || file) - adios (NULL, "only one file at a time!"); + die("only one file at a time!"); if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); + die("missing argument to %s", argp[-2]); file = path (cp, TFILE); continue; - case HEADSW: - headersw++; - continue; - case NHEADSW: - headersw = 0; - continue; - case FORMSW: app_msgarg(&vec, --cp); if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - app_msgarg(&vec, getcpy (etcpath(cp))); + die("missing argument to %s", argp[-2]); + app_msgarg(&vec, mh_xstrdup(etcpath(cp))); continue; case PROGSW: case LENSW: case WIDTHSW: case FMTPROCSW: + case PARTSW: + case TYPESW: + case PREFERSW: + case MARKFORMSW: + case RCACHESW: + case WCACHESW: app_msgarg(&vec, --cp); if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); + die("missing argument to %s", argp[-2]); app_msgarg(&vec, cp); continue; - case SHOWSW: + case SHOWSW: if (!(showproc = *argp++) || *showproc == '-') - adios (NULL, "missing argument to %s", argp[-2]); - nshow = 0; + die("missing argument to %s", argp[-2]); + nshow = false; continue; - case NSHOWSW: - nshow++; + case NSHOWSW: + nshow = true; continue; case SHOWMIMESW: if (!(showmimeproc = *argp++) || *showmimeproc == '-') - adios (NULL, "missing argument to %s", argp[-2]); - nshow = 0; + die("missing argument to %s", argp[-2]); + nshow = false; continue; case CHECKMIMESW: - checkmime++; + checkmime = true; continue; case NOCHECKMIMESW: - checkmime = 0; + checkmime = false; continue; } } if (*cp == '+' || *cp == '@') { if (folder) - adios (NULL, "only one folder at a time!"); - else - folder = pluspath (cp); + die("only one folder at a time!"); + folder = pluspath (cp); } else { if (mode != SHOW) goto usage; - else - app_msgarg(&msgs, cp); + app_msgarg(&msgs, cp); } } @@ -183,11 +214,12 @@ usage: if (draftsw || file) { if (msgs.size) - adios (NULL, "only one file at a time!"); + die("only one file at a time!"); if (draftsw) - app_msgarg(&vec, getcpy (m_draft (folder, NULL, 1, &isdf))); + app_msgarg(&vec, mh_xstrdup(m_draft(folder, NULL, 1, &isdf))); else app_msgarg(&vec, file); + headersw = false; goto go_to_it; } @@ -214,11 +246,11 @@ usage: /* read folder and create message structure */ if (!(mp = folder_read (folder, 1))) - adios (NULL, "unable to read folder %s", folder); + die("unable to read folder %s", folder); /* check for empty folder */ if (mp->nummsg == 0) - adios (NULL, "no messages in %s", folder); + die("no messages in %s", folder); /* parse all the message ranges/sequences and set SELECTED */ for (msgnum = 0; msgnum < msgs.size; msgnum++) @@ -239,39 +271,34 @@ usage: for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) if (is_selected(mp, msgnum)) - app_msgarg(&vec, getcpy (m_name (msgnum))); + app_msgarg(&vec, mh_xstrdup(m_name (msgnum))); seq_setcur (mp, mp->hghsel); /* update current message */ seq_save (mp); /* synchronize sequences */ 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 */ - mime = 0; if (nshow) { proc = catproc; } else { /* check if any messages are non-text MIME messages */ - if (checkmime) { + if (! mime && checkmime) { if (!draftsw && !file) { /* loop through selected messages and check for MIME */ for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) if (is_selected (mp, msgnum) && is_nontext (m_name (msgnum))) { - mime = 1; + mime = true; break; } } else { /* check the file or draft for MIME */ if (is_nontext (vec.msgs[vec.size - 1])) - mime = 1; + mime = true; } } @@ -283,30 +310,60 @@ go_to_it: ; } if (folder && !draftsw && !file) - m_putenv ("mhfolder", folder); + setenv("mhfolder", folder, 1); + + if (strcmp (r1bindex (proc, '/'), "cat") == 0) { + + if (headersw && vec.size == 1) + printf ("(Message %s:%s)\n", folder, vec.msgs[0]); - if (strcmp (r1bindex (proc, '/'), "mhn") == 0) { - /* Add "-file" if showing file or draft, */ - if (draftsw || file) { - app_msgarg(&vec, vec.msgs[vec.size - 1]); - vec.msgs[vec.size - 2] = "-file"; - } - /* and add -show for backward compatibility */ - app_msgarg(&vec, "-show"); - } else if (strcmp (r1bindex (proc, '/'), "mhshow") == 0) { - /* If "mhshow", add "-file" if showing file or draft. */ - if (draftsw || file) { - app_msgarg(&vec, vec.msgs[vec.size - 1]); - vec.msgs[vec.size - 2] = "-file"; - } } 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; + + for (i = 0, mp = non_mhl_vec.msgs; i < non_mhl_vec.size; ++i, ++mp) { + if (draftsw || file) { + /* Insert the switch before the filename. */ + app_msgarg(&vec, vec.msgs[vec.size - 1]); + vec.msgs[vec.size - 2] = *mp; + } else { + app_msgarg(&vec, *mp); + } + } + + if (strcmp (r1bindex (proc, '/'), "mhn") == 0) { + /* Add "-file" if showing file or draft, */ + if (draftsw || file) { + app_msgarg(&vec, vec.msgs[vec.size - 1]); + vec.msgs[vec.size - 2] = "-file"; + } + /* and add -show for backward compatibility */ + app_msgarg(&vec, "-show"); + } else if (strcmp (r1bindex (proc, '/'), "mhshow") == 0) { + /* If "mhshow", add "-file" if showing file or draft. */ + if (draftsw || file) { + 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); @@ -323,16 +380,16 @@ is_nontext (char *msgnam) { int result, state; char *bp, *dp, *cp; - char buf[BUFSIZ], name[NAMESZ]; + char buf[NMH_BUFSIZ], name[NAMESZ]; FILE *fp; - m_getfld_state_t gstate = 0; + m_getfld_state_t gstate; if ((fp = fopen (msgnam, "r")) == NULL) return 0; - + gstate = m_getfld_state_init(fp); for (;;) { int bufsz = sizeof buf; - switch (state = m_getfld (&gstate, name, buf, &bufsz, fp)) { + switch (state = m_getfld2(&gstate, name, buf, &bufsz)) { case FLD: case FLDPLUS: /* @@ -342,10 +399,10 @@ is_nontext (char *msgnam) int passno; char c; - cp = add (buf, NULL); + cp = mh_xstrdup(buf); while (state == FLDPLUS) { bufsz = sizeof buf; - state = m_getfld (&gstate, name, buf, &bufsz, fp); + state = m_getfld2(&gstate, name, buf, &bufsz); cp = add (buf, cp); } bp = cp; @@ -369,7 +426,7 @@ invalid: continue; case '(': i++; - /* and fall... */ + continue; default: continue; case ')': @@ -402,7 +459,7 @@ invalid: if (*dp) { if ((result = !uprf (dp, "charset"))) goto out; - dp += sizeof("charset") - 1; + dp += LEN("charset"); while (isspace ((unsigned char) *dp)) dp++; if (*dp++ != '=') @@ -447,10 +504,10 @@ out: * Check Content-Transfer-Encoding field */ if (!strcasecmp (name, ENCODING_FIELD)) { - cp = add (buf, NULL); + cp = mh_xstrdup(buf); while (state == FLDPLUS) { bufsz = sizeof buf; - state = m_getfld (&gstate, name, buf, &bufsz, fp); + state = m_getfld2(&gstate, name, buf, &bufsz); cp = add (buf, cp); } for (bp = cp; isspace ((unsigned char) *bp); bp++) @@ -477,7 +534,7 @@ out: */ while (state == FLDPLUS) { bufsz = sizeof buf; - state = m_getfld (&gstate, name, buf, &bufsz, fp); + state = m_getfld2(&gstate, name, buf, &bufsz); } break;