X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/51c505fd1a7488d62088d5268ae1f8a5bc885b19..c4c53777458bfcfd288d45b7708e52eb47c56405:/uip/whatnowsbr.c?ds=inline diff --git a/uip/whatnowsbr.c b/uip/whatnowsbr.c index 72e9d1ff..9a9fec1b 100644 --- a/uip/whatnowsbr.c +++ b/uip/whatnowsbr.c @@ -2,8 +2,6 @@ /* * whatnowsbr.c -- the WhatNow shell * - * $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. @@ -46,66 +44,54 @@ #include #include -static struct swit whatnowswitches[] = { -#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 PRMPTSW 5 - { "prompt string", 4 }, -#define VERSIONSW 6 - { "version", 0 }, -#define HELPSW 7 - { "help", 0 }, -#define ATTACHSW 8 - { "attach header-field-name", 0 }, - { NULL, 0 } -}; +#define WHATNOW_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("prompt string", 4, PRMPTSW) \ + X("version", 0, VERSIONSW) \ + X("help", 0, HELPSW) \ + X("attach header-field-name", 0, ATTACHSW) \ + X("noattach", 0, NOATTACHSW) \ + +#define X(sw, minchars, id) id, +DEFINE_SWITCH_ENUM(WHATNOW); +#undef X + +#define X(sw, minchars, id) { sw, minchars, id }, +DEFINE_SWITCH_ARRAY(WHATNOW, whatnowswitches); +#undef X /* * Options at the "whatnow" prompt */ -static struct swit aleqs[] = { -#define EDITSW 0 - { "edit [ ]", 0 }, -#define REFILEOPT 1 - { "refile [] +folder", 0 }, -#define BUILDMIMESW 2 - { "mime []", 0 }, -#define DISPSW 3 - { "display []", 0 }, -#define LISTSW 4 - { "list []", 0 }, -#define SENDSW 5 - { "send []", 0 }, -#define PUSHSW 6 - { "push []", 0 }, -#define WHOMSW 7 - { "whom []", 0 }, -#define QUITSW 8 - { "quit [-delete]", 0 }, -#define DELETESW 9 - { "delete", 0 }, -#define CDCMDSW 10 - { "cd [directory]", 0 }, -#define PWDCMDSW 11 - { "pwd", 0 }, -#define LSCMDSW 12 - { "ls", 0 }, -#define ATTACHCMDSW 13 - { "attach", 0 }, -#define DETACHCMDSW 14 - { "detach [-n]", 2 }, -#define ALISTCMDSW 15 - { "alist [-ln] ", 2 }, - { NULL, 0 } -}; +#define PROMPT_SWITCHES \ + X("edit [ ]", 0, EDITSW) \ + X("refile [] +folder", 0, REFILEOPT) \ + X("mime []", 0, BUILDMIMESW) \ + X("display []", 0, DISPSW) \ + X("list []", 0, LISTSW) \ + X("send []", 0, SENDSW) \ + X("push []", 0, PUSHSW) \ + X("whom []", 0, WHOMSW) \ + X("quit [-delete]", 0, QUITSW) \ + X("delete", 0, DELETESW) \ + X("cd [directory]", 0, CDCMDSW) \ + X("pwd", 0, PWDCMDSW) \ + X("ls", 2, LSCMDSW) \ + X("attach", 0, ATTACHCMDSW) \ + X("detach [-n]", 2, DETACHCMDSW) \ + X("alist [-ln] ", 2, ALISTCMDSW) \ + +#define X(sw, minchars, id) id, +DEFINE_SWITCH_ENUM(PROMPT); +#undef X + +#define X(sw, minchars, id) { sw, minchars, id }, +DEFINE_SWITCH_ARRAY(PROMPT, aleqs); +#undef X static char *myprompt = "\nWhat now? "; @@ -113,7 +99,7 @@ static char *myprompt = "\nWhat now? "; * static prototypes */ static int editfile (char **, char **, char *, int, struct msgs *, - char *, char *, int); + char *, char *, int, int); static int sendfile (char **, char *, int); static void sendit (char *, char **, char *, int); static int buildfile (char **, char *); @@ -121,6 +107,10 @@ static int check_draft (char *); static int whomfile (char **, char *); static int removefile (char *); static void writelscmd(char *, int, char *, char **); +static void writesomecmd(char *buf, int bufsz, char *cmd, char *trailcmd, char **argp); +static FILE* popen_in_dir(const char *dir, const char *cmd, const char *type); +static int system_in_dir(const char *dir, const char *cmd); + #ifdef HAVE_LSTAT static int copyf (char *, char *); @@ -130,16 +120,16 @@ static int copyf (char *, char *); int WhatNow (int argc, char **argv) { - int isdf = 0, nedit = 0, use = 0; + int isdf = 0, nedit = 0, use = 0, atfile = 1; char *cp, *dfolder = NULL, *dmsg = NULL; char *ed = NULL, *drft = NULL, *msgnam = NULL; char buf[BUFSIZ], prompt[BUFSIZ]; char **argp, **arguments; struct stat st; - char *attach = (char *)0; /* attachment header field name */ - char cwd[MAXPATHLEN + 1]; /* current working directory */ - char file[MAXPATHLEN + 1]; /* file name buffer */ - char shell[MAXPATHLEN + 1]; /* shell response buffer */ + char *attach = NMH_ATTACH_HEADER;/* attachment header field name */ + char cwd[PATH_MAX + 1]; /* current working directory */ + char file[PATH_MAX + 1]; /* file name buffer */ + char shell[PATH_MAX + 1]; /* shell response buffer */ FILE *f; /* read pointer for bgnd proc */ char *l; /* set on -l to alist command */ int n; /* set on -n to alist command */ @@ -172,10 +162,10 @@ WhatNow (int argc, char **argv) case HELPSW: snprintf (buf, sizeof(buf), "%s [switches] [file]", invo_name); print_help (buf, whatnowswitches, 1); - done (1); + done (0); case VERSIONSW: print_version(invo_name); - done (1); + done (0); case DFOLDSW: if (dfolder) @@ -211,11 +201,13 @@ WhatNow (int argc, char **argv) continue; case ATTACHSW: - if (attach != (char *)0) - adios(NULL, "only one attachment header field name at a time!"); if (!(attach = *argp++) || *attach == '-') adios (NULL, "missing argument to %s", argp[-2]); continue; + + case NOATTACHSW: + attach = NULL; + continue; } } if (drft) @@ -229,6 +221,9 @@ WhatNow (int argc, char **argv) msgnam = (cp = getenv ("mhaltmsg")) && *cp ? getcpy (cp) : NULL; + if ((cp = getenv ("mhatfile")) && *cp) + atfile = atoi(cp); + if ((cp = getenv ("mhuse")) && *cp) use = atoi (cp); @@ -238,12 +233,17 @@ WhatNow (int argc, char **argv) } /* start editing the draft, unless -noedit was given */ - if (!nedit && editfile (&ed, NULL, drft, use, NULL, msgnam, NULL, 1) < 0) + if (!nedit && editfile (&ed, NULL, drft, use, NULL, msgnam, + NULL, 1, atfile) < 0) done (1); snprintf (prompt, sizeof(prompt), myprompt, invo_name); for (;;) { +#ifdef READLINE_SUPPORT + if (!(argp = getans_via_readline (prompt, aleqs))) { +#else /* ! READLINE_SUPPORT */ if (!(argp = getans (prompt, aleqs))) { +#endif /* READLINE_SUPPORT */ unlink (LINK); done (1); } @@ -265,7 +265,8 @@ WhatNow (int argc, char **argv) /* Call an editor on the draft file */ if (*++argp) ed = *argp++; - if (editfile (&ed, argp, drft, NOUSE, NULL, msgnam, NULL, 1) == NOTOK) + if (editfile (&ed, argp, drft, NOUSE, NULL, msgnam, + NULL, 1, atfile) == NOTOK) done (1); break; @@ -320,16 +321,13 @@ WhatNow (int argc, char **argv) * is accustomed to. Read back the absolute path. */ - if (*++argp == (char *)0) { - (void)sprintf(buf, "$SHELL -c \"cd;pwd\""); - } - else if (strlen(*argp) >= BUFSIZ) { - adios((char *)0, "arguments too long"); + if (*(argp+1) == (char *)0) { + (void)sprintf(buf, "$SHELL -c \"cd&&pwd\""); } else { - (void)sprintf(buf, "$SHELL -c \"cd %s;cd %s;pwd\"", cwd, *argp); + writesomecmd(buf, BUFSIZ, "cd", "pwd", argp); } - if ((f = popen(buf, "r")) != (FILE *)0) { + if ((f = popen_in_dir(cwd, buf, "r")) != (FILE *)0) { fgets(cwd, sizeof (cwd), f); if (strchr(cwd, '\n') != (char *)0) @@ -354,8 +352,8 @@ WhatNow (int argc, char **argv) * Use the user's shell so that we can take advantage of any * syntax that the user is accustomed to. */ - writelscmd(buf, sizeof(buf), cwd, argp); - (void)system(buf); + writelscmd(buf, sizeof(buf), "", argp); + (void)system_in_dir(cwd, buf); break; case ALISTCMDSW: @@ -410,11 +408,16 @@ WhatNow (int argc, char **argv) break; } + if (*(argp+1) == (char *)0) { + advise((char *)0, "attach command requires file argument(s)."); + break; + } + /* * Build a command line that causes the user's shell to list the file name * arguments. This handles and wildcard expansion, tilde expansion, etc. */ - writelscmd(buf, sizeof(buf), cwd, argp); + writelscmd(buf, sizeof(buf), "-d", argp); /* * Read back the response from the shell, which contains a number of lines @@ -424,7 +427,7 @@ WhatNow (int argc, char **argv) * draft. */ - if ((f = popen(buf, "r")) != (FILE *)0) { + if ((f = popen_in_dir(cwd, buf, "r")) != (FILE *)0) { while (fgets(shell, sizeof (shell), f) != (char *)0) { *(strchr(shell, '\n')) = '\0'; @@ -499,35 +502,19 @@ WhatNow (int argc, char **argv) * user's shell for wildcard expansion and other goodies. Do this from * the current working directory if the argument is not an absolute path * name (does not begin with a /). + * + * We feed all the file names to the shell at once, otherwise you can't + * provide a file name with a space in it. */ - - else { - for (arguments = argp + 1; *arguments != (char *)0; arguments++) { - if (**arguments == '/') { - if (strlen(*arguments) + sizeof ("$SHELL -c \"ls \"") >= sizeof (buf)) - adios((char *)0, "arguments too long"); - - (void)sprintf(buf, "$SHELL -c \"ls %s\"", *arguments); - } - else { - if (strlen(cwd) + strlen(*arguments) + sizeof ("$SHELL -c \" cd ; ls \"") >= sizeof (buf)) - adios((char *)0, "arguments too long"); - - (void)sprintf(buf, "$SHELL -c \" cd %s;ls %s\"", cwd, *arguments); - } - - if ((f = popen(buf, "r")) != (FILE *)0) { - while (fgets(shell, sizeof (cwd), f) != (char *)0) { - *(strchr(shell, '\n')) = '\0'; - (void)annotate(drft, attach, shell, 1, 0, 0, 1); - } - - pclose(f); - } - else { - advise("popen", "could not get file from shell"); - } + writelscmd(buf, sizeof(buf), "-d", argp); + if ((f = popen_in_dir(cwd, buf, "r")) != (FILE *)0) { + while (fgets(shell, sizeof (shell), f) != (char *)0) { + *(strchr(shell, '\n')) = '\0'; + (void)annotate(drft, attach, shell, 1, 0, 0, 1); } + pclose(f); + } else { + advise("popen", "could not get file from shell"); } break; @@ -542,39 +529,107 @@ WhatNow (int argc, char **argv) } -/* - * Build a command line that causes the user's shell to list the file name - * arguments. This handles and wildcard expansion, tilde expansion, etc. - */ + +/* Build a command line of the form $SHELL -c "cd 'cwd'; cmd argp ... ; trailcmd". */ static void -writelscmd(char *buf, int bufsz, char *cwd, char **argp) +writesomecmd(char *buf, int bufsz, char *cmd, char *trailcmd, char **argp) { char *cp; - int ln = snprintf(buf, bufsz, "$SHELL -c \" cd %s;ls", cwd); + /* Note that we do not quote -- the argp from the user + * is assumed to be quoted as they desire. (We can't treat + * it as pure literal as that would prevent them using ~, + * wildcards, etc.) The buffer produced by this function + * should be given to popen_in_dir() or system_in_dir() so + * that the current working directory is set correctly. + */ + int ln = snprintf(buf, bufsz, "$SHELL -c \"%s", cmd); /* NB that some snprintf() return -1 on overflow rather than the * new C99 mandated 'number of chars that would have been written' */ /* length checks here and inside the loop allow for the - * trailing " and NUL + * trailing "&&", trailcmd, '"' and NUL */ - if (ln < 0 || ln + 2 > bufsz) + int trailln = strlen(trailcmd) + 4; + if (ln < 0 || ln + trailln > bufsz) adios((char *)0, "arguments too long"); cp = buf + ln; while (*++argp != (char *)0) { ln = strlen(*argp); - /* +3 for leading space and trailing quote and NUL */ - if (ln + 3 > bufsz - (cp-buf)) + /* +1 for leading space */ + if (ln + trailln + 1 > bufsz - (cp-buf)) adios((char *)0, "arguments too long"); *cp++ = ' '; memcpy(cp, *argp, ln+1); cp += ln; } + if (*trailcmd) { + *cp++ = '&'; *cp++ = '&'; + strcpy(cp, trailcmd); + cp += trailln - 4; + } *cp++ = '"'; *cp = 0; } +/* + * Build a command line that causes the user's shell to list the file name + * arguments. This handles and wildcard expansion, tilde expansion, etc. + */ +static void +writelscmd(char *buf, int bufsz, char *lsoptions, char **argp) +{ + char *lscmd = concat ("ls ", lsoptions, " --", NULL); + writesomecmd(buf, bufsz, lscmd, "", argp); + free (lscmd); +} + +/* Like system(), but run the command in directory dir. + * This assumes the program is single-threaded! + */ +static int +system_in_dir(const char *dir, const char *cmd) +{ + char olddir[BUFSIZ]; + int r; + + /* ensure that $SHELL exists, as the cmd was written relying on + a non-blank $SHELL... */ + setenv("SHELL","/bin/sh",0); /* don't overwrite */ + + if (getcwd(olddir, sizeof(olddir)) == 0) + adios("getcwd", "could not get working directory"); + if (chdir(dir) != 0) + adios("chdir", "could not change working directory"); + r = system(cmd); + if (chdir(olddir) != 0) + adios("chdir", "could not change working directory"); + return r; +} + +/* ditto for popen() */ +static FILE* +popen_in_dir(const char *dir, const char *cmd, const char *type) +{ + char olddir[BUFSIZ]; + FILE *f; + + /* ensure that $SHELL exists, as the cmd was written relying on + a non-blank $SHELL... */ + setenv("SHELL","/bin/sh",0); /* don't overwrite */ + + if (getcwd(olddir, sizeof(olddir)) == 0) + adios("getcwd", "could not get working directory"); + if (chdir(dir) != 0) + adios("chdir", "could not change working directory"); + f = popen(cmd, type); + if (chdir(olddir) != 0) + adios("chdir", "could not change working directory"); + return f; +} + + /* * EDIT */ @@ -585,7 +640,7 @@ static char *edsave = NULL; /* the editor we used previously */ static int editfile (char **ed, char **arg, char *file, int use, struct msgs *mp, - char *altmsg, char *cwd, int save_editor) + char *altmsg, char *cwd, int save_editor, int atfile) { int pid, status, vecp; char altpath[BUFSIZ], linkpath[BUFSIZ]; @@ -593,10 +648,7 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp, struct stat st; #ifdef HAVE_LSTAT - int slinked; -#if 0 - int oumask; /* PJS: for setting permissions on symlinks. */ -#endif + int slinked = 0; #endif /* HAVE_LSTAT */ /* Was there a previous edit session? */ @@ -613,8 +665,8 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp, } } else { /* set initial editor */ - if (*ed == NULL && (*ed = context_find ("editor")) == NULL) - *ed = defaulteditor; + if (*ed == NULL) + *ed = get_default_editor(); } if (altmsg) { @@ -626,33 +678,26 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp, strncpy (linkpath, LINK, sizeof(linkpath)); else snprintf (linkpath, sizeof(linkpath), "%s/%s", cwd, LINK); - } - if (altmsg) { - unlink (linkpath); + if (atfile) { + unlink (linkpath); #ifdef HAVE_LSTAT - if (link (altpath, linkpath) == NOTOK) { -#if 0 - /* I don't think permission on symlinks matters /JLR */ - oumask = umask(0044); /* PJS: else symlinks are world 'r' */ -#endif - symlink (altpath, linkpath); -#if 0 - umask(oumask); /* PJS: else symlinks are world 'r' */ -#endif - slinked = 1; - } else { - slinked = 0; - } + if (link (altpath, linkpath) == NOTOK) { + symlink (altpath, linkpath); + slinked = 1; + } else { + slinked = 0; + } #else /* not HAVE_LSTAT */ - link (altpath, linkpath); + link (altpath, linkpath); #endif /* not HAVE_LSTAT */ + } } context_save (); /* save the context file */ fflush (stdout); - switch (pid = vfork ()) { + switch (pid = vfork()) { case NOTOK: advise ("fork", "unable to"); status = NOTOK; @@ -682,13 +727,6 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp, default: if ((status = pidwait (pid, NOTOK))) { -#ifdef ATTVIBUG - if ((cp = r1bindex (*ed, '/')) - && strcmp (cp, "vi") == 0 - && (status & 0x00ff) == 0) - status = 0; - else { -#endif if (((status & 0xff00) != 0xff00) && (!reedit || (status & 0x00ff))) { if (!use && (status & 0xff00) && @@ -700,9 +738,6 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp, } status = -2; /* maybe "reedit ? -2 : -1"? */ break; -#ifdef ATTVIBUG - } -#endif } reedit++; @@ -736,7 +771,7 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp, edsave = getcpy (*ed); *ed = NULL; - if (altmsg) + if (altmsg && atfile) unlink (linkpath); return status; @@ -786,16 +821,14 @@ sendfile (char **arg, char *file, int pushsw) /* Translate MIME composition file, if necessary */ if ((cp = context_find ("automimeproc")) && (!strcmp (cp, "1")) - && !getenv ("NOMHNPROC") && check_draft (file) && (buildfile (NULL, file) == NOTOK)) return 0; /* For backwards compatibility */ if ((cp = context_find ("automhnproc")) - && !getenv ("NOMHNPROC") && check_draft (file) - && (i = editfile (&cp, NULL, file, NOUSE, NULL, NULL, NULL, 0))) + && (i = editfile (&cp, NULL, file, NOUSE, NULL, NULL, NULL, 0, 0))) return 0; /* @@ -874,7 +907,7 @@ buildfile (char **argp, char *file) args[i++] = *argp++; args[i] = NULL; - i = editfile (&ed, args, file, NOUSE, NULL, NULL, NULL, 0); + i = editfile (&ed, args, file, NOUSE, NULL, NULL, NULL, 0, 0); free (args); return (i ? NOTOK : OK); @@ -939,91 +972,70 @@ check_draft (char *msgnam) # define SASLminc(a) 0 #endif /* CYRUS_SASL */ -static struct swit sendswitches[] = { -#define ALIASW 0 - { "alias aliasfile", 0 }, -#define DEBUGSW 1 - { "debug", -5 }, -#define FILTSW 2 - { "filter filterfile", 0 }, -#define NFILTSW 3 - { "nofilter", 0 }, -#define FRMTSW 4 - { "format", 0 }, -#define NFRMTSW 5 - { "noformat", 0 }, -#define FORWSW 6 - { "forward", 0 }, -#define NFORWSW 7 - { "noforward", 0 }, -#define MIMESW 8 - { "mime", 0 }, -#define NMIMESW 9 - { "nomime", 0 }, -#define MSGDSW 10 - { "msgid", 0 }, -#define NMSGDSW 11 - { "nomsgid", 0 }, -#define SPSHSW 12 - { "push", 0 }, -#define NSPSHSW 13 - { "nopush", 0 }, -#define SPLITSW 14 - { "split seconds", 0 }, -#define UNIQSW 15 - { "unique", -6 }, -#define NUNIQSW 16 - { "nounique", -8 }, -#define VERBSW 17 - { "verbose", 0 }, -#define NVERBSW 18 - { "noverbose", 0 }, -#define WATCSW 19 - { "watch", 0 }, -#define NWATCSW 20 - { "nowatch", 0 }, -#define WIDTHSW 21 - { "width columns", 0 }, -#define SVERSIONSW 22 - { "version", 0 }, -#define SHELPSW 23 - { "help", 0 }, -#define BITSTUFFSW 24 - { "dashstuffing", -12 }, -#define NBITSTUFFSW 25 - { "nodashstuffing", -14 }, -#define MAILSW 26 - { "mail", -4 }, -#define SAMLSW 27 - { "saml", -4 }, -#define SSNDSW 28 - { "send", -4 }, -#define SOMLSW 29 - { "soml", -4 }, -#define CLIESW 30 - { "client host", -6 }, -#define SERVSW 31 - { "server host", -6 }, -#define SNOOPSW 32 - { "snoop", -5 }, -#define SDRFSW 33 - { "draftfolder +folder", -6 }, -#define SDRMSW 34 - { "draftmessage msg", -6 }, -#define SNDRFSW 35 - { "nodraftfolder", -3 }, -#define SASLSW 36 - { "sasl", SASLminc(-4) }, -#define SASLMECHSW 37 - { "saslmech", SASLminc(-5) }, -#define USERSW 38 - { "user", SASLminc(-4) }, -#define SNDATTACHSW 39 - { "attach file", 6 }, -#define SNDATTACHFORMAT 40 - { "attachformat", 7 }, - { NULL, 0 } -}; +#ifndef TLS_SUPPORT +# define TLSminc(a) (a) +#else /* TLS_SUPPORT */ +# define TLSminc(a) 0 +#endif /* TLS_SUPPORT */ + +#define SEND_SWITCHES \ + X("alias aliasfile", 0, ALIASW) \ + X("debug", -5, DEBUGSW) \ + X("filter filterfile", 0, FILTSW) \ + X("nofilter", 0, NFILTSW) \ + X("format", 0, FRMTSW) \ + X("noformat", 0, NFRMTSW) \ + X("forward", 0, FORWSW) \ + X("noforward", 0, NFORWSW) \ + X("mime", 0, MIMESW) \ + X("nomime", 0, NMIMESW) \ + X("msgid", 0, MSGDSW) \ + X("nomsgid", 0, NMSGDSW) \ + X("push", 0, SPSHSW) \ + X("nopush", 0, NSPSHSW) \ + X("split seconds", 0, SPLITSW) \ + X("unique", -6, UNIQSW) \ + X("nounique", -8, NUNIQSW) \ + X("verbose", 0, VERBSW) \ + X("noverbose", 0, NVERBSW) \ + X("watch", 0, WATCSW) \ + X("nowatch", 0, NWATCSW) \ + X("width columns", 0, WIDTHSW) \ + X("version", 0, SVERSIONSW) \ + X("help", 0, SHELPSW) \ + X("dashstuffing", -12, BITSTUFFSW) \ + X("nodashstuffing", -14, NBITSTUFFSW) \ + X("mail", -4, MAILSW) \ + X("saml", -4, SAMLSW) \ + X("send", -4, SSNDSW) \ + X("soml", -4, SOMLSW) \ + X("client host", -6, CLIESW) \ + X("server host", 6, SERVSW) \ + X("snoop", -5, SNOOPSW) \ + X("draftfolder +folder", -6, SDRFSW) \ + X("draftmessage msg", -6, SDRMSW) \ + X("nodraftfolder", -3, SNDRFSW) \ + X("sasl", SASLminc(-4), SASLSW) \ + X("nosasl", SASLminc(-6), NOSASLSW) \ + X("saslmaxssf", SASLminc(-10), SASLMXSSFSW) \ + X("saslmech", SASLminc(-5), SASLMECHSW) \ + X("user", SASLminc(-4), USERSW) \ + X("attach file", 6, SNDATTACHSW) \ + X("noattach", 0, SNDNOATTACHSW) \ + X("attachformat", 7, SNDATTACHFORMAT) \ + X("port server-port-name/number", 4, PORTSW) \ + X("tls", TLSminc(-3), TLSSW) \ + X("notls", TLSminc(-5), NTLSSW) \ + X("mts smtp|sendmail/smtp|sendmail/pipe", 2, MTSSW) \ + X("messageid localname|random", 2, MESSAGEIDSW) \ + +#define X(sw, minchars, id) id, +DEFINE_SWITCH_ENUM(SEND); +#undef X + +#define X(sw, minchars, id) { sw, minchars, id }, +DEFINE_SWITCH_ARRAY(SEND, sendswitches); +#undef X extern int debugsw; /* from sendsbr.c */ @@ -1046,16 +1058,13 @@ sendit (char *sp, char **arg, char *file, int pushed) char *cp, buf[BUFSIZ], **argp; char **arguments, *vec[MAXARGS]; struct stat st; - char *attach = (char *)0; /* attachment header field name */ - int attachformat = 0; /* mhbuild format specifier for + char *attach = NMH_ATTACH_HEADER;/* attachment header field name */ + int attachformat = 1; /* mhbuild format specifier for attachments */ #ifndef lint int distsw = 0; #endif -#ifdef UCI - FILE *fp; -#endif /* * Make sure these are defined. In particular, we need @@ -1103,6 +1112,16 @@ sendit (char *sp, char **arg, char *file, int pushed) vec[vecp++] = "-library"; vec[vecp++] = getcpy (m_maildir ("")); + if ((cp = context_find ("fileproc"))) { + vec[vecp++] = "-fileproc"; + vec[vecp++] = cp; + } + + if ((cp = context_find ("mhlproc"))) { + vec[vecp++] = "-mhlproc"; + vec[vecp++] = cp; + } + while ((cp = *argp++)) { if (*cp == '-') { switch (smatch (++cp, sendswitches)) { @@ -1176,6 +1195,9 @@ sendit (char *sp, char **arg, char *file, int pushed) case SOMLSW: case SNOOPSW: case SASLSW: + case NOSASLSW: + case TLSSW: + case NTLSSW: vec[vecp++] = --cp; continue; @@ -1184,8 +1206,12 @@ sendit (char *sp, char **arg, char *file, int pushed) case WIDTHSW: case CLIESW: case SERVSW: + case SASLMXSSFSW: case SASLMECHSW: case USERSW: + case PORTSW: + case MTSSW: + case MESSAGEIDSW: vec[vecp++] = --cp; if (!(cp = *argp++) || *cp == '-') { advise (NULL, "missing argument to %s", argp[-2]); @@ -1209,6 +1235,9 @@ sendit (char *sp, char **arg, char *file, int pushed) return; } continue; + case SNDNOATTACHSW: + attach = NULL; + continue; case SNDATTACHFORMAT: if (! *argp || **argp == '-') @@ -1244,18 +1273,6 @@ sendit (char *sp, char **arg, char *file, int pushed) if ((cp = getenv ("SIGNATURE")) == NULL || *cp == 0) if ((cp = context_find ("signature")) && *cp) m_putenv ("SIGNATURE", cp); -#ifdef UCI - else { - snprintf (buf, sizeof(buf), "%s/.signature", mypath); - if ((fp = fopen (buf, "r")) != NULL - && fgets (buf, sizeof(buf), fp) != NULL) { - fclose (fp); - if (cp = strchr (buf, '\n')) - *cp = 0; - m_putenv ("SIGNATURE", buf); - } - } -#endif /* UCI */ if ((annotext = getenv ("mhannotate")) == NULL || *annotext == 0) annotext = NULL; @@ -1271,7 +1288,8 @@ sendit (char *sp, char **arg, char *file, int pushed) #endif /* not lint */ && altmsg) { vec[vecp++] = "-dist"; - distfile = getcpy (m_scratch (altmsg, invo_name)); + distfile = getcpy (m_mktemp2(altmsg, invo_name, NULL, NULL)); + unlink(distfile); if (link (altmsg, distfile) == NOTOK) adios (distfile, "unable to link %s to", altmsg); } else { @@ -1307,7 +1325,7 @@ whomfile (char **arg, char *file) context_save (); /* save the context file */ fflush (stdout); - switch (pid = vfork ()) { + switch (pid = vfork()) { case NOTOK: advise ("fork", "unable to"); return 1;