#include "common.h"
#include <auth.h>
#include <fcall.h>
#include <libsec.h>
#include <9pclient.h> /* jpc */
#include <thread.h> /* jpc */
#include "dat.h"

enum
{
	OPERM	= 0x3,		// mask of all permission types in open mode
};

typedef struct Fid Fid;

struct Fid
{
	Qid	qid;
	short	busy;
	short	open;
	int	fid;
	Fid	*next;
	Mailbox	*mb;
	Message	*m;
	Message *mtop;		// top level message

	//finger pointers to speed up reads of large directories
	long	foff;	// offset/DIRLEN of finger
	Message	*fptr;	// pointer to message at off
	int	fvers;	// mailbox version when finger was saved
};

ulong	path;		// incremented for each new file
Fid	*fids;
int	mfd[2];
char	user[Elemlen];
int	messagesize = 4*1024*IOHDRSZ;
uchar	mdata[8*1024*IOHDRSZ];
uchar	mbuf[8*1024*IOHDRSZ];
Fcall	thdr;
Fcall	rhdr;
int	fflg;
char	*mntpt;
int	biffing;
int	plumbing = 1;

QLock	mbllock;
Mailbox	*mbl;

Fid		*newfid(int);
void		error(char*);
void		io(void);
void		*erealloc(void*, ulong);
void		*emalloc(ulong);
void		usage(void);
void		run_io(void*);
void		reader(void*);
int		readheader(Message*, char*, int, int);
int		cistrncmp(char*, char*, int);
int		tokenconvert(String*, char*, int);
String*		stringconvert(String*, char*, int);
void		post(char*, char*, int);

char	*rflush(Fid*), *rauth(Fid*),
	*rattach(Fid*), *rwalk(Fid*),
	*ropen(Fid*), *rcreate(Fid*),
	*rread(Fid*), *rwrite(Fid*), *rclunk(Fid*),
	*rremove(Fid*), *rstat(Fid*), *rwstat(Fid*),
	*rversion(Fid*);

char 	*(*fcalls[])(Fid*) = {
	[Tflush]	rflush,
	[Tversion]	rversion,
	[Tauth]	rauth,
	[Tattach]	rattach,
	[Twalk]		rwalk,
	[Topen]		ropen,
	[Tcreate]	rcreate,
	[Tread]		rread,
	[Twrite]	rwrite,
	[Tclunk]	rclunk,
	[Tremove]	rremove,
	[Tstat]		rstat,
	[Twstat]	rwstat,
};

char	Eperm[] =	"permission denied";
char	Enotdir[] =	"not a directory";
char	Enoauth[] =	"upas/fs: authentication not required";
char	Enotexist[] =	"file does not exist";
char	Einuse[] =	"file in use";
char	Eexist[] =	"file exists";
char	Enotowner[] =	"not owner";
char	Eisopen[] = 	"file already open for I/O";
char	Excl[] = 	"exclusive use file already open";
char	Ename[] = 	"illegal name";
char	Ebadctl[] =	"unknown control message";

char *dirtab[] =
{
[Qdir]		".",
[Qbody]		"body",
[Qbcc]		"bcc",
[Qcc]		"cc",
[Qdate]		"date",
[Qdigest]	"digest",
[Qdisposition]	"disposition",
[Qfilename]	"filename",
[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",
[Qctl]		"ctl",
[Qmboxctl]	"ctl",
};

enum
{
	Hsize=	1277,
};

Hash	*htab[Hsize];

int	debug;
int	fflag;
int	logging;

void
usage(void)
{
	fprint(2, "usage: %s [-b -m mountpoint]\n", argv0);
	threadexits("usage");
}

void
notifyf(void *a, char *s)
{
	USED(a);
	if(strncmp(s, "interrupt", 9) == 0)
		noted(NCONT);
	noted(NDFLT);
}

void
threadmain(int argc, char *argv[])
{
	int p[2], std, nodflt;
	char maildir[128];
	char mbox[128];
	char *mboxfile, *err;
	char srvfile[64];
	int srvpost;

	rfork(RFNOTEG);
	mntpt = nil;
	fflag = 0;
	mboxfile = nil;
	std = 0;
	nodflt = 0;
	srvpost = 0;

	ARGBEGIN{
	case 'b':
		biffing = 1;
		break;
	case 'f':
		fflag = 1;
		mboxfile = ARGF();
		break;
	case 'm':
		mntpt = ARGF();
		break;
	case 'd':
		debug = 1;
		break;
	case 'p':
		plumbing = 0;
		break;
	case 's':
		srvpost = 1;
		break;
	case 'l':
		logging = 1;
		break;
	case 'n':
		nodflt = 1;
		break;
	default:
		usage();
	}ARGEND

	if(pipe(p) < 0)
		error("pipe failed");
	mfd[0] = p[0];
	mfd[1] = p[0];

	notify(notifyf);
	strcpy(user, getuser());
	if(mntpt == nil){
		snprint(maildir, sizeof(maildir), "/mail/fs");
		mntpt = maildir;
	}
	if(mboxfile == nil && !nodflt){
		snprint(mbox, sizeof(mbox), "/mail/box/%s/mbox", user);
		mboxfile = mbox;
		std = 1;
	}

	if(debug)
		fmtinstall('F', fcallfmt);

	if(mboxfile != nil){
		err = newmbox(mboxfile, "mbox", std);
		if(err != nil)
			sysfatal("opening mailbox: %s", err);
	}

	switch(rfork(RFFDG|RFPROC|RFNAMEG|RFNOTEG)){ /* jpc removed RFEND */
	case -1:
		error("fork");
	case 0:
		henter(PATH(0, Qtop), dirtab[Qctl],
			(Qid){PATH(0, Qctl), 0, QTFILE}, nil, nil);
		close(p[1]);
		io();
		postnote(PNGROUP, getpid(), "die yankee pig dog");
		break;
	default:
		close(p[0]);	/* don't deadlock if child fails */
		if(srvpost){
			sprint(srvfile, "/srv/upasfs.%s", user);
			/* post(srvfile, "upasfs", p[1]);  jpc */
			post9pservice(p[1], "upasfs");   /* jpc */
		} else {
			error("tried to mount, fixme");     /* jpc */
			/* if(mount(p[1], -1, mntpt, MREPL, "") < 0)
				error("mount failed");   jpc */
		}
	}
	threadexits(0);
}

void run_io(void *v) {
	int *p;

	p =  v;
	henter(PATH(0, Qtop), dirtab[Qctl],
		(Qid){PATH(0, Qctl), 0, QTFILE}, nil, nil);
	close(p[1]);
	io();
	postnote(PNGROUP, getpid(), "die yankee pig dog");
}

static int
fileinfo(Message *m, int t, char **pp)
{
	char *p;
	int len;

	p = "";
	len = 0;
	switch(t){
	case Qbody:
		p = m->body;
		len = m->bend - m->body;
		break;
	case Qbcc:
		if(m->bcc822){
			p = s_to_c(m->bcc822);
			len = strlen(p);
		}
		break;
	case Qcc:
		if(m->cc822){
			p = s_to_c(m->cc822);
			len = strlen(p);
		}
		break;
	case Qdisposition:
		switch(m->disposition){
		case Dinline:
			p = "inline";
			break;
		case Dfile:
			p = "file";
			break;
		}
		len = strlen(p);
		break;
	case Qdate:
		if(m->date822){
			p = s_to_c(m->date822);
			len = strlen(p);
		} else if(m->unixdate != nil){
			p = s_to_c(m->unixdate);
			len = strlen(p);
		}
		break;
	case Qfilename:
		if(m->filename){
			p = s_to_c(m->filename);
			len = strlen(p);
		}
		break;
	case Qinreplyto:
		if(m->inreplyto822){
			p = s_to_c(m->inreplyto822);
			len = strlen(p);
		}
		break;
	case Qmessageid:
		if(m->messageid822){
			p = s_to_c(m->messageid822);
			len = strlen(p);
		}
		break;
	case Qfrom:
		if(m->from822){
			p = s_to_c(m->from822);
			len = strlen(p);
		} else if(m->unixfrom != nil){
			p = s_to_c(m->unixfrom);
			len = strlen(p);
		}
		break;
	case Qheader:
		p = m->header;
		len = headerlen(m);
		break;
	case Qlines:
		p = m->lines;
		if(*p == 0)
			countlines(m);
		len = strlen(m->lines);
		break;
	case Qraw:
		p = m->start;
		if(strncmp(m->start, "From ", 5) == 0){
			p = strchr(p, '\n');
			if(p == nil)
				p = m->start;
			else
				p++;
		}
		len = m->end - p;
		break;
	case Qrawunix:
		p = m->start;
		len = m->end - p;
		break;
	case Qrawbody:
		p = m->rbody;
		len = m->rbend - p;
		break;
	case Qrawheader:
		p = m->header;
		len = m->hend - p;
		break;
	case Qmimeheader:
		p = m->mheader;
		len = m->mhend - p;
		break;
	case Qreplyto:
		p = nil;
		if(m->replyto822 != nil){
			p = s_to_c(m->replyto822);
			len = strlen(p);
		} else if(m->from822 != nil){
			p = s_to_c(m->from822);
			len = strlen(p);
		} else if(m->sender822 != nil){
			p = s_to_c(m->sender822);
			len = strlen(p);
		} else if(m->unixfrom != nil){
			p = s_to_c(m->unixfrom);
			len = strlen(p);
		}
		break;
	case Qsender:
		if(m->sender822){
			p = s_to_c(m->sender822);
			len = strlen(p);
		}
		break;
	case Qsubject:
		p = nil;
		if(m->subject822){
			p = s_to_c(m->subject822);
			len = strlen(p);
		}
		break;
	case Qto:
		if(m->to822){
			p = s_to_c(m->to822);
			len = strlen(p);
		}
		break;
	case Qtype:
		if(m->type){
			p = s_to_c(m->type);
			len = strlen(p);
		}
		break;
	case Qunixdate:
		if(m->unixdate){
			p = s_to_c(m->unixdate);
			len = strlen(p);
		}
		break;
	case Qunixheader:
		if(m->unixheader){
			p = s_to_c(m->unixheader);
			len = s_len(m->unixheader);
		}
		break;
	case Qdigest:
		if(m->sdigest){
			p = s_to_c(m->sdigest);
			len = strlen(p);
		}
		break;
	}
	*pp = p;
	return len;
}

int infofields[] = {
	Qfrom,
	Qto,
	Qcc,
	Qreplyto,
	Qunixdate,
	Qsubject,
	Qtype,
	Qdisposition,
	Qfilename,
	Qdigest,
	Qbcc,
	Qinreplyto,
	Qdate,
	Qsender,
	Qmessageid,
	Qlines,
	-1,
};

static int
readinfo(Message *m, char *buf, long off, int count)
{
	char *p;
	int len, i, n;
	String *s;

	s = s_new();
	len = 0;
	for(i = 0; len < count && infofields[i] >= 0; i++){
		n = fileinfo(m, infofields[i], &p);
		s = stringconvert(s, p, n);
		s_append(s, "\n");
		p = s_to_c(s);
		n = strlen(p);
		if(off > 0){
			if(off >= n){
				off -= n;
				continue;
			}
			p += off;
			n -= off;
			off = 0;
		}
		if(n > count - len)
			n = count - len;
		if(buf)
			memmove(buf+len, p, n);
		len += n;
	}
	s_free(s);
	return len;
}

static void
mkstat(Dir *d, Mailbox *mb, Message *m, int t)
{
	char *p;

	d->uid = user;
	d->gid = user;
	d->muid = user;
	d->mode = 0444;
	d->qid.vers = 0;
	d->qid.type = QTFILE;
	d->type = 0;
	d->dev = 0;
	if(mb != nil && mb->d != nil){
		d->atime = mb->d->atime;
		d->mtime = mb->d->mtime;
	} else {
		d->atime = time(0);
		d->mtime = d->atime;
	}

	switch(t){
	case Qtop:
		d->name = ".";
		d->mode = DMDIR|0555;
		d->atime = d->mtime = time(0);
		d->length = 0;
		d->qid.path = PATH(0, Qtop);
		d->qid.type = QTDIR;
		break;
	case Qmbox:
		d->name = mb->name;
		d->mode = DMDIR|0555;
		d->length = 0;
		d->qid.path = PATH(mb->id, Qmbox);
		d->qid.type = QTDIR;
		d->qid.vers = mb->vers;
		break;
	case Qdir:
		d->name = m->name;
		d->mode = DMDIR|0555;
		d->length = 0;
		d->qid.path = PATH(m->id, Qdir);
		d->qid.type = QTDIR;
		break;
	case Qctl:
		d->name = dirtab[t];
		d->mode = 0666;
		d->atime = d->mtime = time(0);
		d->length = 0;
		d->qid.path = PATH(0, Qctl);
		break;
	case Qmboxctl:
		d->name = dirtab[t];
		d->mode = 0222;
		d->atime = d->mtime = time(0);
		d->length = 0;
		d->qid.path = PATH(mb->id, Qmboxctl);
		break;
	case Qinfo:
		d->name = dirtab[t];
		d->length = readinfo(m, nil, 0, 1<<30);
		d->qid.path = PATH(m->id, t);
		break;
	default:
		d->name = dirtab[t];
		d->length = fileinfo(m, t, &p);
		d->qid.path = PATH(m->id, t);
		break;
	}
}

char*
rversion(Fid* dummy)
{
	Fid *f;

	if(thdr.msize < 256)
		return "max messagesize too small";
	if(thdr.msize < messagesize)
		messagesize = thdr.msize;
	rhdr.msize = messagesize;
	if(strncmp(thdr.version, "9P2000", 6) != 0)
		return "unknown 9P version";
	else
		rhdr.version = "9P2000";
	for(f = fids; f; f = f->next)
		if(f->busy)
			rclunk(f);
	return nil;
}

char*
rauth(Fid* dummy)
{
	return Enoauth;
}

char*
rflush(Fid *f)
{
	USED(f);
	return 0;
}

char*
rattach(Fid *f)
{
	f->busy = 1;
	f->m = nil;
	f->mb = nil;
	f->qid.path = PATH(0, Qtop);
	f->qid.type = QTDIR;
	f->qid.vers = 0;
	rhdr.qid = f->qid;
	if(strcmp(thdr.uname, user) != 0)
		return Eperm;
	return 0;
}

static Fid*
doclone(Fid *f, int nfid)
{
	Fid *nf;

	nf = newfid(nfid);
	if(nf->busy)
		return nil;
	nf->busy = 1;
	nf->open = 0;
	nf->m = f->m;
	nf->mtop = f->mtop;
	nf->mb = f->mb;
	if(f->mb != nil)
		mboxincref(f->mb);
	if(f->mtop != nil){
		qlock(&f->mb->ql);
		msgincref(f->mtop);
		qunlock(&f->mb->ql);
	}
	nf->qid = f->qid;
	return nf;
}

char*
dowalk(Fid *f, char *name)
{
	int t;
	Mailbox *omb, *mb;
	char *rv, *p;
	Hash *h;

	t = FILE(f->qid.path);

	rv = Enotexist;

	omb = f->mb;
	if(omb)
		qlock(&omb->ql);
	else
		qlock(&mbllock);

	// this must catch everything except . and ..
retry:
	h = hlook(f->qid.path, name);
	if(h != nil){
		f->mb = h->mb;
		f->m = h->m;
		switch(t){
		case Qtop:
			if(f->mb != nil)
				mboxincref(f->mb);
			break;
		case Qmbox:
			if(f->m){
				msgincref(f->m);
				f->mtop = f->m;
			}
			break;
		}
		f->qid = h->qid;
		rv = nil;
	} else if((p = strchr(name, '.')) != nil && *name != '.'){
		*p = 0;
		goto retry;
	}

	if(omb)
		qunlock(&omb->ql);
	else
		qunlock(&mbllock);
	if(rv == nil)
		return rv;

	if(strcmp(name, ".") == 0)
		return nil;

	if(f->qid.type != QTDIR)
		return Enotdir;

	if(strcmp(name, "..") == 0){
		switch(t){
		case Qtop:
			f->qid.path = PATH(0, Qtop);
			f->qid.type = QTDIR;
			f->qid.vers = 0;
			break;
		case Qmbox:
			f->qid.path = PATH(0, Qtop);
			f->qid.type = QTDIR;
			f->qid.vers = 0;
			qlock(&mbllock);
			mb = f->mb;
			f->mb = nil;
			mboxdecref(mb);
			qunlock(&mbllock);
			break;
		case Qdir:
			qlock(&f->mb->ql);
			if(f->m->whole == f->mb->root){
				f->qid.path = PATH(f->mb->id, Qmbox);
				f->qid.type = QTDIR;
				f->qid.vers = f->mb->d->qid.vers;
				msgdecref(f->mb, f->mtop);
				f->m = f->mtop = nil;
			} else {
				f->m = f->m->whole;
				f->qid.path = PATH(f->m->id, Qdir);
				f->qid.type = QTDIR;
			}
			qunlock(&f->mb->ql);
			break;
		}
		rv = nil;
	}
	return rv;
}

char*
rwalk(Fid *f)
{
	Fid *nf;
	char *rv;
	int i;

	if(f->open)
		return Eisopen;

	rhdr.nwqid = 0;
	nf = nil;

	/* clone if requested */
	if(thdr.newfid != thdr.fid){
		nf = doclone(f, thdr.newfid);
		if(nf == nil)
			return "new fid in use";
		f = nf;
	}

	/* if it's just a clone, return */
	if(thdr.nwname == 0 && nf != nil)
		return nil;

	/* walk each element */
	rv = nil;
	for(i = 0; i < thdr.nwname; i++){
		rv = dowalk(f, thdr.wname[i]);
		if(rv != nil){
			if(nf != nil)	
				rclunk(nf);
			break;
		}
		rhdr.wqid[i] = f->qid;
	}
	rhdr.nwqid = i;

	/* we only error out if no walk  */
	if(i > 0)
		rv = nil;

	return rv;
}

char *
ropen(Fid *f)
{
	int file;

	if(f->open)
		return Eisopen;

	file = FILE(f->qid.path);
	if(thdr.mode != OREAD)
		if(file != Qctl && file != Qmboxctl)
			return Eperm;

	// make sure we've decoded
	if(file == Qbody){
		if(f->m->decoded == 0)
			decode(f->m);
		if(f->m->converted == 0)
			convert(f->m);
	}

	rhdr.iounit = 0;
	rhdr.qid = f->qid;
	f->open = 1;
	return 0;
}

char *
rcreate(Fid* dummy)
{
	return Eperm;
}

int
readtopdir(Fid* dummy, uchar *buf, long off, int cnt, int blen)
{
	Dir d;
	int m, n;
	long pos;
	Mailbox *mb;

	n = 0;
	pos = 0;
	mkstat(&d, nil, nil, Qctl);
	m = convD2M(&d, &buf[n], blen);
	if(off <= pos){
		if(m <= BIT16SZ || m > cnt)
			return 0;
		n += m;
		cnt -= m;
	}
	pos += m;
		
	for(mb = mbl; mb != nil; mb = mb->next){
		mkstat(&d, mb, nil, Qmbox);
		m = convD2M(&d, &buf[n], blen-n);
		if(off <= pos){
			if(m <= BIT16SZ || m > cnt)
				break;
			n += m;
			cnt -= m;
		}
		pos += m;
	}
	return n;
}

int
readmboxdir(Fid *f, uchar *buf, long off, int cnt, int blen)
{
	Dir d;
	int n, m;
	long pos;
	Message *msg;

	n = 0;
	if(f->mb->ctl){
		mkstat(&d, f->mb, nil, Qmboxctl);
		m = convD2M(&d, &buf[n], blen);
		if(off == 0){
			if(m <= BIT16SZ || m > cnt){
				f->fptr = nil;
				return 0;
			}
			n += m;
			cnt -= m;
		} else
			off -= m;
	}

	// to avoid n**2 reads of the directory, use a saved finger pointer
	if(f->mb->vers == f->fvers && off >= f->foff && f->fptr != nil){
		msg = f->fptr;
		pos = f->foff;
	} else {
		msg = f->mb->root->part;
		pos = 0;
	} 

	for(; cnt > 0 && msg != nil; msg = msg->next){
		// act like deleted files aren't there
		if(msg->deleted)
			continue;

		mkstat(&d, f->mb, msg, Qdir);
		m = convD2M(&d, &buf[n], blen-n);
		if(off <= pos){
			if(m <= BIT16SZ || m > cnt)
				break;
			n += m;
			cnt -= m;
		}
		pos += m;
	}

	// save a finger pointer for next read of the mbox directory
	f->foff = pos;
	f->fptr = msg;
	f->fvers = f->mb->vers;

	return n;
}

int
readmsgdir(Fid *f, uchar *buf, long off, int cnt, int blen)
{
	Dir d;
	int i, n, m;
	long pos;
	Message *msg;

	n = 0;
	pos = 0;
	for(i = 0; i < Qmax; i++){
		mkstat(&d, f->mb, f->m, i);
		m = convD2M(&d, &buf[n], blen-n);
		if(off <= pos){
			if(m <= BIT16SZ || m > cnt)
				return n;
			n += m;
			cnt -= m;
		}
		pos += m;
	}
	for(msg = f->m->part; msg != nil; msg = msg->next){
		mkstat(&d, f->mb, msg, Qdir);
		m = convD2M(&d, &buf[n], blen-n);
		if(off <= pos){
			if(m <= BIT16SZ || m > cnt)
				break;
			n += m;
			cnt -= m;
		}
		pos += m;
	}

	return n;
}

char*
rread(Fid *f)
{
	long off;
	int t, i, n, cnt;
	char *p;

	rhdr.count = 0;
	off = thdr.offset;
	cnt = thdr.count;

	if(cnt > messagesize - IOHDRSZ)
		cnt = messagesize - IOHDRSZ;

	rhdr.data = (char*)mbuf;

	t = FILE(f->qid.path);
	if(f->qid.type & QTDIR){
		if(t == Qtop) {
			qlock(&mbllock);
			n = readtopdir(f, mbuf, off, cnt, messagesize - IOHDRSZ);
			qunlock(&mbllock);
		} else if(t == Qmbox) {
			qlock(&f->mb->ql);
			if(off == 0)
				syncmbox(f->mb, 1);
			n = readmboxdir(f, mbuf, off, cnt, messagesize - IOHDRSZ);
			qunlock(&f->mb->ql);
		} else if(t == Qmboxctl) {
			n = 0;
		} else {
			n = readmsgdir(f, mbuf, off, cnt, messagesize - IOHDRSZ);
		}

		rhdr.count = n;
		return nil;
	}

	if(FILE(f->qid.path) == Qheader){
		rhdr.count = readheader(f->m, (char*)mbuf, off, cnt);
		return nil;
	}

	if(FILE(f->qid.path) == Qinfo){
		rhdr.count = readinfo(f->m, (char*)mbuf, off, cnt);
		return nil;
	}

	i = fileinfo(f->m, FILE(f->qid.path), &p);
	if(off < i){
		if((off + cnt) > i)
			cnt = i - off;
		memmove(mbuf, p + off, cnt);
		rhdr.count = cnt;
	}
	return nil;
}

char*
rwrite(Fid *f)
{
	char *err;
	char *token[1024];
	int t, n;
	String *file;

	t = FILE(f->qid.path);
	rhdr.count = thdr.count;
	switch(t){
	case Qctl:
		if(thdr.count == 0)
			return Ebadctl;
		if(thdr.data[thdr.count-1] == '\n')
			thdr.data[thdr.count-1] = 0;
		else
			thdr.data[thdr.count] = 0;
		n = tokenize(thdr.data, token, nelem(token));
		if(n == 0)
			return Ebadctl;
		if(strcmp(token[0], "open") == 0){
			file = s_new();
			switch(n){
			case 1:
				err = Ebadctl;
				break;
			case 2:
				mboxpath(token[1], getlog(), file, 0);
				err = newmbox(s_to_c(file), nil, 0);
				break;
			default:
				mboxpath(token[1], getlog(), file, 0);
				if(strchr(token[2], '/') != nil)
					err = "/ not allowed in mailbox name";
				else
					err = newmbox(s_to_c(file), token[2], 0);
				break;
			}
			s_free(file);
			return err;
		}
		if(strcmp(token[0], "close") == 0){
			if(n < 2)
				return nil;
			freembox(token[1]);
			return nil;
		}
		if(strcmp(token[0], "delete") == 0){
			if(n < 3)
				return nil;
			delmessages(n-1, &token[1]);
			return nil;
		}
		return Ebadctl;
	case Qmboxctl:
		if(f->mb && f->mb->ctl){
			if(thdr.count == 0)
				return Ebadctl;
			if(thdr.data[thdr.count-1] == '\n')
				thdr.data[thdr.count-1] = 0;
			else
				thdr.data[thdr.count] = 0;
			n = tokenize(thdr.data, token, nelem(token));
			if(n == 0)
				return Ebadctl;
			return (*f->mb->ctl)(f->mb, n, token);
		}
	}
	return Eperm;
}

char *
rclunk(Fid *f)
{
	Mailbox *mb;

	f->busy = 0;
	f->open = 0;
	if(f->mtop != nil){
		qlock(&f->mb->ql);
		msgdecref(f->mb, f->mtop);
		qunlock(&f->mb->ql);
	}
	f->m = f->mtop = nil;
	mb = f->mb;
	if(mb != nil){
		f->mb = nil;
		assert(mb->refs > 0);
		qlock(&mbllock);
		mboxdecref(mb);
		qunlock(&mbllock);
	}
	f->fid = -1;
	return 0;
}

char *
rremove(Fid *f)
{
	if(f->m != nil){
		if(f->m->deleted == 0)
			mailplumb(f->mb, f->m, 1);
		f->m->deleted = 1;
	}
	return rclunk(f);
}

char *
rstat(Fid *f)
{
	Dir d;

	if(FILE(f->qid.path) == Qmbox){
		qlock(&f->mb->ql);
		syncmbox(f->mb, 1);
		qunlock(&f->mb->ql);
	}
	mkstat(&d, f->mb, f->m, FILE(f->qid.path));
	rhdr.nstat = convD2M(&d, mbuf, messagesize - IOHDRSZ);
	rhdr.stat = mbuf;
	return 0;
}

char *
rwstat(Fid* dummy)
{
	return Eperm;
}

Fid *
newfid(int fid)
{
	Fid *f, *ff;

	ff = 0;
	for(f = fids; f; f = f->next)
		if(f->fid == fid)
			return f;
		else if(!ff && !f->busy)
			ff = f;
	if(ff){
		ff->fid = fid;
		ff->fptr = nil;
		return ff;
	}
	f = emalloc(sizeof *f);
	f->fid = fid;
	f->fptr = nil;
	f->next = fids;
	fids = f;
	return f;
}

int
fidmboxrefs(Mailbox *mb)
{
	Fid *f;
	int refs = 0;

	for(f = fids; f; f = f->next){
		if(f->mb == mb)
			refs++;
	}
	return refs;
}

void
io(void)
{
	char *err;
	int n, nw;

	/* start a process to watch the mailboxes*/
	if(plumbing){
		proccreate(reader, nil, 16000);
#if 0 /* jpc */
		switch(rfork(RFPROC|RFMEM)){
		case -1:
			/* oh well */
			break;
		case 0:
			reader();
			threadexits(nil);
		default:
			break;
		}
#endif /* jpc */
	}

	for(;;){
		/*
		 * reading from a pipe or a network device
		 * will give an error after a few eof reads
		 * however, we cannot tell the difference
		 * between a zero-length read and an interrupt
		 * on the processes writing to us,
		 * so we wait for the error
		 */
		checkmboxrefs();
		n = read9pmsg(mfd[0], mdata, messagesize);
		if(n == 0)
			continue;
		if(n < 0)
			return;
		if(convM2S(mdata, n, &thdr) == 0)
			continue;

		if(debug)
			fprint(2, "%s:<-%F\n", argv0, &thdr);

		rhdr.data = (char*)mdata + messagesize;
		if(!fcalls[thdr.type])
			err = "bad fcall type";
		else
			err = (*fcalls[thdr.type])(newfid(thdr.fid));
		if(err){
			rhdr.type = Rerror;
			rhdr.ename = err;
		}else{
			rhdr.type = thdr.type + 1;
			rhdr.fid = thdr.fid;
		}
		rhdr.tag = thdr.tag;
		if(debug)
			fprint(2, "%s:->%F\n", argv0, &rhdr);/**/
		n = convS2M(&rhdr, mdata, messagesize);
		if((nw = write(mfd[1], mdata, n)) != n) {
			fprint(2,"wrote %d bytes\n",nw);
			error("mount write");
		}
	}
}

void
reader(void *dummy)
{
	ulong t;
	Dir *d;
	Mailbox *mb;

	sleep(15*1000);
	for(;;){
		t = time(0);
		qlock(&mbllock);
		for(mb = mbl; mb != nil; mb = mb->next){
			assert(mb->refs > 0);
			if(mb->waketime != 0 && t > mb->waketime){
				qlock(&mb->ql);
				mb->waketime = 0;
				break;
			}

			d = dirstat(mb->path);
			if(d == nil)
				continue;

			qlock(&mb->ql);
			if(mb->d)
			if(d->qid.path != mb->d->qid.path
			   || d->qid.vers != mb->d->qid.vers){
				free(d);
				break;
			}
			qunlock(&mb->ql);
			free(d);
		}
		qunlock(&mbllock);
		if(mb != nil){
			syncmbox(mb, 1);
			qunlock(&mb->ql);
		} else
			sleep(15*1000);
	}
}

int
newid(void)
{
	int rv;
	static int id;
	static Lock idlock;

	lock(&idlock);
	rv = ++id;
	unlock(&idlock);

	return rv;
}

void
error(char *s)
{
	postnote(PNGROUP, getpid(), "die yankee pig dog");
	fprint(2, "%s: %s: %r\n", argv0, s);
	threadexits(s);
}


typedef struct Ignorance Ignorance;
struct Ignorance
{
	Ignorance *next;
	char	*str;		/* string */
	int	partial;	/* true if not exact match */
};
Ignorance *ignorance;

/*
 *  read the file of headers to ignore 
 */
void
readignore(void)
{
	char *p;
	Ignorance *i;
	Biobuf *b;

	if(ignorance != nil)
		return;

	b = Bopen("/mail/lib/ignore", OREAD);
	if(b == 0)
		return;
	while(p = Brdline(b, '\n')){
		p[Blinelen(b)-1] = 0;
		while(*p && (*p == ' ' || *p == '\t'))
			p++;
		if(*p == '#')
			continue;
		i = malloc(sizeof(Ignorance));
		if(i == 0)
			break;
		i->partial = strlen(p);
		i->str = strdup(p);
		if(i->str == 0){
			free(i);
			break;
		}
		i->next = ignorance;
		ignorance = i;
	}
	Bterm(b);
}

int
ignore(char *p)
{
	Ignorance *i;

	readignore();
	for(i = ignorance; i != nil; i = i->next)
		if(cistrncmp(i->str, p, i->partial) == 0)
			return 1;
	return 0;
}

int
hdrlen(char *p, char *e)
{
	char *ep;

	ep = p;
	do {
		ep = strchr(ep, '\n');
		if(ep == nil){
			ep = e;
			break;
		}
		ep++;
		if(ep >= e){
			ep = e;
			break;
		}
	} while(*ep == ' ' || *ep == '\t');
	return ep - p;
}

// rfc2047 non-ascii
typedef struct Charset Charset;
struct Charset {
	char *name;
	int len;
	int convert;
	char *tcsname;
} charsets[] =
{
	{ "us-ascii",		8,	1, nil, },
	{ "utf-8",		5,	0, nil, },
	{ "iso-8859-1",		10,	1, nil, },
	{ "iso-8859-2",		10,	2, "8859-2", },
	{ "big5",		4,	2, "big5", },
	{ "iso-2022-jp",	11, 2, "jis", },
	{ "windows-1251",	12,	2, "cp1251"},
	{ "koi8-r",		6,	2, "koi8"},
};

int
rfc2047convert(String *s, char *token, int len)
{
	char decoded[1024];
	char utfbuf[2*1024];
	int i;
	char *e, *x;

	if(len == 0)
		return -1;

	e = token+len-2;
	token += 2;

	// bail if we don't understand the character set
	for(i = 0; i < nelem(charsets); i++)
		if(cistrncmp(charsets[i].name, token, charsets[i].len) == 0)
		if(token[charsets[i].len] == '?'){
			token += charsets[i].len + 1;
			break;
		}
	if(i >= nelem(charsets))
		return -1;

	// bail if it doesn't fit 
	if(e-token > sizeof(decoded)-1)
		return -1;

	// bail if we don't understand the encoding
	if(cistrncmp(token, "b?", 2) == 0){
		token += 2;
		len = dec64((uchar*)decoded, sizeof(decoded), token, e-token);
		decoded[len] = 0;
	} else if(cistrncmp(token, "q?", 2) == 0){
		token += 2;
		len = decquoted(decoded, token, e);
		if(len > 0 && decoded[len-1] == '\n')
			len--;
		decoded[len] = 0;
	} else
		return -1;

	switch(charsets[i].convert){
	case 0:
		s_append(s, decoded);
		break;
	case 1:
		latin1toutf(utfbuf, decoded, decoded+len);
		s_append(s, utfbuf);
		break;
	case 2:
		if(xtoutf(charsets[i].tcsname, &x, decoded, decoded+len) <= 0){
			s_append(s, decoded);
		} else {
			s_append(s, x);
			free(x);
		}
		break;
	}

	return 0;
}

char*
rfc2047start(char *start, char *end)
{
	int quests;

	if(*--end != '=')
		return nil;
	if(*--end != '?')
		return nil;

	quests = 0;
	for(end--; end >= start; end--){
		switch(*end){
		case '=':
			if(quests == 3 && *(end+1) == '?')
				return end;
			break;
		case '?':
			++quests;
			break;
		case ' ':
		case '\t':
		case '\n':
		case '\r':
			/* can't have white space in a token */
			return nil;
		}
	}
	return nil;
}

// convert a header line
String*
stringconvert(String *s, char *uneaten, int len)
{
	char *token;
	char *p;
	int i;

	s = s_reset(s);
	p = uneaten;
	for(i = 0; i < len; i++){
		if(*p++ == '='){
			token = rfc2047start(uneaten, p);
			if(token != nil){
				s_nappend(s, uneaten, token-uneaten);
				if(rfc2047convert(s, token, p - token) < 0)
					s_nappend(s, token, p - token);
				uneaten = p;
			}
		}
	}
	if(p > uneaten)
		s_nappend(s, uneaten, p-uneaten);
	return s;
}

int
readheader(Message *m, char *buf, int off, int cnt)
{
	char *p, *e;
	int n, ns;
	char *to = buf;
	String *s;

	p = m->header;
	e = m->hend;
	s = nil;

	// copy in good headers
	while(cnt > 0 && p < e){
		n = hdrlen(p, e);
		if(ignore(p)){
			p += n;
			continue;
		}

		// rfc2047 processing
		s = stringconvert(s, p, n);
		ns = s_len(s);
		if(off > 0){
			if(ns <= off){
				off -= ns;
				p += n;
				continue;
			}
			ns -= off;
		}
		if(ns > cnt)
			ns = cnt;
		memmove(to, s_to_c(s)+off, ns);
		to += ns;
		p += n;
		cnt -= ns;
		off = 0;
	}

	s_free(s);
	return to - buf;
}

int
headerlen(Message *m)
{
	char buf[1024];
	int i, n;

	if(m->hlen >= 0)
		return m->hlen;
	for(n = 0; ; n += i){
		i = readheader(m, buf, n, sizeof(buf));
		if(i <= 0)
			break;
	}
	m->hlen = n;
	return n;
}

QLock hashlock;

uint
hash(ulong ppath, char *name)
{
	uchar *p;
	uint h;

	h = 0;
	for(p = (uchar*)name; *p; p++)
		h = h*7 + *p;
	h += ppath;

	return h % Hsize;
}

Hash*
hlook(ulong ppath, char *name)
{
	int h;
	Hash *hp;

	qlock(&hashlock);
	h = hash(ppath, name);
	for(hp = htab[h]; hp != nil; hp = hp->next)
		if(ppath == hp->ppath && strcmp(name, hp->name) == 0){
			qunlock(&hashlock);
			return hp;
		}
	qunlock(&hashlock);
	return nil;
}

void
henter(ulong ppath, char *name, Qid qid, Message *m, Mailbox *mb)
{
	int h;
	Hash *hp, **l;

	qlock(&hashlock);
	h = hash(ppath, name);
	for(l = &htab[h]; *l != nil; l = &(*l)->next){
		hp = *l;
		if(ppath == hp->ppath && strcmp(name, hp->name) == 0){
			hp->m = m;
			hp->mb = mb;
			hp->qid = qid;
			qunlock(&hashlock);
			return;
		}
	}

	*l = hp = emalloc(sizeof(*hp));
	hp->m = m;
	hp->mb = mb;
	hp->qid = qid;
	hp->name = name;
	hp->ppath = ppath;
	qunlock(&hashlock);
}

void
hfree(ulong ppath, char *name)
{
	int h;
	Hash *hp, **l;

	qlock(&hashlock);
	h = hash(ppath, name);
	for(l = &htab[h]; *l != nil; l = &(*l)->next){
		hp = *l;
		if(ppath == hp->ppath && strcmp(name, hp->name) == 0){
			hp->mb = nil;
			*l = hp->next;
			free(hp);
			break;
		}
	}
	qunlock(&hashlock);
}

int
hashmboxrefs(Mailbox *mb)
{
	int h;
	Hash *hp;
	int refs = 0;

	qlock(&hashlock);
	for(h = 0; h < Hsize; h++){
		for(hp = htab[h]; hp != nil; hp = hp->next)
			if(hp->mb == mb)
				refs++;
	}
	qunlock(&hashlock);
	return refs;
}

void
checkmboxrefs(void)
{
	int f, refs;
	Mailbox *mb;

	qlock(&mbllock);
	for(mb=mbl; mb; mb=mb->next){
		qlock(&mb->ql);
		refs = (f=fidmboxrefs(mb))+1;
		if(refs != mb->refs){
			fprint(2, "mbox %s %s ref mismatch actual %d (%d+1) expected %d\n", mb->name, mb->path, refs, f, mb->refs);
			abort();
		}
		qunlock(&mb->ql);
	}
	qunlock(&mbllock);
}

void
post(char *name, char *envname, int srvfd)
{
	int fd;
	char buf[32];

	fd = create(name, OWRITE, 0600);
	if(fd < 0)
		error("post failed");
	sprint(buf, "%d",srvfd);
	if(write(fd, buf, strlen(buf)) != strlen(buf))
		error("srv write");
	close(fd);
	putenv(envname, name);
}
