X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/1e0b1d40a6285c532b722f4584fa7ddde220deff..64ef3b3008a7b990c2c856c24354ed2cabcc76dc:/uip/mhshowsbr.c diff --git a/uip/mhshowsbr.c b/uip/mhshowsbr.c index 31d25eb1..f410d1a4 100644 --- a/uip/mhshowsbr.c +++ b/uip/mhshowsbr.c @@ -33,6 +33,12 @@ char *progsw = NULL; int nomore = 0; char *formsw = NULL; +/* for output markerss and headers */ +char *folder = NULL; +char *markerform; +char *headerform; +int headersw = -1; + /* mhmisc.c */ int part_ok (CT); @@ -59,7 +65,9 @@ static int show_external (CT, int, int, int, int, struct format *); static int parse_display_string (CT, char *, int *, int *, char *, char *, size_t, int multipart); static int convert_content_charset (CT, char **); +static struct format *compile_header(char *); static struct format *compile_marker(char *); +static void output_header (CT, struct format *); static void output_marker (CT, struct format *, int); static void free_markercomps (void); static int pidcheck(int); @@ -69,6 +77,7 @@ static int pidcheck(int); * content marker display. */ +static struct comp *folder_comp = NULL; static struct comp *part_comp = NULL; static struct comp *ctype_comp = NULL; static struct comp *description_comp = NULL; @@ -89,11 +98,10 @@ static struct param_comp_list *dispo_pc_list = NULL; */ void -show_all_messages (CT *cts, int concatsw, int textonly, int inlineonly, - char *markerform) +show_all_messages (CT *cts, int concatsw, int textonly, int inlineonly) { CT ct, *ctp; - struct format *fmt; + struct format *hfmt, *mfmt; /* * If form is not specified, then get default form @@ -103,9 +111,10 @@ show_all_messages (CT *cts, int concatsw, int textonly, int inlineonly, formsw = getcpy (etcpath ("mhl.headers")); /* - * Compile the content marker format line + * Compile the content marker and header format lines */ - fmt = compile_marker(markerform); + mfmt = compile_marker(markerform); + hfmt = compile_header(headerform); /* * If form is "mhl.null", suppress display of header. @@ -117,13 +126,17 @@ show_all_messages (CT *cts, int concatsw, int textonly, int inlineonly, ct = *ctp; /* if top-level type is ok, then display message */ - if (type_ok (ct, 1)) + if (type_ok (ct, 1)) { + if (headersw) output_header(ct, hfmt); + show_single_message (ct, formsw, concatsw, textonly, inlineonly, - fmt); + mfmt); + } } free_markercomps(); - fmt_free(fmt, 1); + fmt_free(hfmt, 1); + fmt_free(mfmt, 1); } @@ -1068,6 +1081,7 @@ convert_charset (CT ct, char *dest_charset, int *message_mods) { char *dest_buffer = mh_xmalloc(dest_buffer_size); HF hf; char *tempfile; + int fromutf8 = !strcasecmp(src_charset, "UTF-8"); if ((conv_desc = iconv_open (dest_charset, src_charset)) == (iconv_t) -1) { @@ -1137,6 +1151,32 @@ iconv_start: outbytes_before += bumpup; goto iconv_start; } + if (errno == EINVAL) { + /* middle of multi-byte sequence */ + if (write (fd, dest_buffer, outbytes_before - outbytes) < 0) { + advise (dest, "write"); + } + fseeko (*fp, -inbytes, SEEK_CUR); + if (end > 0) bytes_to_read += inbytes; + /* advise(NULL, "convert_charset: EINVAL"); */ + continue; + } + if (errno == EILSEQ) { + /* invalid multi-byte sequence */ + if (fromutf8) { + for (++ib, --inbytes; + inbytes > 0 && + (((unsigned char) *ib) & 0xc0) == 0x80; + ++ib, --inbytes) + continue; + } else { + ib++; inbytes--; /* skip it */ + } + (*ob++) = '?'; outbytes --; + /* advise(NULL, "convert_charset: EILSEQ"); */ + goto iconv_start; + } + advise (NULL, "convert_charset: errno = %d", errno); status = NOTOK; break; } else { @@ -1252,6 +1292,7 @@ convert_content_charset (CT ct, char **file) { * Compile our format string and save any parameters we care about. */ +#define DEFAULT_HEADER "[ Message %{folder}%<{folder}:%>%(msg) ]" #define DEFAULT_MARKER "[ part %{part} - %{content-type} - " \ "%<{description}%{description}" \ "%?{cdispo-filename}%{cdispo-filename}" \ @@ -1259,7 +1300,29 @@ convert_content_charset (CT ct, char **file) { "%(kilo(size))B %<(unseen)\\(suppressed\\)%> ]" static struct format * -compile_marker(char *markerform) +compile_header(char *form) +{ + struct format *fmt; + char *fmtstring; + struct comp *comp = NULL; + unsigned int bucket; + + fmtstring = new_fs(form, NULL, DEFAULT_HEADER); + + (void) fmt_compile(fmtstring, &fmt, 1); + free_fs(); + + while ((comp = fmt_nextcomp(comp, &bucket)) != NULL) { + if (strcasecmp(comp->c_name, "folder") == 0) { + folder_comp = comp; + } + } + + return fmt; +} + +static struct format * +compile_marker(char *form) { struct format *fmt; char *fmtstring; @@ -1267,10 +1330,10 @@ compile_marker(char *markerform) unsigned int bucket; struct param_comp_list *pc_entry; - fmtstring = new_fs(markerform, NULL, DEFAULT_MARKER); + fmtstring = new_fs(form, NULL, DEFAULT_MARKER); (void) fmt_compile(fmtstring, &fmt, 1); - free(fmtstring); + free_fs(); /* * Things we care about: @@ -1316,13 +1379,46 @@ compile_marker(char *markerform) * Output on stdout an appropriate marker for this content, using mh-format */ +static void +output_header(CT ct, struct format *fmt) +{ + charstring_t outbuf = charstring_create (BUFSIZ); + int dat[5] = { 0 }; + char *endp; + int message = 0; + + if (folder_comp) + folder_comp->c_text = getcpy(folder); + + if (ct->c_file && *ct->c_file) { + message = strtol(ct->c_file, &endp, 10); + if (*endp) message = 0; + dat[0] = message; + } + + /* it would be nice to populate dat[2], for %(size) here, + * but it's not available. it might also be nice to know + * if the message originally had any mime parts or not -- but + * there's also no record of that. (except for MIME-version:) + */ + + fmt_scan(fmt, outbuf, BUFSIZ, dat, NULL); + + fputs(charstring_buffer (outbuf), stdout); + charstring_free (outbuf); + + fmt_freecomptext(); +} + static void output_marker(CT ct, struct format *fmt, int hidden) { charstring_t outbuf = charstring_create (BUFSIZ); struct param_comp_list *pcentry; int partsize; - int dat[5]; + int message = 0; + char *endp; + int dat[5] = { 0 }; /* * Grab any items we care about. @@ -1360,13 +1456,18 @@ output_marker(CT ct, struct format *fmt, int hidden) else partsize = ct->c_end - ct->c_begin; + if (ct->c_file && *ct->c_file) { + message = strtol(ct->c_file, &endp, 10); + if (*endp) message = 0; + dat[0] = message; + } + dat[2] = partsize; + /* make the part's hidden aspect available by overloading the * %(unseen) function. make the part's size available via %(size). * see comments in h/fmt_scan.h. */ - dat[2] = partsize; dat[4] = hidden; - dat[0] = dat[1] = dat[3] = 0; fmt_scan(fmt, outbuf, BUFSIZ, dat, NULL); @@ -1385,6 +1486,7 @@ free_markercomps(void) { struct param_comp_list *pc_entry, *pc2; + folder_comp = NULL; part_comp = NULL; ctype_comp = NULL; description_comp = NULL;