/*
 * Another stupid program, this one parsing the headers of an
 * email to figure out authorship and subject
 */
#include "cache.h"
#include "builtin.h"
#include "utf8.h"
#include "strbuf.h"

static FILE *cmitmsg, *patchfile, *fin, *fout;

static int keep_subject;
static const char *metainfo_charset;
static struct strbuf line = STRBUF_INIT;
static struct strbuf name = STRBUF_INIT;
static struct strbuf email = STRBUF_INIT;

static enum  {
	TE_DONTCARE, TE_QP, TE_BASE64,
} transfer_encoding;
static enum  {
	TYPE_TEXT, TYPE_OTHER,
} message_type;

static struct strbuf charset = STRBUF_INIT;
static int patch_lines;
static struct strbuf **p_hdr_data, **s_hdr_data;

#define MAX_HDR_PARSED 10
#define MAX_BOUNDARIES 5

static void cleanup_space(struct strbuf *sb);


static void get_sane_name(struct strbuf *out, struct strbuf *name, struct strbuf *email)
{
	struct strbuf *src = name;
	if (name->len < 3 || 60 < name->len || strchr(name->buf, '@') ||
		strchr(name->buf, '<') || strchr(name->buf, '>'))
		src = email;
	else if (name == out)
		return;
	strbuf_reset(out);
	strbuf_addbuf(out, src);
}

static void parse_bogus_from(const struct strbuf *line)
{
	/* John Doe <johndoe> */

	char *bra, *ket;
	/* This is fallback, so do not bother if we already have an
	 * e-mail address.
	 */
	if (email.len)
		return;

	bra = strchr(line->buf, '<');
	if (!bra)
		return;
	ket = strchr(bra, '>');
	if (!ket)
		return;

	strbuf_reset(&email);
	strbuf_add(&email, bra + 1, ket - bra - 1);

	strbuf_reset(&name);
	strbuf_add(&name, line->buf, bra - line->buf);
	strbuf_trim(&name);
	get_sane_name(&name, &name, &email);
}

static void handle_from(const struct strbuf *from)
{
	char *at;
	size_t el;
	struct strbuf f;

	strbuf_init(&f, from->len);
	strbuf_addbuf(&f, from);

	at = strchr(f.buf, '@');
	if (!at) {
		parse_bogus_from(from);
		return;
	}

	/*
	 * If we already have one email, don't take any confusing lines
	 */
	if (email.len && strchr(at + 1, '@')) {
		strbuf_release(&f);
		return;
	}

	/* Pick up the string around '@', possibly delimited with <>
	 * pair; that is the email part.
	 */
	while (at > f.buf) {
		char c = at[-1];
		if (isspace(c))
			break;
		if (c == '<') {
			at[-1] = ' ';
			break;
		}
		at--;
	}
	el = strcspn(at, " \n\t\r\v\f>");
	strbuf_reset(&email);
	strbuf_add(&email, at, el);
	strbuf_remove(&f, at - f.buf, el + (at[el] ? 1 : 0));

	/* The remainder is name.  It could be
	 *
	 * - "John Doe <john.doe@xz>"			(a), or
	 * - "john.doe@xz (John Doe)"			(b), or
	 * - "John (zzz) Doe <john.doe@xz> (Comment)"	(c)
	 *
	 * but we have removed the email part, so
	 *
	 * - remove extra spaces which could stay after email (case 'c'), and
	 * - trim from both ends, possibly removing the () pair at the end
	 *   (cases 'a' and 'b').
	 */
	cleanup_space(&f);
	strbuf_trim(&f);
	if (f.buf[0] == '(' && f.len && f.buf[f.len - 1] == ')') {
		strbuf_remove(&f, 0, 1);
		strbuf_setlen(&f, f.len - 1);
	}

	get_sane_name(&name, &f, &email);
	strbuf_release(&f);
}

static void handle_header(struct strbuf **out, const struct strbuf *line)
{
	if (!*out) {
		*out = xmalloc(sizeof(struct strbuf));
		strbuf_init(*out, line->len);
	} else
		strbuf_reset(*out);

	strbuf_addbuf(*out, line);
}

/* NOTE NOTE NOTE.  We do not claim we do full MIME.  We just attempt
 * to have enough heuristics to grok MIME encoded patches often found
 * on our mailing lists.  For example, we do not even treat header lines
 * case insensitively.
 */

static int slurp_attr(const char *line, const char *name, struct strbuf *attr)
{
	const char *ends, *ap = strcasestr(line, name);
	size_t sz;

	if (!ap) {
		strbuf_setlen(attr, 0);
		return 0;
	}
	ap += strlen(name);
	if (*ap == '"') {
		ap++;
		ends = "\"";
	}
	else
		ends = "; \t";
	sz = strcspn(ap, ends);
	strbuf_add(attr, ap, sz);
	return 1;
}

static struct strbuf *content[MAX_BOUNDARIES];

static struct strbuf **content_top = content;

static void handle_content_type(struct strbuf *line)
{
	struct strbuf *boundary = xmalloc(sizeof(struct strbuf));
	strbuf_init(boundary, line->len);

	if (!strcasestr(line->buf, "text/"))
		 message_type = TYPE_OTHER;
	if (slurp_attr(line->buf, "boundary=", boundary)) {
		strbuf_insert(boundary, 0, "--", 2);
		if (++content_top > &content[MAX_BOUNDARIES]) {
			fprintf(stderr, "Too many boundaries to handle\n");
			exit(1);
		}
		*content_top = boundary;
		boundary = NULL;
	}
	slurp_attr(line->buf, "charset=", &charset);

	if (boundary) {
		strbuf_release(boundary);
		free(boundary);
	}
}

static void handle_content_transfer_encoding(const struct strbuf *line)
{
	if (strcasestr(line->buf, "base64"))
		transfer_encoding = TE_BASE64;
	else if (strcasestr(line->buf, "quoted-printable"))
		transfer_encoding = TE_QP;
	else
		transfer_encoding = TE_DONTCARE;
}

static int is_multipart_boundary(const struct strbuf *line)
{
	return (((*content_top)->len <= line->len) &&
		!memcmp(line->buf, (*content_top)->buf, (*content_top)->len));
}

static void cleanup_subject(struct strbuf *subject)
{
	char *pos;
	size_t remove;
	while (subject->len) {
		switch (*subject->buf) {
		case 'r': case 'R':
			if (subject->len <= 3)
				break;
			if (!memcmp(subject->buf + 1, "e:", 2)) {
				strbuf_remove(subject, 0, 3);
				continue;
			}
			break;
		case ' ': case '\t': case ':':
			strbuf_remove(subject, 0, 1);
			continue;
		case '[':
			if ((pos = strchr(subject->buf, ']'))) {
				remove = pos - subject->buf;
				if (remove <= (subject->len - remove) * 2) {
					strbuf_remove(subject, 0, remove + 1);
					continue;
				}
			} else
				strbuf_remove(subject, 0, 1);
			break;
		}
		strbuf_trim(subject);
		return;
	}
}

static void cleanup_space(struct strbuf *sb)
{
	size_t pos, cnt;
	for (pos = 0; pos < sb->len; pos++) {
		if (isspace(sb->buf[pos])) {
			sb->buf[pos] = ' ';
			for (cnt = 0; isspace(sb->buf[pos + cnt + 1]); cnt++);
			strbuf_remove(sb, pos + 1, cnt);
		}
	}
}

static void decode_header(struct strbuf *line);
static const char *header[MAX_HDR_PARSED] = {
	"From","Subject","Date",
};

static inline int cmp_header(const struct strbuf *line, const char *hdr)
{
	int len = strlen(hdr);
	return !strncasecmp(line->buf, hdr, len) && line->len > len &&
			line->buf[len] == ':' && isspace(line->buf[len + 1]);
}

static int check_header(const struct strbuf *line,
				struct strbuf *hdr_data[], int overwrite)
{
	int i, ret = 0, len;
	struct strbuf sb = STRBUF_INIT;
	/* search for the interesting parts */
	for (i = 0; header[i]; i++) {
		int len = strlen(header[i]);
		if ((!hdr_data[i] || overwrite) && cmp_header(line, header[i])) {
			/* Unwrap inline B and Q encoding, and optionally
			 * normalize the meta information to utf8.
			 */
			strbuf_add(&sb, line->buf + len + 2, line->len - len - 2);
			decode_header(&sb);
			handle_header(&hdr_data[i], &sb);
			ret = 1;
			goto check_header_out;
		}
	}

	/* Content stuff */
	if (cmp_header(line, "Content-Type")) {
		len = strlen("Content-Type: ");
		strbuf_add(&sb, line->buf + len, line->len - len);
		decode_header(&sb);
		strbuf_insert(&sb, 0, "Content-Type: ", len);
		handle_content_type(&sb);
		ret = 1;
		goto check_header_out;
	}
	if (cmp_header(line, "Content-Transfer-Encoding")) {
		len = strlen("Content-Transfer-Encoding: ");
		strbuf_add(&sb, line->buf + len, line->len - len);
		decode_header(&sb);
		handle_content_transfer_encoding(&sb);
		ret = 1;
		goto check_header_out;
	}

	/* for inbody stuff */
	if (!prefixcmp(line->buf, ">From") && isspace(line->buf[5])) {
		ret = 1; /* Should this return 0? */
		goto check_header_out;
	}
	if (!prefixcmp(line->buf, "[PATCH]") && isspace(line->buf[7])) {
		for (i = 0; header[i]; i++) {
			if (!memcmp("Subject", header[i], 7)) {
				handle_header(&hdr_data[i], line);
				ret = 1;
				goto check_header_out;
			}
		}
	}

check_header_out:
	strbuf_release(&sb);
	return ret;
}

static int is_rfc2822_header(const struct strbuf *line)
{
	/*
	 * The section that defines the loosest possible
	 * field name is "3.6.8 Optional fields".
	 *
	 * optional-field = field-name ":" unstructured CRLF
	 * field-name = 1*ftext
	 * ftext = %d33-57 / %59-126
	 */
	int ch;
	char *cp = line->buf;

	/* Count mbox From headers as headers */
	if (!prefixcmp(cp, "From ") || !prefixcmp(cp, ">From "))
		return 1;

	while ((ch = *cp++)) {
		if (ch == ':')
			return 1;
		if ((33 <= ch && ch <= 57) ||
		    (59 <= ch && ch <= 126))
			continue;
		break;
	}
	return 0;
}

static int read_one_header_line(struct strbuf *line, FILE *in)
{
	/* Get the first part of the line. */
	if (strbuf_getline(line, in, '\n'))
		return 0;

	/*
	 * Is it an empty line or not a valid rfc2822 header?
	 * If so, stop here, and return false ("not a header")
	 */
	strbuf_rtrim(line);
	if (!line->len || !is_rfc2822_header(line)) {
		/* Re-add the newline */
		strbuf_addch(line, '\n');
		return 0;
	}

	/*
	 * Now we need to eat all the continuation lines..
	 * Yuck, 2822 header "folding"
	 */
	for (;;) {
		int peek;
		struct strbuf continuation = STRBUF_INIT;

		peek = fgetc(in); ungetc(peek, in);
		if (peek != ' ' && peek != '\t')
			break;
		if (strbuf_getline(&continuation, in, '\n'))
			break;
		continuation.buf[0] = '\n';
		strbuf_rtrim(&continuation);
		strbuf_addbuf(line, &continuation);
	}

	return 1;
}

static struct strbuf *decode_q_segment(const struct strbuf *q_seg, int rfc2047)
{
	const char *in = q_seg->buf;
	int c;
	struct strbuf *out = xmalloc(sizeof(struct strbuf));
	strbuf_init(out, q_seg->len);

	while ((c = *in++) != 0) {
		if (c == '=') {
			int d = *in++;
			if (d == '\n' || !d)
				break; /* drop trailing newline */
			strbuf_addch(out, (hexval(d) << 4) | hexval(*in++));
			continue;
		}
		if (rfc2047 && c == '_') /* rfc2047 4.2 (2) */
			c = 0x20;
		strbuf_addch(out, c);
	}
	return out;
}

static struct strbuf *decode_b_segment(const struct strbuf *b_seg)
{
	/* Decode in..ep, possibly in-place to ot */
	int c, pos = 0, acc = 0;
	const char *in = b_seg->buf;
	struct strbuf *out = xmalloc(sizeof(struct strbuf));
	strbuf_init(out, b_seg->len);

	while ((c = *in++) != 0) {
		if (c == '+')
			c = 62;
		else if (c == '/')
			c = 63;
		else if ('A' <= c && c <= 'Z')
			c -= 'A';
		else if ('a' <= c && c <= 'z')
			c -= 'a' - 26;
		else if ('0' <= c && c <= '9')
			c -= '0' - 52;
		else
			continue; /* garbage */
		switch (pos++) {
		case 0:
			acc = (c << 2);
			break;
		case 1:
			strbuf_addch(out, (acc | (c >> 4)));
			acc = (c & 15) << 4;
			break;
		case 2:
			strbuf_addch(out, (acc | (c >> 2)));
			acc = (c & 3) << 6;
			break;
		case 3:
			strbuf_addch(out, (acc | c));
			acc = pos = 0;
			break;
		}
	}
	return out;
}

/*
 * When there is no known charset, guess.
 *
 * Right now we assume that if the target is UTF-8 (the default),
 * and it already looks like UTF-8 (which includes US-ASCII as its
 * subset, of course) then that is what it is and there is nothing
 * to do.
 *
 * Otherwise, we default to assuming it is Latin1 for historical
 * reasons.
 */
static const char *guess_charset(const struct strbuf *line, const char *target_charset)
{
	if (is_encoding_utf8(target_charset)) {
		if (is_utf8(line->buf))
			return NULL;
	}
	return "ISO8859-1";
}

static void convert_to_utf8(struct strbuf *line, const char *charset)
{
	char *out;

	if (!charset || !*charset) {
		charset = guess_charset(line, metainfo_charset);
		if (!charset)
			return;
	}

	if (!strcasecmp(metainfo_charset, charset))
		return;
	out = reencode_string(line->buf, metainfo_charset, charset);
	if (!out)
		die("cannot convert from %s to %s",
		    charset, metainfo_charset);
	strbuf_attach(line, out, strlen(out), strlen(out));
}

static int decode_header_bq(struct strbuf *it)
{
	char *in, *ep, *cp;
	struct strbuf outbuf = STRBUF_INIT, *dec;
	struct strbuf charset_q = STRBUF_INIT, piecebuf = STRBUF_INIT;
	int rfc2047 = 0;

	in = it->buf;
	while (in - it->buf <= it->len && (ep = strstr(in, "=?")) != NULL) {
		int encoding;
		strbuf_reset(&charset_q);
		strbuf_reset(&piecebuf);
		rfc2047 = 1;

		if (in != ep) {
			/*
			 * We are about to process an encoded-word
			 * that begins at ep, but there is something
			 * before the encoded word.
			 */
			char *scan;
			for (scan = in; scan < ep; scan++)
				if (!isspace(*scan))
					break;

			if (scan != ep || in == it->buf) {
				/*
				 * We should not lose that "something",
				 * unless we have just processed an
				 * encoded-word, and there is only LWS
				 * before the one we are about to process.
				 */
				strbuf_add(&outbuf, in, ep - in);
			}
		}
		/* E.g.
		 * ep : "=?iso-2022-jp?B?GyR...?= foo"
		 * ep : "=?ISO-8859-1?Q?Foo=FCbar?= baz"
		 */
		ep += 2;

		if (ep - it->buf >= it->len || !(cp = strchr(ep, '?')))
			goto decode_header_bq_out;

		if (cp + 3 - it->buf > it->len)
			goto decode_header_bq_out;
		strbuf_add(&charset_q, ep, cp - ep);

		encoding = cp[1];
		if (!encoding || cp[2] != '?')
			goto decode_header_bq_out;
		ep = strstr(cp + 3, "?=");
		if (!ep)
			goto decode_header_bq_out;
		strbuf_add(&piecebuf, cp + 3, ep - cp - 3);
		switch (tolower(encoding)) {
		default:
			goto decode_header_bq_out;
		case 'b':
			dec = decode_b_segment(&piecebuf);
			break;
		case 'q':
			dec = decode_q_segment(&piecebuf, 1);
			break;
		}
		if (metainfo_charset)
			convert_to_utf8(dec, charset_q.buf);

		strbuf_addbuf(&outbuf, dec);
		strbuf_release(dec);
		free(dec);
		in = ep + 2;
	}
	strbuf_addstr(&outbuf, in);
	strbuf_reset(it);
	strbuf_addbuf(it, &outbuf);
decode_header_bq_out:
	strbuf_release(&outbuf);
	strbuf_release(&charset_q);
	strbuf_release(&piecebuf);
	return rfc2047;
}

static void decode_header(struct strbuf *it)
{
	if (decode_header_bq(it))
		return;
	/* otherwise "it" is a straight copy of the input.
	 * This can be binary guck but there is no charset specified.
	 */
	if (metainfo_charset)
		convert_to_utf8(it, "");
}

static void decode_transfer_encoding(struct strbuf *line)
{
	struct strbuf *ret;

	switch (transfer_encoding) {
	case TE_QP:
		ret = decode_q_segment(line, 0);
		break;
	case TE_BASE64:
		ret = decode_b_segment(line);
		break;
	case TE_DONTCARE:
	default:
		return;
	}
	strbuf_reset(line);
	strbuf_addbuf(line, ret);
	strbuf_release(ret);
	free(ret);
}

static void handle_filter(struct strbuf *line);

static int find_boundary(void)
{
	while (!strbuf_getline(&line, fin, '\n')) {
		if (*content_top && is_multipart_boundary(&line))
			return 1;
	}
	return 0;
}

static int handle_boundary(void)
{
	struct strbuf newline = STRBUF_INIT;

	strbuf_addch(&newline, '\n');
again:
	if (line.len >= (*content_top)->len + 2 &&
	    !memcmp(line.buf + (*content_top)->len, "--", 2)) {
		/* we hit an end boundary */
		/* pop the current boundary off the stack */
		strbuf_release(*content_top);
		free(*content_top);
		*content_top = NULL;

		/* technically won't happen as is_multipart_boundary()
		   will fail first.  But just in case..
		 */
		if (--content_top < content) {
			fprintf(stderr, "Detected mismatched boundaries, "
					"can't recover\n");
			exit(1);
		}
		handle_filter(&newline);
		strbuf_release(&newline);

		/* skip to the next boundary */
		if (!find_boundary())
			return 0;
		goto again;
	}

	/* set some defaults */
	transfer_encoding = TE_DONTCARE;
	strbuf_reset(&charset);
	message_type = TYPE_TEXT;

	/* slurp in this section's info */
	while (read_one_header_line(&line, fin))
		check_header(&line, p_hdr_data, 0);

	strbuf_release(&newline);
	/* replenish line */
	if (strbuf_getline(&line, fin, '\n'))
		return 0;
	strbuf_addch(&line, '\n');
	return 1;
}

static inline int patchbreak(const struct strbuf *line)
{
	size_t i;

	/* Beginning of a "diff -" header? */
	if (!prefixcmp(line->buf, "diff -"))
		return 1;

	/* CVS "Index: " line? */
	if (!prefixcmp(line->buf, "Index: "))
		return 1;

	/*
	 * "--- <filename>" starts patches without headers
	 * "---<sp>*" is a manual separator
	 */
	if (line->len < 4)
		return 0;

	if (!prefixcmp(line->buf, "---")) {
		/* space followed by a filename? */
		if (line->buf[3] == ' ' && !isspace(line->buf[4]))
			return 1;
		/* Just whitespace? */
		for (i = 3; i < line->len; i++) {
			unsigned char c = line->buf[i];
			if (c == '\n')
				return 1;
			if (!isspace(c))
				break;
		}
		return 0;
	}
	return 0;
}

static int handle_commit_msg(struct strbuf *line)
{
	static int still_looking = 1;

	if (!cmitmsg)
		return 0;

	if (still_looking) {
		strbuf_ltrim(line);
		if (!line->len)
			return 0;
		if ((still_looking = check_header(line, s_hdr_data, 0)) != 0)
			return 0;
	}

	/* normalize the log message to UTF-8. */
	if (metainfo_charset)
		convert_to_utf8(line, charset.buf);

	if (patchbreak(line)) {
		fclose(cmitmsg);
		cmitmsg = NULL;
		return 1;
	}

	fputs(line->buf, cmitmsg);
	return 0;
}

static void handle_patch(const struct strbuf *line)
{
	fwrite(line->buf, 1, line->len, patchfile);
	patch_lines++;
}

static void handle_filter(struct strbuf *line)
{
	static int filter = 0;

	/* filter tells us which part we left off on */
	switch (filter) {
	case 0:
		if (!handle_commit_msg(line))
			break;
		filter++;
	case 1:
		handle_patch(line);
		break;
	}
}

static void handle_body(void)
{
	int len = 0;
	struct strbuf prev = STRBUF_INIT;

	/* Skip up to the first boundary */
	if (*content_top) {
		if (!find_boundary())
			goto handle_body_out;
	}

	do {
		strbuf_setlen(&line, line.len + len);

		/* process any boundary lines */
		if (*content_top && is_multipart_boundary(&line)) {
			/* flush any leftover */
			if (prev.len) {
				handle_filter(&prev);
				strbuf_reset(&prev);
			}
			if (!handle_boundary())
				goto handle_body_out;
		}

		/* Unwrap transfer encoding */
		decode_transfer_encoding(&line);

		switch (transfer_encoding) {
		case TE_BASE64:
		case TE_QP:
		{
			struct strbuf **lines, **it, *sb;

			/* Prepend any previous partial lines */
			strbuf_insert(&line, 0, prev.buf, prev.len);
			strbuf_reset(&prev);

			/* binary data most likely doesn't have newlines */
			if (message_type != TYPE_TEXT) {
				handle_filter(&line);
				break;
			}
			/*
			 * This is a decoded line that may contain
			 * multiple new lines.  Pass only one chunk
			 * at a time to handle_filter()
			 */
			lines = strbuf_split(&line, '\n');
			for (it = lines; (sb = *it); it++) {
				if (*(it + 1) == NULL) /* The last line */
					if (sb->buf[sb->len - 1] != '\n') {
						/* Partial line, save it for later. */
						strbuf_addbuf(&prev, sb);
						break;
					}
				handle_filter(sb);
			}
			/*
			 * The partial chunk is saved in "prev" and will be
			 * appended by the next iteration of read_line_with_nul().
			 */
			strbuf_list_free(lines);
			break;
		}
		default:
			handle_filter(&line);
		}

		strbuf_reset(&line);
		if (strbuf_avail(&line) < 100)
			strbuf_grow(&line, 100);
	} while ((len = read_line_with_nul(line.buf, strbuf_avail(&line), fin)));

handle_body_out:
	strbuf_release(&prev);
}

static void output_header_lines(FILE *fout, const char *hdr, const struct strbuf *data)
{
	const char *sp = data->buf;
	while (1) {
		char *ep = strchr(sp, '\n');
		int len;
		if (!ep)
			len = strlen(sp);
		else
			len = ep - sp;
		fprintf(fout, "%s: %.*s\n", hdr, len, sp);
		if (!ep)
			break;
		sp = ep + 1;
	}
}

static void handle_info(void)
{
	struct strbuf *hdr;
	int i;

	for (i = 0; header[i]; i++) {
		/* only print inbody headers if we output a patch file */
		if (patch_lines && s_hdr_data[i])
			hdr = s_hdr_data[i];
		else if (p_hdr_data[i])
			hdr = p_hdr_data[i];
		else
			continue;

		if (!memcmp(header[i], "Subject", 7)) {
			if (!keep_subject) {
				cleanup_subject(hdr);
				cleanup_space(hdr);
			}
			output_header_lines(fout, "Subject", hdr);
		} else if (!memcmp(header[i], "From", 4)) {
			cleanup_space(hdr);
			handle_from(hdr);
			fprintf(fout, "Author: %s\n", name.buf);
			fprintf(fout, "Email: %s\n", email.buf);
		} else {
			cleanup_space(hdr);
			fprintf(fout, "%s: %s\n", header[i], hdr->buf);
		}
	}
	fprintf(fout, "\n");
}

static int mailinfo(FILE *in, FILE *out, int ks, const char *encoding,
		    const char *msg, const char *patch)
{
	int peek;
	keep_subject = ks;
	metainfo_charset = encoding;
	fin = in;
	fout = out;

	cmitmsg = fopen(msg, "w");
	if (!cmitmsg) {
		perror(msg);
		return -1;
	}
	patchfile = fopen(patch, "w");
	if (!patchfile) {
		perror(patch);
		fclose(cmitmsg);
		return -1;
	}

	p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*p_hdr_data));
	s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*s_hdr_data));

	do {
		peek = fgetc(in);
	} while (isspace(peek));
	ungetc(peek, in);

	/* process the email header */
	while (read_one_header_line(&line, fin))
		check_header(&line, p_hdr_data, 1);

	handle_body();
	handle_info();

	return 0;
}

static const char mailinfo_usage[] =
	"git mailinfo [-k] [-u | --encoding=<encoding> | -n] msg patch <mail >info";

int cmd_mailinfo(int argc, const char **argv, const char *prefix)
{
	const char *def_charset;

	/* NEEDSWORK: might want to do the optional .git/ directory
	 * discovery
	 */
	git_config(git_default_config, NULL);

	def_charset = (git_commit_encoding ? git_commit_encoding : "UTF-8");
	metainfo_charset = def_charset;

	while (1 < argc && argv[1][0] == '-') {
		if (!strcmp(argv[1], "-k"))
			keep_subject = 1;
		else if (!strcmp(argv[1], "-u"))
			metainfo_charset = def_charset;
		else if (!strcmp(argv[1], "-n"))
			metainfo_charset = NULL;
		else if (!prefixcmp(argv[1], "--encoding="))
			metainfo_charset = argv[1] + 11;
		else
			usage(mailinfo_usage);
		argc--; argv++;
	}

	if (argc != 3)
		usage(mailinfo_usage);

	return !!mailinfo(stdin, stdout, keep_subject, metainfo_charset, argv[1], argv[2]);
}
