Don't use MB_CUR_MAX if compiling without multibyte support.
[mmh] / uip / whatnowsbr.c
index 53320d3..72e9d1f 100644 (file)
@@ -44,6 +44,7 @@
 #include <fcntl.h>
 #include <signal.h>
 #include <h/mime.h>
+#include <h/utils.h>
 
 static struct swit whatnowswitches[] = {
 #define        DFOLDSW                 0
@@ -119,6 +120,7 @@ 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 **);
 
 #ifdef HAVE_LSTAT
 static int copyf (char *, char *);
@@ -352,17 +354,7 @@ 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.
             */
-
-           cp = buf + sprintf(buf, "$SHELL -c \" cd %s;ls", cwd);
-
-           while (*++argp != (char *)0) {
-               if (cp + strlen(*argp) + 2 >= buf + BUFSIZ)
-                   adios((char *)0, "arguments too long");
-
-               cp += sprintf(cp, " %s", *argp);
-           }
-
-           (void)strcat(cp, "\"");
+           writelscmd(buf, sizeof(buf), cwd, argp);
            (void)system(buf);
            break;
 
@@ -422,17 +414,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.
             */
-
-           cp = buf + sprintf(buf, "$SHELL -c \" cd %s;ls", cwd);
-
-           while (*++argp != (char *)0) {
-               if (cp + strlen(*argp) + 3 >= buf + BUFSIZ)
-                   adios((char *)0, "arguments too long");
-
-               cp += sprintf(cp, " %s", *argp);
-           }
-
-           (void)strcat(cp, "\"");
+           writelscmd(buf, sizeof(buf), cwd, argp);
 
            /*
             *  Read back the response from the shell, which contains a number of lines
@@ -447,10 +429,10 @@ WhatNow (int argc, char **argv)
                    *(strchr(shell, '\n')) = '\0';
 
                    if (*shell == '/')
-                       (void)annotate(drft, attach, shell, 1, 0, -1, 1);
+                       (void)annotate(drft, attach, shell, 1, 0, -2, 1);
                    else {
                        (void)sprintf(file, "%s/%s", cwd, shell);
-                       (void)annotate(drft, attach, file, 1, 0, -1, 1);
+                       (void)annotate(drft, attach, file, 1, 0, -2, 1);
                    }
                }
 
@@ -559,6 +541,40 @@ WhatNow (int argc, char **argv)
     /*NOTREACHED*/
 }
 
+
+/*
+ * 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 *cwd, char **argp)
+{
+    char *cp;
+    int ln = snprintf(buf, bufsz, "$SHELL -c \" cd %s;ls", cwd);
+    /* 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
+     */
+    if (ln < 0 || ln + 2 > 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))
+           adios((char *)0, "arguments too long");
+       *cp++ = ' ';
+       memcpy(cp, *argp, ln+1);
+       cp += ln;
+    }
+    *cp++ = '"';
+    *cp = 0;
+}
+
 /*
  * EDIT
  */
@@ -843,8 +859,7 @@ buildfile (char **argp, char *file)
        while (argp[i])
            i++;
     }
-    if ((args = (char **) malloc((i + 2) * sizeof(char *))) == NULL)
-       adios (NULL, "unable to malloc memory");
+    args = (char **) mh_xmalloc((i + 2) * sizeof(char *));
 
     /*
      * For backward compatibility, we need to add -build
@@ -1005,6 +1020,8 @@ static struct swit  sendswitches[] = {
     { "user", SASLminc(-4) },
 #define SNDATTACHSW       39
     { "attach file", 6 },
+#define SNDATTACHFORMAT   40
+    { "attachformat", 7 },
     { NULL, 0 }
 };
 
@@ -1030,6 +1047,8 @@ sendit (char *sp, char **arg, char *file, int pushed)
     char **arguments, *vec[MAXARGS];
     struct stat st;
     char       *attach = (char *)0;    /* attachment header field name */
+    int                attachformat = 0;       /* mhbuild format specifier for
+                                          attachments */
 
 #ifndef        lint
     int        distsw = 0;
@@ -1190,6 +1209,21 @@ sendit (char *sp, char **arg, char *file, int pushed)
                        return;
                    }
                    continue;
+
+               case SNDATTACHFORMAT:
+                   if (! *argp || **argp == '-')
+                       adios (NULL, "missing argument to %s", argp[-1]);
+                   else {
+                       attachformat = atoi (*argp);
+                       if (attachformat < 0 ||
+                           attachformat > ATTACHFORMATS - 1) {
+                           advise (NULL, "unsupported attachformat %d",
+                                   attachformat);
+                           continue;
+                       }
+                   }
+                   ++argp;
+                   continue;
            }
        }
        advise (NULL, "usage: %s [switches]", sp);
@@ -1255,7 +1289,7 @@ sendit (char *sp, char **arg, char *file, int pushed)
     vec[0] = r1bindex (postproc, '/');
     closefds (3);
 
-    if (sendsbr (vec, vecp, file, &st, 1, attach) == OK)
+    if (sendsbr (vec, vecp, file, &st, 1, attach, attachformat) == OK)
        done (0);
 }