Renamed -version switch to -Version to remove the conflict with -verbose.
[mmh] / uip / forw.c
index 13aaaa9..b1148b0 100644 (file)
@@ -23,88 +23,50 @@ static struct swit switches[] = {
        { "noannotate", 0 },
 #define EDITRSW  2
        { "editor editor", 0 },
-#define NEDITSW  3
-       { "noedit", 0 },
-#define FILTSW  4
-       { "filter filterfile", 0 },
-#define FORMSW  5
+#define FORMSW  3
        { "form formfile", 0 },
-#define FRMTSW  6
-       { "format", 5 },
-#define NFRMTSW  7
-       { "noformat", 7 },
-#define INPLSW  8
-       { "inplace", 0 },
-#define NINPLSW  9
-       { "noinplace", 0 },
-#define MIMESW  10
-       { "mime", 0 },
-#define NMIMESW  11
-       { "nomime", 0 },
-#define DGSTSW  12
+#define DGSTSW  4
        { "digest list", 0 },
-#define ISSUESW  13
+#define ISSUESW  5
        { "issue number", 0 },
-#define VOLUMSW  14
+#define VOLUMSW  6
        { "volume number", 0 },
-#define WHATSW  15
+#define WHATSW  7
        { "whatnowproc program", 0 },
-#define NWHATSW  16
-       { "nowhatnowproc", 0 },
-#define BITSTUFFSW  17
-       { "dashstuffing", 0 },  /* interface to mhl */
-#define NBITSTUFFSW  18
-       { "nodashstuffing", 0 },
-#define VERSIONSW  19
-       { "version", 0 },
-#define HELPSW  20
+#define VERSIONSW  8
+       { "Version", 0 },
+#define HELPSW  9
        { "help", 0 },
-#define FILESW  21
-       { "file file", 4 },  /* interface from msh */
-
-#ifdef MHE
-#define BILDSW  22
+#define BILDSW  12
        { "build", 5 },  /* interface from mhe */
-#endif /* MHE */
-
        { NULL, 0 }
 };
 
 static char drft[BUFSIZ];
-
-static char delim3[] =
-       "\n------------------------------------------------------------\n\n";
-static char delim4[] = "\n------------------------------\n\n";
-
-
-static struct msgs *mp = NULL;  /* used a lot */
+static struct msgs *mp = NULL;
 
 
 /*
 ** static prototypes
 */
-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 void add_forw_hdr(char *);
 static int build_form(char *, char *, int, int);
 
 
 int
 main(int argc, char **argv)
 {
-       int msgp = 0, anot = 0, inplace = 1, mime = 0;
-       int issue = 0, volume = 0, dashstuff = 0;
-       int nedit = 0, nwhat = 0, in;
+       int msgp = 0, anot = 0;
+       int issue = 0, volume = 0;
+       int in;
        int out, msgnum;
        char *cp, *cwd, *maildir;
        char *digest = NULL, *ed = NULL;
-       char *file = NULL, *filter = NULL, *folder = NULL;
+       char *folder = NULL;
        char *form = NULL, buf[BUFSIZ], value[10];
        char **argp, **arguments, *msgs[MAXARGS];
-
-#ifdef MHE
+       char *fmtstr;
        int buildsw = 0;
-#endif /* MHE */
 
 #ifdef LOCALE
        setlocale(LC_ALL, "");
@@ -120,178 +82,124 @@ main(int argc, char **argv)
        while ((cp = *argp++)) {
                if (*cp == '-') {
                        switch (smatch(++cp, switches)) {
-                               case AMBIGSW:
-                                       ambigsw(cp, switches);
-                                       done(1);
-                               case UNKWNSW:
-                                       adios(NULL, "-%s unknown", cp);
-
-                               case HELPSW:
-                                       snprintf(buf, sizeof(buf), "%s [+folder] [msgs] [switches]", invo_name);
-                                       print_help(buf, switches, 1);
-                                       done(1);
-                               case VERSIONSW:
-                                       print_version(invo_name);
-                                       done(1);
-
-                               case ANNOSW:
-                                       anot++;
-                                       continue;
-                               case NANNOSW:
-                                       anot = 0;
-                                       continue;
-
-                               case EDITRSW:
-                                       if (!(ed = *argp++) || *ed == '-')
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       nedit = 0;
-                                       continue;
-                               case NEDITSW:
-                                       nedit++;
-                                       continue;
-
-                               case WHATSW:
-                                       if (!(whatnowproc = *argp++) || *whatnowproc == '-')
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       nwhat = 0;
-                                       continue;
-#ifdef MHE
-                               case BILDSW:
-                                       buildsw++;  /* fall... */
-#endif /* MHE */
-                               case NWHATSW:
-                                       nwhat++;
-                                       continue;
-
-                               case FILESW:
-                                       if (file)
-                                               adios(NULL, "only one file at a time!");
-                                       if (!(cp = *argp++) || *cp == '-')
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       file = path(cp, TFILE);
-                                       continue;
-                               case FILTSW:
-                                       if (!(cp = *argp++) || *cp == '-')
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       filter = getcpy(etcpath(cp));
-                                       mime = 0;
-                                       continue;
-                               case FORMSW:
-                                       if (!(form = *argp++) || *form == '-')
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       continue;
-
-                               case FRMTSW:
-                                       filter = getcpy(etcpath(mhlforward));
-                                       continue;
-                               case NFRMTSW:
-                                       filter = NULL;
-                                       continue;
-
-                               case INPLSW:
-                                       inplace++;
-                                       continue;
-                               case NINPLSW:
-                                       inplace = 0;
-                                       continue;
-
-                               case MIMESW:
-                                       mime++;
-                                       filter = NULL;
-                                       continue;
-                               case NMIMESW:
-                                       mime = 0;
-                                       continue;
-
-                               case DGSTSW:
-                                       if (!(digest = *argp++) || *digest == '-')
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       mime = 0;
-                                       continue;
-                               case ISSUESW:
-                                       if (!(cp = *argp++) || *cp == '-')
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       if ((issue = atoi(cp)) < 1)
-                                               adios(NULL, "bad argument %s %s", argp[-2], cp);
-                                       continue;
-                               case VOLUMSW:
-                                       if (!(cp = *argp++) || *cp == '-')
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       if ((volume = atoi(cp)) < 1)
-                                               adios(NULL, "bad argument %s %s", argp[-2], cp);
-                                       continue;
-
-                               case BITSTUFFSW:
-                                       dashstuff = 1;  /* trinary logic */
-                                       continue;
-                               case NBITSTUFFSW:
-                                       dashstuff = -1;  /* trinary logic */
-                                       continue;
+                       case AMBIGSW:
+                               ambigsw(cp, switches);
+                               done(1);
+                       case UNKWNSW:
+                               adios(NULL, "-%s unknown", cp);
+
+                       case HELPSW:
+                               snprintf(buf, sizeof(buf), "%s [+folder] [msgs] [switches]", invo_name);
+                               print_help(buf, switches, 1);
+                               done(1);
+                       case VERSIONSW:
+                               print_version(invo_name);
+                               done(1);
+
+                       case ANNOSW:
+                               anot++;
+                               continue;
+                       case NANNOSW:
+                               anot = 0;
+                               continue;
+
+                       case EDITRSW:
+                               if (!(ed = *argp++) || *ed == '-')
+                                       adios(NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               continue;
+
+                       case WHATSW:
+                               if (!(whatnowproc = *argp++) ||
+                                               *whatnowproc == '-')
+                                       adios(NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               continue;
+
+                       case BILDSW:
+                               buildsw++;
+                               continue;
+
+                       case FORMSW:
+                               if (!(form = *argp++) || *form == '-')
+                                       adios(NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               continue;
+
+                       case DGSTSW:
+                               if (!(digest = *argp++) || *digest == '-')
+                                       adios(NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               //mime = 0;
+                               continue;
+                       case ISSUESW:
+                               if (!(cp = *argp++) || *cp == '-')
+                                       adios(NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               if ((issue = atoi(cp)) < 1)
+                                       adios(NULL, "bad argument %s %s",
+                                                       argp[-2], cp);
+                               continue;
+                       case VOLUMSW:
+                               if (!(cp = *argp++) || *cp == '-')
+                                       adios(NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               if ((volume = atoi(cp)) < 1)
+                                       adios(NULL, "bad argument %s %s",
+                                                       argp[-2], cp);
+                               continue;
                        }
                }
                if (*cp == '+' || *cp == '@') {
                        if (folder)
                                adios(NULL, "only one folder at a time!");
                        else
-                               folder = pluspath(cp);
+                               folder = getcpy(expandfol(cp));
                } else {
                        msgs[msgp++] = cp;
                }
        }
 
        cwd = getcpy(pwd());
-
-       if (!context_find("path"))
-               free(path("./", TFOLDER));
-       if (file && (msgp || folder))
-               adios(NULL, "can't mix files and folders/msgs");
-
-#ifdef MHE
-       strncpy(drft, buildsw ? m_maildir("draft")
-               : m_draft("new"), sizeof(drft));
-#else
-       strncpy(drft, m_draft("new"), sizeof(drft));
-#endif /* MHE */
-
-       if (file) {
-               /*
-               ** Forwarding a file.
-               */
-               anot = 0;  /* don't want to annotate a file */
-       } else {
-               /*
-               ** Forwarding a message.
-               */
-               if (!msgp)
-                       msgs[msgp++] = "cur";
-               if (!folder)
-                       folder = getfolder(1);
-               maildir = m_maildir(folder);
-
-               if (chdir(maildir) == NOTOK)
-                       adios(maildir, "unable to change directory to");
-
-               /* 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);
-               seq_setprev(mp);  /* set the previous sequence */
-       }
-
-       if (filter && access(filter, R_OK) == NOTOK)
-               adios(filter, "unable to read");
+       strncpy(drft, buildsw ? toabsdir("draft") : m_draft(seq_beyond),
+                       sizeof(drft));
+       /*
+       ** FIXME: (concerning MHE support (buildsw) only)
+       ** There's no check if the draft already exists. mmh has removed
+       ** this case by having the draft folder. I won't add code only to
+       ** handle this legacy issue for MHE. -- meillo@marmaro.de 2012-05
+       */
 
        /*
-       ** Open form (component) file.
+       ** Forwarding a message.
        */
+       if (!msgp)
+               msgs[msgp++] = seq_cur;
+       if (!folder)
+               folder = getcurfol();
+       maildir = toabsdir(folder);
+
+       if (chdir(maildir) == NOTOK)
+               adios(maildir, "unable to change directory to");
+
+       /* 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);
+       seq_setprev(mp);  /* set the previous sequence */
+
+       if ((out = creat(drft, m_gmprot())) == NOTOK)
+               adios(drft, "unable to create");
+
+       /* Open form (component) file. */
        if (digest) {
                if (issue == 0) {
                        snprintf(buf, sizeof(buf), IFORMAT, digest);
@@ -300,276 +208,87 @@ main(int argc, char **argv)
                                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);
-
-       if ((out = creat(drft, m_gmprot())) == NOTOK)
-               adios(drft, "unable to create");
-
-       /*
-       ** copy the components into the draft
-       */
-       cpydata(in, out, form, drft);
-       close(in);
-
-       if (file) {
-               /* just copy the file into the draft */
-               if ((in = open(file, O_RDONLY)) == NOTOK)
-                       adios(file, "unable to open");
-               cpydata(in, out, file, drft);
+               cpydata(in, out, form, drft);
                close(in);
-               close(out);
        } else {
-               /*
-               ** If filter file is defined, then format the
-               ** messages into the draft using mhlproc.
-               */
-               if (filter)
-                       mhl_draft(out, digest, volume, issue, drft, filter,
-                                       dashstuff);
-               else if (mime)
-                       copy_mime_draft(out);
-               else
-                       copy_draft(out, digest, drft, volume, issue,
-                                       dashstuff);
-               close(out);
-
-               if (digest) {
-                       snprintf(buf, sizeof(buf), IFORMAT, digest);
-                       snprintf(value, sizeof(value), "%d", issue);
-                       context_replace(buf, getcpy(value));
-                       snprintf(buf, sizeof(buf), VFORMAT, digest);
-                       snprintf(value, sizeof(value), "%d", volume);
-                       context_replace(buf, getcpy(value));
+               fmtstr = new_fs(form, forwcomps);
+               if (write(out, fmtstr, strlen(fmtstr)) != (int)strlen(fmtstr)) {
+                       adios(drft, "error writing");
                }
+       }
+       close(out);
+
+       add_forw_hdr(drft);
 
-               context_replace(pfolder, folder);  /* update current folder */
-               seq_setcur(mp, mp->lowsel);  /* update current message */
-               seq_save(mp);  /* synchronize sequences */
-               context_save();  /* save the context file */
+       if (digest) {
+               snprintf(buf, sizeof(buf), IFORMAT, digest);
+               snprintf(value, sizeof(value), "%d", issue);
+               context_replace(buf, getcpy(value));
+               snprintf(buf, sizeof(buf), VFORMAT, digest);
+               snprintf(value, sizeof(value), "%d", volume);
+               context_replace(buf, getcpy(value));
        }
 
-       if (nwhat)
+       context_replace(curfolder, folder); /* update current folder */
+       seq_setcur(mp, mp->lowsel);  /* update current message */
+       seq_save(mp);  /* synchronize sequences */
+       context_save();  /* save the context file */
+
+       if (buildsw)
                done(0);
-       what_now(ed, nedit, NOUSE, drft, NULL, 0, mp,
-               anot ? "Forwarded" : NULL, inplace, cwd);
+       what_now(ed, NOUSE, drft, NULL, 0, mp,
+               anot ? "Forwarded" : NULL, cwd);
        done(1);
        return 1;
 }
 
 
 /*
-** Filter the messages you are forwarding, into the
-** draft calling the mhlproc, and reading its output
-** from a pipe.
+** Create an attachment header for the to be forward messages.
 */
-
 static void
-mhl_draft(int out, char *digest, int volume, int issue,
-       char *file, char *filter, int dashstuff)
+add_forw_hdr(char *draft)
 {
-       pid_t child_id;
-       int i, msgnum, pd[2];
-       char *vec[MAXARGS];
-       char buf1[BUFSIZ];
-       char buf2[BUFSIZ];
-
-       if (pipe(pd) == NOTOK)
-               adios("pipe", "unable to create");
-
-       vec[0] = mhbasename(mhlproc);
-
-       for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++)
-               sleep(5);
-       switch (child_id) {
-               case NOTOK:
-                       adios("fork", "unable to");
-
-               case OK:
-                       close(pd[0]);
-                       dup2(pd[1], 1);
-                       close(pd[1]);
-
-                       i = 1;
-                       vec[i++] = "-forwall";
-                       vec[i++] = "-form";
-                       vec[i++] = filter;
-
-                       if (digest) {
-                               vec[i++] = "-digest";
-                               vec[i++] = digest;
-                               vec[i++] = "-issue";
-                               snprintf(buf1, sizeof(buf1), "%d", issue);
-                               vec[i++] = buf1;
-                               vec[i++] = "-volume";
-                               snprintf(buf2, sizeof(buf2), "%d", volume);
-                               vec[i++] = buf2;
-                       }
-
-                       /*
-                       ** Are we dashstuffing (quoting) the lines that begin
-                       ** with `-'.  We use the mhl default (don't add any
-                       ** flag) unless the user has specified a specific flag.
-                       */
-                       if (dashstuff > 0)
-                               vec[i++] = "-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]);
-
-                       /*
-                       ** 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++)
-                               if (is_selected(mp, msgnum))
-                                       vec[i++] = getcpy(m_name(msgnum));
-                       vec[i] = NULL;
-
-                       execvp(mhlproc, vec);
-                       fprintf(stderr, "unable to exec ");
-                       perror(mhlproc);
-                       _exit(-1);
-
-               default:
-                       close(pd[1]);
-                       cpydata(pd[0], out, vec[0], file);
-                       close(pd[0]);
-                       pidXwait(child_id, mhlproc);
-                       break;
-       }
-}
-
-
-/*
-** Copy the messages into the draft.  The messages are
-** not filtered through the mhlproc.  Do dashstuffing if
-** necessary.
-*/
-
-static void
-copy_draft(int out, char *digest, char *file, int volume, int issue,
-               int dashstuff)
-{
-       int fd,i, msgcnt, msgnum;
-       int len, buflen;
-       register char *bp, *msgnam;
+       int msgnum;
        char buffer[BUFSIZ];
 
-       msgcnt = 1;
+       snprintf(buffer, sizeof buffer, "anno -append -nodate '%s' "
+                       "-comp '%s' -text '+%s",
+                       draft, attach_hdr, mp->foldpath);
        for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
-               if (is_selected(mp, msgnum)) {
-                       if (digest) {
-                               strncpy(buffer, msgnum == mp->lowsel ?
-                                       delim3 : delim4, sizeof(buffer));
-                       } else {
-                               /* Get buffer ready to go */
-                               bp = buffer;
-                               buflen = sizeof(buffer);
-
-                               strncpy(bp, "\n-------", buflen);
-                               len = strlen(bp);
-                               bp += len;
-                               buflen -= len;
-
-                               if (msgnum == mp->lowsel) {
-                                       snprintf(bp, buflen, " Forwarded Message%s", mp->numsel > 1 ? "s" : "");
-                               } else {
-                                       snprintf(bp, buflen, " Message %d", msgcnt);
-                               }
-                               len = strlen(bp);
-                               bp += len;
-                               buflen -= len;
-
-                               strncpy(bp, "\n\n", buflen);
-                       }
-                       write(out, buffer, strlen(buffer));
-
-                       if ((fd = open(msgnam = m_name (msgnum), O_RDONLY))
-                                       == NOTOK) {
-                               admonish(msgnam, "unable to read message");
-                               continue;
-                       }
-
-                       /*
-                       ** Copy the message.  Add RFC934 quoting (dashstuffing)
-                       ** unless given the -nodashstuffing flag.
-                       */
-                       if (dashstuff >= 0)
-                               cpydgst(fd, out, msgnam, file);
-                       else
-                               cpydata(fd, out, msgnam, file);
-
-                       close(fd);
-                       msgcnt++;
+               if (!is_selected(mp, msgnum)) {
+                       continue;
                }
+               /* TODO: Check for buffer length! */
+               strcat(buffer, " ");
+               strcat(buffer, m_name(msgnum));
        }
-
-       if (digest) {
-               strncpy(buffer, delim4, sizeof(buffer));
-       } else {
-               snprintf(buffer, sizeof(buffer),
-                               "\n------- End of Forwarded Message%s\n\n",
-                               mp->numsel > 1 ? "s" : "");
+       strcat(buffer, "'");
+       /* TODO: This check is bad, but better than nothing */
+       if (strlen(buffer) > BUFSIZ) {
+               adios(NULL, "Too long attachment header line. Forward less messages.");
        }
-       write(out, buffer, strlen(buffer));
-
-       if (digest) {
-               snprintf(buffer, sizeof(buffer),
-                               "End of %s Digest [Volume %d Issue %d]\n",
-                               digest, volume, issue);
-               i = strlen(buffer);
-               for (bp = buffer + i; i > 1; i--)
-                       *bp++ = '*';
-               *bp++ = '\n';
-               *bp = 0;
-               write(out, buffer, strlen(buffer));
+       if (system(buffer) != 0) {
+               advise(NULL, "unable to add attachment header");
        }
 }
 
 
-/*
-** Create a mhbuild composition file for forwarding message.
-*/
-
-static void
-copy_mime_draft(int out)
-{
-       int msgnum;
-       char buffer[BUFSIZ];
-
-       snprintf(buffer, sizeof(buffer), "#forw [forwarded message%s] +%s",
-                       mp->numsel == 1 ? "" : "s", mp->foldpath);
-       write(out, buffer, strlen(buffer));
-       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));
-               }
-       write(out, "\n", 1);
-}
-
-
 static int
 build_form(char *form, char *digest, int volume, int issue)
 {
        int in;
        int fmtsize;
-       register char *nfs;
+       register char *fmtstr;
        char *line, tmpfil[BUFSIZ];
        FILE *tmp;
        register struct comp *cptr;
@@ -578,18 +297,18 @@ build_form(char *form, char *digest, int volume, int issue)
        char *cp = NULL;
 
        /* Get new format string */
-       nfs = new_fs(form, NULL, NULL);
-       fmtsize = strlen(nfs) + 256;
+       fmtstr = new_fs(form, NULL);
+       fmtsize = strlen(fmtstr) + 256;
 
        /* Compile format string */
-       fmt_compile(nfs, &fmt);
+       fmt_compile(fmtstr, &fmt);
 
        FINDCOMP(cptr, "digest");
        if (cptr)
                cptr->c_text = digest;
        FINDCOMP(cptr, "date");
        if (cptr)
-               cptr->c_text = getcpy(dtimenow(0));
+               cptr->c_text = getcpy(dtimenow());
 
        dat[0] = issue;
        dat[1] = volume;