ref: a6466b6c6888d1e56795eb9ae87afb5db136dea7
parent: 88d2711854dfdf65900d9001bf7ee9c78f46ee6a
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Nov 3 23:32:40 EST 2020
handle multipart messages
--- a/mbox.c
+++ b/mbox.c
@@ -780,5 +780,4 @@
threadcreate(mbmain, nil, Stack);
proccreate(plumbsee, nil, Stack);
proccreate(plumbshow, nil, Stack);
-// threadexitsall(nil);
}
--- a/mesg.c
+++ b/mesg.c
@@ -128,22 +128,58 @@
return m;
}
-static int
-mesgshow(Mesg *m)
+static Mesg*
+readparts(Mesg *m)
{
- int rfd, wfd;
- char *buf, *path;
+ char *dpath, *apath;
+ int n, i, dfd;
+ Mesg *a, *best;
+ Dir *d;
+
+ dpath = estrjoin(mbox.path, m->name, nil);
+ dfd = open(dpath, OREAD);
+ free(dpath);
+ if(dfd == -1)
+ return m;
+
+ n = dirreadall(dfd, &d);
+ close(dfd);
+ if(n == -1)
+ sysfatal("%s read: %r", mbox.path);
+
+ best = nil;
+ m->attachments = emalloc(n*sizeof(Mesg*));
+ m->nattachments = 0;
+ for(i = 0; i < n; i++){
+ if(d[i].qid.type != QTDIR)
+ continue;
+
+ apath = estrjoin(m->name, d[i].name, nil);
+ a = mesgload(apath);
+ free(apath);
+ if(a == nil)
+ continue;
+ m->attachments[m->nattachments++] = a;
+ if(a->filename != nil || a->disposition != nil && strcmp(a->disposition, "inline") != 0)
+ continue;
+ if(strcmp(a->type, "text/plain") == 0)
+ best = a;
+ else if(best == nil && strcmp(a->type, "text/html") == 0)
+ best = a;
+ }
+ free(d);
+ if(best == nil)
+ return nil;
+ return best;
+}
+
+static void
+copy(int wfd, int rfd)
+{
+ char *buf;
int n;
buf = emalloc(Bufsz);
- path = estrjoin(mbox.path, m->name, "body", nil);
- if((wfd = winopen(m, "body", OWRITE)) == -1)
- return -1;
- if((rfd = open(path, OREAD)) == -1)
- return -1;
- fprint(wfd, "From: %s\n", m->from);
- fprint(wfd, "Date: %s\n", m->to);
- fprint(wfd, "Subject: %s\n\n", m->subject);
while(1){
n = read(rfd, buf, Bufsz);
if(n <= 0)
@@ -151,11 +187,57 @@
if(write(wfd, buf, n) != n)
break;
}
- close(rfd);
- close(wfd);
free(buf);
+}
+
+static int
+mesgshow(Mesg *m)
+{
+ char *path, *home, *name;
+ int i, rfd, wfd;
+ Mesg *a, *b;
+
+ if((wfd = winopen(m, "body", OWRITE)) == -1)
+ return -1;
+ fprint(wfd, "From: %s\n", m->from);
+ fprint(wfd, "Date: %s\n", m->date);
+ fprint(wfd, "Subject: %s\n\n", m->subject);
+
+ b = readparts(m);
+ path = estrjoin(mbox.path, b->name, "body", nil);
+ if(strcmp(b->type, "text/html"))
+ rfd = open(path, OREAD);//htmlfmt(path);
+ else
+ rfd = open(path, OREAD);
free(path);
- return n;
+ if(rfd != -1){
+ copy(wfd, rfd);
+ close(rfd);
+ }
+
+ home = getenv("home");
+ for(i = 0; i < m->nattachments; i++){
+ a = m->attachments[i];
+ if(a == b)
+ continue;
+ fprint(wfd, "===> %s (%s)\n", a->name, a->type);
+ if(a->disposition != nil && strcmp(a->disposition, "inline") == 0){
+ path = estrjoin(mbox.path, b->name, "body", nil);
+ if((rfd = open(path, OREAD)) != -1){
+ copy(wfd, rfd);
+ close(rfd);
+ }
+ }else{
+ name = a->filename;
+ if(name == nil)
+ name = "body";
+ fprint(wfd, "\tcp %s%sbody %s/%s\n", mbox.path, a->name, home, name);
+ continue;
+ }
+ }
+ close(wfd);
+ free(home);
+ return 0;
}
static void