+++ /dev/null
-/*
-** 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 <h/mh.h>
-#include <h/mime.h>
-#include <h/utils.h>
-
-static struct swit switches[] = {
-#define CHECKMIMESW 0
- { "checkmime", 0 },
-#define NOCHECKMIMESW 1
- { "nocheckmime", 0 },
-#define HEADSW 2
- { "header", 0 },
-#define NHEADSW 3
- { "noheader", 0 },
-#define FORMSW 4
- { "form formfile", 0 },
-#define SHOWSW 5
- { "showproc program", 0 },
-#define SHOWMIMESW 6
- { "showmimeproc program", 0 },
-#define FILESW 7
- { "file file", -4 }, /* interface from whatnow (listproc) */
-#define VERSIONSW 8
- { "version", 0 },
-#define HELPSW 9
- { "help", 0 },
- { NULL, 0 }
-};
-
-/*
-** static prototypes
-*/
-static int is_mime(char *);
-
-#define SHOW 0
-#define NEXT 1
-#define PREV 2
-
-char *showproc = "mhl";
-char *showmimeproc = "mhshow";
-
-int
-main(int argc, char **argv)
-{
- int headersw = 1, msgp = 0;
- int checkmime = 1, mime;
- int vecp = 1, procp = 1, mode = SHOW, msgnum;
- char *cp, *file = NULL, *folder = NULL, *proc;
- char buf[BUFSIZ], **argp, **arguments;
- char *msgs[MAXARGS], *vec[MAXARGS];
- struct msgs *mp = NULL;
-
-#ifdef LOCALE
- setlocale(LC_ALL, "");
-#endif
- invo_name = mhbasename(argv[0]);
-
- /* read user profile/context */
- context_read();
-
- if (!mh_strcasecmp(invo_name, "next")) {
- mode = NEXT;
- } else if (!mh_strcasecmp(invo_name, "prev")) {
- mode = PREV;
- }
- arguments = getarguments(invo_name, argc, argv, 1);
- argp = arguments;
-
- while ((cp = *argp++)) {
- if (*cp == '-') {
- switch (smatch(++cp, switches)) {
- case AMBIGSW:
- ambigsw(cp, switches);
- done(1);
- case UNKWNSW:
- vec[vecp++] = --cp;
- continue;
-
- case HELPSW:
- snprintf(buf, sizeof(buf), "%s [+folder] %s[switches] [switches for showproc]", invo_name, mode == SHOW ? "[msgs] ": "");
- print_help(buf, switches, 1);
- done(1);
- case VERSIONSW:
- print_version(invo_name);
- done(1);
-
- case FILESW:
- if (mode != SHOW)
-usage:
- adios(NULL, "usage: %s [+folder] [switches] [switches for showproc]", invo_name);
-
- if (file)
- adios(NULL, "only one file at a time!");
- if (!(cp = *argp++) || *cp == '-')
- adios(NULL, "missing argument to %s", argp[-2]);
- file = getcpy(expanddir(cp));
- continue;
-
- case HEADSW:
- headersw++;
- continue;
- case NHEADSW:
- headersw = 0;
- continue;
-
- case FORMSW:
- vec[vecp++] = --cp;
- if (!(cp = *argp++) || *cp == '-')
- adios(NULL, "missing argument to %s",
- argp[-2]);
- vec[vecp++] = getcpy(etcpath(cp));
- continue;
-
- case SHOWSW:
- if (!(showproc = *argp++) || *showproc == '-')
- adios(NULL, "missing argument to %s",
- argp[-2]);
- continue;
-
- case SHOWMIMESW:
- if (!(showmimeproc = *argp++) ||
- *showmimeproc == '-')
- adios(NULL, "missing argument to %s",
- argp[-2]);
- continue;
- case CHECKMIMESW:
- checkmime++;
- continue;
- case NOCHECKMIMESW:
- checkmime = 0;
- continue;
- }
- }
- if (*cp == '+' || *cp == '@') {
- if (folder)
- adios(NULL, "only one folder at a time!");
- else
- folder = getcpy(expandfol(cp));
- } else if (mode != SHOW) {
- goto usage;
- } else {
- msgs[msgp++] = cp;
- }
- }
- procp = vecp;
-
- if (file) {
- if (msgp)
- adios(NULL, "only one file at a time!");
- vec[vecp++] = file;
- goto go_to_it;
- }
-
- if (!msgp) {
- switch (mode) {
- case NEXT:
- msgs[msgp++] = seq_next;
- break;
- case PREV:
- msgs[msgp++] = seq_prev;
- break;
- default:
- msgs[msgp++] = seq_cur;
- break;
- }
- }
-
- if (!folder)
- folder = getcurfol();
-
- /* read folder and create message structure */
- if (!(mp = folder_read(folder)))
- adios(NULL, "unable to read folder %s", folder);
-
- /* check for empty folder */
- if (mp->nummsg == 0)
- adios(NULL, "no messages in %s", folder);
-
- /* parse all the message ranges/sequences and set SELECTED */
- for (msgnum = 0; msgnum < msgp; msgnum++)
- if (!m_convert(mp, msgs[msgnum]))
- done(1);
-
- /*
- ** Set the SELECT_UNSEEN bit for all the SELECTED messages,
- ** since we will use that as a tag to know which messages
- ** to remove from the "unseen" sequence.
- */
- for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++)
- if (is_selected(mp, msgnum))
- set_unseen(mp, msgnum);
-
- seq_setprev(mp); /* set the Previous-Sequence */
- seq_setunseen(mp, 0); /* unset unseen seqs for shown msgs */
-
- if (mp->numsel > MAXARGS - 2)
- adios(NULL, "more than %d messages for show exec",
- MAXARGS - 2);
-
- for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++)
- if (is_selected(mp, msgnum))
- vec[vecp++] = getcpy(m_name(msgnum));
-
- seq_setcur(mp, mp->hghsel); /* update current message */
- seq_save(mp); /* synchronize sequences */
- context_replace(curfolder, folder); /* update current folder */
- context_save(); /* save the context file */
-
- if (headersw && vecp == 2)
- printf("(Message %s:%s)\n", folder, vec[1]);
-
-go_to_it: ;
- fflush(stdout);
-
- vec[vecp] = NULL;
-
- /*
- ** Decide which "proc" to use
- */
- mime = 0;
- /* check if any messages are non-text MIME messages */
- if (checkmime) {
- if (file) {
- if (is_mime(vec[vecp - 1])) {
- mime = 1;
- }
- } else {
- for (msgnum = mp->lowsel; msgnum <= mp->hghsel;
- msgnum++) {
- if (!is_selected(mp, msgnum)) {
- continue;
- }
- snprintf(buf, sizeof buf, "%s/%d",
- toabsdir(folder), msgnum);
- if (is_mime(buf)) {
- mime = 1;
- break;
- }
- }
- }
- }
-
- /* Set the "proc" */
- proc = (mime) ? showmimeproc : showproc;
-
- /* Special-cased because mhshow takes msg not files args. */
- if (strcmp(mhbasename(proc), "mhshow")==0) {
- if (file) {
- vec[vecp] = vec[vecp - 1];
- vec[vecp - 1] = "-file";
- vec[++vecp] = NULL;
- }
- vec[vecp++] = concat("+", folder, NULL);
- vec[vecp] = NULL;
- vec[0] = mhbasename(proc);
- execvp(proc, vec);
- adios(proc, "unable to exec");
- }
-
- /* Add the path to the message names. */
- if (!file) {
- for (msgnum = procp; msgnum < vecp; msgnum++) {
- vec[msgnum] = concat(mp->foldpath, "/",
- vec[msgnum], NULL);
- }
- }
-
- vec[0] = mhbasename(proc);
- execvp(proc, vec);
- adios(proc, "unable to exec");
- return 0; /* dead code to satisfy the compiler */
-}
-
-/*
-** Check if a message or file contains MIME.
-*/
-static int
-is_mime(char *msgnam)
-{
- int state = FLD;
- char buf[BUFSIZ], name[NAMESZ];
- FILE *fp;
-
- if ((fp = fopen(msgnam, "r")) == NULL)
- return 0;
-
- while (1) {
- switch (state = m_getfld(state, name, buf, sizeof(buf), fp)) {
- case FLD:
- case FLDPLUS:
- case FLDEOF:
- /* Does it have a Mime-Version header? */
- if (mh_strcasecmp(name, VRSN_FIELD)==0) {
- fclose(fp);
- return 1;
- }
-
- /* else skip the rest of this header field and go on */
- while (state == FLDPLUS) {
- state = m_getfld(state, name, buf, sizeof(buf),
- fp);
- }
- break;
-
- default:
- /* We've passed the header, so message is just text */
- fclose(fp);
- return 0;
- }
- }
-}