X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/de4636bb664106d9932ae7acb517e471b848f1f3..0c50c669:/uip/whatnowsbr.c diff --git a/uip/whatnowsbr.c b/uip/whatnowsbr.c index 86ff81df..82b0d67f 100644 --- a/uip/whatnowsbr.c +++ b/uip/whatnowsbr.c @@ -26,8 +26,12 @@ * pwd command and exists to allow the user * to verify the directory. * - * attach files This option attaches the named files to - * the draft. + * attach [-v [-a 0|1|2]] files + * This option attaches the named files to + * the draft. -v displays the mhbuild + * directive, using the optionally specified + * attachformat [-a] if that is also provided + * to send(1). * * alist [-ln] This option lists the attachments on the * draft. -l gets long listings, -n gets @@ -40,7 +44,6 @@ #include #include -#include #include #include @@ -81,8 +84,8 @@ DEFINE_SWITCH_ARRAY(WHATNOW, whatnowswitches); X("cd [directory]", 0, CDCMDSW) \ X("pwd", 0, PWDCMDSW) \ X("ls", 2, LSCMDSW) \ - X("attach", 0, ATTACHCMDSW) \ - X("detach [-n]", 2, DETACHCMDSW) \ + X("attach [-v [-a 0|1|2]]", 0, ATTACHCMDSW) \ + X("detach [-n]", 0, DETACHCMDSW) \ X("alist [-ln] ", 2, ALISTCMDSW) \ #define X(sw, minchars, id) id, @@ -110,11 +113,7 @@ 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 *); -#endif int @@ -398,18 +397,47 @@ WhatNow (int argc, char **argv) break; - case ATTACHCMDSW: + case ATTACHCMDSW: { /* * Attach files to current draft. */ + int verbose = 0; + int attachformat = 1; + char **ap; + if (attach == (char *)0) { advise((char *)0, "can't attach because no header field name was given."); break; } + for (ap = argp+1; *ap; ++ap) { + if (strcmp(*ap, "-v") == 0) { + ++argp; + verbose = 1; + } else if (strcmp(*ap, "-a") == 0) { + ++argp; + if (*(ap+1) == NULL || + ! isdigit ((unsigned char) *(ap+1)[0])) { + advise(NULL, + "ignoring attach -a without format argument."); + } else { + ++argp; + ++ap; + if ((attachformat = atoi(*ap)) > 2) { + advise(NULL, + "ignoring invalid attachformat value of %d", + attachformat); + attachformat = 1; + } + } + } else if (*ap[0] != '-') { + break; + } + } + if (*(argp+1) == (char *)0) { - advise((char *)0, "attach command requires file argument(s)."); + advise(NULL, "attach command requires file argument(s)."); break; } @@ -417,7 +445,7 @@ 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. */ - writelscmd(buf, sizeof(buf), "-d", argp); + writelscmd(buf, sizeof(buf), "-d --", argp); /* * Read back the response from the shell, which contains a number of lines @@ -429,13 +457,30 @@ WhatNow (int argc, char **argv) if ((f = popen_in_dir(cwd, buf, "r")) != (FILE *)0) { while (fgets(shell, sizeof (shell), f) != (char *)0) { + char *build_directive; + *(strchr(shell, '\n')) = '\0'; - if (*shell == '/') + if (*shell == '/') { (void)annotate(drft, attach, shell, 1, 0, -2, 1); - else { + if (verbose) { + build_directive = + construct_build_directive (shell, NULL, + attachformat); + } + } else { (void)sprintf(file, "%s/%s", cwd, shell); (void)annotate(drft, attach, file, 1, 0, -2, 1); + if (verbose) { + build_directive = + construct_build_directive (file, NULL, + attachformat); + } + } + + if (verbose) { + printf ("%s", build_directive); + free (build_directive); } } @@ -446,7 +491,7 @@ WhatNow (int argc, char **argv) } break; - + } case DETACHCMDSW: /* * Detach files from current draft. @@ -506,7 +551,7 @@ WhatNow (int argc, char **argv) * We feed all the file names to the shell at once, otherwise you can't * provide a file name with a space in it. */ - writelscmd(buf, sizeof(buf), "-d", argp); + 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'; @@ -552,10 +597,10 @@ writesomecmd(char *buf, int bufsz, char *cmd, char *trailcmd, char **argp) int trailln = strlen(trailcmd) + 4; if (ln < 0 || ln + trailln > bufsz) adios((char *)0, "arguments too long"); - + cp = buf + ln; - - while (*++argp != (char *)0) { + + while (*argp && *++argp) { ln = strlen(*argp); /* +1 for leading space */ if (ln + trailln + 1 > bufsz - (cp-buf)) @@ -580,7 +625,7 @@ writesomecmd(char *buf, int bufsz, char *cmd, char *trailcmd, char **argp) static void writelscmd(char *buf, int bufsz, char *lsoptions, char **argp) { - char *lscmd = concat ("ls ", lsoptions, " --", NULL); + char *lscmd = concat ("ls ", lsoptions, NULL); writesomecmd(buf, bufsz, lscmd, "", argp); free (lscmd); } @@ -618,7 +663,7 @@ popen_in_dir(const char *dir, const char *cmd, const char *type) /* 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) @@ -644,12 +689,10 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp, { int pid, status, vecp; char altpath[BUFSIZ], linkpath[BUFSIZ]; - char *cp, *vec[MAXARGS]; + char *cp, *prog, **vec; struct stat st; -#ifdef HAVE_LSTAT int slinked = 0; -#endif /* HAVE_LSTAT */ /* Was there a previous edit session? */ if (reedit) { @@ -665,8 +708,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) { @@ -681,23 +724,19 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp, if (atfile) { unlink (linkpath); -#ifdef HAVE_LSTAT if (link (altpath, linkpath) == NOTOK) { symlink (altpath, linkpath); slinked = 1; } else { slinked = 0; } -#else /* not HAVE_LSTAT */ - link (altpath, linkpath); -#endif /* not HAVE_LSTAT */ } } context_save (); /* save the context file */ fflush (stdout); - switch (pid = vfork()) { + switch (pid = fork()) { case NOTOK: advise ("fork", "unable to"); status = NOTOK; @@ -712,15 +751,15 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp, m_putenv ("editalt", altpath); } - vecp = 0; - vec[vecp++] = r1bindex (*ed, '/'); + vec = argsplit(*ed, &prog, &vecp); + if (arg) while (*arg) vec[vecp++] = *arg++; vec[vecp++] = file; vec[vecp] = NULL; - execvp (*ed, vec); + execvp (prog, vec); fprintf (stderr, "unable to exec "); perror (*ed); _exit (-1); @@ -741,7 +780,6 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp, } reedit++; -#ifdef HAVE_LSTAT if (altmsg && mp && !is_readonly(mp) @@ -754,16 +792,6 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp, && (unlink (altpath) == NOTOK || link (linkpath, altpath) == NOTOK))) advise (linkpath, "unable to update %s from", altmsg); -#else /* HAVE_LSTAT */ - if (altmsg - && mp - && !is_readonly(mp) - && stat (linkpath, &st) != NOTOK - && st.st_nlink == 1 - && (unlink (altpath) == NOTOK - || link (linkpath, altpath) == NOTOK)) - advise (linkpath, "unable to update %s from", altmsg); -#endif /* HAVE_LSTAT */ } /* normally, we remember which editor we used */ @@ -778,7 +806,6 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp, } -#ifdef HAVE_LSTAT static int copyf (char *ifile, char *ofile) { @@ -804,7 +831,6 @@ copyf (char *ifile, char *ofile) close (out); return i; } -#endif /* HAVE_LSTAT */ /* @@ -816,7 +842,7 @@ sendfile (char **arg, char *file, int pushsw) { pid_t child_id; int i, vecp; - char *cp, *sp, *vec[MAXARGS]; + char *cp, *sp, **vec, *program; /* Translate MIME composition file, if necessary */ if ((cp = context_find ("automimeproc")) @@ -845,14 +871,13 @@ sendfile (char **arg, char *file, int pushsw) context_save (); /* save the context file */ fflush (stdout); - for (i = 0; (child_id = vfork()) == NOTOK && i < 5; i++) + for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++) sleep (5); switch (child_id) { case NOTOK: advise (NULL, "unable to fork, so sending directly..."); case OK: - vecp = 0; - vec[vecp++] = invo_name; + vec = argsplit(sendproc, &program, &vecp); if (pushsw) vec[vecp++] = "-push"; if (arg) @@ -861,7 +886,7 @@ sendfile (char **arg, char *file, int pushsw) vec[vecp++] = file; vec[vecp] = NULL; - execvp (sendproc, vec); + execvp (program, vec); fprintf (stderr, "unable to exec "); perror (sendproc); _exit (-1); @@ -924,14 +949,15 @@ check_draft (char *msgnam) int state; char buf[BUFSIZ], name[NAMESZ]; FILE *fp; + m_getfld_state_t gstate = 0; if ((fp = fopen (msgnam, "r")) == NULL) return 0; - for (state = FLD;;) - switch (state = m_getfld (state, name, buf, sizeof(buf), fp)) { + for (;;) { + int bufsz = sizeof buf; + switch (state = m_getfld (&gstate, name, buf, &bufsz, fp)) { case FLD: case FLDPLUS: - case FLDEOF: /* * If draft already contains any of the * Content-XXX fields, then assume it already @@ -939,10 +965,13 @@ check_draft (char *msgnam) */ if (uprf (name, XXX_FIELD_PRF)) { fclose (fp); + m_getfld_state_destroy (&gstate); return 0; } - while (state == FLDPLUS) - state = m_getfld (state, name, buf, sizeof(buf), fp); + while (state == FLDPLUS) { + bufsz = sizeof buf; + state = m_getfld (&gstate, name, buf, &bufsz, fp); + } break; case BODY: @@ -952,17 +981,21 @@ check_draft (char *msgnam) for (bp = buf; *bp; bp++) if (*bp != ' ' && *bp != '\t' && *bp != '\n') { fclose (fp); + m_getfld_state_destroy (&gstate); return 1; } - state = m_getfld (state, name, buf, sizeof(buf), fp); + bufsz = sizeof buf; + state = m_getfld (&gstate, name, buf, &bufsz, fp); } while (state == BODY); /* and fall... */ default: fclose (fp); + m_getfld_state_destroy (&gstate); return 0; } + } } @@ -1005,10 +1038,6 @@ check_draft (char *msgnam) 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) \ @@ -1020,11 +1049,12 @@ check_draft (char *msgnam) X("saslmaxssf", SASLminc(-10), SASLMXSSFSW) \ X("saslmech", SASLminc(-5), SASLMECHSW) \ X("user", SASLminc(-4), USERSW) \ - X("attach file", 6, SNDATTACHSW) \ + X("attach fieldname", 6, SNDATTACHSW) \ X("noattach", 0, SNDNOATTACHSW) \ X("attachformat", 7, SNDATTACHFORMAT) \ X("port server-port-name/number", 4, PORTSW) \ X("tls", TLSminc(-3), TLSSW) \ + X("initialtls", TLSminc(-10), INITTLSSW) \ X("notls", TLSminc(-5), NTLSSW) \ X("mts smtp|sendmail/smtp|sendmail/pipe", 2, MTSSW) \ X("messageid localname|random", 2, MESSAGEIDSW) \ @@ -1055,8 +1085,8 @@ static void sendit (char *sp, char **arg, char *file, int pushed) { int vecp, n = 1; - char *cp, buf[BUFSIZ], **argp; - char **arguments, *vec[MAXARGS]; + char *cp, buf[BUFSIZ], **argp, *program; + char **arguments, *savearg[MAXARGS], **vec; struct stat st; char *attach = NMH_ATTACH_HEADER;/* attachment header field name */ int attachformat = 1; /* mhbuild format specifier for @@ -1068,17 +1098,17 @@ sendit (char *sp, char **arg, char *file, int pushed) /* * Make sure these are defined. In particular, we need - * vec[1] to be NULL, in case "arg" is NULL below. It - * doesn't matter what is the value of vec[0], but we + * savearg[1] to be NULL, in case "arg" is NULL below. It + * doesn't matter what is the value of savearg[0], but we * set it to NULL, to help catch "off-by-one" errors. */ - vec[0] = NULL; - vec[1] = NULL; + savearg[0] = NULL; + savearg[1] = NULL; /* - * Temporarily copy arg to vec, since the brkstring() call in + * Temporarily copy arg to savearg, since the brkstring() call in * getarguments() will wipe it out before it is merged in. - * Also, we skip the first element of vec, since getarguments() + * Also, we skip the first element of savearg, since getarguments() * skips it. Then we count the number of arguments * copied. The value of "n" will be one greater than * this in order to simulate the standard argc/argv. @@ -1086,17 +1116,17 @@ sendit (char *sp, char **arg, char *file, int pushed) if (arg) { char **bp; - copyip (arg, vec+1, MAXARGS-1); - bp = vec+1; + copyip (arg, savearg+1, MAXARGS-1); + bp = savearg+1; while (*bp++) n++; } /* - * Merge any arguments from command line (now in vec) + * Merge any arguments from command line (now in savearg) * and arguments from profile. */ - arguments = getarguments (sp, n, vec, 1); + arguments = getarguments (sp, n, savearg, 1); argp = arguments; debugsw = 0; @@ -1108,18 +1138,29 @@ sendit (char *sp, char **arg, char *file, int pushed) annotext = NULL; distfile = NULL; - vecp = 1; /* we'll get the zero'th element later */ + /* + * Get our initial arguments for postproc now + */ + + vec = argsplit(postproc, &program, &vecp); + vec[vecp++] = "-library"; vec[vecp++] = getcpy (m_maildir ("")); if ((cp = context_find ("fileproc"))) { - vec[vecp++] = "-fileproc"; - vec[vecp++] = cp; + vec[vecp++] = "-fileproc"; + vec[vecp++] = cp; } if ((cp = context_find ("mhlproc"))) { - vec[vecp++] = "-mhlproc"; - vec[vecp++] = cp; + vec[vecp++] = "-mhlproc"; + vec[vecp++] = cp; + } + + if ((cp = context_find ("credentials"))) { + /* post doesn't read context so need to pass credentials. */ + vec[vecp++] = "-credentials"; + vec[vecp++] = cp; } while ((cp = *argp++)) { @@ -1189,14 +1230,11 @@ sendit (char *sp, char **arg, char *file, int pushed) case NMSGDSW: case WATCSW: case NWATCSW: - case MAILSW: - case SAMLSW: - case SSNDSW: - case SOMLSW: case SNOOPSW: case SASLSW: case NOSASLSW: case TLSSW: + case INITTLSSW: case NTLSSW: vec[vecp++] = --cp; continue; @@ -1304,10 +1342,9 @@ sendit (char *sp, char **arg, char *file, int pushed) if ((pushsw = pushed)) push (); - vec[0] = r1bindex (postproc, '/'); closefds (3); - if (sendsbr (vec, vecp, file, &st, 1, attach, attachformat) == OK) + if (sendsbr (vec, vecp, program, file, &st, 1, attach, attachformat) == OK) done (0); } @@ -1320,26 +1357,25 @@ whomfile (char **arg, char *file) { pid_t pid; int vecp; - char *vec[MAXARGS]; + char **vec, *program; context_save (); /* save the context file */ fflush (stdout); - switch (pid = vfork()) { + switch (pid = fork()) { case NOTOK: advise ("fork", "unable to"); return 1; case OK: - vecp = 0; - vec[vecp++] = r1bindex (whomproc, '/'); + vec = argsplit(whomproc, &program, &vecp); vec[vecp++] = file; if (arg) while (*arg) vec[vecp++] = *arg++; vec[vecp] = NULL; - execvp (whomproc, vec); + execvp (program, vec); fprintf (stderr, "unable to exec "); perror (whomproc); _exit (-1); /* NOTREACHED */