/* vi: set sw=4 ts=4: */
/*
 * makemime: create MIME-encoded message
 * reformime: parse MIME-encoded message
 *
 * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
 *
 * Licensed under GPLv2, see file LICENSE in this source tree.
 */

//kbuild:lib-$(CONFIG_REFORMIME) += reformime.o mail.o

#include "libbb.h"
#include "mail.h"

#if 0
# define dbg_error_msg(...) bb_error_msg(__VA_ARGS__)
#else
# define dbg_error_msg(...) ((void)0)
#endif

static const char *find_token(const char *const string_array[], const char *key, const char *defvalue)
{
	const char *r = NULL;
	int i;
	for (i = 0; string_array[i] != NULL; i++) {
		if (strcasecmp(string_array[i], key) == 0) {
			r = (char *)string_array[i+1];
			break;
		}
	}
	return (r) ? r : defvalue;
}

static const char *xfind_token(const char *const string_array[], const char *key)
{
	const char *r = find_token(string_array, key, NULL);
	if (r)
		return r;
	bb_error_msg_and_die("not found: '%s'", key);
}

enum {
	OPT_x = 1 << 0,
	OPT_X = 1 << 1,
#if ENABLE_FEATURE_REFORMIME_COMPAT
	OPT_d = 1 << 2,
	OPT_e = 1 << 3,
	OPT_i = 1 << 4,
	OPT_s = 1 << 5,
	OPT_r = 1 << 6,
	OPT_c = 1 << 7,
	OPT_m = 1 << 8,
	OPT_h = 1 << 9,
	OPT_o = 1 << 10,
	OPT_O = 1 << 11,
#endif
};

static int parse(const char *boundary, char **argv)
{
	int boundary_len = strlen(boundary);
	char uniq[sizeof("%%llu.%u") + sizeof(int)*3];

	dbg_error_msg("BOUNDARY[%s]", boundary);

	// prepare unique string pattern
	sprintf(uniq, "%%llu.%u", (unsigned)getpid());
	dbg_error_msg("UNIQ[%s]", uniq);

	while (1) {
		char *header;
		const char *tokens[32]; /* 32 is enough */
		const char *type;

		/* Read the header (everything up to two \n) */
		{
			unsigned header_idx = 0;
			int last_ch = 0;
			header = NULL;
			while (1) {
				int ch = fgetc(stdin);
				if (ch == '\r') /* Support both line endings */
					continue;
				if (ch == EOF)
					break;
				if (ch == '\n' && last_ch == ch)
					break;
				if (!(header_idx & 0xff))
					header = xrealloc(header, header_idx + 0x101);
				header[header_idx++] = last_ch = ch;
			}
			if (!header) {
				dbg_error_msg("EOF");
				break;
			}
			header[header_idx] = '\0';
			dbg_error_msg("H:'%s'", p);
		}

		/* Split to tokens */
		{
			char *s, *p;
			unsigned ntokens;
			const char *delims = ";=\" \t\n";

			/* Skip to last Content-Type: */
			s = p = header;
			while ((p = strchr(p, '\n')) != NULL) {
				p++;
				if (strncasecmp(p, "Content-Type:", sizeof("Content-Type:")-1) == 0)
					s = p;
			}
			dbg_error_msg("L:'%s'", p);
			ntokens = 0;
			s = strtok(s, delims);
			while (s) {
				tokens[ntokens] = s;
				if (ntokens < ARRAY_SIZE(tokens) - 1)
					ntokens++;
				dbg_error_msg("L[%d]='%s'", ntokens, s);
				s = strtok(NULL, delims);
			}
			tokens[ntokens] = NULL;
			dbg_error_msg("EMPTYLINE, ntokens:%d", ntokens);
			if (ntokens == 0)
				break;
		}

		/* Is it multipart? */
		type = find_token(tokens, "Content-Type:", "text/plain");
		dbg_error_msg("TYPE:'%s'", type);
		if (0 == strncasecmp(type, "multipart/", 10)) {
			/* Yes, recurse */
			if (strcasecmp(type + 10, "mixed") != 0)
				bb_error_msg_and_die("no support of content type '%s'", type);
			parse(xfind_token(tokens, "boundary"), argv);

		} else {
			/* No, process one non-multipart section */
			char *end;
			pid_t pid = pid;
			FILE *fp;

			const char *charset = find_token(tokens, "charset", CONFIG_FEATURE_MIME_CHARSET);
			const char *encoding = find_token(tokens, "Content-Transfer-Encoding:", "7bit");

			/* Compose target filename */
			char *filename = (char *)find_token(tokens, "filename", NULL);
			if (!filename)
				filename = xasprintf(uniq, monotonic_us());
			else
				filename = bb_get_last_path_component_strip(xstrdup(filename));

			if (opts & OPT_X) {
				int fd[2];

				/* start external helper */
				xpipe(fd);
				pid = vfork();
				if (0 == pid) {
					/* child reads from fd[0] */
					close(fd[1]);
					xmove_fd(fd[0], STDIN_FILENO);
					xsetenv("CONTENT_TYPE", type);
					xsetenv("CHARSET", charset);
					xsetenv("ENCODING", encoding);
					xsetenv("FILENAME", filename);
					BB_EXECVP_or_die(argv);
				}
				/* parent will write to fd[1] */
				close(fd[0]);
				fp = xfdopen_for_write(fd[1]);
				signal(SIGPIPE, SIG_IGN);
			} else {
				/* write to file */
				char *fname = xasprintf("%s%s", *argv, filename);
				fp = xfopen_for_write(fname);
				free(fname);
			}
			free(filename);

			/* write to fp */
			end = NULL;
			if (0 == strcasecmp(encoding, "base64")) {
				read_base64(stdin, fp, '-');
			} else
			if (0 != strcasecmp(encoding, "7bit")
			 && 0 != strcasecmp(encoding, "8bit")
			) {
				/* quoted-printable, binary, user-defined are unsupported so far */
				bb_error_msg_and_die("encoding '%s' not supported", encoding);
			} else {
				/* plain 7bit or 8bit */
				while ((end = xmalloc_fgets(stdin)) != NULL) {
					if ('-' == end[0]
					 && '-' == end[1]
					 && strncmp(end + 2, boundary, boundary_len) == 0
					) {
						break;
					}
					fputs(end, fp);
				}
			}
			fclose(fp);

			/* Wait for child */
			if (opts & OPT_X) {
				int rc;
				signal(SIGPIPE, SIG_DFL);
				rc = (wait4pid(pid) & 0xff);
				if (rc != 0)
					return rc + 20;
			}

			/* Multipart ended? */
			if (end && '-' == end[2 + boundary_len] && '-' == end[2 + boundary_len + 1]) {
				dbg_error_msg("FINISHED MPART:'%s'", end);
				break;
			}
			dbg_error_msg("FINISHED:'%s'", end);
			free(end);
		} /* end of "handle one non-multipart block" */

		free(header);
	} /* while (1) */

	dbg_error_msg("ENDPARSE[%s]", boundary);

	return EXIT_SUCCESS;
}

//usage:#define reformime_trivial_usage
//usage:       "[OPTIONS]"
//usage:#define reformime_full_usage "\n\n"
//usage:       "Parse MIME-encoded message on stdin\n"
//usage:     "\n	-x PREFIX	Extract content of MIME sections to files"
//usage:     "\n	-X PROG ARGS	Filter content of MIME sections through PROG"
//usage:     "\n			Must be the last option"
//usage:     "\n"
//usage:     "\nOther options are silently ignored"

/*
Usage: reformime [options]
    -d - parse a delivery status notification.
    -e - extract contents of MIME section.
    -x - extract MIME section to a file.
    -X - pipe MIME section to a program.
    -i - show MIME info.
    -s n.n.n.n - specify MIME section.
    -r - rewrite message, filling in missing MIME headers.
    -r7 - also convert 8bit/raw encoding to quoted-printable, if possible.
    -r8 - also convert quoted-printable encoding to 8bit, if possible.
    -c charset - default charset for rewriting, -o, and -O.
    -m [file] [file]... - create a MIME message digest.
    -h "header" - decode RFC 2047-encoded header.
    -o "header" - encode unstructured header using RFC 2047.
    -O "header" - encode address list header using RFC 2047.
*/

int reformime_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int reformime_main(int argc UNUSED_PARAM, char **argv)
{
	const char *opt_prefix = "";

	INIT_G();

	// parse options
	// N.B. only -x and -X are supported so far
	opt_complementary = "x--X:X--x" IF_FEATURE_REFORMIME_COMPAT(":m::");
	opts = getopt32(argv,
		"x:X" IF_FEATURE_REFORMIME_COMPAT("deis:r:c:m:h:o:O:"),
		&opt_prefix
		IF_FEATURE_REFORMIME_COMPAT(, NULL, NULL, &G.opt_charset, NULL, NULL, NULL, NULL)
	);
	argv += optind;

	return parse("", (opts & OPT_X) ? argv : (char **)&opt_prefix);
}
