]> diplodocus.org Git - nmh/blobdiff - uip/forw.c
Escape literal leading full stop in man/new.man.
[nmh] / uip / forw.c
index 2741f69331c85170d50ff3191275b2a14ac34bba..501f65134766511cfa9d47d6e408c9298034296a 100644 (file)
 #define        IFORMAT "digest-issue-%s"
 #define        VFORMAT "digest-volume-%s"
 
-static struct swit switches[] = {
-#define        ANNOSW                 0
-    { "annotate", 0 },
-#define        NANNOSW                1
-    { "noannotate", 0 },
-#define        DFOLDSW                2
-    { "draftfolder +folder", 0 },
-#define        DMSGSW                 3
-    { "draftmessage msg", 0 },
-#define        NDFLDSW                4
-    { "nodraftfolder", 0 },
-#define        EDITRSW                5
-    { "editor editor", 0 },
-#define        NEDITSW                6
-    { "noedit", 0 },
-#define        FILTSW                 7
-    { "filter filterfile", 0 },
-#define        FORMSW                 8
-    { "form formfile", 0 },
-#define        FRMTSW                 9
-    { "format", 5 },
-#define        NFRMTSW               10
-    { "noformat", 7 },
-#define        INPLSW                11
-    { "inplace", 0 },
-#define        NINPLSW               12
-    { "noinplace", 0 },
-#define MIMESW                13
-    { "mime", 0 },
-#define NMIMESW               14
-    { "nomime", 0 },
-#define        DGSTSW                15
-    { "digest list", 0 },
-#define        ISSUESW               16
-    { "issue number", 0 },
-#define        VOLUMSW               17
-    { "volume number", 0 },
-#define        WHATSW                18
-    { "whatnowproc program", 0 },
-#define        NWHATSW               19
-    { "nowhatnowproc", 0 },
-#define        BITSTUFFSW            20
-    { "dashstuffing", 0 },             /* interface to mhl */
-#define        NBITSTUFFSW           21
-    { "nodashstuffing", 0 },
-#define VERSIONSW             22
-    { "version", 0 },
-#define        HELPSW                23
-    { "help", 0 },
-#define        FILESW                24
-    { "file file", 4 },                        /* interface from msh */
-#define        BILDSW                25
-    { "build", 5 },                    /* interface from mhe */
-#define FROMSW                26
-    { "from address", 0 },
-#define TOSW                  27
-    { "to address", 0 },
-#define CCSW                  28
-    { "cc address", 0 },
-#define SUBJECTSW             29
-    { "subject text", 0 },
-#define FCCSW                 30
-    { "fcc mailbox", 0 },
-#define WIDTHSW               31
-    { "width columns", 0 },
-    { NULL, 0 }
-};
-
-static struct swit aqrnl[] = {
-#define        NOSW         0
-    { "quit", 0 },
-#define        YESW         1
-    { "replace", 0 },
-#define        LISTDSW      2
-    { "list", 0 },
-#define        REFILSW      3
-    { "refile +folder", 0 },
-#define NEWSW        4
-    { "new", 0 },
-    { NULL, 0 }
-};
+#define FORW_SWITCHES \
+    X("annotate", 0, ANNOSW) \
+    X("noannotate", 0, NANNOSW) \
+    X("draftfolder +folder", 0, DFOLDSW) \
+    X("draftmessage msg", 0, DMSGSW) \
+    X("nodraftfolder", 0, NDFLDSW) \
+    X("editor editor", 0, EDITRSW) \
+    X("noedit", 0, NEDITSW) \
+    X("filter filterfile", 0, FILTSW) \
+    X("form formfile", 0, FORMSW) \
+    X("format", 5, FRMTSW) \
+    X("noformat", 7, NFRMTSW) \
+    X("inplace", 0, INPLSW) \
+    X("noinplace", 0, NINPLSW) \
+    X("mime", 0, MIMESW) \
+    X("nomime", 0, NMIMESW) \
+    X("digest list", 0, DGSTSW) \
+    X("issue number", 0, ISSUESW) \
+    X("volume number", 0, VOLUMSW) \
+    X("whatnowproc program", 0, WHATSW) \
+    X("nowhatnowproc", 0, NWHATSW) \
+    X("dashstuffing", 0, BITSTUFFSW)          /* interface to mhl */ \
+    X("nodashstuffing", 0, NBITSTUFFSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("file file", 4, FILESW)                 /* interface from msh */ \
+    X("build", 5, BILDSW)                     /* interface from mhe */ \
+    X("from address", 0, FROMSW) \
+    X("to address", 0, TOSW) \
+    X("cc address", 0, CCSW) \
+    X("subject text", 0, SUBJECTSW) \
+    X("fcc mailbox", 0, FCCSW) \
+    X("width columns", 0, WIDTHSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(FORW);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(FORW, switches);
+#undef X
+
+#define DISPO_SWITCHES \
+    X("quit", 0, NOSW) \
+    X("replace", 0, YESW) \
+    X("list", 0, LISTDSW) \
+    X("refile +folder", 0, REFILSW) \
+    X("new", 0, NEWSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(DISPO);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(DISPO, aqrnl);
+#undef X
 
 static struct swit aqrl[] = {
-    { "quit", 0 },
-    { "replace", 0 },
-    { "list", 0 },
-    { "refile +folder", 0 },
-    { NULL, 0 }
+    { "quit", 0, NOSW },
+    { "replace", 0, YESW },
+    { "list", 0, LISTDSW },
+    { "refile +folder", 0, REFILSW },
+    { NULL, 0, 0 }
 };
 
 static char drft[BUFSIZ];
@@ -127,7 +102,7 @@ static void copy_mime_draft (int);
 int
 main (int argc, char **argv)
 {
-    int msgp = 0, anot = 0, inplace = 1, mime = 0;
+    int anot = 0, inplace = 1, mime = 0;
     int issue = 0, volume = 0, dashstuff = 0;
     int nedit = 0, nwhat = 0, i, in;
     int out, isdf = 0, msgnum = 0;
@@ -138,18 +113,12 @@ main (int argc, char **argv)
     char *file = NULL, *filter = NULL, *folder = NULL, *fwdmsg = NULL;
     char *from = NULL, *to = NULL, *cc = NULL, *subject = NULL, *fcc = NULL;
     char *form = NULL, buf[BUFSIZ], value[10];
-    char **argp, **arguments, *msgs[MAXARGS];
+    char **argp, **arguments;
     struct stat st;
-
+    struct msgs_array msgs = { 0, 0, NULL };
     int buildsw = 0;
 
-#ifdef LOCALE
-    setlocale(LC_ALL, "");
-#endif
-    invo_name = r1bindex (argv[0], '/');
-
-    /* read user profile/context */
-    context_read();
+    if (nmh_init(argv[0], 1)) { return 1; }
 
     arguments = getarguments (invo_name, argc, argv, 1);
     argp = arguments;
@@ -167,10 +136,10 @@ main (int argc, char **argv)
                    snprintf (buf, sizeof(buf), "%s [+folder] [msgs] [switches]",
                        invo_name);
                    print_help (buf, switches, 1);
-                   done (1);
+                   done (0);
                case VERSIONSW:
                    print_version(invo_name);
-                   done (1);
+                   done (0);
 
                case ANNOSW: 
                    anot++;
@@ -194,7 +163,8 @@ main (int argc, char **argv)
                    nwhat = 0;
                    continue;
                case BILDSW:
-                   buildsw++;  /* fall... */
+                   buildsw++;
+                   /* FALLTHRU */
                case NWHATSW: 
                    nwhat++;
                    continue;
@@ -242,7 +212,7 @@ main (int argc, char **argv)
                case DGSTSW: 
                    if (!(cp = *argp++) || *cp == '-')
                        adios (NULL, "missing argument to %s", argp[-2]);
-                   digest = getcpy(cp);
+                   digest = mh_xstrdup(cp);
                    mime = 0;
                    continue;
                case ISSUESW:
@@ -307,7 +277,7 @@ main (int argc, char **argv)
                case SUBJECTSW:
                    if (!(cp = *argp++) || *cp == '-')
                        adios (NULL, "missing argument to %s", argp[-2]);
-                   subject = getcpy(cp);
+                   subject = mh_xstrdup(cp);
                    continue;
 
                case WIDTHSW:
@@ -324,15 +294,15 @@ main (int argc, char **argv)
            else
                folder = pluspath (cp);
        } else {
-           msgs[msgp++] = cp;
+           app_msgarg(&msgs, cp);
        }
     }
 
-    cwd = getcpy (pwd ());
+    cwd = mh_xstrdup(pwd ());
 
     if (!context_find ("path"))
        free (path ("./", TFOLDER));
-    if (file && (msgp || folder))
+    if (file && (msgs.size || folder))
        adios (NULL, "can't mix files and folders/msgs");
 
 try_it_again:
@@ -344,7 +314,8 @@ try_it_again:
     if (!buildsw && stat (drft, &st) != NOTOK) {
        printf ("Draft \"%s\" exists (%ld bytes).", drft, (long) st.st_size);
        for (i = LISTDSW; i != YESW;) {
-           if (!(argp = getans ("\nDisposition? ", isdf ? aqrnl : aqrl)))
+           if (!(argp = read_switch_multiword ("\nDisposition? ",
+                                               isdf ? aqrnl : aqrl)))
                done (1);
            switch (i = smatch (*argp, isdf ? aqrnl : aqrl)) {
                case NOSW: 
@@ -377,8 +348,8 @@ try_it_again:
        /*
         * Forwarding a message.
         */
-       if (!msgp)
-           msgs[msgp++] = "cur";
+       if (!msgs.size)
+           app_msgarg(&msgs, "cur");
        if (!folder)
            folder = getfolder (1);
        maildir = m_maildir (folder);
@@ -387,7 +358,7 @@ try_it_again:
            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 */
@@ -395,9 +366,10 @@ try_it_again:
            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]))
+       for (msgnum = 0; msgnum < msgs.size; msgnum++)
+           if (!m_convert (mp, msgs.msgs[msgnum]))
                done (1);
+
        seq_setprev (mp);       /* set the previous sequence */
 
        /*
@@ -484,10 +456,10 @@ try_it_again:
        if (digest) {
            snprintf (buf, sizeof(buf), IFORMAT, digest);
            snprintf (value, sizeof(value), "%d", issue);
-           context_replace (buf, getcpy (value));
+           context_replace (buf, mh_xstrdup(value));
            snprintf (buf, sizeof(buf), VFORMAT, digest);
            snprintf (value, sizeof(value), "%d", volume);
-           context_replace (buf, getcpy (value));
+           context_replace (buf, mh_xstrdup(value));
        }
 
        context_replace (pfolder, folder);      /* update current folder   */
@@ -499,7 +471,7 @@ try_it_again:
     if (nwhat)
        done (0);
     what_now (ed, nedit, NOUSE, drft, NULL, 0, mp,
-       anot ? "Forwarded" : NULL, inplace, cwd);
+       anot ? "Forwarded" : NULL, inplace, cwd, 0);
     done (1);
     return 1;
 }
@@ -517,17 +489,19 @@ mhl_draft (int out, char *digest, int volume, int issue,
 {
     pid_t child_id;
     int i, msgnum, pd[2];
-    char *vec[MAXARGS];
     char buf1[BUFSIZ];
     char buf2[BUFSIZ];
-    
+    char *program;
+    struct msgs_array vec = { 0, 0, NULL };
+
     if (pipe (pd) == NOTOK)
        adios ("pipe", "unable to create");
 
-    vec[0] = r1bindex (mhlproc, '/');
+    argsplit_msgarg(&vec, mhlproc, &program);
 
     for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++)
        sleep (5);
+
     switch (child_id) {
        case NOTOK: 
            adios ("fork", "unable to");
@@ -537,20 +511,19 @@ mhl_draft (int out, char *digest, int volume, int issue,
            dup2 (pd[1], 1);
            close (pd[1]);
 
-           i = 1;
-           vec[i++] = "-forwall";
-           vec[i++] = "-form";
-           vec[i++] = filter;
+           app_msgarg(&vec, "-forwall");
+           app_msgarg(&vec, "-form");
+           app_msgarg(&vec, filter);
 
            if (digest) {
-               vec[i++] = "-digest";
-               vec[i++] = digest;
-               vec[i++] = "-issue";
+               app_msgarg(&vec, "-digest");
+               app_msgarg(&vec, digest);
+               app_msgarg(&vec, "-issue");
                snprintf (buf1, sizeof(buf1), "%d", issue);
-               vec[i++] = buf1;
-               vec[i++] = "-volume";
+               app_msgarg(&vec, buf1);
+               app_msgarg(&vec, "-volume");
                snprintf (buf2, sizeof(buf2), "%d", volume);
-               vec[i++] = buf2;
+               app_msgarg(&vec, buf2);
            }
 
            /*
@@ -559,34 +532,25 @@ mhl_draft (int out, char *digest, int volume, int issue,
             * unless the user has specified a specific flag.
             */
            if (dashstuff > 0)
-               vec[i++] = "-dashstuffing";
+               app_msgarg(&vec, "-dashstuffing");
            else if (dashstuff < 0)
-               vec[i++] = "-nodashstuffing";
+               app_msgarg(&vec, "-nodashstuffing");
 
-           if (mp->numsel >= MAXARGS - i)
-               adios (NULL, "more than %d messages for %s exec",
-                       MAXARGS - i, vec[0]);
-
-           /*
-            * Now add the message names to filter.  We can only
-            * handle about 995 messages (because vec is fixed size),
-            * but that should be plenty.
-            */
-           for (msgnum = mp->lowsel;
-                 msgnum <= mp->hghsel && i < (int) sizeof(vec) - 1;
-                 msgnum++)
+           for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
                if (is_selected (mp, msgnum))
-                   vec[i++] = getcpy (m_name (msgnum));
-           vec[i] = NULL;
+                   app_msgarg(&vec, mh_xstrdup(m_name (msgnum)));
+           }
+
+           app_msgarg(&vec, NULL);
 
-           execvp (mhlproc, vec);
+           execvp (program, vec.msgs);
            fprintf (stderr, "unable to exec ");
            perror (mhlproc);
            _exit (-1);
 
        default: 
            close (pd[1]);
-           cpydata (pd[0], out, vec[0], file);
+           cpydata (pd[0], out, vec.msgs[0], file);
            close (pd[0]);
            pidXwait(child_id, mhlproc);
            break;
@@ -605,7 +569,7 @@ copy_draft (int out, char *digest, char *file, int volume, int issue, int dashst
 {
     int fd,i, msgcnt, msgnum;
     int len, buflen;
-    register char *bp, *msgnam;
+    char *bp, *msgnam;
     char buffer[BUFSIZ];
 
     msgcnt = 1;
@@ -636,7 +600,9 @@ copy_draft (int out, char *digest, char *file, int volume, int issue, int dashst
 
                strncpy (bp, "\n\n", buflen);
            }
-           write (out, buffer, strlen (buffer));
+           if (write (out, buffer, strlen (buffer)) < 0) {
+               advise (drft, "write");
+           }
 
            if ((fd = open (msgnam = m_name (msgnum), O_RDONLY)) == NOTOK) {
                admonish (msgnam, "unable to read message");
@@ -663,7 +629,9 @@ copy_draft (int out, char *digest, char *file, int volume, int issue, int dashst
        snprintf (buffer, sizeof(buffer), "\n------- End of Forwarded Message%s\n",
                mp->numsel > 1 ? "s" : "");
     }
-    write (out, buffer, strlen (buffer));
+    if (write (out, buffer, strlen (buffer)) < 0) {
+       advise (drft, "write");
+    }
 
     if (digest) {
        snprintf (buffer, sizeof(buffer), "End of %s Digest [Volume %d Issue %d]\n",
@@ -673,7 +641,9 @@ copy_draft (int out, char *digest, char *file, int volume, int issue, int dashst
            *bp++ = '*';
        *bp++ = '\n';
        *bp = 0;
-       write (out, buffer, strlen (buffer));
+       if (write (out, buffer, strlen (buffer)) < 0) {
+           advise (drft, "write");
+       }
     }
 }
 
@@ -690,11 +660,17 @@ copy_mime_draft (int out)
 
     snprintf (buffer, sizeof(buffer), "#forw [forwarded message%s] +%s",
        mp->numsel == 1 ? "" : "s", mp->foldpath);
-    write (out, buffer, strlen (buffer));
+    if (write (out, buffer, strlen (buffer)) < 0) {
+       advise (drft, "write");
+    }
     for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++)
        if (is_selected (mp, msgnum)) {
            snprintf (buffer, sizeof(buffer), " %s", m_name (msgnum));
-           write (out, buffer, strlen (buffer));
+           if (write (out, buffer, strlen (buffer)) < 0) {
+               advise (drft, "write");
+           }
        }
-    write (out, "\n", 1);
+    if (write (out, "\n", 1) < 0) {
+       advise (drft, "write newline");
+    }
 }