/*
 * git-imap-send - drops patches into an imap Drafts folder
 *                 derived from isync/mbsync - mailbox synchronizer
 *
 * Copyright (C) 2000-2002 Michael R. Elkins <me@mutt.org>
 * Copyright (C) 2002-2004 Oswald Buddenhagen <ossi@users.sf.net>
 * Copyright (C) 2004 Theodore Y. Ts'o <tytso@mit.edu>
 * Copyright (C) 2006 Mike McCormack
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "cache.h"

typedef struct store_conf {
	char *name;
	const char *path; /* should this be here? its interpretation is driver-specific */
	char *map_inbox;
	char *trash;
	unsigned max_size; /* off_t is overkill */
	unsigned trash_remote_new:1, trash_only_new:1;
} store_conf_t;

typedef struct string_list {
	struct string_list *next;
	char string[1];
} string_list_t;

typedef struct channel_conf {
	struct channel_conf *next;
	char *name;
	store_conf_t *master, *slave;
	char *master_name, *slave_name;
	char *sync_state;
	string_list_t *patterns;
	int mops, sops;
	unsigned max_messages; /* for slave only */
} channel_conf_t;

typedef struct group_conf {
	struct group_conf *next;
	char *name;
	string_list_t *channels;
} group_conf_t;

/* For message->status */
#define M_RECENT       (1<<0) /* unsyncable flag; maildir_* depend on this being 1<<0 */
#define M_DEAD         (1<<1) /* expunged */
#define M_FLAGS        (1<<2) /* flags fetched */

typedef struct message {
	struct message *next;
	/* string_list_t *keywords; */
	size_t size; /* zero implies "not fetched" */
	int uid;
	unsigned char flags, status;
} message_t;

typedef struct store {
	store_conf_t *conf; /* foreign */

	/* currently open mailbox */
	const char *name; /* foreign! maybe preset? */
	char *path; /* own */
	message_t *msgs; /* own */
	int uidvalidity;
	unsigned char opts; /* maybe preset? */
	/* note that the following do _not_ reflect stats from msgs, but mailbox totals */
	int count; /* # of messages */
	int recent; /* # of recent messages - don't trust this beyond the initial read */
} store_t;

typedef struct {
	char *data;
	int len;
	unsigned char flags;
	unsigned int crlf:1;
} msg_data_t;

#define DRV_OK          0
#define DRV_MSG_BAD     -1
#define DRV_BOX_BAD     -2
#define DRV_STORE_BAD   -3

static int Verbose, Quiet;

static void imap_info( const char *, ... );
static void imap_warn( const char *, ... );

static char *next_arg( char ** );

static void free_generic_messages( message_t * );

static int nfsnprintf( char *buf, int blen, const char *fmt, ... );

static int nfvasprintf(char **strp, const char *fmt, va_list ap)
{
	int len;
	char tmp[8192];

	len = vsnprintf(tmp, sizeof(tmp), fmt, ap);
	if (len < 0)
		die("Fatal: Out of memory\n");
	if (len >= sizeof(tmp))
		die("imap command overflow !\n");
	*strp = xmemdupz(tmp, len);
	return len;
}

static void arc4_init( void );
static unsigned char arc4_getbyte( void );

typedef struct imap_server_conf {
	char *name;
	char *tunnel;
	char *host;
	int port;
	char *user;
	char *pass;
} imap_server_conf_t;

typedef struct imap_store_conf {
	store_conf_t gen;
	imap_server_conf_t *server;
	unsigned use_namespace:1;
} imap_store_conf_t;

#define NIL	(void*)0x1
#define LIST	(void*)0x2

typedef struct _list {
	struct _list *next, *child;
	char *val;
	int len;
} list_t;

typedef struct {
	int fd;
} Socket_t;

typedef struct {
	Socket_t sock;
	int bytes;
	int offset;
	char buf[1024];
} buffer_t;

struct imap_cmd;

typedef struct imap {
	int uidnext; /* from SELECT responses */
	list_t *ns_personal, *ns_other, *ns_shared; /* NAMESPACE info */
	unsigned caps, rcaps; /* CAPABILITY results */
	/* command queue */
	int nexttag, num_in_progress, literal_pending;
	struct imap_cmd *in_progress, **in_progress_append;
	buffer_t buf; /* this is BIG, so put it last */
} imap_t;

typedef struct imap_store {
	store_t gen;
	int uidvalidity;
	imap_t *imap;
	const char *prefix;
	unsigned /*currentnc:1,*/ trashnc:1;
} imap_store_t;

struct imap_cmd_cb {
	int (*cont)( imap_store_t *ctx, struct imap_cmd *cmd, const char *prompt );
	void (*done)( imap_store_t *ctx, struct imap_cmd *cmd, int response);
	void *ctx;
	char *data;
	int dlen;
	int uid;
	unsigned create:1, trycreate:1;
};

struct imap_cmd {
	struct imap_cmd *next;
	struct imap_cmd_cb cb;
	char *cmd;
	int tag;
};

#define CAP(cap) (imap->caps & (1 << (cap)))

enum CAPABILITY {
	NOLOGIN = 0,
	UIDPLUS,
	LITERALPLUS,
	NAMESPACE,
};

static const char *cap_list[] = {
	"LOGINDISABLED",
	"UIDPLUS",
	"LITERAL+",
	"NAMESPACE",
};

#define RESP_OK    0
#define RESP_NO    1
#define RESP_BAD   2

static int get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd );


static const char *Flags[] = {
	"Draft",
	"Flagged",
	"Answered",
	"Seen",
	"Deleted",
};

static void
socket_perror( const char *func, Socket_t *sock, int ret )
{
	if (ret < 0)
		perror( func );
	else
		fprintf( stderr, "%s: unexpected EOF\n", func );
}

static int
socket_read( Socket_t *sock, char *buf, int len )
{
	ssize_t n = xread( sock->fd, buf, len );
	if (n <= 0) {
		socket_perror( "read", sock, n );
		close( sock->fd );
		sock->fd = -1;
	}
	return n;
}

static int
socket_write( Socket_t *sock, const char *buf, int len )
{
	int n = write_in_full( sock->fd, buf, len );
	if (n != len) {
		socket_perror( "write", sock, n );
		close( sock->fd );
		sock->fd = -1;
	}
	return n;
}

/* simple line buffering */
static int
buffer_gets( buffer_t * b, char **s )
{
	int n;
	int start = b->offset;

	*s = b->buf + start;

	for (;;) {
		/* make sure we have enough data to read the \r\n sequence */
		if (b->offset + 1 >= b->bytes) {
			if (start) {
				/* shift down used bytes */
				*s = b->buf;

				assert( start <= b->bytes );
				n = b->bytes - start;

				if (n)
					memmove(b->buf, b->buf + start, n);
				b->offset -= start;
				b->bytes = n;
				start = 0;
			}

			n = socket_read( &b->sock, b->buf + b->bytes,
					 sizeof(b->buf) - b->bytes );

			if (n <= 0)
				return -1;

			b->bytes += n;
		}

		if (b->buf[b->offset] == '\r') {
			assert( b->offset + 1 < b->bytes );
			if (b->buf[b->offset + 1] == '\n') {
				b->buf[b->offset] = 0;  /* terminate the string */
				b->offset += 2; /* next line */
				if (Verbose)
					puts( *s );
				return 0;
			}
		}

		b->offset++;
	}
	/* not reached */
}

static void
imap_info( const char *msg, ... )
{
	va_list va;

	if (!Quiet) {
		va_start( va, msg );
		vprintf( msg, va );
		va_end( va );
		fflush( stdout );
	}
}

static void
imap_warn( const char *msg, ... )
{
	va_list va;

	if (Quiet < 2) {
		va_start( va, msg );
		vfprintf( stderr, msg, va );
		va_end( va );
	}
}

static char *
next_arg( char **s )
{
	char *ret;

	if (!s || !*s)
		return NULL;
	while (isspace( (unsigned char) **s ))
		(*s)++;
	if (!**s) {
		*s = NULL;
		return NULL;
	}
	if (**s == '"') {
		++*s;
		ret = *s;
		*s = strchr( *s, '"' );
	} else {
		ret = *s;
		while (**s && !isspace( (unsigned char) **s ))
			(*s)++;
	}
	if (*s) {
		if (**s)
			*(*s)++ = 0;
		if (!**s)
			*s = NULL;
	}
	return ret;
}

static void
free_generic_messages( message_t *msgs )
{
	message_t *tmsg;

	for (; msgs; msgs = tmsg) {
		tmsg = msgs->next;
		free( msgs );
	}
}

static int
nfsnprintf( char *buf, int blen, const char *fmt, ... )
{
	int ret;
	va_list va;

	va_start( va, fmt );
	if (blen <= 0 || (unsigned)(ret = vsnprintf( buf, blen, fmt, va )) >= (unsigned)blen)
		die( "Fatal: buffer too small. Please report a bug.\n");
	va_end( va );
	return ret;
}

static struct {
	unsigned char i, j, s[256];
} rs;

static void
arc4_init( void )
{
	int i, fd;
	unsigned char j, si, dat[128];

	if ((fd = open( "/dev/urandom", O_RDONLY )) < 0 && (fd = open( "/dev/random", O_RDONLY )) < 0) {
		fprintf( stderr, "Fatal: no random number source available.\n" );
		exit( 3 );
	}
	if (read_in_full( fd, dat, 128 ) != 128) {
		fprintf( stderr, "Fatal: cannot read random number source.\n" );
		exit( 3 );
	}
	close( fd );

	for (i = 0; i < 256; i++)
		rs.s[i] = i;
	for (i = j = 0; i < 256; i++) {
		si = rs.s[i];
		j += si + dat[i & 127];
		rs.s[i] = rs.s[j];
		rs.s[j] = si;
	}
	rs.i = rs.j = 0;

	for (i = 0; i < 256; i++)
		arc4_getbyte();
}

static unsigned char
arc4_getbyte( void )
{
	unsigned char si, sj;

	rs.i++;
	si = rs.s[rs.i];
	rs.j += si;
	sj = rs.s[rs.j];
	rs.s[rs.i] = sj;
	rs.s[rs.j] = si;
	return rs.s[(si + sj) & 0xff];
}

static struct imap_cmd *
v_issue_imap_cmd( imap_store_t *ctx, struct imap_cmd_cb *cb,
		  const char *fmt, va_list ap )
{
	imap_t *imap = ctx->imap;
	struct imap_cmd *cmd;
	int n, bufl;
	char buf[1024];

	cmd = xmalloc( sizeof(struct imap_cmd) );
	nfvasprintf( &cmd->cmd, fmt, ap );
	cmd->tag = ++imap->nexttag;

	if (cb)
		cmd->cb = *cb;
	else
		memset( &cmd->cb, 0, sizeof(cmd->cb) );

	while (imap->literal_pending)
		get_cmd_result( ctx, NULL );

	bufl = nfsnprintf( buf, sizeof(buf), cmd->cb.data ? CAP(LITERALPLUS) ?
			   "%d %s{%d+}\r\n" : "%d %s{%d}\r\n" : "%d %s\r\n",
			   cmd->tag, cmd->cmd, cmd->cb.dlen );
	if (Verbose) {
		if (imap->num_in_progress)
			printf( "(%d in progress) ", imap->num_in_progress );
		if (memcmp( cmd->cmd, "LOGIN", 5 ))
			printf( ">>> %s", buf );
		else
			printf( ">>> %d LOGIN <user> <pass>\n", cmd->tag );
	}
	if (socket_write( &imap->buf.sock, buf, bufl ) != bufl) {
		free( cmd->cmd );
		free( cmd );
		if (cb)
			free( cb->data );
		return NULL;
	}
	if (cmd->cb.data) {
		if (CAP(LITERALPLUS)) {
			n = socket_write( &imap->buf.sock, cmd->cb.data, cmd->cb.dlen );
			free( cmd->cb.data );
			if (n != cmd->cb.dlen ||
			    (n = socket_write( &imap->buf.sock, "\r\n", 2 )) != 2)
			{
				free( cmd->cmd );
				free( cmd );
				return NULL;
			}
			cmd->cb.data = NULL;
		} else
			imap->literal_pending = 1;
	} else if (cmd->cb.cont)
		imap->literal_pending = 1;
	cmd->next = NULL;
	*imap->in_progress_append = cmd;
	imap->in_progress_append = &cmd->next;
	imap->num_in_progress++;
	return cmd;
}

static struct imap_cmd *
issue_imap_cmd( imap_store_t *ctx, struct imap_cmd_cb *cb, const char *fmt, ... )
{
	struct imap_cmd *ret;
	va_list ap;

	va_start( ap, fmt );
	ret = v_issue_imap_cmd( ctx, cb, fmt, ap );
	va_end( ap );
	return ret;
}

static int
imap_exec( imap_store_t *ctx, struct imap_cmd_cb *cb, const char *fmt, ... )
{
	va_list ap;
	struct imap_cmd *cmdp;

	va_start( ap, fmt );
	cmdp = v_issue_imap_cmd( ctx, cb, fmt, ap );
	va_end( ap );
	if (!cmdp)
		return RESP_BAD;

	return get_cmd_result( ctx, cmdp );
}

static int
imap_exec_m( imap_store_t *ctx, struct imap_cmd_cb *cb, const char *fmt, ... )
{
	va_list ap;
	struct imap_cmd *cmdp;

	va_start( ap, fmt );
	cmdp = v_issue_imap_cmd( ctx, cb, fmt, ap );
	va_end( ap );
	if (!cmdp)
		return DRV_STORE_BAD;

	switch (get_cmd_result( ctx, cmdp )) {
	case RESP_BAD: return DRV_STORE_BAD;
	case RESP_NO: return DRV_MSG_BAD;
	default: return DRV_OK;
	}
}

static int
is_atom( list_t *list )
{
	return list && list->val && list->val != NIL && list->val != LIST;
}

static int
is_list( list_t *list )
{
	return list && list->val == LIST;
}

static void
free_list( list_t *list )
{
	list_t *tmp;

	for (; list; list = tmp) {
		tmp = list->next;
		if (is_list( list ))
			free_list( list->child );
		else if (is_atom( list ))
			free( list->val );
		free( list );
	}
}

static int
parse_imap_list_l( imap_t *imap, char **sp, list_t **curp, int level )
{
	list_t *cur;
	char *s = *sp, *p;
	int n, bytes;

	for (;;) {
		while (isspace( (unsigned char)*s ))
			s++;
		if (level && *s == ')') {
			s++;
			break;
		}
		*curp = cur = xmalloc( sizeof(*cur) );
		curp = &cur->next;
		cur->val = NULL; /* for clean bail */
		if (*s == '(') {
			/* sublist */
			s++;
			cur->val = LIST;
			if (parse_imap_list_l( imap, &s, &cur->child, level + 1 ))
				goto bail;
		} else if (imap && *s == '{') {
			/* literal */
			bytes = cur->len = strtol( s + 1, &s, 10 );
			if (*s != '}')
				goto bail;

			s = cur->val = xmalloc( cur->len );

			/* dump whats left over in the input buffer */
			n = imap->buf.bytes - imap->buf.offset;

			if (n > bytes)
				/* the entire message fit in the buffer */
				n = bytes;

			memcpy( s, imap->buf.buf + imap->buf.offset, n );
			s += n;
			bytes -= n;

			/* mark that we used part of the buffer */
			imap->buf.offset += n;

			/* now read the rest of the message */
			while (bytes > 0) {
				if ((n = socket_read (&imap->buf.sock, s, bytes)) <= 0)
					goto bail;
				s += n;
				bytes -= n;
			}

			if (buffer_gets( &imap->buf, &s ))
				goto bail;
		} else if (*s == '"') {
			/* quoted string */
			s++;
			p = s;
			for (; *s != '"'; s++)
				if (!*s)
					goto bail;
			cur->len = s - p;
			s++;
			cur->val = xmemdupz(p, cur->len);
		} else {
			/* atom */
			p = s;
			for (; *s && !isspace( (unsigned char)*s ); s++)
				if (level && *s == ')')
					break;
			cur->len = s - p;
			if (cur->len == 3 && !memcmp ("NIL", p, 3)) {
				cur->val = NIL;
			} else {
				cur->val = xmemdupz(p, cur->len);
			}
		}

		if (!level)
			break;
		if (!*s)
			goto bail;
	}
	*sp = s;
	*curp = NULL;
	return 0;

  bail:
	*curp = NULL;
	return -1;
}

static list_t *
parse_imap_list( imap_t *imap, char **sp )
{
	list_t *head;

	if (!parse_imap_list_l( imap, sp, &head, 0 ))
		return head;
	free_list( head );
	return NULL;
}

static list_t *
parse_list( char **sp )
{
	return parse_imap_list( NULL, sp );
}

static void
parse_capability( imap_t *imap, char *cmd )
{
	char *arg;
	unsigned i;

	imap->caps = 0x80000000;
	while ((arg = next_arg( &cmd )))
		for (i = 0; i < ARRAY_SIZE(cap_list); i++)
			if (!strcmp( cap_list[i], arg ))
				imap->caps |= 1 << i;
	imap->rcaps = imap->caps;
}

static int
parse_response_code( imap_store_t *ctx, struct imap_cmd_cb *cb, char *s )
{
	imap_t *imap = ctx->imap;
	char *arg, *p;

	if (*s != '[')
		return RESP_OK;		/* no response code */
	s++;
	if (!(p = strchr( s, ']' ))) {
		fprintf( stderr, "IMAP error: malformed response code\n" );
		return RESP_BAD;
	}
	*p++ = 0;
	arg = next_arg( &s );
	if (!strcmp( "UIDVALIDITY", arg )) {
		if (!(arg = next_arg( &s )) || !(ctx->gen.uidvalidity = atoi( arg ))) {
			fprintf( stderr, "IMAP error: malformed UIDVALIDITY status\n" );
			return RESP_BAD;
		}
	} else if (!strcmp( "UIDNEXT", arg )) {
		if (!(arg = next_arg( &s )) || !(imap->uidnext = atoi( arg ))) {
			fprintf( stderr, "IMAP error: malformed NEXTUID status\n" );
			return RESP_BAD;
		}
	} else if (!strcmp( "CAPABILITY", arg )) {
		parse_capability( imap, s );
	} else if (!strcmp( "ALERT", arg )) {
		/* RFC2060 says that these messages MUST be displayed
		 * to the user
		 */
		for (; isspace( (unsigned char)*p ); p++);
		fprintf( stderr, "*** IMAP ALERT *** %s\n", p );
	} else if (cb && cb->ctx && !strcmp( "APPENDUID", arg )) {
		if (!(arg = next_arg( &s )) || !(ctx->gen.uidvalidity = atoi( arg )) ||
		    !(arg = next_arg( &s )) || !(*(int *)cb->ctx = atoi( arg )))
		{
			fprintf( stderr, "IMAP error: malformed APPENDUID status\n" );
			return RESP_BAD;
		}
	}
	return RESP_OK;
}

static int
get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd )
{
	imap_t *imap = ctx->imap;
	struct imap_cmd *cmdp, **pcmdp, *ncmdp;
	char *cmd, *arg, *arg1, *p;
	int n, resp, resp2, tag;

	for (;;) {
		if (buffer_gets( &imap->buf, &cmd ))
			return RESP_BAD;

		arg = next_arg( &cmd );
		if (*arg == '*') {
			arg = next_arg( &cmd );
			if (!arg) {
				fprintf( stderr, "IMAP error: unable to parse untagged response\n" );
				return RESP_BAD;
			}

			if (!strcmp( "NAMESPACE", arg )) {
				imap->ns_personal = parse_list( &cmd );
				imap->ns_other = parse_list( &cmd );
				imap->ns_shared = parse_list( &cmd );
			} else if (!strcmp( "OK", arg ) || !strcmp( "BAD", arg ) ||
				   !strcmp( "NO", arg ) || !strcmp( "BYE", arg )) {
				if ((resp = parse_response_code( ctx, NULL, cmd )) != RESP_OK)
					return resp;
			} else if (!strcmp( "CAPABILITY", arg ))
				parse_capability( imap, cmd );
			else if ((arg1 = next_arg( &cmd ))) {
				if (!strcmp( "EXISTS", arg1 ))
					ctx->gen.count = atoi( arg );
				else if (!strcmp( "RECENT", arg1 ))
					ctx->gen.recent = atoi( arg );
			} else {
				fprintf( stderr, "IMAP error: unable to parse untagged response\n" );
				return RESP_BAD;
			}
		} else if (!imap->in_progress) {
			fprintf( stderr, "IMAP error: unexpected reply: %s %s\n", arg, cmd ? cmd : "" );
			return RESP_BAD;
		} else if (*arg == '+') {
			/* This can happen only with the last command underway, as
			   it enforces a round-trip. */
			cmdp = (struct imap_cmd *)((char *)imap->in_progress_append -
			       offsetof(struct imap_cmd, next));
			if (cmdp->cb.data) {
				n = socket_write( &imap->buf.sock, cmdp->cb.data, cmdp->cb.dlen );
				free( cmdp->cb.data );
				cmdp->cb.data = NULL;
				if (n != (int)cmdp->cb.dlen)
					return RESP_BAD;
			} else if (cmdp->cb.cont) {
				if (cmdp->cb.cont( ctx, cmdp, cmd ))
					return RESP_BAD;
			} else {
				fprintf( stderr, "IMAP error: unexpected command continuation request\n" );
				return RESP_BAD;
			}
			if (socket_write( &imap->buf.sock, "\r\n", 2 ) != 2)
				return RESP_BAD;
			if (!cmdp->cb.cont)
				imap->literal_pending = 0;
			if (!tcmd)
				return DRV_OK;
		} else {
			tag = atoi( arg );
			for (pcmdp = &imap->in_progress; (cmdp = *pcmdp); pcmdp = &cmdp->next)
				if (cmdp->tag == tag)
					goto gottag;
			fprintf( stderr, "IMAP error: unexpected tag %s\n", arg );
			return RESP_BAD;
		  gottag:
			if (!(*pcmdp = cmdp->next))
				imap->in_progress_append = pcmdp;
			imap->num_in_progress--;
			if (cmdp->cb.cont || cmdp->cb.data)
				imap->literal_pending = 0;
			arg = next_arg( &cmd );
			if (!strcmp( "OK", arg ))
				resp = DRV_OK;
			else {
				if (!strcmp( "NO", arg )) {
					if (cmdp->cb.create && cmd && (cmdp->cb.trycreate || !memcmp( cmd, "[TRYCREATE]", 11 ))) { /* SELECT, APPEND or UID COPY */
						p = strchr( cmdp->cmd, '"' );
						if (!issue_imap_cmd( ctx, NULL, "CREATE \"%.*s\"", strchr( p + 1, '"' ) - p + 1, p )) {
							resp = RESP_BAD;
							goto normal;
						}
						/* not waiting here violates the spec, but a server that does not
						   grok this nonetheless violates it too. */
						cmdp->cb.create = 0;
						if (!(ncmdp = issue_imap_cmd( ctx, &cmdp->cb, "%s", cmdp->cmd ))) {
							resp = RESP_BAD;
							goto normal;
						}
						free( cmdp->cmd );
						free( cmdp );
						if (!tcmd)
							return 0;	/* ignored */
						if (cmdp == tcmd)
							tcmd = ncmdp;
						continue;
					}
					resp = RESP_NO;
				} else /*if (!strcmp( "BAD", arg ))*/
					resp = RESP_BAD;
				fprintf( stderr, "IMAP command '%s' returned response (%s) - %s\n",
					 memcmp (cmdp->cmd, "LOGIN", 5) ?
							cmdp->cmd : "LOGIN <user> <pass>",
							arg, cmd ? cmd : "");
			}
			if ((resp2 = parse_response_code( ctx, &cmdp->cb, cmd )) > resp)
				resp = resp2;
		  normal:
			if (cmdp->cb.done)
				cmdp->cb.done( ctx, cmdp, resp );
			free( cmdp->cb.data );
			free( cmdp->cmd );
			free( cmdp );
			if (!tcmd || tcmd == cmdp)
				return resp;
		}
	}
	/* not reached */
}

static void
imap_close_server( imap_store_t *ictx )
{
	imap_t *imap = ictx->imap;

	if (imap->buf.sock.fd != -1) {
		imap_exec( ictx, NULL, "LOGOUT" );
		close( imap->buf.sock.fd );
	}
	free_list( imap->ns_personal );
	free_list( imap->ns_other );
	free_list( imap->ns_shared );
	free( imap );
}

static void
imap_close_store( store_t *ctx )
{
	imap_close_server( (imap_store_t *)ctx );
	free_generic_messages( ctx->msgs );
	free( ctx );
}

static store_t *
imap_open_store( imap_server_conf_t *srvc )
{
	imap_store_t *ctx;
	imap_t *imap;
	char *arg, *rsp;
	struct hostent *he;
	struct sockaddr_in addr;
	int s, a[2], preauth;
	pid_t pid;

	ctx = xcalloc( sizeof(*ctx), 1 );

	ctx->imap = imap = xcalloc( sizeof(*imap), 1 );
	imap->buf.sock.fd = -1;
	imap->in_progress_append = &imap->in_progress;

	/* open connection to IMAP server */

	if (srvc->tunnel) {
		imap_info( "Starting tunnel '%s'... ", srvc->tunnel );

		if (socketpair( PF_UNIX, SOCK_STREAM, 0, a )) {
			perror( "socketpair" );
			exit( 1 );
		}

		pid = fork();
		if (pid < 0)
			_exit( 127 );
		if (!pid) {
			if (dup2( a[0], 0 ) == -1 || dup2( a[0], 1 ) == -1)
				_exit( 127 );
			close( a[0] );
			close( a[1] );
			execl( "/bin/sh", "sh", "-c", srvc->tunnel, NULL );
			_exit( 127 );
		}

		close (a[0]);

		imap->buf.sock.fd = a[1];

		imap_info( "ok\n" );
	} else {
		memset( &addr, 0, sizeof(addr) );
		addr.sin_port = htons( srvc->port );
		addr.sin_family = AF_INET;

		imap_info( "Resolving %s... ", srvc->host );
		he = gethostbyname( srvc->host );
		if (!he) {
			perror( "gethostbyname" );
			goto bail;
		}
		imap_info( "ok\n" );

		addr.sin_addr.s_addr = *((int *) he->h_addr_list[0]);

		s = socket( PF_INET, SOCK_STREAM, 0 );

		imap_info( "Connecting to %s:%hu... ", inet_ntoa( addr.sin_addr ), ntohs( addr.sin_port ) );
		if (connect( s, (struct sockaddr *)&addr, sizeof(addr) )) {
			close( s );
			perror( "connect" );
			goto bail;
		}
		imap_info( "ok\n" );

		imap->buf.sock.fd = s;

	}

	/* read the greeting string */
	if (buffer_gets( &imap->buf, &rsp )) {
		fprintf( stderr, "IMAP error: no greeting response\n" );
		goto bail;
	}
	arg = next_arg( &rsp );
	if (!arg || *arg != '*' || (arg = next_arg( &rsp )) == NULL) {
		fprintf( stderr, "IMAP error: invalid greeting response\n" );
		goto bail;
	}
	preauth = 0;
	if (!strcmp( "PREAUTH", arg ))
		preauth = 1;
	else if (strcmp( "OK", arg ) != 0) {
		fprintf( stderr, "IMAP error: unknown greeting response\n" );
		goto bail;
	}
	parse_response_code( ctx, NULL, rsp );
	if (!imap->caps && imap_exec( ctx, NULL, "CAPABILITY" ) != RESP_OK)
		goto bail;

	if (!preauth) {

		imap_info ("Logging in...\n");
		if (!srvc->user) {
			fprintf( stderr, "Skipping server %s, no user\n", srvc->host );
			goto bail;
		}
		if (!srvc->pass) {
			char prompt[80];
			sprintf( prompt, "Password (%s@%s): ", srvc->user, srvc->host );
			arg = getpass( prompt );
			if (!arg) {
				perror( "getpass" );
				exit( 1 );
			}
			if (!*arg) {
				fprintf( stderr, "Skipping account %s@%s, no password\n", srvc->user, srvc->host );
				goto bail;
			}
			/*
			 * getpass() returns a pointer to a static buffer.  make a copy
			 * for long term storage.
			 */
			srvc->pass = xstrdup( arg );
		}
		if (CAP(NOLOGIN)) {
			fprintf( stderr, "Skipping account %s@%s, server forbids LOGIN\n", srvc->user, srvc->host );
			goto bail;
		}
		imap_warn( "*** IMAP Warning *** Password is being sent in the clear\n" );
		if (imap_exec( ctx, NULL, "LOGIN \"%s\" \"%s\"", srvc->user, srvc->pass ) != RESP_OK) {
			fprintf( stderr, "IMAP error: LOGIN failed\n" );
			goto bail;
		}
	} /* !preauth */

	ctx->prefix = "";
	ctx->trashnc = 1;
	return (store_t *)ctx;

  bail:
	imap_close_store( &ctx->gen );
	return NULL;
}

static int
imap_make_flags( int flags, char *buf )
{
	const char *s;
	unsigned i, d;

	for (i = d = 0; i < ARRAY_SIZE(Flags); i++)
		if (flags & (1 << i)) {
			buf[d++] = ' ';
			buf[d++] = '\\';
			for (s = Flags[i]; *s; s++)
				buf[d++] = *s;
		}
	buf[0] = '(';
	buf[d++] = ')';
	return d;
}

#define TUIDL 8

static int
imap_store_msg( store_t *gctx, msg_data_t *data, int *uid )
{
	imap_store_t *ctx = (imap_store_t *)gctx;
	imap_t *imap = ctx->imap;
	struct imap_cmd_cb cb;
	char *fmap, *buf;
	const char *prefix, *box;
	int ret, i, j, d, len, extra, nocr;
	int start, sbreak = 0, ebreak = 0;
	char flagstr[128], tuid[TUIDL * 2 + 1];

	memset( &cb, 0, sizeof(cb) );

	fmap = data->data;
	len = data->len;
	nocr = !data->crlf;
	extra = 0, i = 0;
	if (!CAP(UIDPLUS) && uid) {
	  nloop:
		start = i;
		while (i < len)
			if (fmap[i++] == '\n') {
				extra += nocr;
				if (i - 2 + nocr == start) {
					sbreak = ebreak = i - 2 + nocr;
					goto mktid;
				}
				if (!memcmp( fmap + start, "X-TUID: ", 8 )) {
					extra -= (ebreak = i) - (sbreak = start) + nocr;
					goto mktid;
				}
				goto nloop;
			}
		/* invalid message */
		free( fmap );
		return DRV_MSG_BAD;
	 mktid:
		for (j = 0; j < TUIDL; j++)
			sprintf( tuid + j * 2, "%02x", arc4_getbyte() );
		extra += 8 + TUIDL * 2 + 2;
	}
	if (nocr)
		for (; i < len; i++)
			if (fmap[i] == '\n')
				extra++;

	cb.dlen = len + extra;
	buf = cb.data = xmalloc( cb.dlen );
	i = 0;
	if (!CAP(UIDPLUS) && uid) {
		if (nocr) {
			for (; i < sbreak; i++)
				if (fmap[i] == '\n') {
					*buf++ = '\r';
					*buf++ = '\n';
				} else
					*buf++ = fmap[i];
		} else {
			memcpy( buf, fmap, sbreak );
			buf += sbreak;
		}
		memcpy( buf, "X-TUID: ", 8 );
		buf += 8;
		memcpy( buf, tuid, TUIDL * 2 );
		buf += TUIDL * 2;
		*buf++ = '\r';
		*buf++ = '\n';
		i = ebreak;
	}
	if (nocr) {
		for (; i < len; i++)
			if (fmap[i] == '\n') {
				*buf++ = '\r';
				*buf++ = '\n';
			} else
				*buf++ = fmap[i];
	} else
		memcpy( buf, fmap + i, len - i );

	free( fmap );

	d = 0;
	if (data->flags) {
		d = imap_make_flags( data->flags, flagstr );
		flagstr[d++] = ' ';
	}
	flagstr[d] = 0;

	if (!uid) {
		box = gctx->conf->trash;
		prefix = ctx->prefix;
		cb.create = 1;
		if (ctx->trashnc)
			imap->caps = imap->rcaps & ~(1 << LITERALPLUS);
	} else {
		box = gctx->name;
		prefix = !strcmp( box, "INBOX" ) ? "" : ctx->prefix;
		cb.create = 0;
	}
	cb.ctx = uid;
	ret = imap_exec_m( ctx, &cb, "APPEND \"%s%s\" %s", prefix, box, flagstr );
	imap->caps = imap->rcaps;
	if (ret != DRV_OK)
		return ret;
	if (!uid)
		ctx->trashnc = 0;
	else
		gctx->count++;

	return DRV_OK;
}

#define CHUNKSIZE 0x1000

static int
read_message( FILE *f, msg_data_t *msg )
{
	struct strbuf buf;

	memset(msg, 0, sizeof(*msg));
	strbuf_init(&buf, 0);

	do {
		if (strbuf_fread(&buf, CHUNKSIZE, f) <= 0)
			break;
	} while (!feof(f));

	msg->len  = buf.len;
	msg->data = strbuf_detach(&buf, NULL);
	return msg->len;
}

static int
count_messages( msg_data_t *msg )
{
	int count = 0;
	char *p = msg->data;

	while (1) {
		if (!prefixcmp(p, "From ")) {
			count++;
			p += 5;
		}
		p = strstr( p+5, "\nFrom ");
		if (!p)
			break;
		p++;
	}
	return count;
}

static int
split_msg( msg_data_t *all_msgs, msg_data_t *msg, int *ofs )
{
	char *p, *data;

	memset( msg, 0, sizeof *msg );
	if (*ofs >= all_msgs->len)
		return 0;

	data = &all_msgs->data[ *ofs ];
	msg->len = all_msgs->len - *ofs;

	if (msg->len < 5 || prefixcmp(data, "From "))
		return 0;

	p = strchr( data, '\n' );
	if (p) {
		p = &p[1];
		msg->len -= p-data;
		*ofs += p-data;
		data = p;
	}

	p = strstr( data, "\nFrom " );
	if (p)
		msg->len = &p[1] - data;

	msg->data = xmemdupz(data, msg->len);
	*ofs += msg->len;
	return 1;
}

static imap_server_conf_t server =
{
	NULL,	/* name */
	NULL,	/* tunnel */
	NULL,	/* host */
	0,	/* port */
	NULL,	/* user */
	NULL,	/* pass */
};

static char *imap_folder;

static int
git_imap_config(const char *key, const char *val)
{
	char imap_key[] = "imap.";

	if (strncmp( key, imap_key, sizeof imap_key - 1 ))
		return 0;

	if (!val)
		return config_error_nonbool(key);

	key += sizeof imap_key - 1;

	if (!strcmp( "folder", key )) {
		imap_folder = xstrdup( val );
	} else if (!strcmp( "host", key )) {
		{
			if (!prefixcmp(val, "imap:"))
				val += 5;
			if (!server.port)
				server.port = 143;
		}
		if (!prefixcmp(val, "//"))
			val += 2;
		server.host = xstrdup( val );
	}
	else if (!strcmp( "user", key ))
		server.user = xstrdup( val );
	else if (!strcmp( "pass", key ))
		server.pass = xstrdup( val );
	else if (!strcmp( "port", key ))
		server.port = git_config_int( key, val );
	else if (!strcmp( "tunnel", key ))
		server.tunnel = xstrdup( val );
	return 0;
}

int
main(int argc, char **argv)
{
	msg_data_t all_msgs, msg;
	store_t *ctx = NULL;
	int uid = 0;
	int ofs = 0;
	int r;
	int total, n = 0;

	/* init the random number generator */
	arc4_init();

	git_config( git_imap_config );

	if (!imap_folder) {
		fprintf( stderr, "no imap store specified\n" );
		return 1;
	}
	if (!server.host) {
		if (!server.tunnel) {
			fprintf( stderr, "no imap host specified\n" );
			return 1;
		}
		server.host = "tunnel";
	}

	/* read the messages */
	if (!read_message( stdin, &all_msgs )) {
		fprintf(stderr,"nothing to send\n");
		return 1;
	}

	total = count_messages( &all_msgs );
	if (!total) {
		fprintf(stderr,"no messages to send\n");
		return 1;
	}

	/* write it to the imap server */
	ctx = imap_open_store( &server );
	if (!ctx) {
		fprintf( stderr,"failed to open store\n");
		return 1;
	}

	fprintf( stderr, "sending %d message%s\n", total, (total!=1)?"s":"" );
	ctx->name = imap_folder;
	while (1) {
		unsigned percent = n * 100 / total;
		fprintf( stderr, "%4u%% (%d/%d) done\r", percent, n, total );
		if (!split_msg( &all_msgs, &msg, &ofs ))
			break;
		r = imap_store_msg( ctx, &msg, &uid );
		if (r != DRV_OK) break;
		n++;
	}
	fprintf( stderr,"\n" );

	imap_close_store( ctx );

	return 0;
}
