]> diplodocus.org Git - nmh/blobdiff - uip/whatnowsbr.c
Added check to get_file_info() in attach.c for failed fgets() call.
[nmh] / uip / whatnowsbr.c
index c9cbf50384096b5e6fe556d18cf893db8f7db2e7..82b0d67fdcf10e2e6464a8fa42f7769e78eec3e3 100644 (file)
  *                             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 <h/mh.h>
 #include <fcntl.h>
-#include <signal.h>
 #include <h/mime.h>
 #include <h/utils.h>
 
@@ -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)
@@ -647,9 +692,7 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp,
     char *cp, *prog, **vec;
     struct stat st;
 
-#ifdef HAVE_LSTAT
     int        slinked = 0;
-#endif /* HAVE_LSTAT */
 
     /* Was there a previous edit session? */
     if (reedit) {
@@ -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;
@@ -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);
@@ -940,6 +965,7 @@ check_draft (char *msgnam)
                 */
                if (uprf (name, XXX_FIELD_PRF)) {
                    fclose (fp);
+                   m_getfld_state_destroy (&gstate);
                    return 0;
                }
                while (state == FLDPLUS) {
@@ -955,6 +981,7 @@ check_draft (char *msgnam)
                    for (bp = buf; *bp; bp++)
                        if (*bp != ' ' && *bp != '\t' && *bp != '\n') {
                            fclose (fp);
+                           m_getfld_state_destroy (&gstate);
                            return 1;
                        }
 
@@ -965,10 +992,10 @@ check_draft (char *msgnam)
 
            default:
                fclose (fp);
+               m_getfld_state_destroy (&gstate);
                return 0;
        }
     }
-    m_getfld_state_destroy (&gstate);
 }
 
 
@@ -1011,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) \
@@ -1026,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) \
@@ -1061,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
@@ -1074,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.
@@ -1092,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;
@@ -1114,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++)) {
@@ -1195,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;
@@ -1310,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);
 }
 
@@ -1326,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 */