]> diplodocus.org Git - nmh/blobdiff - uip/show.c
Use a dynamically-allocated buffer for character set conversion, and
[nmh] / uip / show.c
index dade251c48c16128238d638ada576fae3563b79f..acd08afb1bc9cbe1e4ae7a1e5475b6a49ed2e25e 100644 (file)
 #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        PROGSW               5
-    { "moreproc program", 0 },
-#define        NPROGSW              6
-    { "nomoreproc", 0 },
-#define        LENSW                7
-    { "length lines", 0 },
-#define        WIDTHSW              8
-    { "width columns", 0 },
-#define        SHOWSW               9
-    { "showproc program", 0 },
-#define SHOWMIMESW          10
-    { "showmimeproc program", 0 },
-#define        NSHOWSW             11
-    { "noshowproc", 0 },
-#define        DRFTSW              12
-    { "draft", 0 },
-#define        FILESW              13
-    { "file file", -4 },               /* interface from showfile */
-#define FMTPROCSW           14
-    { "fmtproc program", 0 },
-#define NFMTPROCSW          15
-    { "nofmtproc", 0 },
-#define VERSIONSW           16
-    { "version", 0 },
-#define        HELPSW              17
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define SHOW_SWITCHES \
+    X("checkmime", 0, CHECKMIMESW) \
+    X("nocheckmime", 0, NOCHECKMIMESW) \
+    X("header", 0, HEADSW) \
+    X("noheader", 0, NHEADSW) \
+    X("form formfile", 0, FORMSW) \
+    X("moreproc program", 0, PROGSW) \
+    X("nomoreproc", 0, NPROGSW) \
+    X("length lines", 0, LENSW) \
+    X("width columns", 0, WIDTHSW) \
+    X("showproc program", 0, SHOWSW) \
+    X("showmimeproc program", 0, SHOWMIMESW) \
+    X("noshowproc", 0, NSHOWSW) \
+    X("draft", 0, DRFTSW) \
+    X("file file", -4, FILESW) /* interface from showfile */ \
+    X("fmtproc program", 0, FMTPROCSW) \
+    X("nofmtproc", 0, NFMTPROCSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(SHOW);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(SHOW, switches);
+#undef X
 
 /*
  * static prototypes
@@ -67,25 +55,17 @@ main (int argc, char **argv)
     int draftsw = 0, headersw = 1;
     int nshow = 0, checkmime = 1, mime;
     int isdf = 0, mode = SHOW, msgnum;
-    char *cp, *maildir, *file = NULL, *folder = NULL, *proc;
+    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 };
 
-#ifdef LOCALE
-    setlocale(LC_ALL, "");
-#endif
-    invo_name = r1bindex (argv[0], '/');
+    if (nmh_init(argv[0], 1)) { return 1; }
 
-    app_msgarg(&vec, NULL);  /* placeholder, filled later with proc name */
-
-    /* read user profile/context */
-    context_read();
-
-    if (!mh_strcasecmp (invo_name, "next")) {
+    if (!strcasecmp (invo_name, "next")) {
        mode = NEXT;
-    } else if (!mh_strcasecmp (invo_name, "prev")) {
+    } else if (!strcasecmp (invo_name, "prev")) {
        mode = PREV;
     }
     arguments = getarguments (invo_name, argc, argv, 1);
@@ -205,14 +185,6 @@ usage:
        goto go_to_it;
     }
 
-#ifdef WHATNOW
-    if (!msgs.size && !folder && mode == SHOW && (cp = getenv ("mhdraft")) && *cp) {
-       draftsw++;
-       app_msgarg(&vec, cp);
-       goto go_to_it;
-    }
-#endif /* WHATNOW */
-
     if (!msgs.size) {
        switch (mode) {
            case NEXT:
@@ -235,7 +207,7 @@ usage:
        adios (maildir, "unable to change directory to");
 
     /* read folder and create message structure */
-    if (!(mp = folder_read (folder)))
+    if (!(mp = folder_read (folder, 1)))
        adios (NULL, "unable to read folder %s", folder);
 
     /* check for empty folder */
@@ -268,8 +240,8 @@ usage:
     context_replace (pfolder, folder); /* update current folder   */
     context_save ();                   /* save the context file   */
 
-    if (headersw && vec.size == 2)
-       printf ("(Message %s:%s)\n", folder, vec.msgs[1]);
+    if (headersw && vec.size == 1)
+       printf ("(Message %s:%s)\n", folder, vec.msgs[0]);
 
 go_to_it: ;
     fflush (stdout);
@@ -323,15 +295,15 @@ go_to_it: ;
        }
     } else if (strcmp (r1bindex (proc, '/'), "mhl") == 0) {
        /* If "mhl", then run it internally */
-       vec.msgs[0] = "mhl";
+       argsplit_insert(&vec, "mhl", &program);
        app_msgarg(&vec, NULL);
        mhl (vec.size, vec.msgs);
        done (0);
     }
 
-    vec.msgs[0] = r1bindex (proc, '/');
+    argsplit_insert(&vec, proc, &program);
     app_msgarg(&vec, NULL);
-    execvp (proc, vec.msgs);
+    execvp (program, vec.msgs);
     adios (proc, "unable to exec");
     return 0;  /* dead code to satisfy the compiler */
 }
@@ -344,37 +316,37 @@ static int
 is_nontext (char *msgnam)
 {
     int        result, state;
-    unsigned char *bp, *dp;
-    char *cp;
+    char *bp, *dp, *cp;
     char buf[BUFSIZ], name[NAMESZ];
     FILE *fp;
+    m_getfld_state_t gstate = 0;
 
     if ((fp = fopen (msgnam, "r")) == NULL)
        return 0;
 
-    for (state = FLD;;) {
+    for (;;) {
        int bufsz = sizeof buf;
-       switch (state = m_getfld (state, name, buf, &bufsz, fp)) {
+       switch (state = m_getfld (&gstate, name, buf, &bufsz, fp)) {
        case FLD:
        case FLDPLUS:
            /*
             * Check Content-Type field
             */
-           if (!mh_strcasecmp (name, TYPE_FIELD)) {
+           if (!strcasecmp (name, TYPE_FIELD)) {
                int passno;
                char c;
 
                cp = add (buf, NULL);
                while (state == FLDPLUS) {
                    bufsz = sizeof buf;
-                   state = m_getfld (state, name, buf, &bufsz, fp);
+                   state = m_getfld (&gstate, name, buf, &bufsz, fp);
                    cp = add (buf, cp);
                }
                bp = cp;
                passno = 1;
 
 again:
-               for (; isspace (*bp); bp++)
+               for (; isspace ((unsigned char) *bp); bp++)
                    continue;
                if (*bp == '(') {
                    int i;
@@ -416,20 +388,20 @@ invalid:
                if (!*bp)
                    goto invalid;
                if (passno > 1) {
-                   if ((result = (mh_strcasecmp (bp, "plain") != 0)))
+                   if ((result = (strcasecmp (bp, "plain") != 0)))
                        goto out;
                    *dp = c;
-                   for (dp++; isspace (*dp); dp++)
+                   for (dp++; isspace ((unsigned char) *dp); dp++)
                        continue;
                    if (*dp) {
                        if ((result = !uprf (dp, "charset")))
                            goto out;
                        dp += sizeof("charset") - 1;
-                       while (isspace (*dp))
+                       while (isspace ((unsigned char) *dp))
                            dp++;
                        if (*dp++ != '=')
                            goto invalid;
-                       while (isspace (*dp))
+                       while (isspace ((unsigned char) *dp))
                            dp++;
                        if (*dp == '"') {
                            if ((bp = strchr(++dp, '"')))
@@ -448,7 +420,7 @@ invalid:
                    /* Check the character set */
                    result = !check_charset (dp, strlen (dp));
                } else {
-                   if (!(result = (mh_strcasecmp (bp, "text") != 0))) {
+                   if (!(result = (strcasecmp (bp, "text") != 0))) {
                        *dp = c;
                        bp = dp;
                        passno = 2;
@@ -459,6 +431,7 @@ out:
                free (cp);
                if (result) {
                    fclose (fp);
+                   m_getfld_state_destroy (&gstate);
                    return result;
                }
                break;
@@ -467,25 +440,26 @@ out:
            /*
             * Check Content-Transfer-Encoding field
             */
-           if (!mh_strcasecmp (name, ENCODING_FIELD)) {
+           if (!strcasecmp (name, ENCODING_FIELD)) {
                cp = add (buf, NULL);
                while (state == FLDPLUS) {
                    bufsz = sizeof buf;
-                   state = m_getfld (state, name, buf, &bufsz, fp);
+                   state = m_getfld (&gstate, name, buf, &bufsz, fp);
                    cp = add (buf, cp);
                }
-               for (bp = cp; isspace (*bp); bp++)
+               for (bp = cp; isspace ((unsigned char) *bp); bp++)
                    continue;
-               for (dp = bp; istoken (*dp); dp++)
+               for (dp = bp; istoken ((unsigned char) *dp); dp++)
                    continue;
                *dp = '\0';
-               result = (mh_strcasecmp (bp, "7bit")
-                      && mh_strcasecmp (bp, "8bit")
-                      && mh_strcasecmp (bp, "binary"));
+               result = (strcasecmp (bp, "7bit")
+                      && strcasecmp (bp, "8bit")
+                      && strcasecmp (bp, "binary"));
 
                free (cp);
                if (result) {
                    fclose (fp);
+                   m_getfld_state_destroy (&gstate);
                    return result;
                }
                break;
@@ -497,7 +471,7 @@ out:
             */
            while (state == FLDPLUS) {
                bufsz = sizeof buf;
-               state = m_getfld (state, name, buf, &bufsz, fp);
+               state = m_getfld (&gstate, name, buf, &bufsz, fp);
            }
            break;
 
@@ -507,6 +481,7 @@ out:
             */
        default:
            fclose (fp);
+           m_getfld_state_destroy (&gstate);
            return 0;
        }
     }