/*
 * Locking here is not quite right.
 * Calling qlock(&z->lk) can block the proc,
 * and when it comes back, boxes and msgs might have been freed
 * (if the refresh proc was holding the lock and in the middle of a
 * redial).  I've tried to be careful about not assuming boxes continue
 * to exist across imap commands, but maybe this isn't really tenable.
 * Maybe instead we should ref count the boxes and messages.
 */

#include "a.h"
#include <libsec.h>

struct Imap
{
	int		connected;
	int		autoreconnect;
	int		ticks;	/* until boom! */
	char*	server;
	char*	root;
	char*	user;
	int		mode;
	int		fd;
	Biobuf	b;
	Ioproc*	io;
	QLock	lk;
	QLock	rlk;
	Rendez	r;

	Box*		inbox;
	Box*		box;
	Box*		nextbox;

	/* SEARCH results */
	uint		*uid;
	uint		nuid;

	uint		reply;
};

static struct {
	char *name;
	int flag;
} flagstab[] = 
{
	"Junk",	FlagJunk,
	"NonJunk",	FlagNonJunk,
	"\\Answered",	FlagReplied,
	"\\Flagged",	FlagFlagged,
	"\\Deleted",	FlagDeleted,
	"\\Draft",		FlagDraft,
	"\\Recent",	FlagRecent,
	"\\Seen",		FlagSeen,
	"\\NoInferiors",	FlagNoInferiors,
	"\\NoSelect",	FlagNoSelect,
	"\\Marked",	FlagMarked,
	"\\UnMarked",	FlagUnMarked
};

int			chattyimap;

static char	*tag = "#";

static void	checkbox(Imap*, Box*);
static char*	copyaddrs(Sx*);
static void	freeup(UserPasswd*);
static int		getbox(Imap*, Box*);
static int		getboxes(Imap*);
static char*	gsub(char*, char*, char*);
static int		imapcmd(Imap*, Box*, char*, ...);
static Sx*		imapcmdsxlit(Imap*, Box*, char*, ...);
static Sx*		imapcmdsx(Imap*, Box*, char*, ...);
static Sx*		imapcmdsx0(Imap*, char*, ...);
static Sx*		imapvcmdsx(Imap*, Box*, char*, va_list, int);
static Sx*		imapvcmdsx0(Imap*, char*, va_list, int);
static int		imapdial(char*, int);
static int		imaplogin(Imap*);
static int		imapquote(Fmt*);
static int		imapreconnect(Imap*);
static void	imaprefreshthread(void*);
static void	imaptimerproc(void*);
static Sx*		imapwaitsx(Imap*);
static int		isatom(Sx *v, char *name);
static int		islist(Sx *v);
static int		isnil(Sx *v);
static int		isnumber(Sx *sx);
static int		isstring(Sx *sx);
static int		ioimapdial(Ioproc*, char*, int);
static char*	nstring(Sx*);
static void	unexpected(Imap*, Sx*);
static Sx*		zBrdsx(Imap*);

/*
 * Imap connection maintenance and login.
 */

Imap*
imapconnect(char *server, int mode, char *root, char *user)
{
	Imap *z;

	fmtinstall('H', encodefmt);
	fmtinstall('Z', imapquote);

	z = emalloc(sizeof *z);
	z->server = estrdup(server);
	z->mode = mode;
	z->user = user;
	if(root)
		if(root[0] != 0 && root[strlen(root)-1] != '/')
			z->root = smprint("%s/", root);
		else
			z->root = root;
	else
		z->root = "";
	z->fd = -1;
	z->autoreconnect = 0;
	z->io = ioproc();
	
	qlock(&z->lk);
	if(imapreconnect(z) < 0){
		free(z);
		return nil;
	}
	
	z->r.l = &z->rlk;
	z->autoreconnect = 1;
	qunlock(&z->lk);
	
	proccreate(imaptimerproc, z, STACK);
	mailthread(imaprefreshthread, z);
	
	return z;
}

void
imaphangup(Imap *z, int ticks)
{
	z->ticks = ticks;
	if(ticks == 0){
		close(z->fd);
		z->fd = -1;
	}
}

static int
imapreconnect(Imap *z)
{
	Sx *sx;

	z->autoreconnect = 0;
	z->box = nil;
	z->inbox = nil;

	if(z->fd >= 0){
		close(z->fd);
		z->fd = -1;
	}

	if(chattyimap)
		fprint(2, "dial %s...\n", z->server);
	if((z->fd = ioimapdial(z->io, z->server, z->mode)) < 0)
		return -1;
	z->connected = 1;
	Binit(&z->b, z->fd, OREAD);
	if((sx = zBrdsx(z)) == nil){
		werrstr("no greeting");
		goto err;
	}
	if(chattyimap)
		fprint(2, "<I %#$\n", sx);
	if(sx->nsx >= 2 && isatom(sx->sx[0], "*") && isatom(sx->sx[1], "PREAUTH")){
		freesx(sx);
		goto preauth;
	}
	if(!oksx(sx)){
		werrstr("bad greeting - %#$", sx);
		goto err;
	}
	freesx(sx);
	sx = nil;
	if(imaplogin(z) < 0)
		goto err;
preauth:
	if(getboxes(z) < 0 || getbox(z, z->inbox) < 0)
		goto err;
	z->autoreconnect = 1;
	return 0;

err:
	if(z->fd >= 0){
		close(z->fd);
		z->fd = -1;
	}
	if(sx)
		freesx(sx);
	z->autoreconnect = 1;
	z->connected = 0;
	return -1;
}

static int
imaplogin(Imap *z)
{
	Sx *sx;
	UserPasswd *up;

	if(z->user != nil)
		up = auth_getuserpasswd(auth_getkey, "proto=pass role=client service=imap server=%q user=%q", z->server, z->user);
	else
		up = auth_getuserpasswd(auth_getkey, "proto=pass role=client service=imap server=%q", z->server);
	if(up == nil){
		werrstr("getuserpasswd - %r");
		return -1;
	}

	sx = imapcmdsx(z, nil, "LOGIN %Z %Z", up->user, up->passwd);
	freeup(up);
	if(sx == nil)
		return -1;
	if(!oksx(sx)){
		freesx(sx);
		werrstr("login rejected - %#$", sx);
		return -1;
	}
	return 0;
}

static int
getboxes(Imap *z)
{
	int i;
	Box **r, **w, **e;
	
	for(i=0; i<nboxes; i++){
		boxes[i]->mark = 1;
		boxes[i]->exists = 0;
		boxes[i]->maxseen = 0;
	}
	if(imapcmd(z, nil, "LIST %Z *", z->root) < 0)
		return -1;
	if(z->root != nil && imapcmd(z, nil, "LIST %Z INBOX", "") < 0)
		return -1;
	if(z->nextbox && z->nextbox->mark)
		z->nextbox = nil;
	for(r=boxes, w=boxes, e=boxes+nboxes; r<e; r++){
		if((*r)->mark)
{fprint(2, "*** free box %s %s\n", (*r)->name, (*r)->imapname);
			boxfree(*r);
}
		else
			*w++ = *r;
	}
	nboxes = w - boxes;
	return 0;
}

static int
getbox(Imap *z, Box *b)
{
	int i;
	Msg **r, **w, **e;
	
	if(b == nil)
		return 0;
	
	for(i=0; i<b->nmsg; i++)
		b->msg[i]->imapid = 0;
	if(imapcmd(z, b, "UID FETCH 1:* FLAGS") < 0)
		return -1;
	for(r=b->msg, w=b->msg, e=b->msg+b->nmsg; r<e; r++){
		if((*r)->imapid == 0)
			msgfree(*r);
		else{
			(*r)->ix = w-b->msg;
			*w++ = *r;
		}
	}
	b->nmsg = w - b->msg;
	b->imapinit = 1;
	checkbox(z, b);
	return 0;
}

static void
freeup(UserPasswd *up)
{
	memset(up->user, 0, strlen(up->user));
	memset(up->passwd, 0, strlen(up->passwd));
	free(up);
}

static void
imaptimerproc(void *v)
{
	Imap *z;
	
	z = v;
	for(;;){
		sleep(60*1000);
		qlock(z->r.l);
		rwakeup(&z->r);
		qunlock(z->r.l);
	}
}

static void
checkbox(Imap *z, Box *b)
{
	if(imapcmd(z, b, "NOOP") >= 0){
		if(!b->imapinit)
			getbox(z, b);
		if(!b->imapinit)
			return;
		if(b==z->box && b->exists > b->maxseen){
			imapcmd(z, b, "UID FETCH %d:* FULL",
				b->uidnext);
		}
	}
}

static void
imaprefreshthread(void *v)
{
	Imap *z;
	
	z = v;
	for(;;){
		qlock(z->r.l);
		rsleep(&z->r);
		qunlock(z->r.l);
		
		qlock(&z->lk);
		if(z->inbox)
			checkbox(z, z->inbox);
		qunlock(&z->lk);
	}
}

/*
 * Run a single command and return the Sx.  Does NOT redial.
 */
static Sx*
imapvcmdsx0(Imap *z, char *fmt, va_list arg, int dotag)
{
	char *s;
	Fmt f;
	int prefix, len;
	Sx *sx;
	
	if(canqlock(&z->lk))
		abort();

	if(z->fd < 0 || !z->connected)
		return nil;

	prefix = strlen(tag)+1;
	fmtstrinit(&f);
	if(dotag)
		fmtprint(&f, "%s ", tag);
	fmtvprint(&f, fmt, arg);
	fmtprint(&f, "\r\n");
	s = fmtstrflush(&f);
	len = strlen(s);
	s[len-2] = 0;
	if(chattyimap)
		fprint(2, "I> %s\n", s);
	s[len-2] = '\r';
	if(iowrite(z->io, z->fd, s, len) < 0){
		z->connected = 0;
		free(s);
		return nil;
	}
	sx = imapwaitsx(z);
	free(s);
	return sx;
}

static Sx*
imapcmdsx0(Imap *z, char *fmt, ...)
{
	va_list arg;
	Sx *sx;
	
	va_start(arg, fmt);
	sx = imapvcmdsx0(z, fmt, arg, 1);
	va_end(arg);
	return sx;
}

/*
 * Run a single command on box b.  Does redial.
 */
static Sx*
imapvcmdsx(Imap *z, Box *b, char *fmt, va_list arg, int dotag)
{
	int tries;
	Sx *sx;
	
	tries = 0;
	z->nextbox = b;

	if(z->fd < 0 || !z->connected){
reconnect:
		if(!z->autoreconnect)
			return nil;
		if(imapreconnect(z) < 0)
			return nil;
		if(b && z->nextbox == nil)	/* box disappeared on reconnect */
			return nil;
	}

	if(b && b != z->box){
		if(z->box)
			z->box->imapinit = 0;
		z->box = b;
		if((sx=imapcmdsx0(z, "SELECT %Z", b->imapname)) == nil){
			z->box = nil;
			if(tries++ == 0 && (z->fd < 0 || !z->connected))
				goto reconnect;
			return nil;
		}
		freesx(sx);
	}

	if((sx=imapvcmdsx0(z, fmt, arg, dotag)) == nil){
		if(tries++ == 0 && (z->fd < 0 || !z->connected))
			goto reconnect;
		return nil;
	}
	return sx;
}

static int
imapcmd(Imap *z, Box *b, char *fmt, ...)
{
	Sx *sx;
	va_list arg;

	va_start(arg, fmt);
	sx = imapvcmdsx(z, b, fmt, arg, 1);
	va_end(arg);
	if(sx == nil)
		return -1;
	if(sx->nsx < 2 || !isatom(sx->sx[1], "OK")){
		werrstr("%$", sx);
		freesx(sx);
		return -1;
	}
	freesx(sx);
	return 0;
}

static Sx*
imapcmdsx(Imap *z, Box *b, char *fmt, ...)
{
	Sx *sx;
	va_list arg;

	va_start(arg, fmt);
	sx = imapvcmdsx(z, b, fmt, arg, 1);
	va_end(arg);
	return sx;
}

static Sx*
imapcmdsxlit(Imap *z, Box *b, char *fmt, ...)
{
	Sx *sx;
	va_list arg;

	va_start(arg, fmt);
	sx = imapvcmdsx(z, b, fmt, arg, 0);
	va_end(arg);
	return sx;
}

static Sx*
imapwaitsx(Imap *z)
{
	Sx *sx;
	
	while((sx = zBrdsx(z)) != nil){
		if(chattyimap)
			fprint(2, "<| %#$\n", sx);
		if(sx->nsx >= 1 && sx->sx[0]->type == SxAtom && cistrcmp(sx->sx[0]->data, tag) == 0)
			return sx;
		if(sx->nsx >= 1 && sx->sx[0]->type == SxAtom && cistrcmp(sx->sx[0]->data, "+") == 0){
			z->reply = 1;
			return sx;
		}
		if(sx->nsx >= 1 && sx->sx[0]->type == SxAtom && strcmp(sx->sx[0]->data, "*") == 0)
			unexpected(z, sx);
		if(sx->type == SxList && sx->nsx == 0){
			freesx(sx);
			break;
		}
		freesx(sx);
	}
	z->connected = 0;
	return nil;
}

/*
 * Imap interface to mail file system.
 */

static void
_bodyname(char *buf, char *ebuf, Part *p, char *extra)
{
	if(buf >= ebuf){
		fprint(2, "***** BUFFER TOO SMALL\n");
		return;
	}
	*buf = 0;
	if(p->parent){
		_bodyname(buf, ebuf, p->parent, "");
		buf += strlen(buf);
		seprint(buf, ebuf, ".%d", p->pix+1);
	}
	buf += strlen(buf);
	seprint(buf, ebuf, "%s", extra);
}

static char*
bodyname(Part *p, char *extra)
{
	static char buf[256];
	memset(buf, 0, sizeof buf);	/* can't see why this is necessary, but it is */
	_bodyname(buf, buf+sizeof buf, p, extra);
	return buf+1;	/* buf[0] == '.' */
}

static void
fetch1(Imap *z, Part *p, char *s)
{
	qlock(&z->lk);
	imapcmd(z, p->msg->box, "UID FETCH %d BODY[%s]", 
		p->msg->imapuid, bodyname(p, s));
	qunlock(&z->lk);
}

void
imapfetchrawheader(Imap *z, Part *p)
{
	fetch1(z, p, ".HEADER");
}

void
imapfetchrawmime(Imap *z, Part *p)
{
	fetch1(z, p, ".MIME");
}

void
imapfetchrawbody(Imap *z, Part *p)
{
	fetch1(z, p, ".TEXT");
}

void
imapfetchraw(Imap *z, Part *p)
{
	fetch1(z, p, "");
}

static int
imaplistcmd(Imap *z, Box *box, char *before, Msg **m, uint nm, char *after)
{
	int i, r;
	char *cmd;
	Fmt fmt;
	
	if(nm == 0)
		return 0;

	fmtstrinit(&fmt);
	fmtprint(&fmt, "%s ", before);
	for(i=0; i<nm; i++){
		if(i > 0)
			fmtrune(&fmt, ',');
		fmtprint(&fmt, "%ud", m[i]->imapuid);
	}
	fmtprint(&fmt, " %s", after);
	cmd = fmtstrflush(&fmt);
	
	r = 0;
	if(imapcmd(z, box, "%s", cmd) < 0)
		 r = -1;
	free(cmd);
	return r;
}

int
imapcopylist(Imap *z, char *nbox, Msg **m, uint nm)
{
	int rv;
	char *name, *p;
	
	if(nm == 0)
		return 0;

	qlock(&z->lk);
	if(strcmp(nbox, "mbox") == 0)
		name = estrdup("INBOX");
	else{
		p = esmprint("%s%s", z->root, nbox);
		name = esmprint("%Z", p);
		free(p);
	}
	rv = imaplistcmd(z, m[0]->box, "UID COPY", m, nm, name);
	free(name);
	qunlock(&z->lk);
	return rv;
}

int
imapremovelist(Imap *z, Msg **m, uint nm)
{
	int rv;
	
	if(nm == 0)
		return 0;

	qlock(&z->lk);
	rv = imaplistcmd(z, m[0]->box, "UID STORE", m, nm, "+FLAGS.SILENT (\\Deleted)");
	/* careful - box might be gone; use z->box instead */
	if(rv == 0 && z->box)
		rv = imapcmd(z, z->box, "EXPUNGE");
	qunlock(&z->lk);
	return rv;
}

int
imapflaglist(Imap *z, int op, int flag, Msg **m, uint nm)
{
	char *mod, *s, *sep;
	int i, rv;
	Fmt fmt;
	
	if(op > 0)
		mod = "+";
	else if(op == 0)
		mod = "";
	else
		mod = "-";

	fmtstrinit(&fmt);
	fmtprint(&fmt, "%sFLAGS (", mod);
	sep = "";
	for(i=0; i<nelem(flagstab); i++){
		if(flagstab[i].flag & flag){
			fmtprint(&fmt, "%s%s", sep, flagstab[i].name);
			sep = " ";
		}
	}
	fmtprint(&fmt, ")");
	s = fmtstrflush(&fmt);
	
	qlock(&z->lk);
	rv = imaplistcmd(z, m[0]->box, "UID STORE", m, nm, s);
	qunlock(&z->lk);
	free(s);
	return rv;
}

int
imapsearchbox(Imap *z, Box *b, char *search, Msg ***mm)
{
	uint *uid;
	int i, nuid;
	Msg **m;
	int nm;
	Sx *sx;

	qlock(&z->lk);
	sx = imapcmdsx(z, b, "UID SEARCH CHARSET UTF-8 TEXT {%d}", strlen(search));
	freesx(sx);
	if(!z->reply){
		qunlock(&z->lk);
		return -1;
	}
	if((sx = imapcmdsxlit(z, b, "%s", search)) == nil){
		qunlock(&z->lk);
		return -1;
	}
	if(sx->nsx < 2 || !isatom(sx->sx[1], "OK")){
		werrstr("%$", sx);
		freesx(sx);
		qunlock(&z->lk);
		return -1;
	}
	freesx(sx);

	uid = z->uid;
	nuid = z->nuid;
	z->uid = nil;
	z->nuid = 0;
	z->reply = 0;
	qunlock(&z->lk);

	m = emalloc(nuid*sizeof m[0]);
	nm = 0;
	for(i=0; i<nuid; i++)
		if((m[nm] = msgbyimapuid(b, uid[i], 0)) != nil)
			nm++;
	*mm = m;
	free(uid);
	return nm;
}

void
imapcheckbox(Imap *z, Box *b)
{
	if(b == nil)
		return;
	qlock(&z->lk);
	checkbox(z, b);
	qunlock(&z->lk);
}

/*
 * Imap utility routines
 */
static long
_ioimapdial(va_list *arg)
{
	char *server;
	int mode;
	
	server = va_arg(*arg, char*);
	mode = va_arg(*arg, int);
	return imapdial(server, mode);
}
static int
ioimapdial(Ioproc *io, char *server, int mode)
{
	return iocall(io, _ioimapdial, server, mode);
}

static long
_ioBrdsx(va_list *arg)
{
	Biobuf *b;
	Sx **sx;
	
	b = va_arg(*arg, Biobuf*);
	sx = va_arg(*arg, Sx**);
	*sx = Brdsx(b);
	if((*sx) && (*sx)->type == SxList && (*sx)->nsx == 0){
		freesx(*sx);
		*sx = nil;
	}
	return 0;
}
static Sx*
ioBrdsx(Ioproc *io, Biobuf *b)
{
	Sx *sx;

	iocall(io, _ioBrdsx, b, &sx);
	return sx;
}

static Sx*
zBrdsx(Imap *z)
{
	if(z->ticks && --z->ticks==0){
		close(z->fd);
		z->fd = -1;
		return nil;
	}
	return ioBrdsx(z->io, &z->b);
}

static int
imapdial(char *server, int mode)
{
	int p[2];
	int fd[3];
	char *tmp;
	char *fpath;
	
	switch(mode){
	default:
	case Unencrypted:
		return dial(netmkaddr(server, "tcp", "143"), nil, nil, nil);
		
	case Starttls:
		werrstr("starttls not supported");
		return -1;

	case Tls:
		if(pipe(p) < 0)
			return -1;
		fd[0] = dup(p[0], -1);
		fd[1] = dup(p[0], -1);
		fd[2] = dup(2, -1);
#ifdef PLAN9PORT
		tmp = esmprint("%s:993", server);
		fpath = searchpath("stunnel3");
		if (!fpath) {
			werrstr("stunnel not found. it is required for tls support.");
			return -1;
		}
		if(threadspawnl(fd, fpath, "stunnel", "-c", "-r", tmp, nil) < 0) {
#else
		tmp = esmprint("tcp!%s!993", server);
		if(threadspawnl(fd, "/bin/tlsclient", "tlsclient", tmp, nil) < 0){
#endif
			free(tmp);
			close(p[0]);
			close(p[1]);
			close(fd[0]);
			close(fd[1]);
			close(fd[2]);
			return -1;
		}
		free(tmp);
		close(p[0]);
		return p[1];
	
	case Cmd:
		if(pipe(p) < 0)
			return -1;
		fd[0] = dup(p[0], -1);
		fd[1] = dup(p[0], -1);
		fd[2] = dup(2, -1);
		if(threadspawnl(fd, "/usr/local/plan9/bin/rc", "rc", "-c", server, nil) < 0){
			close(p[0]);
			close(p[1]);
			close(fd[0]);
			close(fd[1]);
			close(fd[2]);
			return -1;
		}
		close(p[0]);
		return p[1];
	}
}

enum
{
	Qok = 0,
	Qquote,
	Qbackslash
};

static int
needtoquote(Rune r)
{
	if(r >= Runeself)
		return Qquote;
	if(r <= ' ')
		return Qquote;
	if(r=='\\' || r=='"')
		return Qbackslash;
	return Qok;
}

static int
imapquote(Fmt *f)
{
	char *s, *t;
	int w, quotes;
	Rune r;

	s = va_arg(f->args, char*);
	if(s == nil || *s == '\0')
		return fmtstrcpy(f, "\"\"");

	quotes = 0;
	if(f->flags&FmtSharp)
		quotes = 1;
	for(t=s; *t; t+=w){
		w = chartorune(&r, t);
		quotes |= needtoquote(r);
	}
	if(quotes == 0)
		return fmtstrcpy(f, s);

	fmtrune(f, '"');
	for(t=s; *t; t+=w){
		w = chartorune(&r, t);
		if(needtoquote(r) == Qbackslash)
			fmtrune(f, '\\');
		fmtrune(f, r);
	}
	return fmtrune(f, '"');
}

static int
fmttype(char c)
{
	switch(c){
	case 'A':
		return SxAtom;
	case 'L':
		return SxList;
	case 'N':
		return SxNumber;
	case 'S':
		return SxString;
	default:
		return -1;
	}
}

/*
 * Check S expression against format string.
 */
static int
sxmatch(Sx *sx, char *fmt)
{
	int i;
	
	for(i=0; fmt[i]; i++){
		if(fmt[i] == '*')
			fmt--;	/* like i-- but better */
		if(i == sx->nsx && fmt[i+1] == '*')
			return 1;
		if(i >= sx->nsx)
			return 0;
		if(sx->sx[i] == nil)
			return 0;
		if(sx->sx[i]->type == SxAtom && strcmp(sx->sx[i]->data, "NIL") == 0){
			if(fmt[i] == 'L'){
				free(sx->sx[i]->data);
				sx->sx[i]->data = nil;
				sx->sx[i]->type = SxList;
				sx->sx[i]->sx = nil;
				sx->sx[i]->nsx = 0;
			}
			else if(fmt[i] == 'S'){
				free(sx->sx[i]->data);
				sx->sx[i]->data = nil;
				sx->sx[i]->type = SxString;
			}
		}
		if(sx->sx[i]->type == SxAtom && fmt[i]=='S')
			sx->sx[i]->type = SxString;
		if(sx->sx[i]->type != fmttype(fmt[i])){
			fprint(2, "sxmatch: %$ not %c\n", sx->sx[i], fmt[i]);
			return 0;
		}
	}
	if(i != sx->nsx)
		return 0;
	return 1;
}

/*
 * Check string against format string.
 */
static int
stringmatch(char *fmt, char *s)
{
	for(; *fmt && *s; fmt++, s++){
		switch(*fmt){
		case '0':
			if(*s == ' ')
				break;
			/* fall through */
		case '1':
			if(*s < '0' || *s > '9')
				return 0;
			break;
		case 'A':
			if(*s < 'A' || *s > 'Z')
				return 0;
			break;
		case 'a':
			if(*s < 'a' || *s > 'z')
				return 0;
			break;
		case '+':
			if(*s != '-' && *s != '+')
				return 0;
			break;
		default:
			if(*s != *fmt)
				return 0;
			break;
		}
	}
	if(*fmt || *s)
		return 0;
	return 1;
}

/*
 * Parse simple S expressions and IMAP elements.
 */
static int
isatom(Sx *v, char *name)
{
	int n;
	
	if(v == nil || v->type != SxAtom)
		return 0;
	n = strlen(name);
	if(cistrncmp(v->data, name, n) == 0)
		if(v->data[n] == 0 || (n>0 && v->data[n-1] == '['))
			return 1;
	return 0;
}

static int
isstring(Sx *sx)
{
	if(sx->type == SxAtom)
		sx->type = SxString;
	return sx->type == SxString;
}

static int
isnumber(Sx *sx)
{
	return sx->type == SxNumber;
}

static int
isnil(Sx *v)
{
	return v == nil || 
		(v->type==SxList && v->nsx == 0) ||
		(v->type==SxAtom && strcmp(v->data, "NIL") == 0);
}

static int
islist(Sx *v)
{
	return isnil(v) || v->type==SxList;
}

static uint
parseflags(Sx *v)
{
	int f, i, j;
	
	if(v->type != SxList){
		warn("malformed flags: %$", v);
		return 0;
	}
	f = 0;
	for(i=0; i<v->nsx; i++){
		if(v->sx[i]->type != SxAtom)
			continue;
		for(j=0; j<nelem(flagstab); j++)
			if(cistrcmp(v->sx[i]->data, flagstab[j].name) == 0)
				f |= flagstab[j].flag;
	}
	return f;
}
	
static char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
static int
parsemon(char *s)
{
	int i;
	
	for(i=0; months[i]; i+=3)
		if(memcmp(s, months+i, 3) == 0)
			return i/3;
	return -1;
}

static uint
parsedate(Sx *v)
{
	Tm tm;
	uint t;
	int delta;
	char *p;
	
	if(v->type != SxString || !stringmatch("01-Aaa-1111 01:11:11 +1111", v->data)){
	bad:
		warn("bad date: %$", v);
		return 0;
	}
	
	/* cannot use atoi because 09 is malformed octal! */
	memset(&tm, 0, sizeof tm);
	p = v->data;
	tm.mday = strtol(p, 0, 10);
	tm.mon = parsemon(p+3);
	if(tm.mon == -1)
		goto bad;
	tm.year = strtol(p+7, 0, 10) - 1900;
	tm.hour = strtol(p+12, 0, 10);
	tm.min = strtol(p+15, 0, 10);
	tm.sec = strtol(p+18, 0, 10);
	strcpy(tm.zone, "GMT");

	t = tm2sec(&tm);
	delta = ((p[22]-'0')*10+p[23]-'0')*3600 + ((p[24]-'0')*10+p[25]-'0')*60;
	if(p[21] == '-')
		delta = -delta;
	
	t -= delta;
	return t;
}

static uint
parsenumber(Sx *v)
{
	if(v->type != SxNumber)
		return 0;
	return v->number;
}

static void
hash(DigestState *ds, char *tag, char *val)
{
	if(val == nil)
		val = "";
	md5((uchar*)tag, strlen(tag)+1, nil, ds);
	md5((uchar*)val, strlen(val)+1, nil, ds);
}

static Hdr*
parseenvelope(Sx *v)
{
	Hdr *hdr;
	uchar digest[16];
	DigestState ds;
	
	if(v->type != SxList || !sxmatch(v, "SSLLLLLLSS")){
		warn("bad envelope: %$", v);
		return nil;
	}

	hdr = emalloc(sizeof *hdr);
	hdr->date = nstring(v->sx[0]);
	hdr->subject = unrfc2047(nstring(v->sx[1]));
	hdr->from = copyaddrs(v->sx[2]);
	hdr->sender = copyaddrs(v->sx[3]);
	hdr->replyto = copyaddrs(v->sx[4]);
	hdr->to = copyaddrs(v->sx[5]);
	hdr->cc = copyaddrs(v->sx[6]);
	hdr->bcc = copyaddrs(v->sx[7]);
	hdr->inreplyto = unrfc2047(nstring(v->sx[8]));
	hdr->messageid = unrfc2047(nstring(v->sx[9]));
	
	memset(&ds, 0, sizeof ds);
	hash(&ds, "date", hdr->date);
	hash(&ds, "subject", hdr->subject);
	hash(&ds, "from", hdr->from);
	hash(&ds, "sender", hdr->sender);
	hash(&ds, "replyto", hdr->replyto);
	hash(&ds, "to", hdr->to);
	hash(&ds, "cc", hdr->cc);
	hash(&ds, "bcc", hdr->bcc);
	hash(&ds, "inreplyto", hdr->inreplyto);
	hash(&ds, "messageid", hdr->messageid);
	md5(0, 0, digest, &ds);
	hdr->digest = esmprint("%.16H", digest);

	return hdr;
}

static void
strlwr(char *s)
{
	char *t;
	
	if(s == nil)
		return;
	for(t=s; *t; t++)
		if('A' <= *t && *t <= 'Z')
			*t += 'a' - 'A';
}

static void
nocr(char *s)
{
	char *r, *w;
	
	if(s == nil)
		return;
	for(r=w=s; *r; r++)
		if(*r != '\r')
			*w++ = *r;
	*w = 0;
}

/*
 * substitute all occurrences of a with b in s.
 */
static char*
gsub(char *s, char *a, char *b)
{
	char *p, *t, *w, *last;
	int n;
	
	n = 0;
	for(p=s; (p=strstr(p, a)) != nil; p+=strlen(a))
		n++;
	if(n == 0)
		return s;
	t = emalloc(strlen(s)+n*strlen(b)+1);
	w = t;
	for(p=s; last=p, (p=strstr(p, a)) != nil; p+=strlen(a)){
		memmove(w, last, p-last);
		w += p-last;
		memmove(w, b, strlen(b));
		w += strlen(b);
	}
	strcpy(w, last);
	free(s);
	return t;
}

/*
 * Table-driven IMAP "unexpected response" parser.
 * All the interesting data is in the unexpected responses.
 */
static void xlist(Imap*, Sx*);
static void xrecent(Imap*, Sx*);
static void xexists(Imap*, Sx*);
static void xok(Imap*, Sx*);
static void xflags(Imap*, Sx*);
static void xfetch(Imap*, Sx*);
static void xexpunge(Imap*, Sx*);
static void xbye(Imap*, Sx*);
static void xsearch(Imap*, Sx*);

static struct {
	int		num;
	char		*name;
	char		*fmt;
	void		(*fn)(Imap*, Sx*);
} unextab[] = {
	0,	"BYE",		nil,			xbye,
	0,	"FLAGS",		"AAL",		xflags,
	0,	"LIST",		"AALSS",		xlist,
	0,	"OK",		nil,			xok,
	0,	"SEARCH",	"AAN*",		xsearch,

	1,	"EXISTS",		"ANA",		xexists,
	1,	"EXPUNGE",	"ANA",		xexpunge,
	1,	"FETCH",		"ANAL",		xfetch,
	1,	"RECENT",	"ANA",		xrecent
};

static void
unexpected(Imap *z, Sx *sx)
{
	int i, num;
	char *name;

	if(sx->nsx >= 3 && sx->sx[1]->type == SxNumber && sx->sx[2]->type == SxAtom){
		num = 1;
		name = sx->sx[2]->data;
	}else if(sx->nsx >= 2 && sx->sx[1]->type == SxAtom){
		num = 0;
		name = sx->sx[1]->data;
	}else
		return;
	
	for(i=0; i<nelem(unextab); i++){
		if(unextab[i].num == num && cistrcmp(unextab[i].name, name) == 0){
			if(unextab[i].fmt && !sxmatch(sx, unextab[i].fmt)){
				warn("malformed %s: %$", name, sx);
				continue;
			}
			unextab[i].fn(z, sx);
		}
	}
}

static int
alldollars(char *s)
{
	for(; *s; s++)
		if(*s != '$')
			return 0;
	return 1;
}

static void
xlist(Imap *z, Sx *sx)
{
	int inbox;
	char *s, *t;
	Box *box;

	s = estrdup(sx->sx[4]->data);
	if(sx->sx[3]->data && strcmp(sx->sx[3]->data, "/") != 0){
		s = gsub(s, "/", "_");
		s = gsub(s, sx->sx[3]->data, "/");
	}

	/*
	 * INBOX is the special imap name for the main mailbox.
	 * All other mailbox names have the root prefix removed, if applicable.
	 */
	inbox = 0;
	if(cistrcmp(s, "INBOX") == 0){
		inbox = 1;
		free(s);
		s = estrdup("mbox");
	} else if(z->root && strstr(s, z->root) == s) {
		t = estrdup(s+strlen(z->root));
		free(s);
		s = t;
	}
	
	/* 
	 * Plan 9 calls the main mailbox mbox.  
	 * Rename any existing mbox by appending a $.
	 */
	if(!inbox && strncmp(s, "mbox", 4) == 0 && alldollars(s+4)){
		t = emalloc(strlen(s)+2);
		strcpy(t, s);
		strcat(t, "$");
		free(s);
		s = t;
	}

	box = boxcreate(s);
	if(box == nil)
		return;
	box->imapname = estrdup(sx->sx[4]->data);
	if(inbox)
		z->inbox = box;
	box->mark = 0;
	box->flags = parseflags(sx->sx[2]);
}

static void
xrecent(Imap *z, Sx *sx)
{
	if(z->box)
		z->box->recent = sx->sx[1]->number;
}

static void
xexists(Imap *z, Sx *sx)
{
	if(z->box){
		z->box->exists = sx->sx[1]->number;
		if(z->box->exists < z->box->maxseen)
			z->box->maxseen = z->box->exists;
	}
}

static void
xflags(Imap *z, Sx *sx)
{
	USED(z);
	USED(sx);
	/*
	 * This response contains in sx->sx[2] the list of flags
	 * that can be validly attached to messages in z->box.
	 * We don't have any use for this list, since we 
	 * use only the standard flags.
	 */
}

static void
xbye(Imap *z, Sx *sx)
{
	USED(sx);
	close(z->fd);
	z->fd = -1;
	z->connected = 0;
}

static void
xexpunge(Imap *z, Sx *sx)
{
	int i, n;
	Box *b;

	if((b=z->box) == nil)
		return;
	n = sx->sx[1]->number;
	for(i=0; i<b->nmsg; i++){
		if(b->msg[i]->imapid == n){
			msgplumb(b->msg[i], 1);
			msgfree(b->msg[i]);
			b->nmsg--;
			memmove(b->msg+i, b->msg+i+1, (b->nmsg-i)*sizeof b->msg[0]);
			i--;
			b->maxseen--;
			b->exists--;
			continue;
		}
		if(b->msg[i]->imapid > n)
			b->msg[i]->imapid--;
		b->msg[i]->ix = i;
	}
}

static void
xsearch(Imap *z, Sx *sx)
{
	int i;
	
	free(z->uid);
	z->uid = emalloc((sx->nsx-2)*sizeof z->uid[0]);
	z->nuid = sx->nsx-2;
	for(i=0; i<z->nuid; i++)
		z->uid[i] = sx->sx[i+2]->number;
}

/* 
 * Table-driven FETCH message info parser.
 */
static void xmsgflags(Msg*, Sx*, Sx*);
static void xmsgdate(Msg*, Sx*, Sx*);
static void xmsgrfc822size(Msg*, Sx*, Sx*);
static void xmsgenvelope(Msg*, Sx*, Sx*);
static void xmsgbody(Msg*, Sx*, Sx*);
static void xmsgbodydata(Msg*, Sx*, Sx*);

static struct {
	char *name;
	void (*fn)(Msg*, Sx*, Sx*);
} msgtab[] = {
	"FLAGS", xmsgflags,
	"INTERNALDATE", xmsgdate,
	"RFC822.SIZE", xmsgrfc822size,
	"ENVELOPE", xmsgenvelope,
	"BODY", xmsgbody,
	"BODY[", xmsgbodydata
};

static void
xfetch(Imap *z, Sx *sx)
{
	int i, j, n, uid;
	Msg *msg;

	if(z->box == nil){
		warn("FETCH but no open box: %$", sx);
		return;
	}

	/* * 152 FETCH (UID 185 FLAGS () ...) */
	if(sx->sx[3]->nsx%2){
		warn("malformed FETCH: %$", sx);
		return;
	}

	n = sx->sx[1]->number;
	sx = sx->sx[3];
	for(i=0; i<sx->nsx; i+=2){
		if(isatom(sx->sx[i], "UID")){
			if(sx->sx[i+1]->type == SxNumber){
				uid = sx->sx[i+1]->number;
				goto haveuid;
			}
		}
	}
/* This happens: too bad.
	warn("FETCH without UID: %$", sx);
*/
	return;

haveuid:
	msg = msgbyimapuid(z->box, uid, 1);
	if(msg->imapid && msg->imapid != n)
		warn("msg id mismatch: want %d have %d", msg->id, n);
	msg->imapid = n;
	for(i=0; i<sx->nsx; i+=2){
		for(j=0; j<nelem(msgtab); j++)
			if(isatom(sx->sx[i], msgtab[j].name))
				msgtab[j].fn(msg, sx->sx[i], sx->sx[i+1]);
	}
}

static void
xmsgflags(Msg *msg, Sx *k, Sx *v)
{
	USED(k);
	msg->flags = parseflags(v);
}

static void
xmsgdate(Msg *msg, Sx *k, Sx *v)
{
	USED(k);
	msg->date = parsedate(v);
}

static void
xmsgrfc822size(Msg *msg, Sx *k, Sx *v)
{
	USED(k);
	msg->size = parsenumber(v);
}

static char*
nstring(Sx *v)
{
	char *p;
	
	if(isnil(v))
		return estrdup("");
	p = v->data;
	v->data = nil;
	return p;
}

static char*
copyaddrs(Sx *v)
{
	char *s, *sep;
	char *name, *email, *host, *mbox;
	int i;
	Fmt fmt;
	
	if(v->nsx == 0)
		return nil;

	fmtstrinit(&fmt);
	sep = "";
	for(i=0; i<v->nsx; i++){
		if(!sxmatch(v->sx[i], "SSSS"))
			warn("bad address: %$", v->sx[i]);
		name = unrfc2047(nstring(v->sx[i]->sx[0]));
		/* ignore sx[1] - route */
		mbox = unrfc2047(nstring(v->sx[i]->sx[2]));
		host = unrfc2047(nstring(v->sx[i]->sx[3]));
		if(mbox == nil || host == nil){	/* rfc822 group syntax */
			free(name);
			free(mbox);
			free(host);
			continue;
		}
		email = esmprint("%s@%s", mbox, host);
		free(mbox);
		free(host);
		fmtprint(&fmt, "%s%q %q", sep, name ? name : "", email ? email : "");
		free(name);
		free(email);
		sep = " ";
	}
	s = fmtstrflush(&fmt);
	if(s == nil)
		sysfatal("out of memory");
	return s;
}

static void
xmsgenvelope(Msg *msg, Sx *k, Sx *v)
{
	USED(k);
	hdrfree(msg->part[0]->hdr);
	msg->part[0]->hdr = parseenvelope(v);
	msgplumb(msg, 0);
}

static struct {
	char *name;
	int offset;
} paramtab[] = {
	"charset",	offsetof(Part, charset),
	"name",		offsetof(Part, filename)
};

static void
parseparams(Part *part, Sx *v)
{
	int i, j;
	char *s, *t, **p;
	
	if(isnil(v))
		return;
	if(v->nsx%2){
		warn("bad message params: %$", v);
		return;
	}
	for(i=0; i<v->nsx; i+=2){
		s = nstring(v->sx[i]);
		t = nstring(v->sx[i+1]);
		for(j=0; j<nelem(paramtab); j++){
			if(cistrcmp(paramtab[j].name, s) == 0){
				p = (char**)((char*)part+paramtab[j].offset);
				free(*p);
				*p = t;
				t = nil;
				break;
			}
		}
		free(s);
		free(t);
	}			
}

static void
parsestructure(Part *part, Sx *v)
{
	int i;
	char *s, *t;
	
	if(isnil(v))
		return;
	if(v->type != SxList){
	bad:
		warn("bad structure: %$", v);
		return;
	}
	if(islist(v->sx[0])){
		/* multipart */
		for(i=0; i<v->nsx && islist(v->sx[i]); i++)
			parsestructure(partcreate(part->msg, part), v->sx[i]);
		free(part->type);
		if(i != v->nsx-1 || !isstring(v->sx[i])){
			warn("bad multipart structure: %$", v);
			part->type = estrdup("multipart/mixed");
			return;
		}
		s = nstring(v->sx[i]);
		strlwr(s);
		part->type = esmprint("multipart/%s", s);
		free(s);
		return;
	}
	/* single part */
	if(!isstring(v->sx[0]) || v->nsx < 2)
		goto bad;
	s = nstring(v->sx[0]);
	t = nstring(v->sx[1]);
	strlwr(s);
	strlwr(t);
	free(part->type);
	part->type = esmprint("%s/%s", s, t);
	if(v->nsx < 7 || !islist(v->sx[2]) || !isstring(v->sx[3]) 
	|| !isstring(v->sx[4]) || !isstring(v->sx[5]) || !isnumber(v->sx[6]))
		goto bad;
	parseparams(part, v->sx[2]);
	part->idstr = nstring(v->sx[3]);
	part->desc = nstring(v->sx[4]);
	part->encoding = nstring(v->sx[5]);
	part->size = v->sx[6]->number;
	if(strcmp(s, "message") == 0 && strcmp(t, "rfc822") == 0){
		if(v->nsx < 10 || !islist(v->sx[7]) || !islist(v->sx[8]) || !isnumber(v->sx[9]))
			goto bad;
		part->hdr = parseenvelope(v->sx[7]);
		parsestructure(partcreate(part->msg, part), v->sx[8]);
		part->lines = v->sx[9]->number;
	}
	if(strcmp(s, "text") == 0){
		if(v->nsx < 8 || !isnumber(v->sx[7]))
			goto bad;
		part->lines = v->sx[7]->number;
	}
}

static void
xmsgbody(Msg *msg, Sx *k, Sx *v)
{
	USED(k);
	if(v->type != SxList){
		warn("bad body: %$", v);
		return;
	}
	/*
	 * To follow the structure exactly we should
	 * be doing this to partcreate(msg, msg->part[0]),
	 * and we should leave msg->part[0] with type message/rfc822,
	 * but the extra layer is redundant - what else would be in a mailbox?
	 */
	parsestructure(msg->part[0], v);
	if(msg->box->maxseen < msg->imapid)
		msg->box->maxseen = msg->imapid;
	if(msg->imapuid >= msg->box->uidnext)
		msg->box->uidnext = msg->imapuid+1;
}

static void
xmsgbodydata(Msg *msg, Sx *k, Sx *v)
{
	int i;
	char *name, *p;
	Part *part;
	
	name = k->data;
	name += 5;	/* body[ */
	p = strchr(name, ']');
	if(p)
		*p = 0;
	
	/* now name is something like 1 or 3.2.MIME - walk down parts from root */
	part = msg->part[0];


	while('1' <= name[0] && name[0] <= '9'){
		i = strtol(name, &p, 10);
		if(*p == '.')
			p++;
		else if(*p != 0){
			warn("bad body name: %$", k);
			return;
		}
		if((part = subpart(part, i-1)) == nil){
			warn("unknown body part: %$", k);
			return;
		}
		name = p;
	}


	if(cistrcmp(name, "") == 0){
		free(part->raw);
		part->raw = nstring(v);
		nocr(part->raw);
	}else if(cistrcmp(name, "HEADER") == 0){
		free(part->rawheader);
		part->rawheader = nstring(v);
		nocr(part->rawheader);
	}else if(cistrcmp(name, "MIME") == 0){
		free(part->mimeheader);
		part->mimeheader = nstring(v);
		nocr(part->mimeheader);
	}else if(cistrcmp(name, "TEXT") == 0){
		free(part->rawbody);
		part->rawbody = nstring(v);
		nocr(part->rawbody);
	}
}

/*
 * Table-driven OK info parser.
 */
static void xokuidvalidity(Imap*, Sx*);
static void xokpermflags(Imap*, Sx*);
static void xokunseen(Imap*, Sx*);
static void xokreadwrite(Imap*, Sx*);
static void xokreadonly(Imap*, Sx*);

struct {
	char *name;
	char fmt;
	void (*fn)(Imap*, Sx*);
} oktab[] = {
	"UIDVALIDITY", 'N',	xokuidvalidity,
	"PERMANENTFLAGS", 'L',	xokpermflags,
	"UNSEEN", 'N',	xokunseen,
	"READ-WRITE", 0,	xokreadwrite,
	"READ-ONLY",	0, xokreadonly
};

static void
xok(Imap *z, Sx *sx)
{
	int i;
	char *name;
	Sx *arg;

	if(sx->nsx >= 4 && sx->sx[2]->type == SxAtom && sx->sx[2]->data[0] == '['){
		if(sx->sx[3]->type == SxAtom && sx->sx[3]->data[0] == ']')
			arg = nil;
		else if(sx->sx[4]->type == SxAtom && sx->sx[4]->data[0] == ']')
			arg = sx->sx[3];
		else{
			warn("cannot parse OK: %$", sx);
			return;
		}
		name = sx->sx[2]->data+1;
		for(i=0; i<nelem(oktab); i++){
			if(cistrcmp(name, oktab[i].name) == 0){
				if(oktab[i].fmt && (arg==nil || arg->type != fmttype(oktab[i].fmt))){
					warn("malformed %s: %$", name, arg);
					continue;
				}
				oktab[i].fn(z, arg);
			}
		}
	}
}

static void
xokuidvalidity(Imap *z, Sx *sx)
{
	int i;
	Box *b;
	
	if((b=z->box) == nil)
		return;
	if(b->validity != sx->number){
		b->validity = sx->number;
		b->uidnext = 1;
		for(i=0; i<b->nmsg; i++)
			msgfree(b->msg[i]);
		free(b->msg);
		b->msg = nil;
		b->nmsg = 0;
	}
}

static void
xokpermflags(Imap *z, Sx *sx)
{
	USED(z);
	USED(sx);
/*	z->permflags = parseflags(sx); */
}

static void
xokunseen(Imap *z, Sx *sx)
{
	USED(z);
	USED(sx);
/*	z->unseen = sx->number; */
}

static void
xokreadwrite(Imap *z, Sx *sx)
{
	USED(z);
	USED(sx);
/*	z->boxmode = ORDWR; */
}

static void
xokreadonly(Imap *z, Sx *sx)
{
	USED(z);
	USED(sx);
/*	z->boxmode = OREAD; */
}

