/*
 * 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);
		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);
		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);
}

