X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/6779979cf3a57b458d28e4d1aaac026a61d73572..9cc2510:/uip/mhshowsbr.c?ds=sidebyside diff --git a/uip/mhshowsbr.c b/uip/mhshowsbr.c index 33d1c09d..986ffb91 100644 --- a/uip/mhshowsbr.c +++ b/uip/mhshowsbr.c @@ -135,7 +135,7 @@ show_single_message (CT ct, char *form, int concatsw, int textonly, { sigset_t set, oset; - int status; + int status = OK; /* Allow user executable bit so that temporary directories created by * the viewer (e.g., lynx) are going to be accessible */ @@ -258,8 +258,15 @@ show_switch (CT ct, int alternate, int concatsw, int textonly, int inlineonly, inlineonly, fmt); case MESSAGE_RFC822: - default: return show_message_rfc822 (ct, alternate, fmt); + + /* + * Treat unknown message types as equivalent to + * application/octet-stream for now + */ + default: + return show_content (ct, alternate, textonly, + inlineonly, fmt); } case CT_TEXT: @@ -285,7 +292,7 @@ static int show_content (CT ct, int alternate, int textonly, int inlineonly, struct format *fmt) { - char *cp, buffer[BUFSIZ]; + char *cp; CI ci = &ct->c_ctinfo; /* @@ -298,15 +305,8 @@ show_content (CT ct, int alternate, int textonly, int inlineonly, return OK; } - /* Check for invo_name-show-type/subtype */ - 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, alternate, cp, NULL, fmt); - - /* 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') + /* Check for invo_name-show-type[/subtype] */ + if ((cp = context_find_by_type ("show", ci->ci_type, ci->ci_subtype))) return show_content_aux (ct, alternate, cp, NULL, fmt); if ((cp = ct->c_showproc)) @@ -329,7 +329,7 @@ show_content_aux (CT ct, int alternate, char *cp, char *cracked, struct format * { int fd; int xstdin = 0, xlist = 0; - char *file, buffer[BUFSIZ]; + char *file = NULL, buffer[BUFSIZ]; if (!ct->c_ceopenfnx) { if (!alternate) @@ -338,7 +338,6 @@ show_content_aux (CT ct, int alternate, char *cp, char *cracked, struct format * return NOTOK; } - file = NULL; if ((fd = (*ct->c_ceopenfnx) (ct, &file)) == NOTOK) return NOTOK; if (ct->c_showproc && !strcmp (ct->c_showproc, "true")) @@ -355,10 +354,12 @@ show_content_aux (CT ct, int alternate, char *cp, char *cracked, struct format * if ((fd = (*ct->c_ceopenfnx) (ct, &file)) == NOTOK) return NOTOK; } else { + char *charset = content_charset (ct); admonish (NULL, "unable to convert character set%s%s to %s", ct->c_partno ? " of part " : "", ct->c_partno ? ct->c_partno : "", - content_charset (ct)); + charset); + free (charset); } } @@ -416,6 +417,7 @@ show_content_aux2 (CT ct, int alternate, char *cracked, char *buffer, if (buffer[0] == '\0') { char readbuf[BUFSIZ]; ssize_t cc; + char lastchar = '\n'; if (fd == NOTOK) { advise(NULL, "Cannot use NULL command to display content-type " @@ -424,7 +426,10 @@ show_content_aux2 (CT ct, int alternate, char *cracked, char *buffer, } while ((cc = read(fd, readbuf, sizeof(readbuf))) > 0) { - fwrite(readbuf, sizeof(char), cc, stdout); + if ((ssize_t) fwrite(readbuf, sizeof(char), cc, stdout) < cc) { + advise ("putline", "fwrite"); + } + lastchar = readbuf[cc - 1]; } if (cc < 0) { @@ -432,6 +437,20 @@ show_content_aux2 (CT ct, int alternate, char *cracked, char *buffer, return NOTOK; } + /* + * The MIME standards allow content to not have a trailing newline. + * But because we are (presumably) sending this to stdout, include + * a newline for text content if the final character was not a + * newline. Only do this for mhshow. + */ + + if (strcmp(invo_name, "mhshow") == 0 && ct->c_type == CT_TEXT && + ct->c_subtype == TEXT_PLAIN && lastchar != '\n') { + putc('\n', stdout); + } + + fflush(stdout); + return OK; } @@ -449,8 +468,11 @@ show_content_aux2 (CT ct, int alternate, char *cracked, char *buffer, return NOTOK; case OK: - if (cracked) - chdir (cracked); + if (cracked) { + if (chdir (cracked) < 0) { + advise (cracked, "chdir"); + } + } if (!xstdin) dup2 (fd, 0); close (fd); @@ -482,15 +504,8 @@ show_text (CT ct, int alternate, int concatsw, struct format *fmt) char *cp, buffer[BUFSIZ]; CI ci = &ct->c_ctinfo; - /* Check for invo_name-show-type/subtype */ - 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, alternate, cp, NULL, fmt); - - /* 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') + /* Check for invo_name-show-type[/subtype] */ + if ((cp = context_find_by_type ("show", ci->ci_type, ci->ci_subtype))) return show_content_aux (ct, alternate, cp, NULL, fmt); /* @@ -522,18 +537,11 @@ static int show_multi (CT ct, int alternate, int concatsw, int textonly, int inlineonly, struct format *fmt) { - char *cp, buffer[BUFSIZ]; + char *cp; CI ci = &ct->c_ctinfo; - /* Check for invo_name-show-type/subtype */ - 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, alternate, cp, fmt); - - /* 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') + /* Check for invo_name-show-type[/subtype] */ + if ((cp = context_find_by_type ("show", ci->ci_type, ci->ci_subtype))) return show_multi_aux (ct, alternate, cp, fmt); if ((cp = ct->c_showproc)) @@ -561,7 +569,7 @@ show_multi_internal (CT ct, int alternate, int concatsw, int textonly, int alternating, nowalternate, result; struct multipart *m = (struct multipart *) ct->c_ctparams; struct part *part; - int any_part_ok; + int request_matched; CT p; alternating = 0; @@ -572,13 +580,13 @@ show_multi_internal (CT ct, int alternate, int concatsw, int textonly, alternating = 1; } -/* - * alternate -> we are a part inside an multipart/alternative - * alternating -> we are a multipart/alternative - */ + /* + * alternate -> we are a part inside an multipart/alternative + * alternating -> we are a multipart/alternative + */ result = alternate ? NOTOK : OK; - any_part_ok = 0; + request_matched = 0; for (part = m->mp_parts; part; part = part->mp_next) { p = part->mp_part; @@ -586,7 +594,7 @@ show_multi_internal (CT ct, int alternate, int concatsw, int textonly, if (part_ok (p, 1) && type_ok (p, 1)) { int inneresult; - any_part_ok = 1; + request_matched = 1; inneresult = show_switch (p, nowalternate, concatsw, textonly, inlineonly, fmt); @@ -615,7 +623,7 @@ show_multi_internal (CT ct, int alternate, int concatsw, int textonly, } } - if (alternating && !part && any_part_ok) { + if (alternating && !part && request_matched) { if (!alternate) content_error (NULL, ct, "don't know how to display any of the contents"); result = NOTOK; @@ -623,7 +631,9 @@ show_multi_internal (CT ct, int alternate, int concatsw, int textonly, } out: - return result; + /* if no parts matched what was requested, there can't have been + * any display errors, so we report OK. */ + return request_matched ? result : OK; } @@ -638,7 +648,7 @@ show_multi_aux (CT ct, int alternate, char *cp, struct format *fmt) /* xstdin is only used in the call to parse_display_string(): its value is ignored in the function. */ int xstdin = 0, xlist = 0; - char *file, buffer[BUFSIZ]; + char *file = NULL, buffer[BUFSIZ]; struct multipart *m = (struct multipart *) ct->c_ctparams; struct part *part; CT p; @@ -653,7 +663,6 @@ show_multi_aux (CT ct, int alternate, char *cp, struct format *fmt) } if (p->c_storage == NULL) { - file = NULL; if ((*p->c_ceopenfnx) (p, &file) == NOTOK) return NOTOK; @@ -682,18 +691,11 @@ show_multi_aux (CT ct, int alternate, char *cp, struct format *fmt) static int show_message_rfc822 (CT ct, int alternate, struct format *fmt) { - char *cp, buffer[BUFSIZ]; + char *cp; CI ci = &ct->c_ctinfo; - /* Check for invo_name-show-type/subtype */ - 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, alternate, cp, NULL, fmt); - - /* 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') + /* Check for invo_name-show-type[/subtype] */ + if ((cp = context_find_by_type ("show", ci->ci_type, ci->ci_subtype))) return show_content_aux (ct, alternate, cp, NULL, fmt); if ((cp = ct->c_showproc)) @@ -1039,6 +1041,7 @@ convert_charset (CT ct, char *dest_charset, int *message_mods) { if ((conv_desc = iconv_open (dest_charset, src_charset)) == (iconv_t) -1) { advise (NULL, "Can't convert %s to %s", src_charset, dest_charset); + free (src_charset); return NOTOK; } @@ -1106,7 +1109,10 @@ iconv_start: status = NOTOK; break; } else { - write (fd, dest_buffer, outbytes_before - outbytes); + if (write (fd, dest_buffer, outbytes_before - outbytes) + < 0) { + advise (dest, "write"); + } } } @@ -1176,6 +1182,7 @@ iconv_start: #endif /* ! HAVE_ICONV */ } + free (src_charset); return status; } @@ -1200,9 +1207,8 @@ convert_content_charset (CT ct, char **file) { } else { status = NOTOK; } - - free (charset); } + free (charset); #else /* ! HAVE_ICONV */ NMH_UNUSED (ct); NMH_UNUSED (file); @@ -1282,7 +1288,7 @@ compile_marker(char *markerform) static void output_marker(CT ct, struct format *fmt, int hidden) { - char outbuf[BUFSIZ]; + charstring_t outbuf = charstring_create (BUFSIZ); struct param_comp_list *pcentry; int partsize; int dat[5]; @@ -1331,9 +1337,10 @@ output_marker(CT ct, struct format *fmt, int hidden) dat[4] = hidden; dat[0] = dat[1] = dat[3] = 0; - fmt_scan(fmt, outbuf, sizeof(outbuf), sizeof(outbuf), dat, NULL); + fmt_scan(fmt, outbuf, BUFSIZ, dat, NULL); - fputs(outbuf, stdout); + fputs(charstring_buffer (outbuf), stdout); + charstring_free (outbuf); fmt_freecomptext(); }