Fix uip/whom.c for C89 compatibility
[mmh] / uip / forw.c
index 8992b33..e00ae0e 100644 (file)
@@ -11,7 +11,9 @@
 #include <h/fmt_scan.h>
 #include <h/tws.h>
 #include <h/utils.h>
-
+#include <unistd.h>
+#include <locale.h>
+#include <sysexits.h>
 
 #define IFORMAT  "digest-issue-%s"
 #define VFORMAT  "digest-volume-%s"
@@ -20,36 +22,30 @@ static struct swit switches[] = {
 #define ANNOSW  0
        { "annotate", 0 },
 #define NANNOSW  1
-       { "noannotate", 0 },
+       { "noannotate", 2 },
 #define EDITRSW  2
        { "editor editor", 0 },
-#define NEDITSW  3
-       { "noedit", 0 },
-#define FORMSW  4
+#define FORMSW  3
        { "form formfile", 0 },
-#define DGSTSW  5
+#define DGSTSW  4
        { "digest list", 0 },
-#define ISSUESW  6
+#define ISSUESW  5
        { "issue number", 0 },
-#define VOLUMSW  7
+#define VOLUMSW  6
        { "volume number", 0 },
-#define WHATSW  8
+#define WHATSW  7
        { "whatnowproc program", 0 },
-#define NWHATSW  9
-       { "nowhatnowproc", 0 },
-#define VERSIONSW  10
-       { "version", 0 },
-#define HELPSW  11
+#define VERSIONSW  8
+       { "Version", 0 },
+#define HELPSW  9
        { "help", 0 },
-
-#ifdef MHE
-#define BILDSW  12
+#define BILDSW  10
        { "build", 5 },  /* interface from mhe */
-#endif /* MHE */
-
        { NULL, 0 }
 };
 
+char *version=VERSION;
+
 static char drft[BUFSIZ];
 static struct msgs *mp = NULL;
 
@@ -66,7 +62,7 @@ main(int argc, char **argv)
 {
        int msgp = 0, anot = 0;
        int issue = 0, volume = 0;
-       int nedit = 0, nwhat = 0, in;
+       int in;
        int out, msgnum;
        char *cp, *cwd, *maildir;
        char *digest = NULL, *ed = NULL;
@@ -74,14 +70,9 @@ main(int argc, char **argv)
        char *form = NULL, buf[BUFSIZ], value[10];
        char **argp, **arguments, *msgs[MAXARGS];
        char *fmtstr;
-
-#ifdef MHE
        int buildsw = 0;
-#endif /* MHE */
 
-#ifdef LOCALE
        setlocale(LC_ALL, "");
-#endif
        invo_name = mhbasename(argv[0]);
 
        /* read user profile/context */
@@ -95,17 +86,17 @@ main(int argc, char **argv)
                        switch (smatch(++cp, switches)) {
                        case AMBIGSW:
                                ambigsw(cp, switches);
-                               done(1);
+                               exit(EX_USAGE);
                        case UNKWNSW:
-                               adios(NULL, "-%s unknown", cp);
+                               adios(EX_USAGE, NULL, "-%s unknown", cp);
 
                        case HELPSW:
                                snprintf(buf, sizeof(buf), "%s [+folder] [msgs] [switches]", invo_name);
                                print_help(buf, switches, 1);
-                               done(1);
+                               exit(argc == 2 ? EX_OK : EX_USAGE);
                        case VERSIONSW:
                                print_version(invo_name);
-                               done(1);
+                               exit(argc == 2 ? EX_OK : EX_USAGE);
 
                        case ANNOSW:
                                anot++;
@@ -116,77 +107,69 @@ main(int argc, char **argv)
 
                        case EDITRSW:
                                if (!(ed = *argp++) || *ed == '-')
-                                       adios(NULL, "missing argument to %s",
+                                       adios(EX_USAGE, 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",
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
                                                        argp[-2]);
-                               nwhat = 0;
                                continue;
-#ifdef MHE
+
                        case BILDSW:
-                               buildsw++;  /* fall... */
-#endif /* MHE */
-                       case NWHATSW:
-                               nwhat++;
+                               buildsw++;
                                continue;
 
                        case FORMSW:
                                if (!(form = *argp++) || *form == '-')
-                                       adios(NULL, "missing argument to %s",
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
                                                        argp[-2]);
                                continue;
 
                        case DGSTSW:
                                if (!(digest = *argp++) || *digest == '-')
-                                       adios(NULL, "missing argument to %s",
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
                                                        argp[-2]);
-                               //mime = 0;
                                continue;
                        case ISSUESW:
                                if (!(cp = *argp++) || *cp == '-')
-                                       adios(NULL, "missing argument to %s",
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
                                                        argp[-2]);
                                if ((issue = atoi(cp)) < 1)
-                                       adios(NULL, "bad argument %s %s",
+                                       adios(EX_USAGE, NULL, "bad argument %s %s",
                                                        argp[-2], cp);
                                continue;
                        case VOLUMSW:
                                if (!(cp = *argp++) || *cp == '-')
-                                       adios(NULL, "missing argument to %s",
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
                                                        argp[-2]);
                                if ((volume = atoi(cp)) < 1)
-                                       adios(NULL, "bad argument %s %s",
+                                       adios(EX_USAGE, NULL, "bad argument %s %s",
                                                        argp[-2], cp);
                                continue;
                        }
                }
                if (*cp == '+' || *cp == '@') {
                        if (folder)
-                               adios(NULL, "only one folder at a time!");
+                               adios(EX_USAGE, NULL, "only one folder at a time!");
                        else
-                               folder = getcpy(expandfol(cp));
+                               folder = mh_xstrdup(expandfol(cp));
                } else {
                        msgs[msgp++] = cp;
                }
        }
 
-       cwd = getcpy(pwd());
-
-#ifdef MHE
-       strncpy(drft, buildsw ? toabsdir("draft")
-               : m_draft(seq_beyond), sizeof(drft));
-#else
-       strncpy(drft, m_draft(seq_beyond), sizeof(drft));
-#endif /* MHE */
+       cwd = mh_xstrdup(pwd());
+       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
+       */
 
        /*
        ** Forwarding a message.
@@ -198,24 +181,26 @@ main(int argc, char **argv)
        maildir = toabsdir(folder);
 
        if (chdir(maildir) == NOTOK)
-               adios(maildir, "unable to change directory to");
+               adios(EX_OSERR, 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);
+               adios(EX_IOERR, NULL, "unable to read folder %s", folder);
 
        /* check for empty folder */
        if (mp->nummsg == 0)
-               adios(NULL, "no messages in %s", folder);
+               adios(EX_DATAERR, 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);
+       for (msgnum = 0; msgnum < msgp; msgnum++) {
+               if (!m_convert(mp, msgs[msgnum])) {
+                       exit(EX_SOFTWARE);
+               }
+       }
        seq_setprev(mp);  /* set the previous sequence */
 
        if ((out = creat(drft, m_gmprot())) == NOTOK)
-               adios(drft, "unable to create");
+               adios(EX_CANTCREAT, drft, "unable to create");
 
        /* Open form (component) file. */
        if (digest) {
@@ -226,11 +211,12 @@ 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);
@@ -238,8 +224,8 @@ main(int argc, char **argv)
                close(in);
        } else {
                fmtstr = new_fs(form, forwcomps);
-               if (write(out, fmtstr, strlen(fmtstr)) != strlen(fmtstr)) {
-                       adios(drft, "error writing");
+               if (write(out, fmtstr, strlen(fmtstr)) != (int)strlen(fmtstr)) {
+                       adios(EX_IOERR, drft, "error writing");
                }
        }
        close(out);
@@ -249,10 +235,10 @@ main(int argc, char **argv)
        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(curfolder, folder); /* update current folder */
@@ -260,12 +246,11 @@ main(int argc, char **argv)
        seq_save(mp);  /* synchronize sequences */
        context_save();  /* save the context file */
 
-       if (nwhat)
-               done(0);
-       what_now(ed, nedit, NOUSE, drft, NULL, 0, mp,
+       if (buildsw)
+               exit(EX_OK);
+       what_now(ed, NOUSE, drft, NULL, 0, mp,
                anot ? "Forwarded" : NULL, cwd);
-       done(1);
-       return 1;
+       return EX_OSERR;
 }
 
 
@@ -276,19 +261,35 @@ static void
 add_forw_hdr(char *draft)
 {
        int msgnum;
-       char buffer[BUFSIZ];
-
-       snprintf(buffer, sizeof(buffer), "+%s", mp->foldpath);
+       char buf[BUFSIZ];
+       char *vec[MAXARGS];
+       int vecp = 0;
+
+       vec[vecp++] = "anno";
+       vec[vecp++] = "-append";
+       vec[vecp++] = "-nodate";
+       vec[vecp++] = draft;
+       vec[vecp++] = "-comp";
+       vec[vecp++] = attach_hdr;
+       vec[vecp++] = "-text";
+       snprintf(buf, sizeof buf, "+%s", mp->foldpath);
        for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
                if (!is_selected(mp, msgnum)) {
                        continue;
                }
-               /* TODO: improve the code */
-               strncat(buffer, " ", sizeof(buffer)-strlen(buffer)-1);
-               strncat(buffer, m_name(msgnum),
-                               sizeof(buffer)-strlen(buffer)-1);
+               if (strlen(buf) + 1 + strlen(m_name(msgnum)) + 1
+                               > sizeof buf) {
+                       adios(EX_DATAERR, NULL, "Attachment header line too long. "
+                                       "Forward less messages.");
+               }
+               strcat(buf, " ");
+               strcat(buf, m_name(msgnum));
+       }
+       vec[vecp++] = buf;
+       vec[vecp] = NULL;
+       if (execprog(*vec, vec) != 0) {
+               advise(NULL, "unable to add attachment header");
        }
-       annotate(draft, attach_hdr, buffer, 0, -2, 1, 0);
 }
 
 
@@ -297,10 +298,10 @@ build_form(char *form, char *digest, int volume, int issue)
 {
        int in;
        int fmtsize;
-       register char *fmtstr;
+       char *fmtstr;
        char *line, tmpfil[BUFSIZ];
        FILE *tmp;
-       register struct comp *cptr;
+       struct comp *cptr;
        struct format *fmt;
        int dat[5];
        char *cp = NULL;
@@ -317,7 +318,7 @@ build_form(char *form, char *digest, int volume, int issue)
                cptr->c_text = digest;
        FINDCOMP(cptr, "date");
        if (cptr)
-               cptr->c_text = getcpy(dtimenow(0));
+               cptr->c_text = mh_xstrdup(dtimenow());
 
        dat[0] = issue;
        dat[1] = volume;
@@ -326,18 +327,20 @@ build_form(char *form, char *digest, int volume, int issue)
        dat[4] = 0;
 
        cp = m_mktemp2(NULL, invo_name, NULL, &tmp);
-       if (cp == NULL) adios("forw", "unable to create temporary file");
+       if (cp == NULL) {
+               adios(EX_CANTCREAT, "forw", "unable to create temporary file");
+       }
        strncpy(tmpfil, cp, sizeof(tmpfil));
        unlink(tmpfil);
        if ((in = dup(fileno(tmp))) == NOTOK)
-               adios("dup", "unable to");
+               adios(EX_OSERR, "dup", "unable to");
 
-       line = mh_xmalloc((unsigned) fmtsize);
+       line = mh_xcalloc(fmtsize, sizeof(char));
        fmt_scan(fmt, line, fmtsize, dat);
        fputs(line, tmp);
-       free(line);
+       mh_free0(&line);
        if (fclose(tmp))
-               adios(tmpfil, "error writing");
+               adios(EX_IOERR, tmpfil, "error writing");
 
        lseek(in, (off_t) 0, SEEK_SET);
        return in;