Cleaned up sendfiles(1) man page just a bit.
[mmh] / uip / forw.c
index 8b5e008..2d6709e 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <h/mh.h>
 #include <fcntl.h>
-#include <h/fmt_scan.h>
 #include <h/tws.h>
 #include <h/utils.h>
 
@@ -70,7 +69,18 @@ static struct swit switches[] = {
     { "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 }
 };
 
@@ -112,22 +122,25 @@ static struct msgs *mp = NULL;            /* used a lot */
 static void mhl_draft (int, char *, int, int, char *, char *, int);
 static void copy_draft (int, char *, char *, int, int, int);
 static void copy_mime_draft (int);
-static int build_form (char *, char *, int, 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;
+    int out, isdf = 0, msgnum = 0;
+    int outputlinelen = OUTPUTLINELEN;
+    int dat[5];
     char *cp, *cwd, *maildir, *dfolder = NULL;
     char *dmsg = NULL, *digest = NULL, *ed = NULL;
-    char *file = NULL, *filter = NULL, *folder = NULL;
+    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;
 
@@ -155,10 +168,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++;
@@ -228,8 +241,9 @@ main (int argc, char **argv)
                    continue;
 
                case DGSTSW: 
-                   if (!(digest = *argp++) || *digest == '-')
+                   if (!(cp = *argp++) || *cp == '-')
                        adios (NULL, "missing argument to %s", argp[-2]);
+                   digest = getcpy(cp);
                    mime = 0;
                    continue;
                case ISSUESW:
@@ -270,6 +284,39 @@ main (int argc, char **argv)
                case NBITSTUFFSW: 
                    dashstuff = -1;     /* trinary logic */
                    continue;
+
+               case FROMSW:
+                   if (!(cp = *argp++) || *cp == '-')
+                       adios (NULL, "missing argument to %s", argp[-2]);
+                   from = addlist(from, cp);
+                   continue;
+               case TOSW:
+                   if (!(cp = *argp++) || *cp == '-')
+                       adios (NULL, "missing argument to %s", argp[-2]);
+                   to = addlist(to, cp);
+                   continue;
+               case CCSW:
+                   if (!(cp = *argp++) || *cp == '-')
+                       adios (NULL, "missing argument to %s", argp[-2]);
+                   cc = addlist(cc, cp);
+                   continue;
+               case FCCSW:
+                   if (!(cp = *argp++) || *cp == '-')
+                       adios (NULL, "missing argument to %s", argp[-2]);
+                   fcc = addlist(fcc, cp);
+                   continue;
+               case SUBJECTSW:
+                   if (!(cp = *argp++) || *cp == '-')
+                       adios (NULL, "missing argument to %s", argp[-2]);
+                   subject = getcpy(cp);
+                   continue;
+
+               case WIDTHSW:
+                   if (!(cp = *argp++) || *cp == '-')
+                       adios (NULL, "missing argument to %s", argp[-2]);
+                   if ((outputlinelen = atoi(cp)) < 10)
+                       adios (NULL, "impossible width %d", outputlinelen);
+                   continue;
            }
        }
        if (*cp == '+' || *cp == '@') {
@@ -278,7 +325,7 @@ main (int argc, char **argv)
            else
                folder = pluspath (cp);
        } else {
-           msgs[msgp++] = cp;
+           app_msgarg(&msgs, cp);
        }
     }
 
@@ -286,7 +333,7 @@ main (int argc, char **argv)
 
     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:
@@ -331,8 +378,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);
@@ -349,10 +396,25 @@ 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 */
+
+       /*
+        * Find the first message in our set and use it as the input
+        * for the component scanner
+        */
+
+       for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++)
+           if (is_selected (mp, msgnum)) {
+               fwdmsg = strdup(m_name(msgnum));
+               break;
+           }
+
+       if (! fwdmsg)
+           adios (NULL, "Unable to find input message");
     }
 
     if (filter && access (filter, R_OK) == NOTOK)
@@ -370,15 +432,27 @@ try_it_again:
                issue = 0;
            issue++;
        }
-       if (volume == 0)
+       if (volume == 0) {
            snprintf (buf, sizeof(buf), VFORMAT, digest);
-       if ((cp = context_find (buf)) == NULL || (volume = atoi (cp)) <= 0)
-           volume = 1;
+           if ((cp = context_find (buf)) == NULL || (volume = atoi (cp)) <= 0)
+               volume = 1;
+       }
        if (!form)
            form = digestcomps;
-       in = build_form (form, digest, volume, issue);
-    } else
-       in = open_form(&form, forwcomps);
+    } else {
+       if (!form)
+           form = forwcomps;
+    }
+
+    dat[0] = digest ? issue : msgnum;
+    dat[1] = volume;
+    dat[2] = 0;
+    dat[3] = outputlinelen;
+    dat[4] = 0;
+
+
+    in = build_form (form, digest, dat, from, to, cc, fcc, subject,
+                    file ? file : fwdmsg);
 
     if ((out = creat (drft, m_gmprot ())) == NOTOK)
        adios (drft, "unable to create");
@@ -427,7 +501,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;
 }
@@ -445,17 +519,18 @@ 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];
-    
+    struct msgs_array vec = { 0, 0, NULL };
+
     if (pipe (pd) == NOTOK)
        adios ("pipe", "unable to create");
 
-    vec[0] = r1bindex (mhlproc, '/');
+    app_msgarg(&vec, r1bindex (mhlproc, '/'));
 
     for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++)
        sleep (5);
+
     switch (child_id) {
        case NOTOK: 
            adios ("fork", "unable to");
@@ -466,19 +541,19 @@ mhl_draft (int out, char *digest, int volume, int issue,
            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);
            }
 
            /*
@@ -487,33 +562,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";
-
-           if (mp->numsel >= MAXARGS - i)
-               adios (NULL, "more than %d messages for %s exec",
-                       MAXARGS - i, vec[0]);
+               app_msgarg(&vec, "-nodashstuffing");
 
-           /*
-            * 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 < 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, getcpy (m_name (msgnum)));
+           }
+
+           app_msgarg(&vec, NULL);
 
-           execvp (mhlproc, vec);
+           execvp (mhlproc, 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;
@@ -587,7 +654,7 @@ copy_draft (int out, char *digest, char *file, int volume, int issue, int dashst
     if (digest) {
        strncpy (buffer, delim4, sizeof(buffer));
     } else {
-       snprintf (buffer, sizeof(buffer), "\n------- End of Forwarded Message%s\n\n",
+       snprintf (buffer, sizeof(buffer), "\n------- End of Forwarded Message%s\n",
                mp->numsel > 1 ? "s" : "");
     }
     write (out, buffer, strlen (buffer));
@@ -625,55 +692,3 @@ copy_mime_draft (int out)
        }
     write (out, "\n", 1);
 }
-
-
-static int
-build_form (char *form, char *digest, int volume, int issue)
-{
-    int        in;
-    int fmtsize;
-    register char *nfs;
-    char *line, tmpfil[BUFSIZ];
-    FILE *tmp;
-    register struct comp *cptr;
-    struct format *fmt;
-    int dat[5];
-    char *cp = NULL;
-
-    /* Get new format string */
-    nfs = new_fs (form, NULL, NULL);
-    fmtsize = strlen (nfs) + 256;
-
-    /* Compile format string */
-    fmt_compile (nfs, &fmt);
-
-    FINDCOMP (cptr, "digest");
-    if (cptr)
-       cptr->c_text = digest;
-    FINDCOMP (cptr, "date");
-    if (cptr)
-       cptr->c_text = getcpy(dtimenow (0));
-
-    dat[0] = issue;
-    dat[1] = volume;
-    dat[2] = 0;
-    dat[3] = fmtsize;
-    dat[4] = 0;
-
-    cp = m_mktemp2(NULL, invo_name, NULL, &tmp);
-    if (cp == NULL) adios("forw", "unable to create temporary file");
-    strncpy (tmpfil, cp, sizeof(tmpfil));
-    unlink (tmpfil);
-    if ((in = dup (fileno (tmp))) == NOTOK)
-       adios ("dup", "unable to");
-
-    line = mh_xmalloc ((unsigned) fmtsize);
-    fmt_scan (fmt, line, fmtsize, dat);
-    fputs (line, tmp);
-    free (line);
-    if (fclose (tmp))
-       adios (tmpfil, "error writing");
-
-    lseek (in, (off_t) 0, SEEK_SET);
-    return in;
-}