/*
 * Copyright 1999-2002 Ben Smithurst <ben@smithurst.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * Append to a mailbox, using correct locking.
 */

static const char rcsid[] =
	"$BCPS: src/mailutils/mail-append.c,v 1.23 2003/01/19 19:18:25 ben Exp $";

#include "misc.h"

void usage(void);
void lock_append(FILE *);
void mail_append(FILE *);

static int mailmode;

int
main(int argc, char *argv[]) {
	int ch, quiet, maildir;
	char *file;
	FILE *out_fp;

	quiet = 0;

	/* don't treat as a mail file if not called as "mail-append". */
	mailmode = (strstr(argv[0], "mail") != NULL);

	while ((ch = getopt(argc, argv, "q")) != -1)
		switch (ch) {
		case 'q':
			quiet = 1;
			break;
		default:
			usage();
		}

	argv += optind;
	argc -= optind;

	if (argc != 1) {
		if (quiet)
			exit(EX_USAGE);
		usage();
	}

	out_fp = open_mailbox(argv[0], &file, &maildir);
	if (out_fp == NULL)
		err(1, "open_mailbox %s", argv[0]);

	if (mailmode)
		mail_append(out_fp);
	else
		lock_append(out_fp);

	if (fclose(out_fp) != 0)
		err(1, "fclose");

	mailboxlock(file, maildir, -1, LF_REL);

	return (EXIT_SUCCESS);
}

void
mail_append(FILE *out_fp) {
	int hdr;
	char *line;
	size_t len;

	hdr = 1;
	while ((line = gl_getline(stdin)) != NULL) {
		len = strlen(line);
		if (!hdr && len >= 5 && is_from(line, 0)) {
			if (fputc('>', out_fp) == EOF)
				err(1, "fputc");
		}

		if (fwrite(line, 1, len, out_fp) != len)
			err(1, "fwrite");

		assertnl(line, len);

		/* Detect end of headers */
		if (len == 0) {
			hdr = 0;
			continue;
		}
	}

	gl_destroy(stdin);

	if (ferror(stdin))
		err(1, "stdin");
}

void
lock_append(FILE *out_fp) {
	char buf[8192];
	size_t b;

	while ((b = fread(buf, 1, sizeof buf, stdin)) > 0)
		if (fwrite(buf, 1, b, out_fp) != b)
			err(1, "fwrite");

	if (ferror(stdin))
		err(1, "stdin");
}

void
usage(void) {
	fprintf(stderr, "usage: %s-append [-q] file\n",
	  mailmode ? "mail" : "lock");
	exit(EX_USAGE);
}


syntax highlighted by Code2HTML, v. 0.9.1