/*
* comp.c -- compose a message
*
- * $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 <h/utils.h>
+#include <h/fmt_scan.h>
#include <fcntl.h>
-static struct swit switches[] = {
-#define DFOLDSW 0
- { "draftfolder +folder", 0 },
-#define DMSGSW 1
- { "draftmessage msg", 0 },
-#define NDFLDSW 2
- { "nodraftfolder", 0 },
-#define EDITRSW 3
- { "editor editor", 0 },
-#define NEDITSW 4
- { "noedit", 0 },
-#define FILESW 5
- { "file file", 0 },
-#define FORMSW 6
- { "form formfile", 0 },
-#define USESW 7
- { "use", 0 },
-#define NUSESW 8
- { "nouse", 0 },
-#define WHATSW 9
- { "whatnowproc program", 0 },
-#define NWHATSW 10
- { "nowhatnowproc", 0 },
-#define VERSIONSW 11
- { "version", 0 },
-#define HELPSW 12
- { "help", 0 },
- { NULL, 0 }
-};
-
-static struct swit aqrunl[] = {
-#define NOSW 0
- { "quit", 0 },
-#define YESW 1
- { "replace", 0 },
-#define USELSW 2
- { "use", 0 },
-#define LISTDSW 3
- { "list", 0 },
-#define REFILSW 4
- { "refile +folder", 0 },
-#define NEWSW 5
- { "new", 0 },
- { NULL, 0 }
-};
+#define COMP_SWITCHES \
+ X("draftfolder +folder", 0, DFOLDSW) \
+ X("draftmessage msg", 0, DMSGSW) \
+ X("nodraftfolder", 0, NDFLDSW) \
+ X("editor editor", 0, EDITRSW) \
+ X("noedit", 0, NEDITSW) \
+ X("file file", 0, FILESW) \
+ X("form formfile", 0, FORMSW) \
+ X("use", 0, USESW) \
+ X("nouse", 0, NUSESW) \
+ X("whatnowproc program", 0, WHATSW) \
+ X("nowhatnowproc", 0, NWHATSW) \
+ X("build", 5, BILDSW) \
+ X("version", 0, VERSIONSW) \
+ X("help", 0, HELPSW) \
+ X("to address", 0, TOSW) \
+ X("cc address", 0, CCSW) \
+ X("from address", 0, FROMSW) \
+ X("fcc mailbox", 0, FCCSW) \
+ X("width colums", 0, WIDTHSW) \
+ X("subject text", 0, SUBJECTSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(COMP);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(COMP, switches);
+#undef X
+
+#define DISPO_SWITCHES \
+ X("quit", 0, NOSW) \
+ X("replace", 0, YESW) \
+ X("use", 0, USELSW) \
+ 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, aqrunl);
+#undef X
static struct swit aqrul[] = {
- { "quit", 0 },
- { "replace", 0 },
- { "use", 0 },
- { "list", 0 },
- { "refile", 0 },
- { NULL, 0 }
+ { "quit", 0, NOSW },
+ { "replace", 0, YESW },
+ { "use", 0, USELSW },
+ { "list", 0, LISTDSW },
+ { "refile", 0, REFILSW },
+ { NULL, 0, 0 }
};
-
int
main (int argc, char **argv)
{
- int use = NOUSE, nedit = 0, nwhat = 0;
- int i, in, isdf = 0, out;
+ int use = NOUSE, nedit = 0, nwhat = 0, build = 0;
+ int i, in = NOTOK, isdf = 0, out, dat[5], format_len = 0;
+ int outputlinelen = OUTPUTLINELEN;
char *cp, *cwd, *maildir, *dfolder = NULL;
char *ed = NULL, *file = NULL, *form = NULL;
char *folder = NULL, *msg = NULL, buf[BUFSIZ];
+ char *to = NULL, *from = NULL, *cc = NULL, *fcc = NULL, *dp;
+ char *subject = NULL;
char drft[BUFSIZ], **argp, **arguments;
struct msgs *mp = NULL;
+ struct format *fmt;
struct stat st;
-#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] [msg] [switches]",
invo_name);
print_help (buf, switches, 1);
- done (1);
+ done (0);
case VERSIONSW:
print_version(invo_name);
- done (1);
+ done (0);
case EDITRSW:
if (!(ed = *argp++) || *ed == '-')
adios (NULL, "missing argument to %s", argp[-2]);
nwhat = 0;
continue;
+
+ case BILDSW:
+ build++;
+ /* fall through */
case NWHATSW:
nwhat++;
continue;
dfolder = NULL;
isdf = NOTOK;
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 FROMSW:
+ if (!(cp = *argp++) || *cp == '-')
+ adios (NULL, "missing argument to %s", argp[-2]);
+ from = addlist(from, cp);
+ continue;
+
+ case FCCSW:
+ if (!(cp = *argp++) || *cp == '-')
+ adios (NULL, "missing argument to %s", argp[-2]);
+ dp = NULL;
+ if (*cp == '@')
+ cp = dp = path(cp + 1, TSUBCWF);
+ fcc = addlist(fcc, cp);
+ mh_xfree(dp);
+ 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;
+
+ case SUBJECTSW:
+ if (!(cp = *argp++) || *cp == '-')
+ adios (NULL, "missing argument to %s", argp[-2]);
+ subject = cp;
+ continue;
}
}
if (*cp == '+' || *cp == '@') {
}
}
- cwd = getcpy (pwd ());
+ cwd = mh_xstrdup(pwd ());
if (!context_find ("path"))
free (path ("./", TFOLDER));
if (form && (folder || msg))
adios (NULL, "can't mix forms and folders/msgs");
+ cp = NULL;
+
if (folder || msg) {
/*
* Use a message as the "form" for the new message.
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 */
if (!m_convert (mp, msg))
done (1);
seq_setprev (mp); /* set the previous-sequence */
+ seq_save (mp);
if (mp->numsel > 1)
adios (NULL, "only one message at a time!");
- if ((in = open (form = getcpy (m_name (mp->lowsel)), O_RDONLY)) == NOTOK)
+ if ((in = open (form = mh_xstrdup(m_name (mp->lowsel)), O_RDONLY)) == NOTOK)
adios (form, "unable to open message");
- } else
- in = open_form(&form, components);
+ } else {
+ struct comp *cptr;
+
+ if (! form)
+ form = components;
+
+ cp = new_fs(form, NULL, NULL);
+ format_len = strlen(cp);
+ fmt_compile(cp, &fmt, 1);
+
+ /*
+ * Set up any components that were fed to us on the command line
+ */
+
+ if (from) {
+ cptr = fmt_findcomp("from");
+ if (cptr)
+ cptr->c_text = from;
+ }
+ if (to) {
+ cptr = fmt_findcomp("to");
+ if (cptr)
+ cptr->c_text = to;
+ }
+ if (cc) {
+ cptr = fmt_findcomp("cc");
+ if (cptr)
+ cptr->c_text = cc;
+ }
+ if (fcc) {
+ cptr = fmt_findcomp("fcc");
+ if (cptr)
+ cptr->c_text = fcc;
+ }
+ if (subject) {
+ cptr = fmt_findcomp("subject");
+ if (cptr)
+ cptr->c_text = subject;
+ }
+ }
try_it_again:
- strncpy (drft, m_draft (dfolder, file, use, &isdf), sizeof(drft));
+ strncpy (drft, build ? m_maildir ("draft")
+ : m_draft (dfolder, file, use, &isdf), sizeof(drft));
/*
* Check if we have an existing draft
*/
- if ((out = open (drft, O_RDONLY)) != NOTOK) {
+ if (!build && (out = open (drft, O_RDONLY)) != NOTOK) {
i = fdcompare (in, out);
close (out);
adios (drft, "unable to stat");
printf ("Draft \"%s\" exists (%ld bytes).", drft, (long) st.st_size);
for (i = LISTDSW; i != YESW;) {
- if (!(argp = getans ("\nDisposition? ", isdf ? aqrunl : aqrul)))
+ if (!(argp = read_switch_multiword ("\nDisposition? ",
+ isdf ? aqrunl : aqrul)))
done (1);
switch (i = smatch (*argp, isdf ? aqrunl : aqrul)) {
case NOSW:
if ((out = creat (drft, m_gmprot ())) == NOTOK)
adios (drft, "unable to create");
- cpydata (in, out, form, drft);
- close (in);
+ if (cp) {
+ charstring_t scanl;
+
+ i = format_len + 1024;
+ scanl = charstring_create (i + 2);
+ dat[0] = 0;
+ dat[1] = 0;
+ dat[2] = 0;
+ dat[3] = outputlinelen;
+ dat[4] = 0;
+ fmt_scan(fmt, scanl, i, dat, NULL);
+ if (write(out, charstring_buffer (scanl),
+ charstring_bytes (scanl)) < 0) {
+ advise (drft, "write");
+ }
+ charstring_free(scanl);
+ } else {
+ cpydata (in, out, form, drft);
+ close (in);
+ }
close (out);
edit_it:
if (nwhat)
done (0);
- what_now (ed, nedit, use, drft, NULL, 0, NULLMP, NULL, 0, cwd);
- return done (1);
+ what_now (ed, nedit, use, drft, NULL, 0, NULLMP, NULL, 0, cwd, 0);
+ done (1);
+ return 1;
}