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
/*
* 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 *);
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);
+}
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);
app_msgarg(&vec, NULL);
- execvp (mhlproc, vec.msgs);
+ execvp (program, vec.msgs);
fprintf (stderr, "unable to exec ");
perror (mhlproc);
_exit (-1);
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 };
#endif
invo_name = r1bindex (argv[0], '/');
- app_msgarg(&vec, NULL); /* placeholder, filled later with proc name */
-
/* read user profile/context */
context_read();
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);
}
} 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 */
}
{
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"))
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";
vec[vecp++] = file;
vec[vecp] = NULL;
- execvp (sendproc, vec);
+ execvp (program, vec);
fprintf (stderr, "unable to exec ");
perror (sendproc);
_exit (-1);
{
pid_t pid;
int vecp;
- char *vec[MAXARGS];
+ char **vec, *program;
context_save (); /* save the context file */
fflush (stdout);
return 1;
case OK:
- vecp = 0;
+ vec = argsplit(whomproc, &program, &vecp);
vec[vecp++] = r1bindex (whomproc, '/');
vec[vecp++] = file;
if (arg)
vec[vecp++] = *arg++;
vec[vecp] = NULL;
- execvp (whomproc, vec);
+ execvp (program, vec);
fprintf (stderr, "unable to exec ");
perror (whomproc);
_exit (-1); /* NOTREACHED */