X-Git-Url: http://git.marmaro.de/?a=blobdiff_plain;f=uip%2Fwhatnowsbr.c;h=7b637628b374a26969cfd1a0e6a46df049f68a55;hb=2d3d6cb7011b7fe432ffda2889e1f27860c49f37;hp=72e9d1ffdd288bcaa2d8581fdf1888ce355db06c;hpb=51c505fd1a7488d62088d5268ae1f8a5bc885b19;p=mmh diff --git a/uip/whatnowsbr.c b/uip/whatnowsbr.c index 72e9d1f..7b63762 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. @@ -65,6 +63,8 @@ static struct swit whatnowswitches[] = { { "help", 0 }, #define ATTACHSW 8 { "attach header-field-name", 0 }, +#define NOATTACHSW 9 + { "noattach", 0 }, { NULL, 0 } }; @@ -120,7 +120,11 @@ static int buildfile (char **, char *); static int check_draft (char *); static int whomfile (char **, char *); static int removefile (char *); -static void writelscmd(char *, int, char *, char **); +static void writelscmd(char *, int, 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 *); @@ -136,7 +140,7 @@ WhatNow (int argc, char **argv) char buf[BUFSIZ], prompt[BUFSIZ]; char **argp, **arguments; struct stat st; - char *attach = (char *)0; /* attachment header field name */ + char *attach = NMH_ATTACH_HEADER;/* 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 */ @@ -211,11 +215,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) @@ -320,16 +326,13 @@ WhatNow (int argc, char **argv) * is accustomed to. Read back the absolute path. */ - if (*++argp == (char *)0) { + if (*(argp+1) == (char *)0) { (void)sprintf(buf, "$SHELL -c \"cd;pwd\""); } - else if (strlen(*argp) >= BUFSIZ) { - adios((char *)0, "arguments too long"); - } 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 +357,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 +413,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), argp); /* * Read back the response from the shell, which contains a number of lines @@ -424,7 +432,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 +507,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), 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,40 +534,96 @@ 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) + 3; + 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++ = ';'; + strcpy(cp, trailcmd); + cp += trailln - 3; + } *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 **argp) +{ + writesomecmd(buf, bufsz, "ls", "", argp); +} + +/* 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; + 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; + 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 */ @@ -593,10 +641,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? */ @@ -626,20 +671,11 @@ 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); #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; @@ -652,7 +688,7 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp, context_save (); /* save the context file */ fflush (stdout); - switch (pid = vfork ()) { + switch (pid = vfork()) { case NOTOK: advise ("fork", "unable to"); status = NOTOK; @@ -682,13 +718,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 +729,6 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp, } status = -2; /* maybe "reedit ? -2 : -1"? */ break; -#ifdef ATTVIBUG - } -#endif } reedit++; @@ -939,6 +965,12 @@ check_draft (char *msgnam) # define SASLminc(a) 0 #endif /* CYRUS_SASL */ +#ifndef TLS_SUPPORT +# define TLSminc(a) (a) +#else /* TLS_SUPPORT */ +# define TLSminc(a) 0 +#endif /* TLS_SUPPORT */ + static struct swit sendswitches[] = { #define ALIASW 0 { "alias aliasfile", 0 }, @@ -1003,7 +1035,7 @@ static struct swit sendswitches[] = { #define CLIESW 30 { "client host", -6 }, #define SERVSW 31 - { "server host", -6 }, + { "server host", 6 }, #define SNOOPSW 32 { "snoop", -5 }, #define SDRFSW 33 @@ -1014,14 +1046,26 @@ static struct swit sendswitches[] = { { "nodraftfolder", -3 }, #define SASLSW 36 { "sasl", SASLminc(-4) }, -#define SASLMECHSW 37 +#define NOSASLSW 37 + { "nosasl", SASLminc(-6) }, +#define SASLMXSSFSW 38 + { "saslmaxssf", SASLminc(-10) }, +#define SASLMECHSW 39 { "saslmech", SASLminc(-5) }, -#define USERSW 38 +#define USERSW 40 { "user", SASLminc(-4) }, -#define SNDATTACHSW 39 +#define SNDATTACHSW 41 { "attach file", 6 }, -#define SNDATTACHFORMAT 40 +#define SNDNOATTACHSW 42 + { "noattach", 0 }, +#define SNDATTACHFORMAT 43 { "attachformat", 7 }, +#define PORTSW 44 + { "port server-port-name/number", 4 }, +#define TLSSW 45 + { "tls", TLSminc(-3) }, +#define NTLSSW 46 + { "notls", TLSminc(-5) }, { NULL, 0 } }; @@ -1046,16 +1090,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 +1144,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 +1227,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 +1238,10 @@ sendit (char *sp, char **arg, char *file, int pushed) case WIDTHSW: case CLIESW: case SERVSW: + case SASLMXSSFSW: case SASLMECHSW: case USERSW: + case PORTSW: vec[vecp++] = --cp; if (!(cp = *argp++) || *cp == '-') { advise (NULL, "missing argument to %s", argp[-2]); @@ -1209,6 +1265,9 @@ sendit (char *sp, char **arg, char *file, int pushed) return; } continue; + case SNDNOATTACHSW: + attach = NULL; + continue; case SNDATTACHFORMAT: if (! *argp || **argp == '-') @@ -1244,18 +1303,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 +1318,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 +1355,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;