#include <u.h>
#include <libc.h>
#include <bio.h>
#include <thread.h>
#include <ctype.h>
#include <9pclient.h>
#include <plumb.h>
#include "dat.h"

enum
{
	DIRCHUNK = 32*sizeof(Dir)
};

char	regexchars[] = "\\/[].+?()*^$";
char	deleted[] = "(deleted)-";
char	deletedrx[] = "\\(deleted\\)-";
char	deletedrx01[] = "(\\(deleted\\)-)?";
char	deletedaddr[] = "-#0;/^\\(deleted\\)-/";

struct{
	char	*type;
	char	*port;
	char *suffix;
} ports[] = {
	"text/",			"edit",	".txt", /* must be first for plumbport() */
	"image/gif",		"image",	".gif",
	"image/jpeg",		"image",	".jpg",
	"image/jpeg",		"image",	".jpeg",
	"image/png",		"image",	".png",
	"application/postscript",	"postscript",	".ps",
	"application/pdf",	"postscript",	".pdf",
	"application/msword",	"msword",	".doc",
	"application/rtf",	"msword",	".rtf",
	nil,	nil
};

char *goodtypes[] = {
	"text",
	"text/plain",
	"message/rfc822",
	"text/richtext",
	"text/tab-separated-values",
	"application/octet-stream",
	nil
};

char *okheaders[] =
{
	"From:",
	"Date:",
	"To:",
	"CC:",
	"Subject:",
	nil
};

char *extraheaders[] =
{
	"Resent-From:",
	"Resent-To:",
	"Sort:",
	nil
};

char*
line(char *data, char **pp)
{
	char *p, *q;

	for(p=data; *p!='\0' && *p!='\n'; p++)
		;
	if(*p == '\n')
		*pp = p+1;
	else
		*pp = p;
	q = emalloc(p-data + 1);
	memmove(q, data, p-data);
	return q;
}

static char*
mkaddrs(char *t, char **colon)
{
	int i, nf, inquote;
	char **f, *s;
	Fmt fmt;
	
	inquote = 0;
	nf = 2;
	for(s=t; *s; s++){
		if(*s == '\'')
			inquote = !inquote;
		if(*s == ' ' && !inquote)
			nf++;
	}
	f = emalloc(nf*sizeof f[0]);
	nf = tokenize(t, f, nf);
	if(colon){
		fmtstrinit(&fmt);
		for(i=0; i+1<nf; i+=2){
			if(i > 0)
				fmtprint(&fmt, ", ");
			if(f[i][0] == 0 || strcmp(f[i], f[i+1]) == 0)
				fmtprint(&fmt, "%s", f[i+1]);
			else
				fmtprint(&fmt, "%s <%s>", f[i], f[i+1]);
		}
		*colon = fmtstrflush(&fmt);
	}
	fmtstrinit(&fmt);
	for(i=0; i+1<nf; i+=2){
		if(i > 0)
			fmtprint(&fmt, ", ");
		fmtprint(&fmt, "%s", f[i+1]);
	}
	free(f);
	return fmtstrflush(&fmt);
}

int
loadinfo(Message *m, char *dir)
{
	int n;
	char *data, *p, *s, *t;

	data = readfile(dir, "info", &n);
	if(data == nil)
		return 0;
	
	p = data;
	while((s = line(p, &p)) != nil && *s != 0){
		t = strchr(s, ' ');
		if(t == nil)
			continue;
		*t++ = 0;
		if(strcmp(s, "from") == 0){
			free(m->from);
			m->from = mkaddrs(t, &m->fromcolon);
		}else if(strcmp(s, "sender") == 0){
			free(m->sender);
			m->sender = mkaddrs(t, nil);
		}else if(strcmp(s, "to") == 0){
			free(m->to);
			m->to = mkaddrs(t, nil);
		}else if(strcmp(s, "cc") == 0){
			free(m->cc);
			m->cc = mkaddrs(t, nil);
		}else if(strcmp(s, "replyto") == 0){
			free(m->replyto);
			m->replyto = mkaddrs(t, nil);
		}else if(strcmp(s, "subject") == 0){
			free(m->subject);
			m->subject = estrdup(t);
		}else if(strcmp(s, "type") == 0){
			free(m->type);
			m->type = estrdup(t);
		}else if(strcmp(s, "unixdate") == 0 && (t=strchr(t, ' ')) != nil){
			free(m->date);
			m->date = estrdup(t+1);
		}else if(strcmp(s, "digest") == 0){
			free(m->digest);
			m->digest = estrdup(t);
		}else if(strcmp(s, "filename") == 0){
			free(m->filename);
			m->filename = estrdup(t);
		}
		free(s);
	}
	free(s);
	free(data);
	if(m->replyto == nil){
		if(m->sender)
			m->replyto = estrdup(m->sender);
		else if(m->from)
			m->replyto = estrdup(m->from);
		else
			m->replyto = estrdup("");
	}
	if(m->from == nil)
		m->from = estrdup("");
	if(m->to == nil)
		m->to = estrdup("");
	if(m->cc == nil)
		m->cc = estrdup("");
	if(m->subject == nil)
		m->subject = estrdup("");
	if(m->type == nil)
		m->type = estrdup("");
	if(m->date == nil)
		m->date = estrdup("");
	if(m->disposition == nil)
		m->disposition = estrdup("");
	if(m->filename == nil)
		m->filename = estrdup("");
	if(m->digest == nil)
		m->digest = estrdup("");
	return 1;
}

int
isnumeric(char *s)
{
	while(*s){
		if(!isdigit(*s))
			return 0;
		s++;
	}
	return 1;
}

CFid*
mailopen(char *name, int mode)
{
	if(strncmp(name, "Mail/", 5) != 0)
		return nil;
	return fsopen(mailfs, name+5, mode);
}

Dir*
loaddir(char *name, int *np)
{
	CFid *fid;
	Dir *dp;

	fid = mailopen(name, OREAD);
	if(fid == nil)
		return nil;
	*np = fsdirreadall(fid, &dp);
	fsclose(fid);
	return dp;
}

void
readmbox(Message *mbox, char *dir, char *subdir)
{
	char *name;
	Dir *d, *dirp;
	int i, n;

	name = estrstrdup(dir, subdir);
	dirp = loaddir(name, &n);
	mbox->recursed = 1;
	if(dirp)
		for(i=0; i<n; i++){
			d = &dirp[i];
			if(isnumeric(d->name))
				mesgadd(mbox, name, d, nil);
		}
	free(dirp);
	free(name);
}

/* add message to box, in increasing numerical order */
int
mesgadd(Message *mbox, char *dir, Dir *d, char *digest)
{
	Message *m;
	char *name;
	int loaded;

	m = emalloc(sizeof(Message));
	m->name = estrstrdup(d->name, "/");
	m->next = nil;
	m->prev = mbox->tail;
	m->level= mbox->level+1;
	m->recursed = 0;
	name = estrstrdup(dir, m->name);
	loaded = loadinfo(m, name);
	free(name);
	/* if two upas/fs are running, we can get misled, so check digest before accepting message */
	if(loaded==0 || (digest!=nil && m->digest!=nil && strcmp(digest, m->digest)!=0)){
		mesgfreeparts(m);
		free(m);
		return 0;
	}
	if(mbox->tail != nil)
		mbox->tail->next = m;
	mbox->tail = m;
	if(mbox->head == nil)
		mbox->head = m;

	if (m->level != 1){
		m->recursed = 1;
		readmbox(m, dir, m->name); 
	}
	return 1;
}

int
thisyear(char *year)
{
	static char now[10];
	char *s;

	if(now[0] == '\0'){
		s = ctime(time(nil));
		strcpy(now, s+24);
	}
	return strncmp(year, now, 4) == 0;
}

char*
stripdate(char *as)
{
	int n;
	char *s, *fld[10];

	as = estrdup(as);
	s = estrdup(as);
	n = tokenize(s, fld, 10);
	if(n > 5){
		sprint(as, "%.3s ", fld[0]);	/* day */
		/* some dates have 19 Apr, some Apr 19 */
		if(strlen(fld[1])<4 && isnumeric(fld[1]))
			sprint(as+strlen(as), "%.3s %.3s ", fld[1], fld[2]);	/* date, month */
		else
			sprint(as+strlen(as), "%.3s %.3s ", fld[2], fld[1]);	/* date, month */
		/* do we use time or year?  depends on whether year matches this one */
		if(thisyear(fld[5])){
			if(strchr(fld[3], ':') != nil)
				sprint(as+strlen(as), "%.5s ", fld[3]);	/* time */
			else if(strchr(fld[4], ':') != nil)
				sprint(as+strlen(as), "%.5s ", fld[4]);	/* time */
		}else
			sprint(as+strlen(as), "%.4s ", fld[5]);	/* year */
	}
	free(s);
	return as;
}

char*
readfile(char *dir, char *name, int *np)
{
	char *file, *data;
	int len;
	Dir *d;
	CFid *fid;
	char buf[1];

	if(np != nil)
		*np = 0;
	file = estrstrdup(dir, name);
	fid = mailopen(file, OREAD);
	if(fid == nil)
		return nil;
	d = fsdirfstat(fid);
	if(d && d->length == 0){
		/* some files, e.g. body, are not loaded until we read them */
		fsread(fid, buf, 1);
		fsseek(fid, 0, 0);
		free(d);
		d = fsdirfstat(fid);
	}	
	free(file);
	len = 0;
	if(d != nil)
		len = d->length;
	free(d);
	data = emalloc(len+1);
	len = fsreadn(fid, data, len);
	if(len <= 0){
		fsclose(fid);
		free(data);
		return nil;
	}
	fsclose(fid);
	if(np != nil)
		*np = len;
	return data;
}

char*
info(Message *m, int ind, int ogf)
{
	char *i;
	int j, len, lens;
	char *p;
	char fmt[80], s[80];

	if (ogf)
		p=m->to;
	else
		p=m->fromcolon;

	if(ind==0 && shortmenu){
		len = 30;
		lens = 30;
		if(shortmenu > 1){
			len = 10;
			lens = 25;
		}
		if(ind==0 && m->subject[0]=='\0'){
			snprint(fmt, sizeof fmt, " %%-%d.%ds", len, len);
			snprint(s, sizeof s, fmt, p);
		}else{
			snprint(fmt, sizeof fmt, " %%-%d.%ds  %%-%d.%ds", len, len, lens, lens);
			snprint(s, sizeof s, fmt, p, m->subject);
		}
		i = estrdup(s);

		return i;
	} 

	i = estrdup("");
	i = eappend(i, "\t", p);
	i = egrow(i, "\t", stripdate(m->date));
	if(ind == 0){
		if(strcmp(m->type, "text")!=0 && strncmp(m->type, "text/", 5)!=0 && 
		   strncmp(m->type, "multipart/", 10)!=0)
			i = egrow(i, "\t(", estrstrdup(m->type, ")"));
	}else if(strncmp(m->type, "multipart/", 10) != 0)
		i = egrow(i, "\t(", estrstrdup(m->type, ")"));
	if(m->subject[0] != '\0'){
		i = eappend(i, "\n", nil);
		for(j=0; j<ind; j++)
			i = eappend(i, "\t", nil);
		i = eappend(i, "\t", m->subject);
	}
	return i;
}

void
mesgmenu0(Window *w, Message *mbox, char *realdir, char *dir, int ind, CFid *fd, int onlyone, int dotail)
{
	int i;
	Message *m;
	char *name, *tmp;
	int ogf=0;

	if(strstr(realdir, "outgoing") != nil)
		ogf=1;

	/* show mail box in reverse order, pieces in forward order */
	if(ind > 0)
		m = mbox->head;
	else
		m = mbox->tail;
	while(m != nil){
		for(i=0; i<ind; i++)
			fsprint(fd, "\t");
		if(ind != 0)
			fsprint(fd, "  ");
		name = estrstrdup(dir, m->name);
		tmp = info(m, ind, ogf);
		fsprint(fd, "%s%s\n", name, tmp);
		free(tmp);
		if(dotail && m->tail)
			mesgmenu0(w, m, realdir, name, ind+1, fd, 0, dotail);
		free(name);
		if(ind)
			m = m->next;
		else
			m = m->prev;
		if(onlyone)
			m = nil;
	}
}

void
mesgmenu(Window *w, Message *mbox)
{
	winopenbody(w, OWRITE);
	mesgmenu0(w, mbox, mbox->name, "", 0, w->body, 0, !shortmenu);
	winclosebody(w);
}

/* one new message has arrived, as mbox->tail */
void
mesgmenunew(Window *w, Message *mbox)
{
	Biobuf *b;

	winselect(w, "0", 0);
	w->data = winopenfile(w, "data");
	b = emalloc(sizeof(Biobuf));
	mesgmenu0(w, mbox, mbox->name, "", 0, w->data, 1, !shortmenu);
	free(b);
	if(!mbox->dirty)
		winclean(w);
	/* select tag line plus following indented lines, but not final newline (it's distinctive) */
	winselect(w, "0/.*\\n((\t.*\\n)*\t.*)?/", 1);
	fsclose(w->addr);
	fsclose(w->data);
	w->addr = nil;
	w->data = nil;
}

char*
name2regexp(char *prefix, char *s)
{
	char *buf, *p, *q;

	buf = emalloc(strlen(prefix)+2*strlen(s)+50);	/* leave room to append more */
	p = buf;
	*p++ = '0';
	*p++ = '/';
	*p++ = '^';
	strcpy(p, prefix);
	p += strlen(prefix);
	for(q=s; *q!='\0'; q++){
		if(strchr(regexchars, *q) != nil)
			*p++ = '\\';
		*p++ = *q;
	}
	*p++ = '/';
	*p = '\0';
	return buf;
}

void
mesgmenumarkdel(Window *w, Message *mbox, Message *m, int writeback)
{
	char *buf;


	if(m->deleted)
		return;
	m->writebackdel = writeback;
	if(w->data == nil)
		w->data = winopenfile(w, "data");
	buf = name2regexp("", m->name);
	strcat(buf, "-#0");
	if(winselect(w, buf, 1))
		fswrite(w->data, deleted, 10);
	free(buf);
	fsclose(w->data);
	fsclose(w->addr);
	w->addr = nil;
	w->data = nil;
	mbox->dirty = 1;
	m->deleted = 1;
}

void
mesgmenumarkundel(Window *w, Message *v, Message *m)
{
	char *buf;

	USED(v);
	if(m->deleted == 0)
		return;
	if(w->data == nil)
		w->data = winopenfile(w, "data");
	buf = name2regexp(deletedrx, m->name);
	if(winselect(w, buf, 1))
		if(winsetaddr(w, deletedaddr, 1))
			fswrite(w->data, "", 0);
	free(buf);
	fsclose(w->data);
	fsclose(w->addr);
	w->addr = nil;
	w->data = nil;
	m->deleted = 0;
}

void
mesgmenudel(Window *w, Message *mbox, Message *m)
{
	char *buf;

	if(w->data ==nil)
		w->data = winopenfile(w, "data");
	buf = name2regexp(deletedrx, m->name);
	if(winsetaddr(w, buf, 1) && winsetaddr(w, ".,./.*\\n(\t.*\\n)*/", 1))
		fswrite(w->data, "", 0);
	free(buf);
	fsclose(w->data);
	fsclose(w->addr);
	w->addr = nil;
	w->data = nil;
/* assume caller knows best	mbox->dirty = 1; */
	m->deleted = 1;
}

void
mesgmenumark(Window *w, char *which, char *mark)
{
	char *buf;

	if(w->data == nil)
		w->data = winopenfile(w, "data");
	buf = name2regexp(deletedrx01, which);
	if(winsetaddr(w, buf, 1) && winsetaddr(w, "+0-#1", 1))	/* go to end of line */
		fswrite(w->data, mark, strlen(mark));
	free(buf);
	fsclose(w->data);
	fsclose(w->addr);
	w->addr = nil;
	w->data = nil;
	if(!mbox.dirty)
		winclean(w);
}

void
mesgfreeparts(Message *m)
{
	free(m->name);
	free(m->replyname);
	free(m->from);
	free(m->to);
	free(m->cc);
	free(m->replyto);
	free(m->date);
	free(m->subject);
	free(m->type);
	free(m->disposition);
	free(m->filename);
	free(m->digest);
}

void
mesgdel(Message *mbox, Message *m)
{
	Message *n, *next;

	if(m->opened)
		error("internal error: deleted message still open in mesgdel\n");
	/* delete subparts */
	for(n=m->head; n!=nil; n=next){
		next = n->next;
		mesgdel(m, n);
	}
	/* remove this message from list */
	if(m->next)
		m->next->prev = m->prev;
	else
		mbox->tail = m->prev;
	if(m->prev)
		m->prev->next = m->next;
	else
		mbox->head = m->next;

	mesgfreeparts(m);
}

int
mesgsave(Message *m, char *s, int save)
{
	int ofd, n, k, ret;
	char *t, *raw, *unixheader, *all;

	if(save){
		if(fsprint(mbox.ctlfd, "save %q %q", s, m->name) < 0){
			fprint(2, "Mail: can't save %s to %s: %r\n", m->name, s);
			return 0;
		}
		return 1;
	}
		
	t = estrstrdup(mbox.name, m->name);
	raw = readfile(t, "raw", &n);
	unixheader = readfile(t, "unixheader", &k);
	if(raw==nil || unixheader==nil){
		fprint(2, "Mail: can't read %s: %r\n", t);
		free(t);
		return 0;
	}
	free(t);

	all = emalloc(n+k+1);
	memmove(all, unixheader, k);
	memmove(all+k, raw, n);
	memmove(all+k+n, "\n", 1);
	n = k+n+1;
	free(unixheader);
	free(raw);
	ret = 1;
	s = estrdup(s);
	if(s[0] != '/')
		s = egrow(estrdup(mailboxdir), "/", s);
	ofd = open(s, OWRITE);
	if(ofd < 0){
		fprint(2, "Mail: can't open %s: %r\n", s);
		ret = 0;
	}else if(seek(ofd, 0LL, 2)<0 || write(ofd, all, n)!=n){
		fprint(2, "Mail: save failed: can't write %s: %r\n", s);
		ret = 0;
	}
	free(all);
	close(ofd);
	free(s);
	return ret;
}

int
mesgcommand(Message *m, char *cmd)
{
	char *s;
	char *args[10];
	int save, ok, ret, nargs;

	s = cmd;
	ret = 1;
	nargs = tokenize(s, args, nelem(args));
	if(nargs == 0)
		return 0;
	if(strcmp(args[0], "Post") == 0){
		mesgsend(m);
		goto Return;
	}
	if(strncmp(args[0], "Save", 4) == 0 || strncmp(args[0], "Write", 5) == 0){
		if(m->isreply)
			goto Return;
		save = args[0][0]=='S';
		if(save)
			s = estrdup("\t[saved");
		else
			s = estrdup("\t[wrote");
		if(nargs==1 || strcmp(args[1], "")==0){
			ok = mesgsave(m, "stored", save);
		}else{
			ok = mesgsave(m, args[1], save);
			s = eappend(s, " ", args[1]);
		}
		if(ok){
			s = egrow(s, "]", nil);
			mesgmenumark(mbox.w, m->name, s);
		}
		free(s);
		goto Return;
	}
	if(strcmp(args[0], "Reply")==0){
		if(nargs>=2 && strcmp(args[1], "all")==0)
			mkreply(m, "Replyall", nil, nil, nil);
		else
			mkreply(m, "Reply", nil, nil, nil);
		goto Return;
	}
	if(strcmp(args[0], "Q") == 0){
		s = winselection(m->w);	/* will be freed by mkreply */
		if(nargs>=3 && strcmp(args[1], "Reply")==0 && strcmp(args[2], "all")==0)
			mkreply(m, "QReplyall", nil, nil, s);
		else
			mkreply(m, "QReply", nil, nil, s);
		goto Return;
	}
	if(strcmp(args[0], "Del") == 0){
		if(windel(m->w, 0)){
			windecref(m->w);
			m->w = nil;
			if(m->isreply)
				delreply(m);
			else{
				m->opened = 0;
				m->tagposted = 0;
			}
			free(cmd);
			threadexits(nil);
		}
		goto Return;
	}
	if(strcmp(args[0], "Delmesg") == 0){
		if(!m->isreply){
			mesgmenumarkdel(wbox, &mbox, m, 1);
			free(cmd);	/* mesgcommand might not return */
			mesgcommand(m, estrdup("Del"));
			return 1;
		}
		goto Return;
	}
	if(strcmp(args[0], "UnDelmesg") == 0){
		if(!m->isreply && m->deleted)
			mesgmenumarkundel(wbox, &mbox, m);
		goto Return;
	}
/*	if(strcmp(args[0], "Headers") == 0){ */
/*		m->showheaders(); */
/*		return True; */
/*	} */

	ret = 0;

    Return:
	free(cmd);
	return ret;
}

void
mesgtagpost(Message *m)
{
	if(m->tagposted)
		return;
	wintagwrite(m->w, " Post", 5);
	m->tagposted = 1;
}

/* need to expand selection more than default word */
#pragma varargck argpos eval 2

long
eval(Window *w, char *s, ...)
{
	char buf[64];
	va_list arg;

	va_start(arg, s);
	vsnprint(buf, sizeof buf, s, arg);
	va_end(arg);

	if(winsetaddr(w, buf, 1)==0)
		return -1;

	if(fspread(w->addr, buf, 24, 0) != 24)
		return -1;
	return strtol(buf, 0, 10);
}

int
isemail(char *s)
{
	int nat;

	nat = 0;
	for(; *s; s++)
		if(*s == '@')
			nat++;
		else if(!isalpha(*s) && !isdigit(*s) && !strchr("_.-+/", *s))
			return 0;
	return nat==1;
}

char addrdelim[] =  "/[ \t\\n<>()\\[\\]]/";
char*
expandaddr(Window *w, Event *e)
{
	char *s;
	long q0, q1;

	if(e->q0 != e->q1)	/* cannot happen */
		return nil;

	q0 = eval(w, "#%d-%s", e->q0, addrdelim);
	if(q0 == -1)	/* bad char not found */
		q0 = 0;
	else			/* increment past bad char */
		q0++;

	q1 = eval(w, "#%d+%s", e->q0, addrdelim);
	if(q1 < 0){
		q1 = eval(w, "$");
		if(q1 < 0)
			return nil;
	}
	if(q0 >= q1)
		return nil;
	s = emalloc((q1-q0)*UTFmax+1);
	winread(w, q0, q1, s);
	return s;
}

int
replytoaddr(Window *w, Message *m, Event *e, char *s)
{
	int did;
	char *buf;
	Plumbmsg *pm;

	buf = nil;
	did = 0;
	if(e->flag & 2){
		/* autoexpanded; use our own bigger expansion */
		buf = expandaddr(w, e);
		if(buf == nil)
			return 0;
		s = buf;
	}
	if(isemail(s)){
		did = 1;
		pm = emalloc(sizeof(Plumbmsg));
		pm->src = estrdup("Mail");
		pm->dst = estrdup("sendmail");
		pm->data = estrdup(s);
		pm->ndata = -1;
		if(m->subject && m->subject[0]){
			pm->attr = emalloc(sizeof(Plumbattr));
			pm->attr->name = estrdup("Subject");
			if(tolower(m->subject[0]) != 'r' || tolower(m->subject[1]) != 'e' || m->subject[2] != ':')
				pm->attr->value = estrstrdup("Re: ", m->subject);
			else
				pm->attr->value = estrdup(m->subject);
			pm->attr->next = nil;
		}
		if(plumbsendtofid(plumbsendfd, pm) < 0)
			fprint(2, "error writing plumb message: %r\n");
		plumbfree(pm);
	}
	free(buf);
	return did;
}


void
mesgctl(void *v)
{
	Message *m;
	Window *w;
	Event *e, *eq, *e2, *ea;
	int na, nopen, i, j;
	char *os, *s, *t, *buf;

	m = v;
	w = m->w;
	threadsetname("mesgctl");
	winincref(w);
	proccreate(wineventproc, w, STACK);
	for(;;){
		e = recvp(w->cevent);
		switch(e->c1){
		default:
		Unk:
			print("unknown message %c%c\n", e->c1, e->c2);
			break;

		case 'E':	/* write to body; can't affect us */
			break;

		case 'F':	/* generated by our actions; ignore */
			break;

		case 'K':	/* type away; we don't care */
		case 'M':
			switch(e->c2){
			case 'x':	/* mouse only */
			case 'X':
				ea = nil;
				eq = e;
				if(e->flag & 2){
					e2 = recvp(w->cevent);
					eq = e2;
				}
				if(e->flag & 8){
					ea = recvp(w->cevent);
					recvp(w->cevent);
					na = ea->nb;
				}else
					na = 0;
				if(eq->q1>eq->q0 && eq->nb==0){
					s = emalloc((eq->q1-eq->q0)*UTFmax+1);
					winread(w, eq->q0, eq->q1, s);
				}else
					s = estrdup(eq->b);
				if(na){
					t = emalloc(strlen(s)+1+na+1);
					sprint(t, "%s %s", s, ea->b);
					free(s);
					s = t;
				}
				if(!mesgcommand(m, s))	/* send it back */
					winwriteevent(w, e);
				break;

			case 'l':	/* mouse only */
			case 'L':
				buf = nil;
				eq = e;
				if(e->flag & 2){
					e2 = recvp(w->cevent);
					eq = e2;
				}
				s = eq->b;
				if(eq->q1>eq->q0 && eq->nb==0){
					buf = emalloc((eq->q1-eq->q0)*UTFmax+1);
					winread(w, eq->q0, eq->q1, buf);
					s = buf;
				}
				os = s;
				nopen = 0;
				do{
					/* skip mail box name if present */
					if(strncmp(s, mbox.name, strlen(mbox.name)) == 0)
						s += strlen(mbox.name);
					if(strstr(s, "body") != nil){
						/* strip any known extensions */
						for(i=0; ports[i].suffix!=nil; i++){
							j = strlen(ports[i].suffix);
							if(strlen(s)>j && strcmp(s+strlen(s)-j, ports[i].suffix)==0){
								s[strlen(s)-j] = '\0';
								break;
							}
						}
						if(strlen(s)>5 && strcmp(s+strlen(s)-5, "/body")==0)
							s[strlen(s)-4] = '\0';	/* leave / in place */
					}
					nopen += mesgopen(&mbox, mbox.name, s, m, 0, nil);
					while(*s!=0 && *s++!='\n')
						;
				}while(*s);
				if(nopen == 0 && e->c1 == 'L')
					nopen += replytoaddr(w, m, e, os);
				if(nopen == 0)
					winwriteevent(w, e);
				free(buf);
				break;

			case 'I':	/* modify away; we don't care */
			case 'D':
				mesgtagpost(m);
				/* fall through */
			case 'd':
			case 'i':
				break;

			default:
				goto Unk;
			}
		}
	}
}

void
mesgline(Message *m, char *header, char *value)
{
	if(strlen(value) > 0)
		fsprint(m->w->body, "%s: %s\n", header, value);
}

int
isprintable(char *type)
{
	int i;

	for(i=0; goodtypes[i]!=nil; i++)
		if(strcmp(type, goodtypes[i])==0)
			return 1;
	return 0;
}

char*
ext(char *type)
{
	int i;

	for(i=0; ports[i].type!=nil; i++)
		if(strcmp(type, ports[i].type)==0)
			return ports[i].suffix;
	return "";
}

void
mimedisplay(Message *m, char *name, char *rootdir, Window *w, int fileonly)
{
	char *dest;

	if(strcmp(m->disposition, "file")==0 || strlen(m->filename)!=0 || !fileonly){
		if(strlen(m->filename) == 0)
			dest = estrstrdup("a", ext(m->type));
		else
			dest = estrdup(m->filename);
		if(m->filename[0] != '/')
			dest = egrow(estrdup(home), "/", dest);
		fsprint(w->body, "\t9p read %s/%s/%sbody > %s\n",
			srvname, mboxname, name, dest);
		free(dest);
	}
}

void
printheader(char *dir, CFid *fid, char **okheaders)
{
	char *s;
	char *lines[100];
	int i, j, n;

	s = readfile(dir, "header", nil);
	if(s == nil)
		return;
	n = getfields(s, lines, nelem(lines), 0, "\n");
	for(i=0; i<n; i++)
		for(j=0; okheaders[j]; j++)
			if(cistrncmp(lines[i], okheaders[j], strlen(okheaders[j])) == 0)
				fsprint(fid, "%s\n", lines[i]);
	free(s);
}

void
mesgload(Message *m, char *rootdir, char *file, Window *w)
{
	char *s, *subdir, *name, *dir;
	Message *mp, *thisone;
	int n;

	dir = estrstrdup(rootdir, file);

	if(strcmp(m->type, "message/rfc822") != 0){	/* suppress headers of envelopes */
		if(strlen(m->from) > 0){
			fsprint(w->body, "From: %s\n", m->from);
			mesgline(m, "Date", m->date);
			mesgline(m, "To", m->to);
			mesgline(m, "CC", m->cc);
			mesgline(m, "Subject", m->subject);
			printheader(dir, w->body, extraheaders);
		}else{
			printheader(dir, w->body, okheaders);
			printheader(dir, w->body, extraheaders);
		}
		fsprint(w->body, "\n");
	}

	if(m->level == 1 && m->recursed == 0){
		m->recursed = 1;
		readmbox(m, rootdir, m->name);
	}
	if(m->head == nil){	/* single part message */
		if(strcmp(m->type, "text")==0 || strncmp(m->type, "text/", 5)==0){
			mimedisplay(m, m->name, rootdir, w, 1);
			s = readbody(m->type, dir, &n);
			winwritebody(w, s, n);
			free(s);
		}else
			mimedisplay(m, m->name, rootdir, w, 0);
	}else{
		/* multi-part message, either multipart/* or message/rfc822 */
		thisone = nil;
		if(strcmp(m->type, "multipart/alternative") == 0){
			thisone = m->head;	/* in case we can't find a good one */
			for(mp=m->head; mp!=nil; mp=mp->next)
				if(isprintable(mp->type)){
					thisone = mp;
					break;
				}
		}
		for(mp=m->head; mp!=nil; mp=mp->next){
			if(thisone!=nil && mp!=thisone)
				continue;
			subdir = estrstrdup(dir, mp->name);
			name = estrstrdup(file, mp->name);
			/* skip first element in name because it's already in window name */
			if(mp != m->head)
				fsprint(w->body, "\n===> %s (%s) [%s]\n", strchr(name, '/')+1, mp->type, mp->disposition);
			if(strcmp(mp->type, "text")==0 || strncmp(mp->type, "text/", 5)==0){
				mimedisplay(mp, name, rootdir, w, 1);
				printheader(subdir, w->body, okheaders);
				printheader(subdir, w->body, extraheaders);
				winwritebody(w, "\n", 1);
				s = readbody(mp->type, subdir, &n);
				winwritebody(w, s, n);
				free(s);
			}else{
				if(strncmp(mp->type, "multipart/", 10)==0 || strcmp(mp->type, "message/rfc822")==0){
					mp->w = w;
					mesgload(mp, rootdir, name, w);
					mp->w = nil;
				}else
					mimedisplay(mp, name, rootdir, w, 0);
			}
			free(name);
			free(subdir);
		}
	}
	free(dir);
}

int
tokenizec(char *str, char **args, int max, char *splitc)
{
	int i, na;
	int intok = 0;
	char *p;

	if(max <= 0)
		return 0;
		
/*	if(strchr(str, ',') || strchr(str, '"') || strchr(str, '<') || strchr(str, '(')) */
/*		splitc = ","; */
	for(na=0; *str != '\0';str++){
		if(strchr(splitc, *str) == nil){
			if(intok)
				continue;
			args[na++] = str;
			intok = 1;
		}else{
			/* it's a separator/skip character */
			*str = '\0';
			if(intok){
				intok = 0;
				if(na >= max)
					break;
			}
		}
	}
	for(i=0; i<na; i++){
		while(*args[i] && strchr(" \t\r\n", *args[i]))
			args[i]++;
		p = args[i]+strlen(args[i]);
		while(p>args[i] && strchr(" \t\r\n", *(p-1)))
			*--p = 0;
	}
	return na;
}

Message*
mesglookup(Message *mbox, char *name, char *digest)
{
	int n;
	Message *m;
	char *t;

	if(digest && digest[0]){
		/* can find exactly */
		for(m=mbox->head; m!=nil; m=m->next)
			if(strcmp(digest, m->digest) == 0)
				break;
		return m;
	}

	n = strlen(name);
	if(n == 0)
		return nil;
	if(name[n-1] == '/')
		t = estrdup(name);
	else
		t = estrstrdup(name, "/");
	for(m=mbox->head; m!=nil; m=m->next)
		if(strcmp(t, m->name) == 0)
			break;
	free(t);
	return m;
}

/*
 * Find plumb port, knowing type is text, given file name (by extension)
 */
int
plumbportbysuffix(char *file)
{
	char *suf;
	int i, nsuf, nfile;

	nfile = strlen(file);
	for(i=0; ports[i].type!=nil; i++){
		suf = ports[i].suffix;
		nsuf = strlen(suf);
		if(nfile > nsuf)
			if(cistrncmp(file+nfile-nsuf, suf, nsuf) == 0)
				return i;
	}
	return 0;
}

/*
 * Find plumb port using type and file name (by extension)
 */
int
plumbport(char *type, char *file)
{
	int i;

	for(i=0; ports[i].type!=nil; i++)
		if(strncmp(type, ports[i].type, strlen(ports[i].type)) == 0)
			return i;
	/* see if it's a text type */
	for(i=0; goodtypes[i]!=nil; i++)
		if(strncmp(type, goodtypes[i], strlen(goodtypes[i])) == 0)
			return plumbportbysuffix(file);
	return -1;
}

void
plumb(Message *m, char *dir)
{
	int i;
	char *port;
	Plumbmsg *pm;

	if(strlen(m->type) == 0)
		return;
	i = plumbport(m->type, m->filename);
	if(i < 0)
		fprint(2, "can't find destination for message subpart\n");
	else{
		port = ports[i].port;
		pm = emalloc(sizeof(Plumbmsg));
		pm->src = estrdup("Mail");
		if(port)
			pm->dst = estrdup(port);
		else
			pm->dst = nil;
		pm->wdir = nil;
		pm->type = estrdup("text");
		pm->ndata = -1;
		pm->data = estrstrdup(dir, "body");
		pm->data = eappend(pm->data, "", ports[i].suffix);
		if(plumbsendtofid(plumbsendfd, pm) < 0)
			fprint(2, "error writing plumb message: %r\n");
		plumbfree(pm);
	}
}

int
mesgopen(Message *mbox, char *dir, char *s, Message *mesg, int plumbed, char *digest)
{
	char *t, *u, *v;
	Message *m;
	char *direlem[10];
	int i, ndirelem, reuse;

	/* find white-space-delimited first word */
	for(t=s; *t!='\0' && !isspace(*t); t++)
		;
	u = emalloc(t-s+1);
	memmove(u, s, t-s);
	/* separate it on slashes */
	ndirelem = tokenizec(u, direlem, nelem(direlem), "/");
	if(ndirelem <= 0){
    Error:
		free(u);
		return 0;
	}
	/*XXX
	if(plumbed)
		drawtopwindow();
	*/
	/* open window for message */
	m = mesglookup(mbox, direlem[0], digest);
	if(m == nil)
		goto Error;
	if(mesg!=nil && m!=mesg)	/* string looked like subpart but isn't part of this message */
		goto Error;
	if(m->opened == 0){
		if(m->w == nil){
			reuse = 0;
			m->w = newwindow();
		}else{
			reuse = 1;
			/* re-use existing window */
			if(winsetaddr(m->w, "0,$", 1)){
				if(m->w->data == nil)
					m->w->data = winopenfile(m->w, "data");
				fswrite(m->w->data, "", 0);
			}
		}
		v = estrstrdup(mbox->name, m->name);
		winname(m->w, v);
		free(v);
		if(!reuse){
			if(m->deleted)
				wintagwrite(m->w, "Q Reply all UnDelmesg Save ", 2+6+4+10+5);
			else
				wintagwrite(m->w, "Q Reply all Delmesg Save ", 2+6+4+8+5);
		}
		threadcreate(mesgctl, m, STACK);
		winopenbody(m->w, OWRITE);
		mesgload(m, dir, m->name, m->w);
		winclosebody(m->w);
		/* sleep(100); */
		winclean(m->w);
		m->opened = 1;
		if(ndirelem == 1){
			free(u);
			return 1;
		}
	}
	if(ndirelem == 1 && plumbport(m->type, m->filename) <= 0){
		/* make sure dot is visible */
		ctlprint(m->w->ctl, "show\n");
		return 0;
	}
	/* walk to subpart */
	dir = estrstrdup(dir, m->name);
	for(i=1; i<ndirelem; i++){
		m = mesglookup(m, direlem[i], digest);
		if(m == nil)
			break;
		dir = egrow(dir, m->name, nil);
	}
	if(m != nil && plumbport(m->type, m->filename) > 0)
		plumb(m, dir);
	free(dir);
	free(u);
	return 1;
}

void
rewritembox(Window *w, Message *mbox)
{
	Message *m, *next;
	char *deletestr, *t;
	int nopen;

	deletestr = estrstrdup("delete ", fsname);

	nopen = 0;
	for(m=mbox->head; m!=nil; m=next){
		next = m->next;
		if(m->deleted == 0)
			continue;
		if(m->opened){
			nopen++;
			continue;
		}
		if(m->writebackdel){
			/* messages deleted by plumb message are not removed again */
			t = estrdup(m->name);
			if(strlen(t) > 0)
				t[strlen(t)-1] = '\0';
			deletestr = egrow(deletestr, " ", t);
		}
		mesgmenudel(w, mbox, m);
		mesgdel(mbox, m);
	}
	if(fswrite(mbox->ctlfd, deletestr, strlen(deletestr)) < 0)
		fprint(2, "Mail: warning: error removing mail message files: %r\n");
	free(deletestr);
	winselect(w, "0", 0);
	if(nopen == 0)
		winclean(w);
	mbox->dirty = 0;
}

/* name is a full file name, but it might not belong to us */
Message*
mesglookupfile(Message *mbox, char *name, char *digest)
{
	int k, n;

	k = strlen(name);
	n = strlen(mbox->name);
	if(k==0 || strncmp(name, mbox->name, n) != 0){
/*		fprint(2, "Mail: message %s not in this mailbox\n", name); */
		return nil;
	}
	return mesglookup(mbox, name+n, digest);
}
