/*
 * Mail file system.
 * 
 * Serve the bulk of requests out of memory, so they can
 * be in the main loop (will never see their flushes). 
 * Some requests do block and they get handled in
 * separate threads.  They're all okay to give up on
 * early, though, so we just respond saying interrupted
 * and then when they finish, silently discard the request.

TO DO:

	decode subject, etc.
	decode body

	digest
	disposition
	filename
	
	ctl messages

	fetch mail on demand

 */

#include "a.h"

enum
{
	/* directories */
	Qroot,
	Qbox,
	Qmsg,

	/* control files */
	Qctl,
	Qboxctl,
	Qsearch,

	/* message header - same order as struct Hdr */
	Qdate,
	Qsubject,
	Qfrom,
	Qsender,
	Qreplyto,
	Qto,
	Qcc,
	Qbcc,
	Qinreplyto,
	Qmessageid,
	
	/* part data - same order as stuct Part */
	Qtype,
	Qidstr,
	Qdesc,
	Qencoding,	/* only here temporarily! */
	Qcharset,
	Qraw,
	Qrawheader,
	Qrawbody,
	Qmimeheader,
	
	/* part numbers - same order as struct Part */
	Qsize,
	Qlines,

	/* other message files */
	Qbody,
	Qheader,
	Qdigest,
	Qdisposition,
	Qfilename,
	Qflags,
	Qinfo,
	Qrawunix,
	Qunixdate,
	Qunixheader,
	
	Qfile0 = Qbody,
	Qnfile = Qunixheader+1-Qfile0,
};

static char Egreg[] = "gone postal";
static char Enobox[] = "no such mailbox";
static char Enomsg[] = "no such message";
static char Eboxgone[] = "mailbox not available";
static char Emsggone[] = "message not available";
static char Eperm[] = "permission denied";
static char Ebadctl[] = "bad control message";

Channel *fsreqchan;
Srv fs;
Qid rootqid;
ulong t0;

void
responderror(Req *r)
{
	char e[ERRMAX];
	
	rerrstr(e, sizeof e);
	respond(r, e);
}

int
qtype(Qid q)
{
	return q.path&0x3F;
}

int
qboxid(Qid q)
{
	return (q.path>>40)&0xFFFF;
}

int
qmsgid(Qid q)
{
	return ((q.path>>32)&0xFF000000) | ((q.path>>16)&0xFFFFFF);
}

int
qpartid(Qid q)
{
	return ((q.path>>6)&0x3FF);
}

Qid
qid(int ctl, Box *box, Msg *msg, Part *part)
{
	Qid q;
	
	q.type = 0;
	if(ctl == Qroot || ctl == Qbox || ctl == Qmsg)
		q.type = QTDIR;
	q.path = (vlong)((msg ? msg->id : 0)&0xFF000000)<<32;
	q.path |= (vlong)((msg ? msg->id : 0)&0xFFFFFF)<<16;
	q.path |= (vlong)((box ? box->id : 0)&0xFFFF)<<40;
	q.path |= ((part ? part->ix : 0)&0x3FF)<<6;
	q.path |= ctl&0x3F;
	q.vers = box ? box->validity : 0;
	return q;
}

int
parseqid(Qid q, Box **box, Msg **msg, Part **part)
{
	*msg = nil;
	*part = nil;
	
	*box = boxbyid(qboxid(q));
	if(*box){
		*msg = msgbyid(*box, qmsgid(q));
	}
	if(*msg)
		*part = partbyid(*msg, qpartid(q));
	return qtype(q);
}

static struct {
	int type;
	char *name;
} typenames[] = {
	Qbody,			"body",
	Qbcc,			"bcc",
	Qcc,				"cc",
	Qdate,			"date",
	Qfilename,		"filename",
	Qflags,			"flags",
	Qfrom,			"from",
	Qheader,			"header",
	Qinfo,			"info",
	Qinreplyto,		"inreplyto",
	Qlines,			"lines",
	Qmimeheader,	"mimeheader",
	Qmessageid,		"messageid",
	Qraw,			"raw",
	Qrawunix,		"rawunix",
	Qrawbody,		"rawbody",
	Qrawheader,		"rawheader",
	Qreplyto,			"replyto",
	Qsender,			"sender",
	Qsubject,		"subject",
	Qto,				"to",
	Qtype,			"type",
	Qunixdate,		"unixdate",
	Qunixheader,		"unixheader",
	Qidstr,			"idstr",
	Qdesc,			"desc",
	Qencoding,		"encoding",
	Qcharset,		"charset",
};

char*
nameoftype(int t)
{
	int i;
	
	for(i=0; i<nelem(typenames); i++)
		if(typenames[i].type == t)
			return typenames[i].name;
	return "???";
}

int
typeofname(char *name)
{
	int i;
	
	for(i=0; i<nelem(typenames); i++)
		if(strcmp(typenames[i].name, name) == 0)
			return typenames[i].type;
	return 0;
}

static void
fsattach(Req *r)
{
	r->fid->qid = rootqid;
	r->ofcall.qid = rootqid;
	respond(r, nil);
}

static int
isnumber(char *s)
{
	int n;

	if(*s < '1' || *s > '9')
		return 0;
	n = strtol(s, &s, 10);
	if(*s != 0)
		return 0;
	return n;
}

static char*
fswalk1(Fid *fid, char *name, void *arg)
{
	int a, type;
	Box *b, *box;
	Msg *msg;
	Part *p, *part;

	USED(arg);
	
	switch(type = parseqid(fid->qid, &box, &msg, &part)){
	case Qroot:
		if(strcmp(name, "..") == 0)
			return nil;
		if(strcmp(name, "ctl") == 0){
			fid->qid = qid(Qctl, nil, nil, nil);
			return nil;
		}
		if((box = boxbyname(name)) != nil){
			fid->qid = qid(Qbox, box, nil, nil);
			return nil;
		}
		break;

	case Qbox:
		/*
		 * Would be nice if .. could work even if the box is gone,
		 * but we don't know how deep the directory was.
		 */
		if(box == nil)
			return Eboxgone;
		if(strcmp(name, "..") == 0){
			if((box = box->parent) == nil){
				fid->qid = rootqid;
				return nil;
			}
			fid->qid = qid(Qbox, box, nil, nil);
			return nil;
		}
		if(strcmp(name, "ctl") == 0){
			fid->qid = qid(Qboxctl, box, nil, nil);
			return nil;
		}
		if(strcmp(name, "search") == 0){
			fid->qid = qid(Qsearch, box, nil, nil);
			return nil;
		}
		if((b = subbox(box, name)) != nil){
			fid->qid = qid(Qbox, b, nil, nil);
			return nil;
		}
		if((a = isnumber(name)) != 0){
			if((msg = msgbyid(box, a)) == nil){
				return Enomsg;
			}
			fid->qid = qid(Qmsg, box, msg, nil);
			return nil;
		}
		break;

	case Qmsg:
		if(strcmp(name, "..") == 0){
			if(part == msg->part[0]){
				fid->qid = qid(Qbox, box, nil, nil);
				return nil;
			}
			fid->qid = qid(Qmsg, box, msg, part->parent);
			return nil;
		}
		if((type = typeofname(name)) > 0){
			/* XXX - should check that type makes sense (see msggen) */
			fid->qid = qid(type, box, msg, part);
			return nil;
		}
		if((a = isnumber(name)) != 0){
			if((p = subpart(part, a-1)) != nil){
				fid->qid = qid(Qmsg, box, msg, p);
				return nil;
			}
		}
		break;
	}
	return "not found";
}

static void
fswalk(Req *r)
{
	walkandclone(r, fswalk1, nil, nil);
}

static struct {
	int flag;
	char *name;
} flagtab[] = {
	FlagJunk,			"junk",
	FlagNonJunk,		"notjunk",
	FlagReplied,	"replied",
	FlagFlagged,		"flagged",
//	FlagDeleted,		"deleted",
	FlagDraft,		"draft",
	FlagSeen,			"seen",
};

static void
addaddrs(Fmt *fmt, char *prefix, char *addrs)
{
	char **f;
	int i, nf, inquote;
	char *p, *sep;
	
	if(addrs == nil)
		return;
	addrs = estrdup(addrs);
	nf = 0;
	inquote = 0;
	for(p=addrs; *p; p++){
		if(*p == ' ' && !inquote)
			nf++;
		if(*p == '\'')
			inquote = !inquote;
	}
	nf += 10;
	f = emalloc(nf*sizeof f[0]);
	nf = tokenize(addrs, f, nf);
	fmtprint(fmt, "%s:", prefix);
	sep = " ";
	for(i=0; i+1<nf; i+=2){
		if(f[i][0])
			fmtprint(fmt, "%s%s <%s>", sep, f[i], f[i+1]);
		else
			fmtprint(fmt, "%s%s", sep, f[i+1]);
		sep = ", ";
	}
	fmtprint(fmt, "\n");
	free(addrs);
}

static void
mkbody(Part *p, Qid q)
{
	char *t;
	int len;
	
	if(p->msg->part[0] == p)
		t = p->rawbody;
	else
		t = p->raw;
	if(t == nil)
		return;

	len = -1;
	if(p->encoding && cistrcmp(p->encoding, "quoted-printable") == 0)
		t = decode(QuotedPrintable, t, &len);
	else if(p->encoding && cistrcmp(p->encoding, "base64") == 0)
		t = decode(Base64, t, &len);
	else
		t = estrdup(t);

	if(p->charset){
		t = tcs(p->charset, t);
		len = -1;
	}
	p->body = t;
	if(len == -1)
		p->nbody = strlen(t);
	else
		p->nbody = len;
}

static Qid ZQ;
	
static int
filedata(int type, Box *box, Msg *msg, Part *part, char **pp, int *len, int *freeme, int force, Qid q)
{
	int i, inquote, n, t;
	char *from, *s;
	static char buf[256];
	Fmt fmt;

	*pp = nil;
	*freeme = 0;
	if(len)
		*len = -1;

	if(msg == nil || part == nil){
		werrstr(Emsggone);
		return -1;
	}
	switch(type){
	case Qdate:
	case Qsubject:
	case Qfrom:
	case Qsender:
	case Qreplyto:
	case Qto:
	case Qcc:
	case Qbcc:
	case Qinreplyto:
	case Qmessageid:
		if(part->hdr == nil){
			werrstr(Emsggone);
			return -1;
		}
		*pp = ((char**)&part->hdr->date)[type-Qdate];
		return 0;
	
	case Qunixdate:
		strcpy(buf, ctime(msg->date));
		*pp = buf;
		return 0;

	case Qunixheader:
		if(part->hdr == nil){
			werrstr(Emsggone);
			return -1;
		}
		from = part->hdr->from;
		if(from == nil)
			from = "???";
		else{
			inquote = 0;
			for(; *from; from++){
				if(*from == '\'')
					inquote = !inquote;
				if(!inquote && *from == ' '){
					from++;
					break;
				}
			}
			if(*from == 0)
				from = part->hdr->from;
		}
		n = snprint(buf, sizeof buf, "From %s %s", from, ctime(msg->date));
		if(n+1 < sizeof buf){
			*pp = buf;
			return 0;
		}
		fmtstrinit(&fmt);
		fmtprint(&fmt, "From %s %s", from, ctime(msg->date));
		s = fmtstrflush(&fmt);
		if(s){
			*pp = s;
			*freeme = 1;
		}else
			*pp = buf;
		return 0;

	case Qtype:
	case Qidstr:
	case Qdesc:
	case Qencoding:
	case Qcharset:
	case Qraw:
	case Qrawheader:
	case Qrawbody:
	case Qmimeheader:
		*pp = ((char**)&part->type)[type-Qtype];
		if(*pp == nil && force){
			switch(type){
			case Qraw:
				imapfetchraw(imap, part);
				break;
			case Qrawheader:
				imapfetchrawheader(imap, part);
				break;
			case Qrawbody:
				imapfetchrawbody(imap, part);
				break;
			case Qmimeheader:
				imapfetchrawmime(imap, part);
				break;
			default:
				return 0;
			}
			/*
			 * We ran fetchsomething, which might have changed
			 * the mailbox contents.  Msg might even be gone.
			 */
			t = parseqid(q, &box, &msg, &part);
			if(t != type || msg == nil || part == nil)
				return 0;
			*pp = ((char**)&part->type)[type-Qtype];
		}
		return 0;

	case Qbody:
		if(part->body){
			*pp = part->body;
			if(len)
				*len = part->nbody;
			return 0;
		}
		if(!force)
			return 0;
		if(part->rawbody == nil){
			if(part->msg->part[0] == part)
				imapfetchrawbody(imap, part);
			else
				imapfetchraw(imap, part);
			t = parseqid(q, &box, &msg, &part);
			if(t != type || msg == nil || part == nil)
				return 0;
		}
		mkbody(part, q);
		*pp = part->body;
		if(len)
			*len = part->nbody;
		return 0;

	case Qsize:
	case Qlines:
		n = ((uint*)&part->size)[type-Qsize];
		snprint(buf, sizeof buf, "%d", n);
		*pp = buf;
		return 0;

	case Qflags:
		s = buf;
		*s = 0;
		for(i=0; i<nelem(flagtab); i++){
			if(msg->flags&flagtab[i].flag){
				if(s > buf)
					*s++ = ' ';
				strcpy(s, flagtab[i].name);
				s += strlen(s);
			}
		}
		*pp = buf;
		return 0;

	case Qinfo:
		fmtstrinit(&fmt);
		if(part == msg->part[0]){
			if(msg->date)
				fmtprint(&fmt, "unixdate %lud %s", msg->date, ctime(msg->date));
			if(msg->flags){
				filedata(Qflags, box, msg, part, pp, nil, freeme, 0, ZQ);
				fmtprint(&fmt, "flags %s\n", buf);
			}
		}
		if(part->hdr){
			if(part->hdr->digest)
				fmtprint(&fmt, "digest %s\n", part->hdr->digest);
			if(part->hdr->from)
				fmtprint(&fmt, "from %s\n", part->hdr->from);
			if(part->hdr->to)
				fmtprint(&fmt, "to %s\n", part->hdr->to);
			if(part->hdr->cc)
				fmtprint(&fmt, "cc %s\n", part->hdr->cc);
			if(part->hdr->replyto)
				fmtprint(&fmt, "replyto %s\n", part->hdr->replyto);
			if(part->hdr->bcc)
				fmtprint(&fmt, "bcc %s\n", part->hdr->bcc);
			if(part->hdr->inreplyto)
				fmtprint(&fmt, "inreplyto %s\n", part->hdr->inreplyto);
			if(part->hdr->date)
				fmtprint(&fmt, "date %s\n", part->hdr->date);
			if(part->hdr->sender)
				fmtprint(&fmt, "sender %s\n", part->hdr->sender);
			if(part->hdr->messageid)
				fmtprint(&fmt, "messageid %s\n", part->hdr->messageid);
			if(part->hdr->subject)
				fmtprint(&fmt, "subject %s\n", part->hdr->subject);
		}
		if(part->type)
			fmtprint(&fmt, "type %s\n", part->type);
		if(part->lines)
			fmtprint(&fmt, "lines %d\n", part->lines);
	//	fmtprint(&fmt, "disposition %s\n", "" /* disposition */);
	//	fmtprint(&fmt, "filename %s\n", "" /* filename */);
	//	fmtprint(&fmt, "digest %s\n", "" /* digest */);
		s = fmtstrflush(&fmt);
		if(s == nil)
			s = estrdup("");
		*freeme = 1;
		*pp = s;
		return 0;

	case Qheader:
		if(part->hdr == nil)
			return 0;
		fmtstrinit(&fmt);
		if(part == msg->part[0])
			fmtprint(&fmt, "Date: %s", ctime(msg->date));
		else
			fmtprint(&fmt, "Date: %s\n", part->hdr->date);
		addaddrs(&fmt, "To", part->hdr->to);
		addaddrs(&fmt, "From", part->hdr->from);
		if(part->hdr->from==nil
		|| (part->hdr->sender && strcmp(part->hdr->sender, part->hdr->from) != 0))
			addaddrs(&fmt, "Sender", part->hdr->sender);
		if(part->hdr->from==nil 
		|| (part->hdr->replyto && strcmp(part->hdr->replyto, part->hdr->from) != 0))
			addaddrs(&fmt, "Reply-To", part->hdr->replyto);
		addaddrs(&fmt, "Subject", part->hdr->subject);
		s = fmtstrflush(&fmt);
		if(s == nil)
			s = estrdup("");
		*freeme = 1;
		*pp = s;
		return 0;

	default:
		werrstr(Egreg);
		return -1;
	}
}

int
filldir(Dir *d, int type, Box *box, Msg *msg, Part *part)
{
	int freeme, len;
	char *s;

	memset(d, 0, sizeof *d);
	if(box){
		d->atime = box->time;
		d->mtime = box->time;
	}else{
		d->atime = t0;
		d->mtime = t0;
	}
	d->uid = estrdup9p("upas");
	d->gid = estrdup9p("upas");
	d->muid = estrdup9p("upas");
	d->qid = qid(type, box, msg, part);

	switch(type){
	case Qroot:
	case Qbox:
	case Qmsg:
		d->mode = 0555|DMDIR;
		if(box && !(box->flags&FlagNoInferiors))
			d->mode = 0775|DMDIR;
		break;
	case Qctl:
	case Qboxctl:
		d->mode = 0222;
		break;
	case Qsearch:
		d->mode = 0666;
		break;
	
	case Qflags:
		d->mode = 0666;
		goto msgfile;
	default:
		d->mode = 0444;
	msgfile:
		if(filedata(type, box, msg, part, &s, &len, &freeme, 0, ZQ) >= 0){
			if(s){
				if(len == -1)
					d->length = strlen(s);
				else
					d->length = len;
				if(freeme)
					free(s);
			}
		}else if(type == Qraw && msg && part == msg->part[0])
			d->length = msg->size;
		break;
	}

	switch(type){
	case Qroot:
		d->name = estrdup9p("/");
		break;
	case Qbox:
		if(box == nil){
			werrstr(Enobox);
			return -1;
		}
		d->name = estrdup9p(box->elem);
		break;
	case Qmsg:
		if(msg == nil){
			werrstr(Enomsg);
			return -1;
		}
		if(part == nil || part == msg->part[0])
			d->name = esmprint("%d", msg->id);
		else
			d->name = esmprint("%d", part->pix+1);
		break;
	case Qctl:
	case Qboxctl:
		d->name = estrdup9p("ctl");
		break;
	case Qsearch:
		d->name = estrdup9p("search");
		break;
	default:
		d->name = estrdup9p(nameoftype(type));
		break;
	}
	return 0;
}
	
static void
fsstat(Req *r)
{
	int type;
	Box *box;
	Msg *msg;
	Part *part;
	
	type = parseqid(r->fid->qid, &box, &msg, &part);
	if(filldir(&r->d, type, box, msg, part) < 0)
		responderror(r);
	else
		respond(r, nil);
}

int
rootgen(int i, Dir *d, void *aux)
{
	USED(aux);
	
	if(i == 0)
		return filldir(d, Qctl, nil, nil, nil);
	i--;
	if(i < rootbox->nsub)
		return filldir(d, Qbox, rootbox->sub[i], nil, nil);
	return -1;
}

int
boxgen(int i, Dir *d, void *aux)
{
	Box *box;

	box = aux;
	if(i == 0)
		return filldir(d, Qboxctl, box, nil, nil);
	i--;
	if(i == 0)
		return filldir(d, Qsearch, box, nil, nil);
	if(i < box->nsub)
		return filldir(d, Qbox, box->sub[i], nil, nil);
	i -= box->nsub;
	if(i < box->nmsg)
		return filldir(d, Qmsg, box, box->msg[i], nil);
	return -1;
}

static int msgdir[] = {
	Qtype, 
	Qbody, Qbcc, Qcc, Qdate, Qflags, Qfrom, Qheader, Qinfo, 
	Qinreplyto, Qlines, Qmimeheader, Qmessageid, 
	Qraw, Qrawunix, Qrawbody, Qrawheader,
	Qreplyto, Qsender, Qsubject, Qto,
	Qunixdate, Qunixheader
};
static int mimemsgdir[] = {
	Qtype, 
	Qbody, Qbcc, Qcc, Qdate, Qfrom, Qheader, Qinfo, 
	Qinreplyto, Qlines, Qmimeheader, Qmessageid, 
	Qraw, Qrawunix, Qrawbody, Qrawheader,
	Qreplyto, Qsender, Qsubject, Qto,
};
static int mimedir[] = {
	Qtype,
	Qbody,
	Qmimeheader,
	Qraw,
};
	
int
msggen(int i, Dir *d, void *aux)
{
	Box *box;
	Msg *msg;
	Part *part;
	
	part = aux;
	msg = part->msg;
	box = msg->box;
	if(part->ix == 0){
		if(i < nelem(msgdir))
			return filldir(d, msgdir[i], box, msg, part);
		i -= nelem(msgdir);
	}else if(part->type && strcmp(part->type, "message/rfc822") == 0){
		if(i < nelem(mimemsgdir))
			return filldir(d, mimemsgdir[i], box, msg, part);
		i -= nelem(mimemsgdir);
	}else{
		if(i < nelem(mimedir))
			return filldir(d, mimedir[i], box, msg, part);
		i -= nelem(mimedir);
	}
	if(i < part->nsub)
		return filldir(d, Qmsg, box, msg, part->sub[i]);
	return -1;
}

enum
{
	CMhangup,
};
static Cmdtab ctltab[] =
{
	CMhangup, "hangup", 2,
};

enum
{
	CMdelete,
	CMrefresh,
	CMreplied,
	CMread,
	CMsave,
	CMjunk,
	CMnonjunk,
};
static Cmdtab boxctltab[] =
{
	CMdelete,	"delete",	0,
	CMrefresh,	"refresh", 1,
	CMreplied,	"replied", 0,
	CMread,		"read", 0,
	CMsave,		"save", 0,
	CMjunk,		"junk", 0,
	CMnonjunk,	"nonjunk", 0,
};

static void
fsread(Req *r)
{
	char *s;
	int type, len, freeme;
	Box *box;
	Msg *msg;
	Part *part;
	
	switch(type = parseqid(r->fid->qid, &box, &msg, &part)){
	case Qroot:
		dirread9p(r, rootgen, nil);
		respond(r, nil);
		return;

	case Qbox:
		if(box == nil){
			respond(r, Eboxgone);
			return;
		}
		if(box->nmsg == 0)
			imapcheckbox(imap, box);
		parseqid(r->fid->qid, &box, &msg, &part);
		if(box == nil){
			respond(r, Eboxgone);
			return;
		}
		dirread9p(r, boxgen, box);
		respond(r, nil);
		return;

	case Qmsg:
		if(msg == nil || part == nil){
			respond(r, Emsggone);
			return;
		}
		dirread9p(r, msggen, part);
		respond(r, nil);
		return;
	
	case Qctl:
	case Qboxctl:
		respond(r, Egreg);
		return;

	case Qsearch:
		readstr(r, r->fid->aux);
		respond(r, nil);
		return;

	default:
		if(filedata(type, box, msg, part, &s, &len, &freeme, 1, r->fid->qid) < 0){
			responderror(r);
			return;
		}
		if(s && len == -1)
			len = strlen(s);
		readbuf(r, s, len);
		if(freeme)
			free(s);
		respond(r, nil);
		return;
	}
}

int
mkmsglist(Box *box, char **f, int nf, Msg ***mm)
{
	int i, nm;
	Msg **m;
	
	m = emalloc(nf*sizeof m[0]);
	nm = 0;
	for(i=0; i<nf; i++)
		if((m[nm] = msgbyid(box, atoi(f[i]))) != nil)
			nm++;
	*mm = m;
	return nm;
}

static void
fswrite(Req *r)
{
	int i, j, c, type, flag, unflag, flagset, f, reset;
	Box *box;
	Msg *msg;
	Part *part;
	Cmdbuf *cb;
	Cmdtab *ct;
	Msg **m;
	int nm;
	Fmt fmt;

	r->ofcall.count = r->ifcall.count;
	switch(type = parseqid(r->fid->qid, &box, &msg, &part)){
	default:
		respond(r, Egreg);
		break;

	case Qctl:
		cb = parsecmd(r->ifcall.data, r->ifcall.count);
		if((ct = lookupcmd(cb, ctltab, nelem(ctltab))) == nil){
			respondcmderror(r, cb, "unknown message");
			free(cb);
			return;
		}
		r->ofcall.count = r->ifcall.count;
		switch(ct->index){
		case CMhangup:
			imaphangup(imap, atoi(cb->f[1]));
			respond(r, nil);
			break;
		default:
			respond(r, Egreg);
			break;
		}
		free(cb);
		return;

	case Qboxctl:
		cb = parsecmd(r->ifcall.data, r->ifcall.count);
		if((ct = lookupcmd(cb, boxctltab, nelem(boxctltab))) == nil){
			respondcmderror(r, cb, "bad message");
			free(cb);
			return;
		}
		r->ofcall.count = r->ifcall.count;
		switch(ct->index){
		case CMsave:
			if(cb->nf <= 2){
				respondcmderror(r, cb, Ebadctl);
				break;
			}
			nm = mkmsglist(box, cb->f+2, cb->nf-2, &m);
			if(nm != cb->nf-2){
			//	free(m);
				respond(r, Enomsg);
				break;
			}
			if(nm > 0 && imapcopylist(imap, cb->f[1], m, nm) < 0)
				responderror(r);
			else
				respond(r, nil);
			free(m);
			break;
		
		case CMjunk:
			flag = FlagJunk;
			goto flagit;
		case CMnonjunk:
			flag = FlagNonJunk;
			goto flagit;
		case CMreplied:
			flag = FlagReplied;
			goto flagit;
		case CMread:
			flag = FlagSeen;
		flagit:
			if(cb->nf <= 1){
				respondcmderror(r, cb, Ebadctl);
				break;
			}
			nm = mkmsglist(box, cb->f+1, cb->nf-1, &m);
			if(nm != cb->nf-1){
				free(m);
				respond(r, Enomsg);
				break;
			}
			if(nm > 0 && imapflaglist(imap, +1, flag, m, nm) < 0)
				responderror(r);
			else
				respond(r, nil);
			free(m);
			break;

		case CMrefresh:
			imapcheckbox(imap, box);
			respond(r, nil);
			break;

		case CMdelete:
			if(cb->nf <= 1){
				respondcmderror(r, cb, Ebadctl);
				break;
			}
			nm = mkmsglist(box, cb->f+1, cb->nf-1, &m);
			if(nm > 0 && imapremovelist(imap, m, nm) < 0)
				responderror(r);
			else
				respond(r, nil);
			free(m);
			break;

		default:
			respond(r, Egreg);
			break;
		}
		free(cb);
		return;

	case Qflags:
		if(msg == nil){
			respond(r, Enomsg);
			return;
		}
		cb = parsecmd(r->ifcall.data, r->ifcall.count);
		flag = 0;
		unflag = 0;
		flagset = 0;
		reset = 0;
		for(i=0; i<cb->nf; i++){
			f = 0;
			c = cb->f[i][0];
			if(c == '+' || c == '-')
				cb->f[i]++;
			for(j=0; j<nelem(flagtab); j++){
				if(strcmp(flagtab[j].name, cb->f[i]) == 0){
					f = flagtab[j].flag;
					break;
				}
			}
			if(f == 0){
				respondcmderror(r, cb, "unknown flag %s", cb->f[i]);
				free(cb);
				return;
			}
			if(c == '+')
				flag |= f;
			else if(c == '-')
				unflag |= f;
			else
				flagset |= f;
		}
		free(cb);
		if((flagset!=0)+(unflag!=0)+(flag!=0) != 1){
			respondcmderror(r, cb, Ebadctl);
			return;
		}
		if(flag)
			i = 1;
		else if(unflag){
			i = -1;
			flag = unflag;
		}else{
			i = 0;
			flag = flagset;
		}
		if(imapflaglist(imap, i, flag, &msg, 1) < 0)
			responderror(r);
		else
			respond(r, nil);
		return;

	case Qsearch:
		if(box == nil){
			respond(r, Eboxgone);
			return;
		}
		fmtstrinit(&fmt);
		nm = imapsearchbox(imap, box, r->ifcall.data, &m);
		for(i=0; i<nm; i++){
			if(i>0)
				fmtrune(&fmt, ' ');
			fmtprint(&fmt, "%d", m[i]->id);
		}
		free(r->fid->aux);
		r->fid->aux = fmtstrflush(&fmt);
		respond(r, nil);
		return;
	}
}

static void
fsopen(Req *r)
{
	switch(qtype(r->fid->qid)){
	case Qctl:
	case Qboxctl:
		if((r->ifcall.mode&~OTRUNC) != OWRITE){
			respond(r, Eperm);
			return;
		}
		respond(r, nil);
		return;

	case Qflags:
	case Qsearch:
		if((r->ifcall.mode&~OTRUNC) > ORDWR){
			respond(r, Eperm);
			return;
		}
		respond(r, nil);
		return;

	default:
		if(r->ifcall.mode != OREAD){
			respond(r, Eperm);
			return;
		}
		respond(r, nil);
		return;
	}
}

static void
fsflush(Req *r)
{
	/*
	 * We only handle reads and writes outside the main loop,
	 * so we must be flushing one of those.  In both cases it's
	 * okay to just ignore the results of the request, whenever
	 * they're ready.
	 */
	incref(&r->oldreq->ref);
	respond(r->oldreq, "interrupted");
	respond(r, nil);
}

static void
fsthread(void *v)
{
	Req *r;
	
	r = v;
	switch(r->ifcall.type){
	case Tread:
		fsread(r);
		break;
	case Twrite:
		fswrite(r);
		break;
	}
}

static void
fsrecv(void *v)
{
	Req *r;
	
	while((r = recvp(fsreqchan)) != nil){
		switch(r->ifcall.type){
		case Tattach:
			fsattach(r);
			break;
		case Tflush:
			fsflush(r);
			break;
		case Topen:
			fsopen(r);
			break;
		case Twalk:
			fswalk(r);
			break;
		case Tstat:
			fsstat(r);
			break;
		default:
			threadcreate(fsthread, r, STACK);
			break;
		}
	}
}

static void
fssend(Req *r)
{
	sendp(fsreqchan, r);
}

static void
fsdestroyfid(Fid *f)
{
	free(f->aux);
}

void
fsinit0(void)	/* bad planning - clash with lib9pclient */
{
	t0 = time(0);

	fs.attach = fssend;
	fs.flush = fssend;
	fs.open = fssend;
	fs.walk = fssend;
	fs.read = fssend;
	fs.write = fssend;
	fs.stat = fssend;
	fs.destroyfid = fsdestroyfid;
	
	rootqid = qid(Qroot, nil, nil, nil);
	
	fsreqchan = chancreate(sizeof(void*), 0);
	mailthread(fsrecv, nil);
}

