#include "common.h"
#include <ctype.h>
#include <plumb.h>
#include <libsec.h>
#include <thread.h>
#include "dat.h"

extern char* dirtab[]; /* jpc */

typedef struct Header Header;

struct Header {
	char *type;
	void (*f)(Message*, Header*, char*);
	int len;
};

/* headers */
static	void	ctype(Message*, Header*, char*);
static	void	cencoding(Message*, Header*, char*);
static	void	cdisposition(Message*, Header*, char*);
static	void	date822(Message*, Header*, char*);
static	void	from822(Message*, Header*, char*);
static	void	to822(Message*, Header*, char*);
static	void	sender822(Message*, Header*, char*);
static	void	replyto822(Message*, Header*, char*);
static	void	subject822(Message*, Header*, char*);
static	void	inreplyto822(Message*, Header*, char*);
static	void	cc822(Message*, Header*, char*);
static	void	bcc822(Message*, Header*, char*);
static	void	messageid822(Message*, Header*, char*);
static	void	mimeversion(Message*, Header*, char*);
static	void	nullsqueeze(Message*);
enum
{
	Mhead=	11,	/* offset of first mime header */
};

Header head[] =
{
	{ "date:", date822, },
	{ "from:", from822, },
	{ "to:", to822, },
	{ "sender:", sender822, },
	{ "reply-to:", replyto822, },
	{ "subject:", subject822, },
	{ "cc:", cc822, },
	{ "bcc:", bcc822, },
	{ "in-reply-to:", inreplyto822, },
	{ "mime-version:", mimeversion, },
	{ "message-id:", messageid822, },

[Mhead]	{ "content-type:", ctype, },
	{ "content-transfer-encoding:", cencoding, },
	{ "content-disposition:", cdisposition, },
	{ 0, },
};

/* static	void	fatal(char *fmt, ...); jpc */
static	void	initquoted(void);
/* static	void	startheader(Message*);
static	void	startbody(Message*); jpc */
static	char*	skipwhite(char*);
static	char*	skiptosemi(char*);
static	char*	getstring(char*, String*, int);
static	void	setfilename(Message*, char*);
/* static	char*	lowercase(char*); jpc */
static	int	is8bit(Message*);
static	int	headerline(char**, String*);
static	void	initheaders(void);
static void	parseattachments(Message*, Mailbox*);

int		debug;

char *Enotme = "path not served by this file server";

enum
{
	Chunksize = 1024,
};

Mailboxinit *boxinit[] = {
	imap4mbox,
	pop3mbox,
	plan9mbox,
};

char*
syncmbox(Mailbox *mb, int doplumb)
{
	return (*mb->sync)(mb, doplumb);
}

/* create a new mailbox */
char*
newmbox(char *path, char *name, int std)
{
	Mailbox *mb, **l;
	char *p, *rv;
	int i;

	initheaders();

	mb = emalloc(sizeof(*mb));
	strncpy(mb->path, path, sizeof(mb->path)-1);
	if(name == nil){
		p = strrchr(path, '/');
		if(p == nil)
			p = path;
		else
			p++;
		if(*p == 0){
			free(mb);
			return "bad mbox name";
		}
		strncpy(mb->name, p, sizeof(mb->name)-1);
	} else {
		strncpy(mb->name, name, sizeof(mb->name)-1);
	}

	rv = nil;
	// check for a mailbox type
	for(i=0; i<nelem(boxinit); i++)
		if((rv = (*boxinit[i])(mb, path)) != Enotme)
			break;
	if(i == nelem(boxinit)){
		free(mb);
		return "bad path";
	}

	// on error, give up
	if(rv){
		free(mb);
		return rv;
	}

	// make sure name isn't taken
	qlock(&mbllock);
	for(l = &mbl; *l != nil; l = &(*l)->next){
		if(strcmp((*l)->name, mb->name) == 0){
			if(strcmp(path, (*l)->path) == 0)
				rv = nil;
			else
				rv = "mbox name in use";
			if(mb->close)
				(*mb->close)(mb);
			free(mb);
			qunlock(&mbllock);
			return rv;
		}
	}

	// always try locking
	mb->dolock = 1;

	mb->refs = 1;
	mb->next = nil;
	mb->id = newid();
	mb->root = newmessage(nil);
	mb->std = std;
	*l = mb;
	qunlock(&mbllock);

	qlock(&mb->ql);
	if(mb->ctl){
		henter(PATH(mb->id, Qmbox), "ctl",
			(Qid){PATH(mb->id, Qmboxctl), 0, QTFILE}, nil, mb);
	}
	rv = syncmbox(mb, 0);
	qunlock(&mb->ql);

	return rv;
}

// close the named mailbox
void
freembox(char *name)
{
	Mailbox **l, *mb;

	qlock(&mbllock);
	for(l=&mbl; *l != nil; l=&(*l)->next){
		if(strcmp(name, (*l)->name) == 0){
			mb = *l;
			*l = mb->next;
			mboxdecref(mb);
			break;
		}
	}
	hfree(PATH(0, Qtop), name);
	qunlock(&mbllock);
}

static void
initheaders(void)
{
	Header *h;
	static int already;

	if(already)
		return;
	already = 1;

	for(h = head; h->type != nil; h++)
		h->len = strlen(h->type);
}

/*
 *  parse a Unix style header
 */
void
parseunix(Message *m)
{
	char *p;
	String *h;

	h = s_new();
	for(p = m->start + 5; *p && *p != '\r' && *p != '\n'; p++)
		s_putc(h, *p);
	s_terminate(h);
	s_restart(h);

	m->unixfrom = s_parse(h, s_reset(m->unixfrom));
	m->unixdate = s_append(s_reset(m->unixdate), h->ptr);

	s_free(h);
}

/*
 *  parse a message
 */
void
parseheaders(Message *m, int justmime, Mailbox *mb, int addfrom)
{
	String *hl;
	Header *h;
	char *p, *q;
	int i;

	if(m->whole == m->whole->whole){
		henter(PATH(mb->id, Qmbox), m->name,
			(Qid){PATH(m->id, Qdir), 0, QTDIR}, m, mb);
	} else {
		henter(PATH(m->whole->id, Qdir), m->name,
			(Qid){PATH(m->id, Qdir), 0, QTDIR}, m, mb);
	}
	for(i = 0; i < Qmax; i++)
		henter(PATH(m->id, Qdir), dirtab[i],
			(Qid){PATH(m->id, i), 0, QTFILE}, m, mb);

	// parse mime headers
	p = m->header;
	hl = s_new();
	while(headerline(&p, hl)){
		if(justmime)
			h = &head[Mhead];
		else
			h = head;
		for(; h->type; h++){
			if(cistrncmp(s_to_c(hl), h->type, h->len) == 0){
				(*h->f)(m, h, s_to_c(hl));
				break;
			}
		}
		s_reset(hl);
	}
	s_free(hl);

	// the blank line isn't really part of the body or header
	if(justmime){
		m->mhend = p;
		m->hend = m->header;
	} else {
		m->hend = p;
	}
	if(*p == '\n')
		p++;
	m->rbody = m->body = p;

	// if type is text, get any nulls out of the body.  This is
	// for the two seans and imap clients that get confused.
	if(strncmp(s_to_c(m->type), "text/", 5) == 0)
		nullsqueeze(m);

	//
	// cobble together Unix-style from line
	// for local mailbox messages, we end up recreating the
	// original header.
	// for pop3 messages, the best we can do is 
	// use the From: information and the RFC822 date.
	//
	if(m->unixdate == nil || strcmp(s_to_c(m->unixdate), "???") == 0
	|| strcmp(s_to_c(m->unixdate), "Thu Jan 1 00:00:00 GMT 1970") == 0){
		if(m->unixdate){
			s_free(m->unixdate);
			m->unixdate = nil;
		}
		// look for the date in the first Received: line.
		// it's likely to be the right time zone (it's
	 	// the local system) and in a convenient format.
		if(cistrncmp(m->header, "received:", 9)==0){
			if((q = strchr(m->header, ';')) != nil){
				p = q;
				while((p = strchr(p, '\n')) != nil){
					if(p[1] != ' ' && p[1] != '\t' && p[1] != '\n')
						break;
					p++;
				}
				if(p){
					*p = '\0';
					m->unixdate = date822tounix(q+1);
					*p = '\n';
				}
			}
		}

		// fall back on the rfc822 date	
		if(m->unixdate==nil && m->date822)
			m->unixdate = date822tounix(s_to_c(m->date822));
	}

	if(m->unixheader != nil)
		s_free(m->unixheader);

	// only fake header for top-level messages for pop3 and imap4
	// clients (those protocols don't include the unix header).
	// adding the unix header all the time screws up mime-attached
	// rfc822 messages.
	if(!addfrom && !m->unixfrom){
		m->unixheader = nil;
		return;
	}

	m->unixheader = s_copy("From ");
	if(m->unixfrom && strcmp(s_to_c(m->unixfrom), "???") != 0)
		s_append(m->unixheader, s_to_c(m->unixfrom));
	else if(m->from822)
		s_append(m->unixheader, s_to_c(m->from822));
	else
		s_append(m->unixheader, "???");

	s_append(m->unixheader, " ");
	if(m->unixdate)
		s_append(m->unixheader, s_to_c(m->unixdate));
	else
		s_append(m->unixheader, "Thu Jan  1 00:00:00 GMT 1970");

	s_append(m->unixheader, "\n");
}

String*
promote(String **sp)
{
	String *s;

	if(*sp != nil)
		s = s_clone(*sp);
	else
		s = nil;
	return s;
}

void
parsebody(Message *m, Mailbox *mb)
{
	Message *nm;

	// recurse
	if(strncmp(s_to_c(m->type), "multipart/", 10) == 0){
		parseattachments(m, mb);
	} else if(strcmp(s_to_c(m->type), "message/rfc822") == 0){
		decode(m);
		parseattachments(m, mb);
		nm = m->part;

		// promote headers
		if(m->replyto822 == nil && m->from822 == nil && m->sender822 == nil){
			m->from822 = promote(&nm->from822);
			m->to822 = promote(&nm->to822);
			m->date822 = promote(&nm->date822);
			m->sender822 = promote(&nm->sender822);
			m->replyto822 = promote(&nm->replyto822);
			m->subject822 = promote(&nm->subject822);
			m->unixdate = promote(&nm->unixdate);
		}
	}
}

void
parse(Message *m, int justmime, Mailbox *mb, int addfrom)
{
	parseheaders(m, justmime, mb, addfrom);
	parsebody(m, mb);
}

static void
parseattachments(Message *m, Mailbox *mb)
{
	Message *nm, **l;
	char *p, *x;

	// if there's a boundary, recurse...
	if(m->boundary != nil){
		p = m->body;
		nm = nil;
		l = &m->part;
		for(;;){
			x = strstr(p, s_to_c(m->boundary));

			/* no boundary, we're done */
			if(x == nil){
				if(nm != nil)
					nm->rbend = nm->bend = nm->end = m->bend;
				break;
			}

			/* boundary must be at the start of a line */
			if(x != m->body && *(x-1) != '\n'){
				p = x+1;
				continue;
			}

			if(nm != nil)
				nm->rbend = nm->bend = nm->end = x;
			x += strlen(s_to_c(m->boundary));

			/* is this the last part? ignore anything after it */
			if(strncmp(x, "--", 2) == 0)
				break;

			p = strchr(x, '\n');
			if(p == nil)
				break;
			nm = newmessage(m);
			nm->start = nm->header = nm->body = nm->rbody = ++p;
			nm->mheader = nm->header;
			*l = nm;
			l = &nm->next;
		}
		for(nm = m->part; nm != nil; nm = nm->next)
			parse(nm, 1, mb, 0);
		return;
	}

	// if we've got an rfc822 message, recurse...
	if(strcmp(s_to_c(m->type), "message/rfc822") == 0){
		nm = newmessage(m);
		m->part = nm;
		nm->start = nm->header = nm->body = nm->rbody = m->body;
		nm->end = nm->bend = nm->rbend = m->bend;
		parse(nm, 0, mb, 0);
	}
}

/*
 *  pick up a header line
 */
static int
headerline(char **pp, String *hl)
{
	char *p, *x;

	s_reset(hl);
	p = *pp;
	x = strpbrk(p, ":\n");
	if(x == nil || *x == '\n')
		return 0;
	for(;;){
		x = strchr(p, '\n');
		if(x == nil)
			x = p + strlen(p);
		s_nappend(hl, p, x-p);
		p = x;
		if(*p != '\n' || *++p != ' ' && *p != '\t')
			break;
		while(*p == ' ' || *p == '\t')
			p++;
		s_putc(hl, ' ');
	}
	*pp = p;
	return 1;
}

static String*
addr822(char *p)
{
	String *s, *list;
	int incomment, addrdone, inanticomment, quoted;
	int n;
	int c;

	list = s_new();
	s = s_new();
	quoted = incomment = addrdone = inanticomment = 0;
	n = 0;
	for(; *p; p++){
		c = *p;

		// whitespace is ignored
		if(!quoted && isspace(c) || c == '\r')
			continue;

		// strings are always treated as atoms
		if(!quoted && c == '"'){
			if(!addrdone && !incomment)
				s_putc(s, c);
			for(p++; *p; p++){
				if(!addrdone && !incomment)
					s_putc(s, *p);
				if(!quoted && *p == '"')
					break;
				if(*p == '\\')
					quoted = 1;
				else
					quoted = 0;
			}
			if(*p == 0)
				break;
			quoted = 0;
			continue;
		}

		// ignore everything in an expicit comment
		if(!quoted && c == '('){
			incomment = 1;
			continue;
		}
		if(incomment){
			if(!quoted && c == ')')
				incomment = 0;
			quoted = 0;
			continue;
		}

		// anticomments makes everything outside of them comments
		if(!quoted && c == '<' && !inanticomment){
			inanticomment = 1;
			s = s_reset(s);
			continue;
		}
		if(!quoted && c == '>' && inanticomment){
			addrdone = 1;
			inanticomment = 0;
			continue;
		}

		// commas separate addresses
		if(!quoted && c == ',' && !inanticomment){
			s_terminate(s);
			addrdone = 0;
			if(n++ != 0)
				s_append(list, " ");
			s_append(list, s_to_c(s));
			s = s_reset(s);
			continue;
		}

		// what's left is part of the address
		s_putc(s, c);

		// quoted characters are recognized only as characters
		if(c == '\\')
			quoted = 1;
		else
			quoted = 0;

	}

	if(*s_to_c(s) != 0){
		s_terminate(s);
		if(n++ != 0)
			s_append(list, " ");
		s_append(list, s_to_c(s));
	}
	s_free(s);

	if(n == 0){
		s_free(list);
		return nil;
	}
	return list;
}

static void
to822(Message *m, Header *h, char *p)
{
	p += strlen(h->type);
	s_free(m->to822);
	m->to822 = addr822(p);
}

static void
cc822(Message *m, Header *h, char *p)
{
	p += strlen(h->type);
	s_free(m->cc822);
	m->cc822 = addr822(p);
}

static void
bcc822(Message *m, Header *h, char *p)
{
	p += strlen(h->type);
	s_free(m->bcc822);
	m->bcc822 = addr822(p);
}

static void
from822(Message *m, Header *h, char *p)
{
	p += strlen(h->type);
	s_free(m->from822);
	m->from822 = addr822(p);
}

static void
sender822(Message *m, Header *h, char *p)
{
	p += strlen(h->type);
	s_free(m->sender822);
	m->sender822 = addr822(p);
}

static void
replyto822(Message *m, Header *h, char *p)
{
	p += strlen(h->type);
	s_free(m->replyto822);
	m->replyto822 = addr822(p);
}

static void
mimeversion(Message *m, Header *h, char *p)
{
	p += strlen(h->type);
	s_free(m->mimeversion);
	m->mimeversion = addr822(p);
}

static void
killtrailingwhite(char *p)
{
	char *e;

	e = p + strlen(p) - 1;
	while(e > p && isspace(*e))
		*e-- = 0;
}

static void
date822(Message *m, Header *h, char *p)
{
	p += strlen(h->type);
	p = skipwhite(p);
	s_free(m->date822);
	m->date822 = s_copy(p);
	p = s_to_c(m->date822);
	killtrailingwhite(p);
}

static void
subject822(Message *m, Header *h, char *p)
{
	p += strlen(h->type);
	p = skipwhite(p);
	s_free(m->subject822);
	m->subject822 = s_copy(p);
	p = s_to_c(m->subject822);
	killtrailingwhite(p);
}

static void
inreplyto822(Message *m, Header *h, char *p)
{
	p += strlen(h->type);
	p = skipwhite(p);
	s_free(m->inreplyto822);
	m->inreplyto822 = s_copy(p);
	p = s_to_c(m->inreplyto822);
	killtrailingwhite(p);
}

static void
messageid822(Message *m, Header *h, char *p)
{
	p += strlen(h->type);
	p = skipwhite(p);
	s_free(m->messageid822);
	m->messageid822 = s_copy(p);
	p = s_to_c(m->messageid822);
	killtrailingwhite(p);
}

static int
isattribute(char **pp, char *attr)
{
	char *p;
	int n;

	n = strlen(attr);
	p = *pp;
	if(cistrncmp(p, attr, n) != 0)
		return 0;
	p += n;
	while(*p == ' ')
		p++;
	if(*p++ != '=')
		return 0;
	while(*p == ' ')
		p++;
	*pp = p;
	return 1;
}

static void
ctype(Message *m, Header *h, char *p)
{
	String *s;

	p += h->len;
	p = skipwhite(p);

	p = getstring(p, m->type, 1);
	
	while(*p){
		if(isattribute(&p, "boundary")){
			s = s_new();
			p = getstring(p, s, 0);
			m->boundary = s_reset(m->boundary);
			s_append(m->boundary, "--");
			s_append(m->boundary, s_to_c(s));
			s_free(s);
		} else if(cistrncmp(p, "multipart", 9) == 0){
			/*
			 *  the first unbounded part of a multipart message,
			 *  the preamble, is not displayed or saved
			 */
		} else if(isattribute(&p, "name")){
			if(m->filename == nil)
				setfilename(m, p);
		} else if(isattribute(&p, "charset")){
			p = getstring(p, s_reset(m->charset), 0);
		}
		
		p = skiptosemi(p);
	}
}

static void
cencoding(Message *m, Header *h, char *p)
{
	p += h->len;
	p = skipwhite(p);
	if(cistrncmp(p, "base64", 6) == 0)
		m->encoding = Ebase64;
	else if(cistrncmp(p, "quoted-printable", 16) == 0)
		m->encoding = Equoted;
}

static void
cdisposition(Message *m, Header *h, char *p)
{
	p += h->len;
	p = skipwhite(p);
	while(*p){
		if(cistrncmp(p, "inline", 6) == 0){
			m->disposition = Dinline;
		} else if(cistrncmp(p, "attachment", 10) == 0){
			m->disposition = Dfile;
		} else if(cistrncmp(p, "filename=", 9) == 0){
			p += 9;
			setfilename(m, p);
		}
		p = skiptosemi(p);
	}

}

ulong msgallocd, msgfreed;

Message*
newmessage(Message *parent)
{
	/* static int id; jpc */
	Message *m;

	msgallocd++;

	m = emalloc(sizeof(*m));
	memset(m, 0, sizeof(*m));
	m->disposition = Dnone;
	m->type = s_copy("text/plain");
	m->charset = s_copy("iso-8859-1");
	m->id = newid();
	if(parent)
		sprint(m->name, "%d", ++(parent->subname));
	if(parent == nil)
		parent = m;
	m->whole = parent;
	m->hlen = -1;
	return m;
}

// delete a message from a mailbox
void
delmessage(Mailbox *mb, Message *m)
{
	Message **l;
	int i;

	mb->vers++;
	msgfreed++;

	if(m->whole != m){
		// unchain from parent
		for(l = &m->whole->part; *l && *l != m; l = &(*l)->next)
			;
		if(*l != nil)
			*l = m->next;

		// clear out of name lookup hash table
		if(m->whole->whole == m->whole)
			hfree(PATH(mb->id, Qmbox), m->name);
		else
			hfree(PATH(m->whole->id, Qdir), m->name);
		for(i = 0; i < Qmax; i++)
			hfree(PATH(m->id, Qdir), dirtab[i]);
	}

	/* recurse through sub-parts */
	while(m->part)
		delmessage(mb, m->part);

	/* free memory */
	if(m->mallocd)
		free(m->start);
	if(m->hallocd)
		free(m->header);
	if(m->ballocd)
		free(m->body);
	s_free(m->unixfrom);
	s_free(m->unixdate);
	s_free(m->unixheader);
	s_free(m->from822);
	s_free(m->sender822);
	s_free(m->to822);
	s_free(m->bcc822);
	s_free(m->cc822);
	s_free(m->replyto822);
	s_free(m->date822);
	s_free(m->inreplyto822);
	s_free(m->subject822);
	s_free(m->messageid822);
	s_free(m->addrs);
	s_free(m->mimeversion);
	s_free(m->sdigest);
	s_free(m->boundary);
	s_free(m->type);
	s_free(m->charset);
	s_free(m->filename);

	free(m);
}

// mark messages (identified by path) for deletion
void
delmessages(int ac, char **av)
{
	Mailbox *mb;
	Message *m;
	int i, needwrite;

	qlock(&mbllock);
	for(mb = mbl; mb != nil; mb = mb->next)
		if(strcmp(av[0], mb->name) == 0){
			qlock(&mb->ql);
			break;
		}
	qunlock(&mbllock);
	if(mb == nil)
		return;

	needwrite = 0;
	for(i = 1; i < ac; i++){
		for(m = mb->root->part; m != nil; m = m->next)
			if(strcmp(m->name, av[i]) == 0){
				if(!m->deleted){
					mailplumb(mb, m, 1);
					needwrite = 1;
					m->deleted = 1;
					logmsg("deleting", m);
				}
				break;
			}
	}
	if(needwrite)
		syncmbox(mb, 1);
	qunlock(&mb->ql);
}

/*
 *  the following are called with the mailbox qlocked
 */
void
msgincref(Message *m)
{
	m->refs++;
}
void
msgdecref(Mailbox *mb, Message *m)
{
	m->refs--;
	if(m->refs == 0 && m->deleted)
		syncmbox(mb, 1);
}

/*
 *  the following are called with mbllock'd
 */
void
mboxincref(Mailbox *mb)
{
	assert(mb->refs > 0);
	mb->refs++;
}
void
mboxdecref(Mailbox *mb)
{
	assert(mb->refs > 0);
	qlock(&mb->ql);
	mb->refs--;
	if(mb->refs == 0){
		delmessage(mb, mb->root);
		if(mb->ctl)
			hfree(PATH(mb->id, Qmbox), "ctl");
		if(mb->close)
			(*mb->close)(mb);
		free(mb);
	} else
		qunlock(&mb->ql);
}

int
cistrncmp(char *a, char *b, int n)
{
	while(n-- > 0){
		if(tolower(*a++) != tolower(*b++))
			return -1;
	}
	return 0;
}

int
cistrcmp(char *a, char *b)
{
	for(;;){
		if(tolower(*a) != tolower(*b++))
			return -1;
		if(*a++ == 0)
			break;
	}
	return 0;
}

static char*
skipwhite(char *p)
{
	while(isspace(*p))
		p++;
	return p;
}

static char*
skiptosemi(char *p)
{
	while(*p && *p != ';')
		p++;
	while(*p == ';' || isspace(*p))
		p++;
	return p;
}

static char*
getstring(char *p, String *s, int dolower)
{
	s = s_reset(s);
	p = skipwhite(p);
	if(*p == '"'){
		p++;
		for(;*p && *p != '"'; p++)
			if(dolower)
				s_putc(s, tolower(*p));
			else
				s_putc(s, *p);
		if(*p == '"')
			p++;
		s_terminate(s);

		return p;
	}

	for(; *p && !isspace(*p) && *p != ';'; p++)
		if(dolower)
			s_putc(s, tolower(*p));
		else
			s_putc(s, *p);
	s_terminate(s);

	return p;
}

static void
setfilename(Message *m, char *p)
{
	m->filename = s_reset(m->filename);
	getstring(p, m->filename, 0);
	for(p = s_to_c(m->filename); *p; p++)
		if(*p == ' ' || *p == '\t' || *p == ';')
			*p = '_';
}

//
// undecode message body
//
void
decode(Message *m)
{
	int i, len;
	char *x;

	if(m->decoded)
		return;
	switch(m->encoding){
	case Ebase64:
		len = m->bend - m->body;
		i = (len*3)/4+1;	// room for max chars + null
		x = emalloc(i);
		len = dec64((uchar*)x, i, m->body, len);
		if(m->ballocd)
			free(m->body);
		m->body = x;
		m->bend = x + len;
		m->ballocd = 1;
		break;
	case Equoted:
		len = m->bend - m->body;
		x = emalloc(len+2);	// room for null and possible extra nl
		len = decquoted(x, m->body, m->bend);
		if(m->ballocd)
			free(m->body);
		m->body = x;
		m->bend = x + len;
		m->ballocd = 1;
		break;
	default:
		break;
	}
	m->decoded = 1;
}

// convert latin1 to utf
void
convert(Message *m)
{
	int len;
	char *x;

	// don't convert if we're not a leaf, not text, or already converted
	if(m->converted)
		return;
	if(m->part != nil)
		return;
	if(cistrncmp(s_to_c(m->type), "text", 4) != 0)
		return;

	if(cistrcmp(s_to_c(m->charset), "us-ascii") == 0 ||
	   cistrcmp(s_to_c(m->charset), "iso-8859-1") == 0){
		len = is8bit(m);
		if(len > 0){
			len = 2*len + m->bend - m->body + 1;
			x = emalloc(len);
			len = latin1toutf(x, m->body, m->bend);
			if(m->ballocd)
				free(m->body);
			m->body = x;
			m->bend = x + len;
			m->ballocd = 1;
		}
	} else if(cistrcmp(s_to_c(m->charset), "iso-8859-2") == 0){
		len = xtoutf("8859-2", &x, m->body, m->bend);
		if(len != 0){
			if(m->ballocd)
				free(m->body);
			m->body = x;
			m->bend = x + len;
			m->ballocd = 1;
		}
	} else if(cistrcmp(s_to_c(m->charset), "iso-8859-15") == 0){
		len = xtoutf("8859-15", &x, m->body, m->bend);
		if(len != 0){
			if(m->ballocd)
				free(m->body);
			m->body = x;
			m->bend = x + len;
			m->ballocd = 1;
		}
	} else if(cistrcmp(s_to_c(m->charset), "big5") == 0){
		len = xtoutf("big5", &x, m->body, m->bend);
		if(len != 0){
			if(m->ballocd)
				free(m->body);
			m->body = x;
			m->bend = x + len;
			m->ballocd = 1;
		}
	} else if(cistrcmp(s_to_c(m->charset), "iso-2022-jp") == 0){
		len = xtoutf("jis", &x, m->body, m->bend);
		if(len != 0){
			if(m->ballocd)
				free(m->body);
			m->body = x;
			m->bend = x + len;
			m->ballocd = 1;
		}
	} else if(cistrcmp(s_to_c(m->charset), "windows-1257") == 0
			|| cistrcmp(s_to_c(m->charset), "windows-1252") == 0){
		len = is8bit(m);
		if(len > 0){
			len = 2*len + m->bend - m->body + 1;
			x = emalloc(len);
			len = windows1257toutf(x, m->body, m->bend);
			if(m->ballocd)
				free(m->body);
			m->body = x;
			m->bend = x + len;
			m->ballocd = 1;
		}
	} else if(cistrcmp(s_to_c(m->charset), "windows-1251") == 0){
		len = xtoutf("cp1251", &x, m->body, m->bend);
		if(len != 0){
			if(m->ballocd)
				free(m->body);
			m->body = x;
			m->bend = x + len;
			m->ballocd = 1;
		}
	} else if(cistrcmp(s_to_c(m->charset), "koi8-r") == 0){
		len = xtoutf("koi8", &x, m->body, m->bend);
		if(len != 0){
			if(m->ballocd)
				free(m->body);
			m->body = x;
			m->bend = x + len;
			m->ballocd = 1;
		}
	}

	m->converted = 1;
}

enum
{
	Self=	1,
	Hex=	2,
};
uchar	tableqp[256];

static void
initquoted(void)
{
	int c;

	memset(tableqp, 0, 256);
	for(c = ' '; c <= '<'; c++)
		tableqp[c] = Self;
	for(c = '>'; c <= '~'; c++)
		tableqp[c] = Self;
	tableqp['\t'] = Self;
	tableqp['='] = Hex;
}

static int
hex2int(int x)
{
	if(x >= '0' && x <= '9')
		return x - '0';
	if(x >= 'A' && x <= 'F')
		return (x - 'A') + 10;
	if(x >= 'a' && x <= 'f')
		return (x - 'a') + 10;
	return 0;
}

static char*
decquotedline(char *out, char *in, char *e)
{
	int c, soft;

	/* dump trailing white space */
	while(e >= in && (*e == ' ' || *e == '\t' || *e == '\r' || *e == '\n'))
		e--;

	/* trailing '=' means no newline */
	if(*e == '='){
		soft = 1;
		e--;
	} else
		soft = 0;

	while(in <= e){
		c = (*in++) & 0xff;
		switch(tableqp[c]){
		case Self:
			*out++ = c;
			break;
		case Hex:
			c = hex2int(*in++)<<4;
			c |= hex2int(*in++);
			*out++ = c;
			break;
		}
	}
	if(!soft)
		*out++ = '\n';
	*out = 0;

	return out;
}

int
decquoted(char *out, char *in, char *e)
{
	char *p, *nl;

	if(tableqp[' '] == 0)
		initquoted();

	p = out;
	while((nl = strchr(in, '\n')) != nil && nl < e){
		p = decquotedline(p, in, nl);
		in = nl + 1;
	}
	if(in < e)
		p = decquotedline(p, in, e-1);

	// make sure we end with a new line
	if(*(p-1) != '\n'){
		*p++ = '\n';
		*p = 0;
	}

	return p - out;
}

#if 0 /* jpc */
static char*
lowercase(char *p)
{
	char *op;
	int c;

	for(op = p; c = *p; p++)
		if(isupper(c))
			*p = tolower(c);
	return op;
}
#endif

/*
 *  return number of 8 bit characters
 */
static int
is8bit(Message *m)
{
	int count = 0;
	char *p;

	for(p = m->body; p < m->bend; p++)
		if(*p & 0x80)
			count++;
	return count;
}

// translate latin1 directly since it fits neatly in utf
int
latin1toutf(char *out, char *in, char *e)
{
	Rune r;
	char *p;

	p = out;
	for(; in < e; in++){
		r = (*in) & 0xff;
		p += runetochar(p, &r);
	}
	*p = 0;
	return p - out;
}

// translate any thing else using the tcs program
int
xtoutf(char *charset, char **out, char *in, char *e)
{
	char *av[4];
	int totcs[2];
	int fromtcs[2];
	int n, len, sofar;
	char *p;

	len = e-in+1;
	sofar = 0;
	*out = p = malloc(len+1);
	if(p == nil)
		return 0;

	av[0] = charset;
	av[1] = "-f";
	av[2] = charset;
	av[3] = 0;
	if(pipe(totcs) < 0)
		return 0;
	if(pipe(fromtcs) < 0){
		close(totcs[0]); close(totcs[1]);
		return 0;
	}
	switch(rfork(RFPROC|RFFDG|RFNOWAIT)){
	case -1:
		close(fromtcs[0]); close(fromtcs[1]);
		close(totcs[0]); close(totcs[1]);
		return 0;
	case 0:
		close(fromtcs[0]); close(totcs[1]);
		dup(fromtcs[1], 1);
		dup(totcs[0], 0);
		close(fromtcs[1]); close(totcs[0]);
		dup(open("/dev/null", OWRITE), 2);
		//jpc exec("/bin/tcs", av);
		exec(unsharp("#9/bin/tcs"), av);
		/* _exits(0); */
		threadexits(nil);
	default:
		close(fromtcs[1]); close(totcs[0]);
		switch(rfork(RFPROC|RFFDG|RFNOWAIT)){
		case -1:
			close(fromtcs[0]); close(totcs[1]);
			return 0;
		case 0:
			close(fromtcs[0]);
			while(in < e){
				n = write(totcs[1], in, e-in);
				if(n <= 0)
					break;
				in += n;
			}
			close(totcs[1]);
			/* _exits(0); */
			threadexits(nil);
		default:
			close(totcs[1]);
			for(;;){
				n = read(fromtcs[0], &p[sofar], len-sofar);
				if(n <= 0)
					break;
				sofar += n;
				p[sofar] = 0;
				if(sofar == len){
					len += 1024;
					*out = p = realloc(p, len+1);
					if(p == nil)
						return 0;
				}
			}
			close(fromtcs[0]);
			break;
		}
		break;
	}
	return sofar;
}

enum {
	Winstart= 0x7f,
	Winend= 0x9f,
};

Rune winchars[] = {
	L'•',
	L'•', L'•', L'‚', L'ƒ', L'„', L'…', L'†', L'‡',
	L'ˆ', L'‰', L'Š', L'‹', L'Œ', L'•', L'•', L'•',
	L'•', L'‘', L'’', L'“', L'”', L'•', L'–', L'—',
	L'˜', L'™', L'š', L'›', L'œ', L'•', L'•', L'Ÿ',
};

int
windows1257toutf(char *out, char *in, char *e)
{
	Rune r;
	char *p;

	p = out;
	for(; in < e; in++){
		r = (*in) & 0xff;
		if(r >= 0x7f && r <= 0x9f)
			r = winchars[r-0x7f];
		p += runetochar(p, &r);
	}
	*p = 0;
	return p - out;
}

void *
emalloc(ulong n)
{
	void *p;

	p = mallocz(n, 1);
	if(!p){
		fprint(2, "%s: out of memory alloc %lud\n", argv0, n);
		threadexits("out of memory");
	}
	setmalloctag(p, getcallerpc(&n));
	return p;
}

void *
erealloc(void *p, ulong n)
{
	if(n == 0)
		n = 1;
	p = realloc(p, n);
	if(!p){
		fprint(2, "%s: out of memory realloc %lud\n", argv0, n);
		threadexits("out of memory");
	}
	setrealloctag(p, getcallerpc(&p));
	return p;
}

void
mailplumb(Mailbox *mb, Message *m, int delete)
{
	Plumbmsg p;
	Plumbattr a[7];
	char buf[256];
	int ai;
	char lenstr[10], *from, *subject, *date;
	static int fd = -1;

	if(m->subject822 == nil)
		subject = "";
	else
		subject = s_to_c(m->subject822);

	if(m->from822 != nil)
		from = s_to_c(m->from822);
	else if(m->unixfrom != nil)
		from = s_to_c(m->unixfrom);
	else
		from = "";

	if(m->unixdate != nil)
		date = s_to_c(m->unixdate);
	else
		date = "";

	sprint(lenstr, "%ld", m->end-m->start);

	if(biffing && !delete)
		print("[ %s / %s / %s ]\n", from, subject, lenstr);

	if(!plumbing)
		return;

	if(fd < 0)
		fd = plumbopen("send", OWRITE);
	if(fd < 0)
		return;

	p.src = "mailfs";
	p.dst = "seemail";
	p.wdir = "/mail/fs";
	p.type = "text";

	ai = 0;
	a[ai].name = "filetype";
	a[ai].value = "mail";

	a[++ai].name = "sender";
	a[ai].value = from;
	a[ai-1].next = &a[ai];

	a[++ai].name = "length";
	a[ai].value = lenstr;
	a[ai-1].next = &a[ai];

	a[++ai].name = "mailtype";
	a[ai].value = delete?"delete":"new";
	a[ai-1].next = &a[ai];

	a[++ai].name = "date";
	a[ai].value = date;
	a[ai-1].next = &a[ai];

	if(m->sdigest){
		a[++ai].name = "digest";
		a[ai].value = s_to_c(m->sdigest);
		a[ai-1].next = &a[ai];
	}

	a[ai].next = nil;

	p.attr = a;
	snprint(buf, sizeof(buf), "%s/%s/%s",
		mntpt, mb->name, m->name);
	p.ndata = strlen(buf);
	p.data = buf;

	plumbsend(fd, &p);
}

//
// count the number of lines in the body (for imap4)
//
void
countlines(Message *m)
{
	int i;
	char *p;

	i = 0;
	for(p = strchr(m->rbody, '\n'); p != nil && p < m->rbend; p = strchr(p+1, '\n'))
		i++;
	sprint(m->lines, "%d", i);
}

char *LOG = "fs";

void
logmsg(char *s, Message *m)
{
	int pid;

	if(!logging)
		return;
	pid = getpid();
	if(m == nil)
		syslog(0, LOG, "%s.%d: %s", user, pid, s);
	else
		syslog(0, LOG, "%s.%d: %s msg from %s digest %s",
			user, pid, s,
			m->from822 ? s_to_c(m->from822) : "?",
			s_to_c(m->sdigest));
}

/*
 *  squeeze nulls out of the body
 */
static void
nullsqueeze(Message *m)
{
	char *p, *q;

	q = memchr(m->body, 0, m->end-m->body);
	if(q == nil)
		return;

	for(p = m->body; q < m->end; q++){
		if(*q == 0)
			continue;
		*p++ = *q;
	}
	m->bend = m->rbend = m->end = p;
}


//
// convert an RFC822 date into a Unix style date
// for when the Unix From line isn't there (e.g. POP3).
// enough client programs depend on having a Unix date
// that it's easiest to write this conversion code once, right here.
//
// people don't follow RFC822 particularly closely,
// so we use strtotm, which is a bunch of heuristics.
//

extern int strtotm(char*, Tm*);
String*
date822tounix(char *s)
{
	char *p, *q;
	Tm tm;

	if(strtotm(s, &tm) < 0)
		return nil;

	p = asctime(&tm);
	if(q = strchr(p, '\n'))
		*q = '\0';
	return s_copy(p);
}

