X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/a2806483a53fcdb62ca8e2bec4f4e023355f4470..a4f7db8d70e4a1f285fb8345d3c9173b4a0cbe17:/uip/mhshowsbr.c diff --git a/uip/mhshowsbr.c b/uip/mhshowsbr.c index ab87831f..c53f22f3 100644 --- a/uip/mhshowsbr.c +++ b/uip/mhshowsbr.c @@ -23,8 +23,6 @@ extern int debugsw; -int pausesw = 1; -int serialsw = 0; int nolist = 0; char *progsw = NULL; @@ -33,10 +31,6 @@ char *progsw = NULL; int nomore = 0; char *formsw = NULL; -pid_t xpid = 0; - -static sigjmp_buf intrenv; - /* mhmisc.c */ int part_ok (CT, int); @@ -44,37 +38,31 @@ int type_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 const char *parameter_value (CI, const char *); -static void intrser (int); +static int pidcheck(int); /* @@ -130,11 +118,9 @@ show_single_message (CT ct, char *form) */ 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); @@ -159,7 +145,6 @@ show_single_message (CT ct, char *form) /* reset the signal mask */ sigprocmask (SIG_SETMASK, &oset, &set); - xpid = 0; flush_errors (); } @@ -212,7 +197,7 @@ DisplayMsgHeader (CT ct, char *form) /* NOTREACHED */ default: - xpid = -child_id; + pidcheck(pidwait(child_id, NOTOK)); break; } @@ -226,33 +211,33 @@ DisplayMsgHeader (CT ct, char *form) */ 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); @@ -267,7 +252,7 @@ show_switch (CT ct, int serial, int alternate) */ 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; @@ -276,15 +261,15 @@ show_content (CT ct, int serial, int alternate) 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) @@ -299,10 +284,10 @@ show_content (CT ct, int serial, int 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) { @@ -337,15 +322,15 @@ show_content_aux (CT ct, int serial, int alternate, char *cp, char *cracked) 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); } @@ -354,8 +339,8 @@ got_command: */ 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; @@ -374,41 +359,11 @@ show_content_aux2 (CT ct, int serial, int alternate, char *cracked, char *buffer 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 to show content...")) - printf ("Press 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); @@ -439,13 +394,7 @@ show_content_aux2 (CT ct, int serial, int alternate, char *cracked, char *buffer 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); @@ -459,7 +408,7 @@ show_content_aux2 (CT ct, int serial, int alternate, char *cracked, char *buffer */ 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; @@ -468,22 +417,22 @@ show_text (CT ct, int serial, int alternate) 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; @@ -495,7 +444,7 @@ show_text (CT ct, int serial, int alternate) */ 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; @@ -504,22 +453,22 @@ show_multi (CT ct, int serial, int alternate) 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); } @@ -529,40 +478,19 @@ show_multi (CT ct, int serial, int 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); } /* @@ -578,7 +506,7 @@ show_multi_internal (CT ct, int serial, int alternate) 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) { @@ -611,46 +539,7 @@ show_multi_internal (CT ct, int serial, int alternate) 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; } @@ -661,11 +550,11 @@ out: */ 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; @@ -693,14 +582,13 @@ show_multi_aux (CT ct, int serial, int alternate, char *cp) } } - 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); } @@ -709,7 +597,7 @@ show_multi_aux (CT ct, int serial, int alternate, char *cp) */ 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; @@ -718,20 +606,20 @@ show_message_rfc822 (CT ct, int serial, int alternate) 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 ("%pecho -file %F", NULL)); - 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 */ @@ -747,9 +635,8 @@ show_message_rfc822 (CT ct, int serial, int alternate) */ 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, @@ -765,7 +652,7 @@ show_partial (CT ct, int serial, int alternate) */ 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; @@ -773,13 +660,13 @@ show_external (CT ct, int serial, int alternate) 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; @@ -795,11 +682,12 @@ parse_display_string (CT ct, char *cp, int *xstdin, int *xlist, int *xpause, 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; @@ -820,14 +708,12 @@ parse_display_string (CT ct, char *cp, int *xstdin, int *xlist, int *xpause, 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': @@ -881,8 +767,7 @@ parse_display_string (CT ct, char *cp, int *xstdin, int *xlist, int *xpause, break; case 'p': - /* %l, and pause prior to displaying content */ - *xpause = pausesw; + /* No longer supported */ /* and fall... */ case 'l': @@ -905,11 +790,11 @@ parse_display_string (CT ct, char *cp, int *xstdin, int *xlist, int *xpause, if (closing_brace) { const size_t param_len = closing_brace - cp - 1; char *param = mh_xmalloc(param_len + 1); - const char *value; + char *value; (void) strncpy(param, cp + 1, param_len); param[param_len] = '\0'; - value = parameter_value(ci, param); + value = get_param(ci->ci_first_pm, param, '?', 0); free(param); cp += param_len + 1; /* Skip both braces, too. */ @@ -918,6 +803,7 @@ parse_display_string (CT ct, char *cp, int *xstdin, int *xlist, int *xpause, /* %{param} is set in the Content-Type header. After the break below, quote it if necessary. */ (void) strncpy(bp, value, buflen); + free(value); } else { /* %{param} not found, so skip it completely. cp was advanced above. */ @@ -1008,9 +894,8 @@ parse_display_string (CT ct, char *cp, int *xstdin, int *xlist, int *xpause, if (! found_quote) { *bp++ = '\''; buflen--; + quoted = 0; } - - quoted = 0; } } } else { @@ -1156,13 +1041,21 @@ convert_charset (CT ct, char *dest_charset, int *message_mods) { ++*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; @@ -1171,10 +1064,7 @@ convert_charset (CT ct, char *dest_charset, int *message_mods) { /* 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; @@ -1222,32 +1112,19 @@ convert_content_charset (CT ct, char **file) { return OK; } - /* - * If a Content-Type parameter named param exists, returns its value. - * Otherwise, returns NULL. + * Exit if the display process returned with a nonzero exit code, or terminated + * with a SIGQUIT signal. */ -static const char * -parameter_value (CI ci, const char *param) { - const char *value = NULL; - char **ap, **vp; - - for (ap = ci->ci_attrs, vp = ci->ci_values; *ap; ++ap, ++vp) { - if (! strcasecmp (*ap, param)) { - value = *vp; - break; - } - } - return value; -} - - -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; }