/*
 * 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.
 */

/*
 * Strip annoying subject prefixes, e.g. Subject: [Exim] foo bar...
 * and append to the specified mailbox, stdout if none given.
 */

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

#include "misc.h"

void usage(void);

int quiet;

int
main(int argc, char *argv[]) {
	char *file, *line, *p;
	int ch, header, done_subj, maildir = 0;
	size_t len;
	FILE *fp;

	quiet = -1;

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

	argv += optind;
	argc -= optind;

	/* If -q or -v not specified, assume -q if stderr is not a terminal */
	if (quiet == -1)
		quiet = !isatty(STDERR_FILENO);

	if (argc > 1) {
		if (quiet)
			exit(EX_TEMPFAIL);
		usage();
	}

	if (argc == 1) {
		/* Open the specified file */
		fp = open_mailbox(argv[0], &file, &maildir);
		if (file == NULL || fp == NULL)
			xerr(1, "open_mailbox %s", argv[0]);
	} else {
		file = NULL;
		fp = stdout;
	}

	/* initial state */
	header = 1;
	done_subj = 0;

	/* Read input from stdin... */
	while ((line = gl_getline(stdin)) != NULL) {
		len = strlen(line);
		chop(line, len);

		/* Blank line denoting end of headers, just print it */
		if (len == 0) {
			header = 0;
			xfprintf(fp, "\n");
			continue;
		}

		/* Check for From_ line in body. */
		if (!header && is_from(line, 0)) {
			xfprintf(fp, ">%s\n", line);
			continue;
		}

		/*
		 * It's either not the header, it's still the header
		 * but we've already done the Subject: and therefore don't
		 * need to look any further, or we still need to do the
		 * Subject: header but this isn't it.
		 */
		if (!header || done_subj ||
		  strncasecmp(line, "Subject:", 8) != 0) {
			xfprintf(fp, "%s\n", line);
			continue;
		}

		done_subj = 1;

		/* Skip past Subject: and space */
		line += 8;
		len -= 8;
		while (isspace(*line))
			line++, len--;
		xfprintf(fp, "Subject: ");

		/* See if the line starts with a bracket */
		if (*line != '[') {
			/*
			 * No? maybe there's one just after "Re:" or
			 * some foreign equivalent sent by some broken
			 * mail program.
			 */
			char *res[] = { "Re", "Sv", NULL };
			char **re;
			int relen;

			for (re = res, relen = 0; *re != NULL; re++) {
				relen = strlen(*re);
				if (relen > len)
					continue;
				if (strncasecmp(line, *re, relen) == 0 &&
				    line[relen] == ':')
					break;
			}

			if (*re == NULL) {
				/* No Re:, no tag. */
				xfprintf(fp, "%s\n", line);
				continue;
			}

			/* Skip over Re: and space */
			line += relen + 1;
			len -= relen + 1;
			while (isspace(*line))
				line++, len--;
			xfprintf(fp, "%s: ", *re);

			/* maybe there's a bracket now */
			if (*line != '[') {
				/*
				 * Still no bracket, so there's no
				 * tag here. Print and process the
				 * next line.
				 */
				xfprintf(fp, "%s\n", line);
				continue;
			}
		}

		/* Point `p' after the bracket. */
		p = line + 1;
		for (;;) {
			if (*p == ']') {
				/* Found end of tag, print rest of line */
				p++;
				while (isspace(*p))
					p++;
				xfprintf(fp, "%s\n", p);
				break;
			}
			if (isspace(*p) || *p == '\0') {
				/* Found space or \0, so not really a tag */
				xfprintf(fp, "%s\n", line);
				break;
			}
			p++;
		}
	}

	gl_destroy(stdin);

	if (fclose(fp) != 0)
		xerr(1, "fclose");

	if (file != NULL)
		mailboxlock(file, maildir, -1, LF_REL);

	return (0);
}

void
usage(void) {
	fprintf(stderr, "usage: strip-prefix [-qv] [file]\n");
	exit(EX_USAGE);
}


syntax highlighted by Code2HTML, v. 0.9.1