/*
 * 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,
	Qfilename,
	Qraw,
	Qrawheader,
	Qrawbody,
	Qmimeheader,
	
	/* part numbers - same order as struct Part */
	Qsize,
	Qlines,

	/* other message files */
	Qbody,
	Qheader,
	Qdigest,
	Qdisposition,
	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;

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

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;

	USED(q);
	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 Qfilename:
	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 %ud %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);
		if(part->filename)
			fmtprint(&fmt, "filename %s\n", part->filename);
		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);
		fmtprint(&fmt, "Subject: %s\n", 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);
	i--;
	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,
	Qfilename,
	Qcharset,
	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;

	USED(v);
	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);
}

