#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];
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;
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;
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++;
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:
case SUBJECTSW:
if (!(cp = *argp++) || *cp == '-')
adios (NULL, "missing argument to %s", argp[-2]);
- subject = getcpy(cp);
+ subject = mh_xstrdup(cp);
continue;
case WIDTHSW:
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:
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:
/*
* Forwarding a message.
*/
- if (!msgp)
- msgs[msgp++] = "cur";
+ if (!msgs.size)
+ app_msgarg(&msgs, "cur");
if (!folder)
folder = getfolder (1);
maildir = m_maildir (folder);
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 */
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 */
/*
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 */
{
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");
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);
}
/*
* 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;
{
int fd,i, msgcnt, msgnum;
int len, buflen;
- register char *bp, *msgnam;
+ char *bp, *msgnam;
char buffer[BUFSIZ];
msgcnt = 1;
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");
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",
*bp++ = '*';
*bp++ = '\n';
*bp = 0;
- write (out, buffer, strlen (buffer));
+ if (write (out, buffer, strlen (buffer)) < 0) {
+ advise (drft, "write");
+ }
}
}
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");
+ }
}