/*
* forw.c -- forward a message, or group of messages.
*
- * $Id$
- *
* This code is Copyright (c) 2002, by the authors of nmh. See the
* COPYRIGHT file in the root directory of the nmh distribution for
* complete copyright information.
#include <h/mh.h>
#include <fcntl.h>
-#include <h/fmt_scan.h>
#include <h/tws.h>
#include <h/utils.h>
{ "help", 0 },
#define FILESW 24
{ "file file", 4 }, /* interface from msh */
-
-#ifdef MHE
#define BILDSW 25
{ "build", 5 }, /* interface from mhe */
-#endif /* 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 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 };
-#ifdef MHE
int buildsw = 0;
-#endif /* MHE */
#ifdef LOCALE
setlocale(LC_ALL, "");
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++;
adios (NULL, "missing argument to %s", argp[-2]);
nwhat = 0;
continue;
-#ifdef MHE
case BILDSW:
buildsw++; /* fall... */
-#endif /* MHE */
case NWHATSW:
nwhat++;
continue;
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:
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 == '@') {
if (folder)
adios (NULL, "only one folder at a time!");
else
- folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
+ folder = pluspath (cp);
} else {
- msgs[msgp++] = cp;
+ app_msgarg(&msgs, cp);
}
}
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:
-#ifdef MHE
strncpy (drft, buildsw ? m_maildir ("draft")
: m_draft (dfolder, NULL, NOUSE, &isdf), sizeof(drft));
/* Check if a draft already exists */
if (!buildsw && stat (drft, &st) != NOTOK) {
-#else
- strncpy (drft, m_draft (dfolder, dmsg, NOUSE, &isdf), sizeof(drft));
-
- /* Check if a draft already exists */
- if (stat (drft, &st) != NOTOK) {
-#endif /* MHE */
printf ("Draft \"%s\" exists (%ld bytes).", drft, (long) st.st_size);
for (i = LISTDSW; i != YESW;) {
if (!(argp = getans ("\nDisposition? ", isdf ? aqrnl : aqrl)))
/*
* 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 (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)
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");
if (nwhat)
done (0);
what_now (ed, nedit, NOUSE, drft, NULL, 0, mp,
- anot ? "Forwarded" : NULL, inplace, cwd);
- return done (1);
+ anot ? "Forwarded" : NULL, inplace, cwd, 0);
+ done (1);
+ return 1;
}
{
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");
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",
- vec[0], MAXARGS - i);
-
- /*
- * 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)));
+ }
- execvp (mhlproc, vec);
+ app_msgarg(&vec, NULL);
+
+ 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;
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));
}
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];
- register FILE *tmp;
- register struct comp *cptr;
- struct format *fmt;
- int dat[5];
-
- /* 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;
-
- strncpy (tmpfil, m_tmpfil (invo_name), sizeof(tmpfil));
- if ((tmp = fopen (tmpfil, "w+")) == NULL)
- adios (tmpfil, "unable to create");
- 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;
-}