#include "common.h"
#include "send.h"

#include "../smtp/smtp.h"
#include "../smtp/rfc822.tab.h"

/* global to this file */
static Reprog *rfprog;
static Reprog *fprog;

#define VMLIMIT (64*1024)
#define MSGLIMIT (128*1024*1024)

int received;	/* from rfc822.y */

static String*	getstring(Node *p);
static String*	getaddr(Node *p);

extern int
default_from(message *mp)
{
	char *cp, *lp;

	cp = getenv("upasname");
	lp = getlog();
	if(lp == nil)
		return -1;

	if(cp && *cp)
		s_append(mp->sender, cp);
	else
		s_append(mp->sender, lp);
	s_append(mp->date, thedate());
	return 0;
}

extern message *
m_new(void)
{
	message *mp;

	mp = (message *)mallocz(sizeof(message), 1);
	if (mp == 0) {
		perror("message:");
		exit(1);
	}
	mp->sender = s_new();
	mp->replyaddr = s_new();
	mp->date = s_new();
	mp->body = s_new();
	mp->size = 0;
	mp->fd = -1;
	return mp;
}

extern void
m_free(message *mp)
{
	if(mp->fd >= 0){
		close(mp->fd);
		sysremove(s_to_c(mp->tmp));
		s_free(mp->tmp);
	}
	s_free(mp->sender);
	s_free(mp->date);
	s_free(mp->body);
	s_free(mp->havefrom);
	s_free(mp->havesender);
	s_free(mp->havereplyto);
	s_free(mp->havesubject);
	free((char *)mp);
}

/* read a message into a temp file , return an open fd to it */
static int
m_read_to_file(Biobuf *fp, message *mp)
{
	int fd;
	int n;
	String *file;
	char buf[4*1024];

	file = s_new();
	/*
	 *  create temp file to be remove on close
	 */
	abspath("mtXXXXXX", UPASTMP, file);
	mktemp(s_to_c(file));
	if((fd = syscreate(s_to_c(file), ORDWR|ORCLOSE, 0600))<0){
		s_free(file);
		return -1;
	}
	mp->tmp = file;

	/*
	 *  read the rest into the temp file
	 */
	while((n = Bread(fp, buf, sizeof(buf))) > 0){
		if(write(fd, buf, n) != n){
			close(fd);
			return -1;
		}
		mp->size += n;
		if(mp->size > MSGLIMIT){
			mp->size = -1;
			break;
		}
	}

	mp->fd = fd;
	return 0;
}

/* get the first address from a node */
static String*
getaddr(Node *p)
{
	for(; p; p = p->next)
		if(p->s && p->addr)
			return s_copy(s_to_c(p->s));
	return nil;
}

/* get the text of a header line minus the field name */
static String*
getstring(Node *p)
{
	String *s;

	s = s_new();
	if(p == nil)
		return s;

	for(p = p->next; p; p = p->next){
		if(p->s){
			s_append(s, s_to_c(p->s));
		}else{
			s_putc(s, p->c);
			s_terminate(s);
		}
		if(p->white)
			s_append(s, s_to_c(p->white));
	}
	return s;
}

#if 0
static char *fieldname[] =
{
[WORD-WORD]	"WORD",
[DATE-WORD]	"DATE",
[RESENT_DATE-WORD]	"RESENT_DATE",
[RETURN_PATH-WORD]	"RETURN_PATH",
[FROM-WORD]	"FROM",
[SENDER-WORD]	"SENDER",
[REPLY_TO-WORD]	"REPLY_TO",
[RESENT_FROM-WORD]	"RESENT_FROM",
[RESENT_SENDER-WORD]	"RESENT_SENDER",
[RESENT_REPLY_TO-WORD]	"RESENT_REPLY_TO",
[SUBJECT-WORD]	"SUBJECT",
[TO-WORD]	"TO",
[CC-WORD]	"CC",
[BCC-WORD]	"BCC",
[RESENT_TO-WORD]	"RESENT_TO",
[RESENT_CC-WORD]	"RESENT_CC",
[RESENT_BCC-WORD]	"RESENT_BCC",
[REMOTE-WORD]	"REMOTE",
[PRECEDENCE-WORD]	"PRECEDENCE",
[MIMEVERSION-WORD]	"MIMEVERSION",
[CONTENTTYPE-WORD]	"CONTENTTYPE",
[MESSAGEID-WORD]	"MESSAGEID",
[RECEIVED-WORD]	"RECEIVED",
[MAILER-WORD]	"MAILER",
[BADTOKEN-WORD]	"BADTOKEN",
};
#endif

/* fix 822 addresses */
static void
rfc822cruft(message *mp)
{
	Field *f;
	Node *p;
	String *body, *s;
	char *cp;

	/*
	 *  parse headers in in-core part
	 */
	yyinit(s_to_c(mp->body), s_len(mp->body));
	mp->rfc822headers = 0;
	yyparse();
	mp->rfc822headers = 1;
	mp->received = received;

	/*
	 *  remove equivalent systems in all addresses
	 */
	body = s_new();
	cp = s_to_c(mp->body);
	for(f = firstfield; f; f = f->next){
		if(f->node->c == MIMEVERSION)
			mp->havemime = 1;
		if(f->node->c == FROM)
			mp->havefrom = getaddr(f->node);
		if(f->node->c == SENDER)
			mp->havesender = getaddr(f->node);
		if(f->node->c == REPLY_TO)
			mp->havereplyto = getaddr(f->node);
		if(f->node->c == TO)
			mp->haveto = 1;
		if(f->node->c == DATE)
			mp->havedate = 1;
		if(f->node->c == SUBJECT)
			mp->havesubject = getstring(f->node);
		if(f->node->c == PRECEDENCE && f->node->next && f->node->next->next){
			s = f->node->next->next->s;
			if(s && (strcmp(s_to_c(s), "bulk") == 0
				|| strcmp(s_to_c(s), "Bulk") == 0))
					mp->bulk = 1;
		}
		for(p = f->node; p; p = p->next){
			if(p->s){
				if(p->addr){
					cp = skipequiv(s_to_c(p->s));
					s_append(body, cp);
				} else 
					s_append(body, s_to_c(p->s));
			}else{
				s_putc(body, p->c);
				s_terminate(body);
			}
			if(p->white)
				s_append(body, s_to_c(p->white));
			cp = p->end+1;
		}
		s_append(body, "\n");
	}

	if(*s_to_c(body) == 0){
		s_free(body);
		return;
	}

	if(*cp != '\n')
		s_append(body, "\n");
	s_memappend(body, cp, s_len(mp->body) - (cp - s_to_c(mp->body)));
	s_terminate(body);

	firstfield = 0;
	mp->size += s_len(body) - s_len(mp->body);
	s_free(mp->body);
	mp->body = body;
}

/* read in a message, interpret the 'From' header */
extern message *
m_read(Biobuf *fp, int rmail, int interactive)
{
	message *mp;
	Resub subexp[10];
	char *line;
	int first;
	int n;

	mp = m_new();

	/* parse From lines if remote */
	if (rmail) {
		/* get remote address */
		String *sender=s_new();

		if (rfprog == 0)
			rfprog = regcomp(REMFROMRE);
		first = 1;
		while(s_read_line(fp, s_restart(mp->body)) != 0) {
			memset(subexp, 0, sizeof(subexp));
			if (regexec(rfprog, s_to_c(mp->body), subexp, 10) == 0){
				if(first == 0)
					break;
				if (fprog == 0)
					fprog = regcomp(FROMRE);
				memset(subexp, 0, sizeof(subexp));
				if(regexec(fprog, s_to_c(mp->body), subexp,10) == 0)
					break;
				s_restart(mp->body);
				append_match(subexp, s_restart(sender), SENDERMATCH);
				append_match(subexp, s_restart(mp->date), DATEMATCH);
				break;
			}
			append_match(subexp, s_restart(sender), REMSENDERMATCH);
			append_match(subexp, s_restart(mp->date), REMDATEMATCH);
			if(subexp[REMSYSMATCH].s.sp!=subexp[REMSYSMATCH].e.ep){
				append_match(subexp, mp->sender, REMSYSMATCH);
				s_append(mp->sender, "!");
			}
			first = 0;
		}
		s_append(mp->sender, s_to_c(sender));

		s_free(sender);
	}
	if(*s_to_c(mp->sender)=='\0')
		default_from(mp);

	/* if sender address is unreturnable, treat message as bulk mail */
	if(!returnable(s_to_c(mp->sender)))
		mp->bulk = 1;

	/* get body */
	if(interactive && !rmail){
		/* user typing on terminal: terminator == '.' or EOF */
		for(;;) {
			line = s_read_line(fp, mp->body);
			if (line == 0)
				break;
			if (strcmp(".\n", line)==0) {
				mp->body->ptr -= 2;
				*mp->body->ptr = '\0';
				break;
			}
		}
		mp->size = mp->body->ptr - mp->body->base;
	} else {
		/*
		 *  read up to VMLIMIT bytes (more or less) into main memory.
		 *  if message is longer put the rest in a tmp file.
		 */
		mp->size = mp->body->ptr - mp->body->base;
		n = s_read(fp, mp->body, VMLIMIT);
		if(n < 0){
			perror("m_read");
			exit(1);
		}
		mp->size += n;
		if(n == VMLIMIT){
			if(m_read_to_file(fp, mp) < 0){
				perror("m_read_to_file");
				exit(1);
			}
		}
	}

	/*
	 *  ignore 0 length messages from a terminal
	 */
	if (!rmail && mp->size == 0)
		return 0;

	rfc822cruft(mp);

	return mp;
}

/* return a piece of message starting at `offset' */
extern int
m_get(message *mp, long offset, char **pp)
{
	static char buf[4*1024];

	/*
	 *  are we past eof?
	 */
	if(offset >= mp->size)
		return 0;

	/*
	 *  are we in the virtual memory portion?
	 */
	if(offset < s_len(mp->body)){
		*pp = mp->body->base + offset;
		return mp->body->ptr - mp->body->base - offset;
	}

	/*
	 *  read it from the temp file
	 */
	offset -= s_len(mp->body);
	if(mp->fd < 0)
		return -1;
	if(seek(mp->fd, offset, 0)<0)
		return -1;
	*pp = buf;
	return read(mp->fd, buf, sizeof buf);
}

/* output the message body without ^From escapes */
static int
m_noescape(message *mp, Biobuf *fp)
{
	long offset;
	int n;
	char *p;

	for(offset = 0; offset < mp->size; offset += n){
		n = m_get(mp, offset, &p);
		if(n <= 0){
			Bflush(fp);
			return -1;
		}
		if(Bwrite(fp, p, n) < 0)
			return -1;
	}
	return Bflush(fp);
}

/*
 *  Output the message body with '^From ' escapes.
 *  Ensures that any line starting with a 'From ' gets a ' ' stuck
 *  in front of it.
 */
static int
m_escape(message *mp, Biobuf *fp)
{
	char *p, *np;
	char *end;
	long offset;
	int m, n;
	char *start;

	for(offset = 0; offset < mp->size; offset += n){
		n = m_get(mp, offset, &start);
		if(n < 0){
			Bflush(fp);
			return -1;
		}

		p = start;
		for(end = p+n; p < end; p += m){
			np = memchr(p, '\n', end-p);
			if(np == 0){
				Bwrite(fp, p, end-p);
				break;
			}
			m = np - p + 1;
			if(m > 5 && strncmp(p, "From ", 5) == 0)
				Bputc(fp, ' ');
			Bwrite(fp, p, m);
		}
	}
	Bflush(fp);
	return 0;
}

static int
printfrom(message *mp, Biobuf *fp)
{
	String *s;
	int rv;

	if(!returnable(s_to_c(mp->sender)))
		return Bprint(fp, "From: Postmaster\n");

	s = username(mp->sender);
	if(s) {
		s_append(s, " <");
		s_append(s, s_to_c(mp->sender));
		s_append(s, ">");
	} else {
		s = s_copy(s_to_c(mp->sender));
	}
	s = unescapespecial(s);
	rv = Bprint(fp, "From: %s\n", s_to_c(s));
	s_free(s);
	return rv;
}

static char *
rewritezone(char *z)
{
	int mindiff;
	char s;
	Tm *tm;
	static char x[7];

	tm = localtime(time(0));
	mindiff = tm->tzoff/60;

	/* if not in my timezone, don't change anything */
	if(strcmp(tm->zone, z) != 0)
		return z;

	if(mindiff < 0){
		s = '-';
		mindiff = -mindiff;
	} else
		s = '+';

	sprint(x, "%c%.2d%.2d", s, mindiff/60, mindiff%60);
	return x;
}

int
isutf8(String *s)
{
	char *p;
	
	for(p = s_to_c(s);  *p; p++)
		if(*p&0x80)
			return 1;
	return 0;
}

void
printutf8mime(Biobuf *b)
{
	Bprint(b, "MIME-Version: 1.0\n");
	Bprint(b, "Content-Type: text/plain; charset=\"UTF-8\"\n");
	Bprint(b, "Content-Transfer-Encoding: 8bit\n");
}

/* output a message */
extern int
m_print(message *mp, Biobuf *fp, char *remote, int mbox)
{
	String *date, *sender;
	char *f[6];
	int n;

	sender = unescapespecial(s_clone(mp->sender));

	if (remote != 0){
		if(print_remote_header(fp,s_to_c(sender),s_to_c(mp->date),remote) < 0){
			s_free(sender);
			return -1;
		}
	} else {
		if(print_header(fp, s_to_c(sender), s_to_c(mp->date)) < 0){
			s_free(sender);
			return -1;
		}
	}
	s_free(sender);
	if(!rmail && !mp->havedate){
		/* add a date: line Date: Sun, 19 Apr 1998 12:27:52 -0400 */
		date = s_copy(s_to_c(mp->date));
		n = getfields(s_to_c(date), f, 6, 1, " \t");
		if(n == 6)
			Bprint(fp, "Date: %s, %s %s %s %s %s\n", f[0], f[2], f[1],
			 f[5], f[3], rewritezone(f[4]));
	}
	if(!rmail && !mp->havemime && isutf8(mp->body))
		printutf8mime(fp);
	if(mp->to){
		/* add the to: line */
		if (Bprint(fp, "%s\n", s_to_c(mp->to)) < 0)
			return -1;
		/* add the from: line */
		if (!mp->havefrom && printfrom(mp, fp) < 0)
			return -1;
		if(!mp->rfc822headers && *s_to_c(mp->body) != '\n')
			if (Bprint(fp, "\n") < 0)
				return -1;
	} else if(!rmail){
		/* add the from: line */
		if (!mp->havefrom && printfrom(mp, fp) < 0)
			return -1;
		if(!mp->rfc822headers && *s_to_c(mp->body) != '\n')
			if (Bprint(fp, "\n") < 0)
				return -1;
	}

	if (!mbox)
		return m_noescape(mp, fp);
	return m_escape(mp, fp);
}

/* print just the message body */
extern int
m_bprint(message *mp, Biobuf *fp)
{
	return m_noescape(mp, fp);
}
