From: Ken Hornstein Date: Tue, 12 Feb 2013 20:37:00 +0000 (-0500) Subject: Final conversion to new argsplit() code. X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/685dd439ef0166954c59c3f8a2f6903d0a7cbab9?ds=inline;hp=e4dc6d154b593b5fc0baa96091a2fbd4ec59ba89 Final conversion to new argsplit() code. --- diff --git a/docs/pending-release-notes b/docs/pending-release-notes index 9624ac6c..1cd1cd76 100644 --- a/docs/pending-release-notes +++ b/docs/pending-release-notes @@ -38,6 +38,9 @@ NEW FEATURES characters when accounting for column widths. - burst(1) now can burst MIME-formatted digests (messages that contain message/rfc822 parts instead of messages formatted with RFC 934). +- All proc entries (showproc, moreproc, etc) can now accept entries that + contain spaces and shell metacharacters. If found, such entries will + either be space-splitted or processed by /bin/sh. ---------------------------- OBSOLETE/DEPRECATED FEATURES diff --git a/h/prototypes.h b/h/prototypes.h index 3f2caee8..a3263195 100644 --- a/h/prototypes.h +++ b/h/prototypes.h @@ -23,11 +23,16 @@ char *etcpath(char *); /* * prototypes from the nmh subroutine library */ + +struct msgs_array; + void adios (char *, char *, ...) NORETURN; void admonish (char *, char *, ...); void advertise (char *, char *, char *, va_list); void advise (char *, char *, ...); char **argsplit (char *, char **, int *); +void argsplit_msgarg (struct msgs_array *, char *, char **); +void argsplit_insert (struct msgs_array *, char *, char **); void arglist_free (char *, char **); void ambigsw (char *, struct swit *); int atooi(char *); diff --git a/sbr/arglist.c b/sbr/arglist.c index aa143eee..f40f1e89 100644 --- a/sbr/arglist.c +++ b/sbr/arglist.c @@ -142,3 +142,81 @@ arglist_free(char *command, char **argvarray) free(argvarray); } } + +/* + * Similar in functionality to argsplit, but is designed to deal with + * a msgs_array. + */ + +void +argsplit_msgarg(struct msgs_array *msgs, char *command, char **program) +{ + int argp, i; + char **vec; + + vec = argsplit(command, program, &argp); + + /* + * As usual, there is lousy memory management in nmh. Nothing ever + * free's the msgs_array, and a lot of the arguments are allocated + * from static memory. I could have app_msgarg() allocate new + * memory for each pointer, but for now I decided to stick with + * the existing interface; maybe that will be revisited later. + * So we'll just copy over our pointers and free the pointer list + * (not the actual pointers themselves). Note that we don't + * include a trailing NULL, since we are expecting the application + * to take care of that. + */ + + for (i = 0; i < argp; i++) { + app_msgarg(msgs, vec[i]); + } + + free(vec); +} + +/* + * Insert a arglist vector into the beginning of an struct msgs array + * + * Uses by some programs (e.g., show) who want to decide which proc + * to use after the argument vector has been constructed + */ + +#ifndef MAXMSGS +#define MAXMSGS 256 +#endif + +void +argsplit_insert(struct msgs_array *msgs, char *command, char **program) +{ + int argp, i; + char **vec; + + vec = argsplit(command, program, &argp); + + /* + * Okay, we want to shuffle all of our arguments down so we have room + * for argp number of arguments. This means we need to know about + * msgs_array internals. If that changes, we need to change this + * code here. + */ + + if (msgs->size + argp >= msgs->max) { + msgs->max += MAXMSGS > argp ? MAXMSGS : argp; + msgs->msgs = mh_xrealloc(msgs->msgs, msgs->max * sizeof(*msgs->msgs)); + } + + for (i = msgs->size - 1; i >= 0; i--) + msgs->msgs[i + argp] = msgs->msgs[i]; + + msgs->size += argp; + + /* + * Now fill in the arguments at the beginning of the vector. + */ + + for (i = 0; i < argp; i++) + msgs->msgs[i] = vec[i]; + + free(vec); +} diff --git a/uip/forw.c b/uip/forw.c index 97714dc4..18a4f03b 100644 --- a/uip/forw.c +++ b/uip/forw.c @@ -496,12 +496,13 @@ mhl_draft (int out, char *digest, int volume, int issue, int i, msgnum, pd[2]; char buf1[BUFSIZ]; char buf2[BUFSIZ]; + char *program; struct msgs_array vec = { 0, 0, NULL }; if (pipe (pd) == NOTOK) adios ("pipe", "unable to create"); - app_msgarg(&vec, r1bindex (mhlproc, '/')); + argsplit_msgarg(&vec, mhlproc, &program); for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++) sleep (5); @@ -548,7 +549,7 @@ mhl_draft (int out, char *digest, int volume, int issue, app_msgarg(&vec, NULL); - execvp (mhlproc, vec.msgs); + execvp (program, vec.msgs); fprintf (stderr, "unable to exec "); perror (mhlproc); _exit (-1); diff --git a/uip/show.c b/uip/show.c index f513ebd5..dc426130 100644 --- a/uip/show.c +++ b/uip/show.c @@ -55,7 +55,7 @@ main (int argc, char **argv) int draftsw = 0, headersw = 1; int nshow = 0, checkmime = 1, mime; int isdf = 0, mode = SHOW, msgnum; - char *cp, *maildir, *file = NULL, *folder = NULL, *proc; + char *cp, *maildir, *file = NULL, *folder = NULL, *proc, *program; char buf[BUFSIZ], **argp, **arguments; struct msgs *mp = NULL; struct msgs_array msgs = { 0, 0, NULL }; @@ -66,8 +66,6 @@ main (int argc, char **argv) #endif invo_name = r1bindex (argv[0], '/'); - app_msgarg(&vec, NULL); /* placeholder, filled later with proc name */ - /* read user profile/context */ context_read(); @@ -256,8 +254,8 @@ usage: context_replace (pfolder, folder); /* update current folder */ context_save (); /* save the context file */ - if (headersw && vec.size == 2) - printf ("(Message %s:%s)\n", folder, vec.msgs[1]); + if (headersw && vec.size == 1) + printf ("(Message %s:%s)\n", folder, vec.msgs[0]); go_to_it: ; fflush (stdout); @@ -311,15 +309,15 @@ go_to_it: ; } } else if (strcmp (r1bindex (proc, '/'), "mhl") == 0) { /* If "mhl", then run it internally */ - vec.msgs[0] = "mhl"; + argsplit_insert(&vec, "mhl", &program); app_msgarg(&vec, NULL); mhl (vec.size, vec.msgs); done (0); } - vec.msgs[0] = r1bindex (proc, '/'); + argsplit_insert(&vec, proc, &program); app_msgarg(&vec, NULL); - execvp (proc, vec.msgs); + execvp (program, vec.msgs); adios (proc, "unable to exec"); return 0; /* dead code to satisfy the compiler */ } diff --git a/uip/whatnowsbr.c b/uip/whatnowsbr.c index 712ea7bb..ab90eb86 100644 --- a/uip/whatnowsbr.c +++ b/uip/whatnowsbr.c @@ -816,7 +816,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")) @@ -851,7 +851,7 @@ sendfile (char **arg, char *file, int pushsw) case NOTOK: advise (NULL, "unable to fork, so sending directly..."); case OK: - vecp = 0; + vec = argsplit(sendproc, &program, &vecp); vec[vecp++] = invo_name; if (pushsw) vec[vecp++] = "-push"; @@ -861,7 +861,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); @@ -1332,7 +1332,7 @@ whomfile (char **arg, char *file) { pid_t pid; int vecp; - char *vec[MAXARGS]; + char **vec, *program; context_save (); /* save the context file */ fflush (stdout); @@ -1343,7 +1343,7 @@ whomfile (char **arg, char *file) return 1; case OK: - vecp = 0; + vec = argsplit(whomproc, &program, &vecp); vec[vecp++] = r1bindex (whomproc, '/'); vec[vecp++] = file; if (arg) @@ -1351,7 +1351,7 @@ whomfile (char **arg, char *file) vec[vecp++] = *arg++; vec[vecp] = NULL; - execvp (whomproc, vec); + execvp (program, vec); fprintf (stderr, "unable to exec "); perror (whomproc); _exit (-1); /* NOTREACHED */