From 08f5a8e1ddc2e4699f0e3aa4704fc37f1577ed9d Mon Sep 17 00:00:00 2001 From: Christian Neukirchen Date: Fri, 29 Jul 2016 17:07:25 +0200 Subject: [PATCH] mshow: hard-code simple multipart/alternative policy --- man/mshow.1 | 15 +++++++++++++++ mshow.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/man/mshow.1 b/man/mshow.1 index 5f9a7fe..60456b9 100644 --- a/man/mshow.1 +++ b/man/mshow.1 @@ -7,6 +7,7 @@ .Sh SYNOPSIS .Nm .Op Fl h Ar headers +.Op Fl A Ar mimetypes .Op Fl qrHL .Op Ar msgs\ ... .Nm @@ -38,6 +39,20 @@ Display the headers in the colon-separated list .Ar headers instead of the default headers .Sq Li from:subject:to:cc:date: . +.It Fl A Ar mimetypes +Define +.Sq Li "mixed/alternative" +preference. +.Ar mimetypes +is a colon-separated list of +MIME types, the ones appearing first will +be preferred when rendering +.Sq Li "mixed/alternative" +parts. +If no MIME type matches, the first MIME part will be rendered. +.Pp +Defaults to +.Sq Li "text/plain:text/html" . .It Fl q Don't render the body, stop after header output. .It Fl r diff --git a/mshow.c b/mshow.c index d5bd971..3b592b6 100644 --- a/mshow.c +++ b/mshow.c @@ -31,6 +31,9 @@ struct message *filters; static int mimecount; +static char defaultAflags[] = "text/plain:text/html"; +static char *Aflag = defaultAflags; + void printhdr(char *hdr) { @@ -167,6 +170,8 @@ mime_filename(struct message *msg) return filename; } +static void choose_alternative(struct message *msg, int depth); + mime_action render_mime(int depth, struct message *msg, char *body, size_t bodylen) { @@ -207,7 +212,7 @@ render_mime(int depth, struct message *msg, char *body, size_t bodylen) size_t outlen; int e = filter(body, bodylen, cmd, &output, &outlen); - if (e == 0) { + if (e == 0) { // replace output printf(" render=\"%s\" ---\n", cmd); print_ascii(output, outlen); } else if (e == 63) { // skip filter @@ -262,8 +267,12 @@ nofilter: printhdr(d); } printf("\n"); + } else if (strncmp(ct, "multipart/alternative", 21) == 0) { + choose_alternative(msg, depth); + + r = MIME_PRUNE; } else if (strncmp(ct, "multipart/", 10) == 0) { - ; + ; // default mime_walk action } else { printf("no filter or default handler\n"); } @@ -275,6 +284,39 @@ nofilter: return r; } +static void +choose_alternative(struct message *msg, int depth) +{ + int n = 1; + int m = 0; + char *p = Aflag + strlen(Aflag); + + struct message *imsg = 0; + while (blaze822_multipart(msg, &imsg)) { + m++; + char *ict = blaze822_hdr(imsg, "content-type"); + if (!ict) + ict = "text/x-unknown"; + char *imt = mimetype(ict); + + char *s = strstr(Aflag, imt); + if (s && s < p && + (s[strlen(imt)] == 0 || s[strlen(imt)] == ':')) { + p = s; + n = m; + } + + free(imt); + } + blaze822_free(imsg); + + imsg = 0; + while (blaze822_multipart(msg, &imsg)) + if (--n == 0) + walk_mime(imsg, depth+1, render_mime); + blaze822_free(imsg); +} + mime_action reply_mime(int depth, struct message *msg, char *body, size_t bodylen) { @@ -676,9 +718,10 @@ int main(int argc, char *argv[]) { int c; - while ((c = getopt(argc, argv, "h:qrtHLx:O:Rn")) != -1) + while ((c = getopt(argc, argv, "h:A:qrtHLx:O:Rn")) != -1) switch(c) { case 'h': hflag = optarg; break; + case 'A': Aflag = optarg; break; case 'q': qflag = 1; break; case 'r': rflag = 1; break; case 'H': Hflag = 1; break; @@ -690,7 +733,7 @@ main(int argc, char *argv[]) case 'n': nflag = 1; break; default: fprintf(stderr, - "Usage: mshow [-h headers] [-qrHL] [msgs...]\n" + "Usage: mshow [-h headers] [-A mimetypes] [-qrHL] [msgs...]\n" " mshow -x msg parts...\n" " mshow -O msg parts...\n" " mshow -t msgs...\n"