extern int debugsw;
-int pausesw = 1;
-int serialsw = 0;
int nolist = 0;
char *progsw = NULL;
int nomore = 0;
char *formsw = NULL;
-pid_t xpid = 0;
-
-static sigjmp_buf intrenv;
-
/* mhmisc.c */
int part_ok (CT, int);
void content_error (char *, CT, char *, ...);
void flush_errors (void);
-/* mhlistsbr.c */
-int list_switch (CT, int, int, int, int);
-int list_content (CT, int, int, int, int);
-
/*
* prototypes
*/
void show_all_messages (CT *);
-int show_content_aux (CT, int, int, char *, char *);
+int show_content_aux (CT, int, char *, char *);
/*
* static prototypes
*/
static void show_single_message (CT, char *);
static void DisplayMsgHeader (CT, char *);
-static int show_switch (CT, int, int);
-static int show_content (CT, int, int);
-static int show_content_aux2 (CT, int, int, char *, char *, int, int, int, int,
- int);
-static int show_text (CT, int, int);
-static int show_multi (CT, int, int);
-static int show_multi_internal (CT, int, int);
-static int show_multi_aux (CT, int, int, char *);
-static int show_message_rfc822 (CT, int, int);
-static int show_partial (CT, int, int);
-static int show_external (CT, int, int);
-static int parse_display_string (CT, char *, int *, int *, int *, int *, char *,
- char *, size_t, int multipart);
+static int show_switch (CT, int);
+static int show_content (CT, int);
+static int show_content_aux2 (CT, int, char *, char *, int, int, int);
+static int show_text (CT, int);
+static int show_multi (CT, int);
+static int show_multi_internal (CT, int);
+static int show_multi_aux (CT, int, char *);
+static int show_message_rfc822 (CT, int);
+static int show_partial (CT, int);
+static int show_external (CT, int);
+static int parse_display_string (CT, char *, int *, int *, char *, char *,
+ size_t, int multipart);
static int convert_content_charset (CT, char **);
-static int parameter_value (CI, const char *, const char *, const char **);
-static void intrser (int);
+static int pidcheck(int);
/*
*/
if (form)
DisplayMsgHeader(ct, form);
- else
- xpid = 0;
/* Show the body of the message */
- show_switch (ct, 1, 0);
+ show_switch (ct, 0);
if (ct->c_fp) {
fclose (ct->c_fp);
/* reset the signal mask */
sigprocmask (SIG_SETMASK, &oset, &set);
- xpid = 0;
flush_errors ();
}
/* NOTREACHED */
default:
- xpid = -child_id;
+ pidcheck(pidwait(child_id, NOTOK));
break;
}
*/
static int
-show_switch (CT ct, int serial, int alternate)
+show_switch (CT ct, int alternate)
{
switch (ct->c_type) {
case CT_MULTIPART:
- return show_multi (ct, serial, alternate);
+ return show_multi (ct, alternate);
case CT_MESSAGE:
switch (ct->c_subtype) {
case MESSAGE_PARTIAL:
- return show_partial (ct, serial, alternate);
+ return show_partial (ct, alternate);
case MESSAGE_EXTERNAL:
- return show_external (ct, serial, alternate);
+ return show_external (ct, alternate);
case MESSAGE_RFC822:
default:
- return show_message_rfc822 (ct, serial, alternate);
+ return show_message_rfc822 (ct, alternate);
}
case CT_TEXT:
- return show_text (ct, serial, alternate);
+ return show_text (ct, alternate);
case CT_AUDIO:
case CT_IMAGE:
case CT_VIDEO:
case CT_APPLICATION:
- return show_content (ct, serial, alternate);
+ return show_content (ct, alternate);
default:
adios (NULL, "unknown content type %d", ct->c_type);
*/
static int
-show_content (CT ct, int serial, int alternate)
+show_content (CT ct, int alternate)
{
char *cp, buffer[BUFSIZ];
CI ci = &ct->c_ctinfo;
snprintf (buffer, sizeof(buffer), "%s-show-%s/%s",
invo_name, ci->ci_type, ci->ci_subtype);
if ((cp = context_find (buffer)) && *cp != '\0')
- return show_content_aux (ct, serial, alternate, cp, NULL);
+ return show_content_aux (ct, alternate, cp, NULL);
/* Check for invo_name-show-type */
snprintf (buffer, sizeof(buffer), "%s-show-%s", invo_name, ci->ci_type);
if ((cp = context_find (buffer)) && *cp != '\0')
- return show_content_aux (ct, serial, alternate, cp, NULL);
+ return show_content_aux (ct, alternate, cp, NULL);
if ((cp = ct->c_showproc))
- return show_content_aux (ct, serial, alternate, cp, NULL);
+ return show_content_aux (ct, alternate, cp, NULL);
/* complain if we are not a part of a multipart/alternative */
if (!alternate)
*/
int
-show_content_aux (CT ct, int serial, int alternate, char *cp, char *cracked)
+show_content_aux (CT ct, int alternate, char *cp, char *cracked)
{
int fd;
- int xstdin = 0, xlist = 0, xpause = 0, xtty = 0;
+ int xstdin = 0, xlist = 0;
char *file, buffer[BUFSIZ];
if (!ct->c_ceopenfnx) {
goto got_command;
}
- if (parse_display_string (ct, cp, &xstdin, &xlist, &xpause, &xtty, file,
- buffer, sizeof(buffer) - 1, 0)) {
+ if (parse_display_string (ct, cp, &xstdin, &xlist, file, buffer,
+ sizeof(buffer) - 1, 0)) {
admonish (NULL, "Buffer overflow constructing show command!\n");
return NOTOK;
}
got_command:
- return show_content_aux2 (ct, serial, alternate, cracked, buffer,
- fd, xlist, xpause, xstdin, xtty);
+ return show_content_aux2 (ct, alternate, cracked, buffer,
+ fd, xlist, xstdin);
}
*/
static int
-show_content_aux2 (CT ct, int serial, int alternate, char *cracked, char *buffer,
- int fd, int xlist, int xpause, int xstdin, int xtty)
+show_content_aux2 (CT ct, int alternate, char *cracked, char *buffer,
+ int fd, int xlist, int xstdin)
{
pid_t child_id;
int i, vecp;
fprintf (stderr, " using command %s\n", buffer);
}
- if (xpid < 0 || (xtty && xpid)) {
- if (xpid < 0)
- xpid = -xpid;
- pidcheck(pidwait (xpid, NOTOK));
- xpid = 0;
- }
-
if (xlist) {
- char prompt[BUFSIZ];
-
if (ct->c_type == CT_MULTIPART)
- list_content (ct, -1, 1, 0, 0);
+ list_content (ct, -1, 1, 0, 0, 0);
else
- list_switch (ct, -1, 1, 0, 0);
-
- if (xpause && isatty (fileno (stdout))) {
- int intr;
- SIGNAL_HANDLER istat;
-
- if (SOprintf ("Press <return> to show content..."))
- printf ("Press <return> to show content...");
-
- istat = SIGNAL (SIGINT, intrser);
- if ((intr = sigsetjmp (intrenv, 1)) == OK) {
- fflush (stdout);
- prompt[0] = 0;
- read (fileno (stdout), prompt, sizeof(prompt));
- }
- SIGNAL (SIGINT, istat);
- if (intr != OK || prompt[0] == 'n') {
- (*ct->c_ceclosefnx) (ct);
- return (alternate ? DONE : NOTOK);
- }
- if (prompt[0] == 'q') done(OK);
- }
+ list_switch (ct, -1, 1, 0, 0, 0);
}
vec = argsplit(buffer, &file, &vecp);
default:
arglist_free(file, vec);
- if (!serial) {
- ct->c_pid = child_id;
- if (xtty)
- xpid = child_id;
- } else {
- pidcheck (pidXwait (child_id, NULL));
- }
+ pidcheck (pidXwait (child_id, NULL));
if (fd != NOTOK)
(*ct->c_ceclosefnx) (ct);
*/
static int
-show_text (CT ct, int serial, int alternate)
+show_text (CT ct, int alternate)
{
char *cp, buffer[BUFSIZ];
CI ci = &ct->c_ctinfo;
snprintf (buffer, sizeof(buffer), "%s-show-%s/%s",
invo_name, ci->ci_type, ci->ci_subtype);
if ((cp = context_find (buffer)) && *cp != '\0')
- return show_content_aux (ct, serial, alternate, cp, NULL);
+ return show_content_aux (ct, alternate, cp, NULL);
/* Check for invo_name-show-type */
snprintf (buffer, sizeof(buffer), "%s-show-%s", invo_name, ci->ci_type);
if ((cp = context_find (buffer)) && *cp != '\0')
- return show_content_aux (ct, serial, alternate, cp, NULL);
+ return show_content_aux (ct, alternate, cp, NULL);
/*
* Use default method if content is text/plain, or if
* if it is not a text part of a multipart/alternative
*/
if (!alternate || ct->c_subtype == TEXT_PLAIN) {
- snprintf (buffer, sizeof(buffer), "%%p%s '%%F'", progsw ? progsw :
+ snprintf (buffer, sizeof(buffer), "%%l%s %%F", progsw ? progsw :
moreproc && *moreproc ? moreproc : DEFAULT_PAGER);
cp = (ct->c_showproc = add (buffer, NULL));
- return show_content_aux (ct, serial, alternate, cp, NULL);
+ return show_content_aux (ct, alternate, cp, NULL);
}
return NOTOK;
*/
static int
-show_multi (CT ct, int serial, int alternate)
+show_multi (CT ct, int alternate)
{
char *cp, buffer[BUFSIZ];
CI ci = &ct->c_ctinfo;
snprintf (buffer, sizeof(buffer), "%s-show-%s/%s",
invo_name, ci->ci_type, ci->ci_subtype);
if ((cp = context_find (buffer)) && *cp != '\0')
- return show_multi_aux (ct, serial, alternate, cp);
+ return show_multi_aux (ct, alternate, cp);
/* Check for invo_name-show-type */
snprintf (buffer, sizeof(buffer), "%s-show-%s", invo_name, ci->ci_type);
if ((cp = context_find (buffer)) && *cp != '\0')
- return show_multi_aux (ct, serial, alternate, cp);
+ return show_multi_aux (ct, alternate, cp);
if ((cp = ct->c_showproc))
- return show_multi_aux (ct, serial, alternate, cp);
+ return show_multi_aux (ct, alternate, cp);
/*
* Use default method to display this multipart content. Even
* unknown types are displayable, since they're treated as mixed
* per RFC 2046.
*/
- return show_multi_internal (ct, serial, alternate);
+ return show_multi_internal (ct, alternate);
}
*/
static int
-show_multi_internal (CT ct, int serial, int alternate)
+show_multi_internal (CT ct, int alternate)
{
- int alternating, nowalternate, nowserial, result;
+ int alternating, nowalternate, result;
struct multipart *m = (struct multipart *) ct->c_ctparams;
struct part *part;
CT p;
- sigset_t set, oset;
alternating = 0;
nowalternate = alternate;
- if (ct->c_subtype == MULTI_PARALLEL) {
- nowserial = serialsw;
- } else if (ct->c_subtype == MULTI_ALTERNATE) {
+ if (ct->c_subtype == MULTI_ALTERNATE) {
nowalternate = 1;
alternating = 1;
- nowserial = serial;
- } else {
- /*
- * multipart/mixed
- * mutlipart/digest
- * unknown subtypes of multipart (treat as mixed per rfc2046)
- */
- nowserial = serial;
- }
-
- /* block a few signals */
- if (!nowserial) {
- sigemptyset (&set);
- sigaddset (&set, SIGHUP);
- sigaddset (&set, SIGINT);
- sigaddset (&set, SIGQUIT);
- sigaddset (&set, SIGTERM);
- sigprocmask (SIG_BLOCK, &set, &oset);
}
/*
if (part_ok (p, 1) && type_ok (p, 1)) {
int inneresult;
- inneresult = show_switch (p, nowserial, nowalternate);
+ inneresult = show_switch (p, nowalternate);
switch (inneresult) {
case NOTOK:
if (alternate && !alternating) {
goto out;
}
- if (serial && !nowserial) {
- pid_t pid;
- int kids;
- int status;
-
- kids = 0;
- for (part = m->mp_parts; part; part = part->mp_next) {
- p = part->mp_part;
-
- if (p->c_pid > OK) {
- if (kill (p->c_pid, 0) == NOTOK)
- p->c_pid = 0;
- else
- kids++;
- }
- }
-
- while (kids > 0 && (pid = wait (&status)) != NOTOK) {
- pidcheck (status);
-
- for (part = m->mp_parts; part; part = part->mp_next) {
- p = part->mp_part;
-
- if (xpid == pid)
- xpid = 0;
- if (p->c_pid == pid) {
- p->c_pid = 0;
- kids--;
- break;
- }
- }
- }
- }
-
out:
- if (!nowserial) {
- /* reset the signal mask */
- sigprocmask (SIG_SETMASK, &oset, &set);
- }
-
return result;
}
*/
static int
-show_multi_aux (CT ct, int serial, int alternate, char *cp)
+show_multi_aux (CT ct, int alternate, char *cp)
{
/* xstdin is only used in the call to parse_display_string():
its value is ignored in the function. */
- int xstdin = 0, xlist = 0, xpause = 0, xtty = 0;
+ int xstdin = 0, xlist = 0;
char *file, buffer[BUFSIZ];
struct multipart *m = (struct multipart *) ct->c_ctparams;
struct part *part;
if ((*p->c_ceopenfnx) (p, &file) == NOTOK)
return NOTOK;
- /* I'm not sure if this is necessary? */
p->c_storage = add (file, NULL);
if (p->c_showproc && !strcmp (p->c_showproc, "true"))
}
}
- if (parse_display_string (ct, cp, &xstdin, &xlist, &xpause, &xtty, file,
+ if (parse_display_string (ct, cp, &xstdin, &xlist, file,
buffer, sizeof(buffer) - 1, 1)) {
admonish (NULL, "Buffer overflow constructing show command!\n");
return NOTOK;
}
- return show_content_aux2 (ct, serial, alternate, NULL, buffer,
- NOTOK, xlist, xpause, 0, xtty);
+ return show_content_aux2 (ct, alternate, NULL, buffer, NOTOK, xlist, 0);
}
*/
static int
-show_message_rfc822 (CT ct, int serial, int alternate)
+show_message_rfc822 (CT ct, int alternate)
{
char *cp, buffer[BUFSIZ];
CI ci = &ct->c_ctinfo;
snprintf (buffer, sizeof(buffer), "%s-show-%s/%s",
invo_name, ci->ci_type, ci->ci_subtype);
if ((cp = context_find (buffer)) && *cp != '\0')
- return show_content_aux (ct, serial, alternate, cp, NULL);
+ return show_content_aux (ct, alternate, cp, NULL);
/* Check for invo_name-show-type */
snprintf (buffer, sizeof(buffer), "%s-show-%s", invo_name, ci->ci_type);
if ((cp = context_find (buffer)) && *cp != '\0')
- return show_content_aux (ct, serial, alternate, cp, NULL);
+ return show_content_aux (ct, alternate, cp, NULL);
if ((cp = ct->c_showproc))
- return show_content_aux (ct, serial, alternate, cp, NULL);
+ return show_content_aux (ct, alternate, cp, NULL);
/* default method for message/rfc822 */
if (ct->c_subtype == MESSAGE_RFC822) {
- cp = (ct->c_showproc = add ("%pshow -file '%F'", NULL));
- return show_content_aux (ct, serial, alternate, cp, NULL);
+ cp = (ct->c_showproc = add ("%pecho -file %F", NULL));
+ return show_content_aux (ct, alternate, cp, NULL);
}
/* complain if we are not a part of a multipart/alternative */
*/
static int
-show_partial (CT ct, int serial, int alternate)
+show_partial (CT ct, int alternate)
{
- NMH_UNUSED (serial);
NMH_UNUSED (alternate);
content_error (NULL, ct,
*/
static int
-show_external (CT ct, int serial, int alternate)
+show_external (CT ct, int alternate)
{
struct exbody *e = (struct exbody *) ct->c_ctparams;
CT p = e->eb_content;
if (!type_ok (p, 0))
return OK;
- return show_switch (p, serial, alternate);
+ return show_switch (p, alternate);
}
static int
-parse_display_string (CT ct, char *cp, int *xstdin, int *xlist, int *xpause,
- int *xtty, char *file, char *buffer, size_t buflen,
+parse_display_string (CT ct, char *cp, int *xstdin, int *xlist,
+ char *file, char *buffer, size_t buflen,
int multipart) {
int len, quoted = 0;
char *bp = buffer, *pp;
case 'a':
/* insert parameters from Content-Type field */
{
- char **ap, **ep;
+ PM pm;
char *s = "";
- for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
- snprintf (bp, buflen, "%s%s=\"%s\"", s, *ap, *ep);
+ for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) {
+ snprintf (bp, buflen, "%s%s=\"%s\"", s, pm->pm_name,
+ get_param_value(pm, '?'));
len = strlen (bp);
bp += len;
buflen -= len;
break;
case 'e':
- /* exclusive execution */
- *xtty = 1;
+ /* no longer implemented */
break;
case 'F':
- /* %e, %f, and stdin is terminal not content */
+ /* %f, and stdin is terminal not content */
*xstdin = 1;
- *xtty = 1;
/* and fall... */
case 'f':
for (part = m->mp_parts; part; part = part->mp_next) {
p = part->mp_part;
- /* Don't quote filename if it's already quoted. */
- if (p->c_storage && *(p->c_storage-1) == '\'') {
- /* If there isn't a matching close quote, bail
- out. */
- if (*(cp+1) != '\'') {
- adios(NULL, "%%f/%%F not properly escaped: "
- "%s%s\n",
- buffer, cp);
- }
- snprintf (bp, buflen, "%s%s", s, p->c_storage);
- } else {
- if (*(cp+1) != '\0' && *(cp+1) == '\'') {
- adios(NULL, "%%f/%%F not properly escaped: "
- "%s%s\n",
- buffer, cp);
- }
- snprintf (bp, buflen, "%s'%s'", s, p->c_storage);
- }
-
+ snprintf (bp, buflen, "%s%s", s, p->c_storage);
len = strlen (bp);
bp += len;
buflen -= len;
}
} else {
/* insert filename containing content */
- if (bp > buffer && *(bp-1) == '\'') {
- /* Don't quote filename if it's already quoted. */
- /* If there isn't a matching close quote, bail
- out. */
- if (*(cp+1) != '\'') {
- adios(NULL, "%%f/%%F not properly escaped: %s%s\n",
- buffer, cp);
- }
- snprintf (bp, buflen, "%s", file);
- } else {
- if (*(cp+1) != '\0' && *(cp+1) == '\'') {
- adios(NULL, "%%f/%%F not properly escaped: %s%s\n",
- buffer, cp);
- }
- snprintf (bp, buflen, "'%s'", file);
- }
+ snprintf (bp, buflen, "%s", file);
+ /*
+ * Old comments below are left here for posterity.
+ * This was/is tricky.
+ */
/* since we've quoted the file argument, set things up
* to look past it, to avoid problems with the quoting
* logic below. (I know, I should figure out what's
* code below.
* The fix was to always quote the filename. But
* that broke '%F' because it expanded to ''filename''.
- * That's why I added the condition above to not
- * quote if the escape was wrapped with single
- * quotes. It would be (much) better to rely on
- * the quoting code below, but until I understand
- * what is wrong with it, I won't do that.
*/
- len = strlen(bp);
- bp += len;
- buflen -= len;
+ /*
+ * Old comments above are left here for posterity.
+ * The quoting below should work properly now.
+ */
}
-
- /* set our starting pointer back to bp, to avoid
- * requoting the filenames we just added
- */
- pp = bp;
break;
case 'p':
- /* %l, and pause prior to displaying content */
- *xpause = pausesw;
+ /* No longer supported */
/* and fall... */
case 'l':
goto raw;
case '{' : {
- static const char param[] = "charset";
- const char *value;
- const int found = parameter_value (ci, param, cp, &value);
-
- if (found == OK) {
- /* Because it'll get incremented in the next iteration,
- just increment by 1 for the '{'. */
- cp += strlen(param) + 1;
+ const char *closing_brace = strchr(cp, '}');
- /* cp pointed to the param and it's set in the
- Content-Type header. */
- strncpy (bp, value, buflen);
+ if (closing_brace) {
+ const size_t param_len = closing_brace - cp - 1;
+ char *param = mh_xmalloc(param_len + 1);
+ char *value;
- /* since we've quoted the file argument, set things up
- * to look past it, to avoid problems with the quoting
- * logic below. (I know, I should figure out what's
- * broken with the quoting logic, but..)
- */
- len = strlen(bp);
- bp += len;
- buflen -= len;
- pp = bp;
+ (void) strncpy(param, cp + 1, param_len);
+ param[param_len] = '\0';
+ value = get_param(ci->ci_first_pm, param, '?', 0);
+ free(param);
- break;
- } else if (found == 1) {
- /* cp points to the param and it's not set in the
- Content-Type header, so skip it. */
- cp += strlen(param) + 1;
+ cp += param_len + 1; /* Skip both braces, too. */
- if (*cp == '\0') {
- break;
+ if (value) {
+ /* %{param} is set in the Content-Type header.
+ After the break below, quote it if necessary. */
+ (void) strncpy(bp, value, buflen);
+ free(value);
} else {
- if (*(cp + 1) == '\0') {
- break;
- } else {
- ++cp;
- /* Increment cp again so that the last
- character of the %{} token isn't output
- after falling thru below. */
- ++cp;
- }
+ /* %{param} not found, so skip it completely. cp
+ was advanced above. */
+ continue;
}
} else {
- /* cp points to an unrecognized parameter. Output
- it as-is, starting here with the "%{". */
- *bp++ = '%';
- *bp++ = '{';
- *bp = '\0';
- buflen -= 2;
- continue;
+ /* This will get confused if there are multiple %{}'s,
+ but its real purpose is to avoid doing bad things
+ above if a closing brace wasn't found. */
+ admonish(NULL,
+ "no closing brace for display string escape %s",
+ cp);
}
-
- /* No parameter was found, so fall thru to default to
- output the rest of the text as-is. */
+ break;
}
default:
len = strlen (bp);
bp += len;
buflen -= len;
+ *bp = '\0';
/* Did we actually insert something? */
if (bp != pp) {
/* Insert single quote if not inside quotes already */
if (!quoted && buflen) {
len = strlen (pp);
- memmove (pp + 1, pp, len);
+ memmove (pp + 1, pp, len+1);
*pp++ = '\'';
buflen--;
bp++;
+ quoted = 1;
}
/* Escape existing quotes */
while ((pp = strchr (pp, '\'')) && buflen > 3) {
len = strlen (pp++);
- memmove (pp + 3, pp, len);
- *pp++ = '\\';
- *pp++ = '\'';
- *pp++ = '\'';
- buflen -= 3;
- bp += 3;
+ if (quoted) {
+ /* Quoted. Let this quote close that quoting.
+ Insert an escaped quote to replace it and
+ another quote to reopen quoting, which will be
+ closed below. */
+ memmove (pp + 2, pp, len);
+ *pp++ = '\\';
+ *pp++ = '\'';
+ buflen -= 2;
+ bp += 2;
+ quoted = 0;
+ } else {
+ /* Not quoted. This should not be reached with
+ the current code, but handle the condition
+ in case the code changes. Just escape the
+ quote. */
+ memmove (pp, pp-1, len+1);
+ *(pp++-1) = '\\';
+ buflen -= 1;
+ bp += 1;
+ }
}
/* If pp is still set, that means we ran out of space. */
if (pp)
buflen = 0;
- if (!quoted && buflen) {
- *bp++ = '\'';
- *bp = '\0';
- buflen--;
+ /* Close quoting. */
+ if (quoted && buflen) {
+ /* See if we need to close the quote by looking
+ for an odd number of unescaped close quotes in
+ the remainder of the display string. */
+ int found_quote = 0, escaped = 0;
+ char *c;
+
+ for (c = cp+1; *c; ++c) {
+ if (*c == '\\') {
+ escaped = ! escaped;
+ } else {
+ if (escaped) {
+ escaped = 0;
+ } else {
+ if (*c == '\'') {
+ found_quote = ! found_quote;
+ }
+ }
+ }
+ }
+ if (! found_quote) {
+ *bp++ = '\'';
+ buflen--;
+ quoted = 0;
+ }
}
}
} else {
raw:
*bp++ = *cp;
- *bp = '\0';
buflen--;
if (*cp == '\'')
quoted = !quoted;
}
+
+ *bp = '\0';
}
if (buflen <= 0 ||
++*message_mods;
- /* Update ci_attrs. */
- src_charset = dest_charset;
-
/* Update ct->c_ctline. */
if (ct->c_ctline) {
- char *ctline =
- update_attr (ct->c_ctline, "charset=", dest_charset);
+ char *ctline = concat(" ", ct->c_ctinfo.ci_type, "/",
+ ct->c_ctinfo.ci_subtype, NULL);
+ char *outline;
+
+ replace_param(&ct->c_ctinfo.ci_first_pm,
+ &ct->c_ctinfo.ci_last_pm, "charset",
+ dest_charset, 0);
+ outline = output_params(strlen(TYPE_FIELD) + 1 + strlen(ctline),
+ ct->c_ctinfo.ci_first_pm, NULL, 0);
+ if (outline) {
+ ctline = add(outline, ctline);
+ free(outline);
+ }
free (ct->c_ctline);
ct->c_ctline = ctline;
/* Update Content-Type header field. */
for (hf = ct->c_first_hf; hf; hf = hf->next) {
if (! strcasecmp (TYPE_FIELD, hf->name)) {
- char *ctline_less_newline =
- update_attr (hf->value, "charset=", dest_charset);
- char *ctline = concat (ctline_less_newline, "\n", NULL);
- free (ctline_less_newline);
+ char *ctline = concat (ct->c_ctline, "\n", NULL);
free (hf->value);
hf->value = ctline;
return OK;
}
-
/*
- * Return values:
- * NOTOK if cp doesn't point to {param}
- * OK if cp points to {param} and that attribute exists, and returns
- * its value
- * 1 if cp points to {param} and that attribute doesn't exist
+ * Exit if the display process returned with a nonzero exit code, or terminated
+ * with a SIGQUIT signal.
*/
-int
-parameter_value (CI ci, const char *param, const char *cp, const char **value) {
- int found = NOTOK;
- char *braced_param = concat ("{", param, "}", NULL);
-
- if (! strncasecmp(cp, braced_param, strlen (braced_param))) {
- char **ap, **ep;
- found = 1;
-
- for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ++ap, ++ep) {
- if (!strcasecmp (*ap, param)) {
- found = OK;
- *value = *ep;
- break;
- }
- }
- }
-
- free (braced_param);
- return found;
-}
-
-
-static void
-intrser (int i)
+static int
+pidcheck (int status)
{
- NMH_UNUSED (i);
+ if ((status & 0xff00) == 0xff00 || (status & 0x007f) != SIGQUIT)
+ return status;
- putchar ('\n');
- siglongjmp (intrenv, DONE);
+ fflush (stdout);
+ fflush (stderr);
+ done (1);
+ return 1;
}