/*
** packf.c -- pack a nmh folder into a file
**
** This code is Copyright (c) 2002, by the authors of nmh.  See the
** COPYRIGHT file in the root directory of the nmh distribution for
** complete copyright information.
*/

#include <h/mh.h>
#include <fcntl.h>
#include <h/dropsbr.h>
#include <h/utils.h>
#include <errno.h>
#include <unistd.h>
#include <locale.h>
#include <sysexits.h>

static struct swit switches[] = {
#define VERSIONSW  0
	{ "Version", 0 },
#define HELPSW  1
	{ "help", 0 },
	{ NULL, 0 }
};

char *version=VERSION;

int
main(int argc, char **argv)
{
	int fd, msgnum;
	char *cp, *maildir, *msgnam, *folder = NULL, buf[BUFSIZ];
	char **argp, **arguments;
	struct msgs_array msgs = { 0, 0, NULL };
	struct msgs *mp;

	setlocale(LC_ALL, "");
	invo_name = mhbasename(argv[0]);

	/* read user profile/context */
	context_read();

	arguments = getarguments(invo_name, argc, argv, 1);
	argp = arguments;

	/*
	** Parse arguments
	*/
	while ((cp = *argp++)) {
		if (*cp == '-') {
			switch (smatch(++cp, switches)) {
			case AMBIGSW:
				ambigsw(cp, switches);
				exit(EX_USAGE);
			case UNKWNSW:
				adios(EX_USAGE, NULL, "-%s unknown", cp);

			case HELPSW:
				snprintf(buf, sizeof(buf), "%s [+folder] [msgs] [switches]", invo_name);
				print_help(buf, switches, 1);
				exit(argc == 2 ? EX_OK : EX_USAGE);
			case VERSIONSW:
				print_version(invo_name);
				exit(argc == 2 ? EX_OK : EX_USAGE);
			}
		}
		if (*cp == '+' || *cp == '@') {
			if (folder)
				adios(EX_USAGE, NULL, "only one folder at a time!");
			folder = mh_xstrdup(expandfol(cp));
		} else
			app_msgarg(&msgs, cp);
	}

	/* default is to pack whole folder */
	if (!msgs.size)
		app_msgarg(&msgs, seq_all);

	if (!folder)
		folder = getcurfol();
	maildir = toabsdir(folder);

	if (chdir(maildir) == NOTOK)
		adios(EX_OSERR, maildir, "unable to change directory to ");

	/* read folder and create message structure */
	if (!(mp = folder_read(folder)))
		adios(EX_IOERR, NULL, "unable to read folder %s", folder);

	/* check for empty folder */
	if (mp->nummsg == 0)
		adios(EX_DATAERR, NULL, "no messages in %s", folder);

	/* parse all the message ranges/sequences and set SELECTED */
	for (msgnum = 0; msgnum < msgs.size; msgnum++)
		if (!m_convert(mp, msgs.msgs[msgnum]))
			exit(EX_USAGE);
	seq_setprev(mp);  /* set the previous-sequence */

	/* copy all the SELECTED messages to stdout */
	for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
		if (is_selected(mp, msgnum)) {
			if ((fd = open(msgnam = m_name(msgnum), O_RDONLY))
					== NOTOK) {
				admonish(msgnam, "unable to read message");
				break;
			}
			if (mbox_copy(fileno(stdout), fd) == NOTOK) {
				adios(EX_IOERR, NULL, "error writing to stdout");
			}
			close(fd);
		}
	}
	context_replace(curfolder, folder);
	if (mp->hghsel != mp->curmsg)
		seq_setcur(mp, mp->lowsel);
	seq_save(mp);
	context_save();
	folder_free(mp);
	return 0;
}
