#ifdef	ournix
#include "ournix.h"
#endif
char sccsID[] = "@(#) mailstri.c V0.2 Copyright Julian H. Stacey, Munich, 1988\n" ;
/* strip news of useless headers */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/signal.h>
#include <fcntl.h>
#include <sys/types.h>
#ifdef	unix	/* { */
#include <sys/file.h>
#endif	    	/* } */

char	**ARGV ;
/* strings that are not to be stripped */
char	*nostrip[] = { "From", "Subject", "Date", (char *)0, };

#ifdef scs	/* { */
extern char *mktemp() ;
#define TMP_NAME "nsXXXXXX"
#else		/* }{ */
#include <unistd.h>
#ifdef MSDOS	/* { */
#define TMP_NAME "nsXXXXXX"
#else		/* }{ */
#define TMP_NAME "news_strip.XXXXXX"
#endif		/* } */
#endif		/* } */
#include <sys/param.h>	/* for MAXPATHLEN */
char	tmp_name[MAXPATHLEN] ;		/* temporary file name */

#define MAXBUF	25000

/*
 * output/tmpfile variables
 */
char	out_buf[MAXBUF];
int	tmpf;
char	*out_p = out_buf;

/*
 * input file variables
 */
char	in_buf[MAXBUF];
char	*in_end;
char	*in_p;

void clean()
{
	if(tmpf > 0){
		close(tmpf);
		tmpf = 0;
		unlink(tmp_name);
	}
	out_p = out_buf;
}

void cleanup()
	{
	clean();
	exit(2);
	}

void out_c(c)
{
	int	i;
	if (tmpf == 0){
		/* no temporary file yet */
		tmpf = open(tmp_name, 
#ifdef	MSDOS	/* { */
		O_BINARY|
#endif		/* } */
		O_CREAT|O_TRUNC|O_RDWR, 0200);
		if (tmpf < 0){
			fprintf(stderr, "Cannot create temporary file '%s'\n",
								tmp_name);
			exit(3);
		}
	}
	i = out_p - out_buf;
	out_p = out_buf;
	if (write(tmpf, out_buf, i) != i){
		fprintf(stderr, "Write failure on temporary file\n");
		clean();
		exit(4);
	}
	*out_p++ = c;
}

int in_c(f)
int	f;
{
	int	i;

	i = read(f, in_buf, MAXBUF);
	if (i <= 0)
		return(EOF);
	in_end = in_buf + i;
	in_p = in_buf;
	return(*in_p++);
}

#define IN_C(f) ((in_p < in_end) ? *in_p++ : in_c(f))

#define OUTC(c) ((out_p < &out_buf[MAXBUF] )? *out_p++ = c : out_c(c))

/*
 * actually do the denewsing
 */

void denews(f)
int	f;
{
	register int	c;
	char	lbuf[512];
	register char	*p;
	char	*q, **xp;
	int	fline = 1;

	for(;;){
		for(p = lbuf ; (c = IN_C(f)) != EOF ; *p++ = c)
			if (c == '\n')
				break;
		if (c == EOF) break;
		*p = 0;
		for(p = lbuf ; *p == ' ' || *p == '\t' ; p++);
		/*
		 * blank line, end of header, or not got to header yet
		 */
		if (*p == '\0'){
			if (fline)
				continue;
			OUTC('\n');
			break;
		}
		fline = 0;
		for(q = p ; *q && *q != ':' ; q++);
		if (!*q){
			/* a duff line, no :, ignore line and go onto text */
			for(p = lbuf ; *p ; p++)
#ifdef	MSDOS
				if (*p != '\r')
#endif
				OUTC(*p);
			OUTC('\n');
			break;
		}
		while(q > p && (*(q-1) == ' ' || *(q-1) == '\t'))
			q--;
		if (q == p){	/* line starts with :, ignore, go into text */
			for(p = lbuf ; *p ; p++)
#ifdef	MSDOS
				if (*p != '\r')
#endif
				OUTC(*p);
			OUTC('\n');
			break;
		}
		c = *q;
		*q = '\0';
		for(xp = nostrip ; *xp ; xp++)
			if (strcmp(*xp, p) == 0)
				break;
		if (!*xp)	/* no match - ignore line */
			continue;
		*q = c;
		for(p = lbuf ; *p ; p++)
#ifdef	MSDOS
			if (*p != '\r')
#endif
			OUTC(*p);
		OUTC('\n');
	}
	if (c == EOF)
		return;
	while( (c = IN_C(f)) != EOF)
#ifdef	MSDOS
		if (c != '\r')
#endif
		OUTC(c);
}

void fls_tmp()
{
	int	i, res;

	if(tmpf == 0)
		return;
	i = out_p - out_buf;
	if(i != 0)
		res = write(tmpf, out_buf, i);
	out_p = out_buf;
	if(i != res){
		fprintf(stderr, "Write error on temporary file\n");
		close(tmpf);
		unlink(tmp_name);
		exit(1);
	}
	lseek(tmpf, (off_t)0, 0);	/* go back to beginning */
}

void copyback(f)
int	f;
{
	unsigned i; int res = 1;

	if(tmpf == 0){	/* no temporary file */
		i = out_p - out_buf;
		out_p = out_buf;
		if (i && write(f, out_buf, i) != i)
			res = -1;
	}
	else {
		while((i = read(tmpf, out_buf, MAXBUF)) > 0)
			if (write(f, out_buf, i) != i){
				res = -1;
				break;
			}
	}
	if (res < 0){
		fprintf(stderr, "Write failure on source file\n");
		clean();
		exit(2);
	}
	close(f);
}

void do_file(file)
	char	*file;
	{
	int	f;

	f = open(file, 
#ifdef	MSDOS	/* { */
	O_BINARY |
#endif		/* } */
	O_RDONLY);
	if(f < 0){
		fprintf(stderr, "Cannot open '%s'\n", file);
		return;
	}
	printf("%s\n", file);
	denews(f);
	close(f);
	fls_tmp();
	signal(SIGINT, SIG_IGN);
	f = open(file, 
#ifdef	MSDOS	/* { */
	O_BINARY |
#endif		/* } */
	O_WRONLY|O_CREAT|O_TRUNC, 0200);
	if(f < 0){
		signal(SIGINT, (void *)&cleanup);
		fprintf(stderr, "Cannot recreate '%s'\n", file);
		clean();
		return;
	}
	copyback(f);
	signal(SIGINT, (void *)&cleanup);
	clean();
	}

/*
 * read list of files from stdin
 */

void readstdin()
{
	char	lbuf[100];
	char	*p;
	int	c;

	for(;;){
		for(p = lbuf ; (c = getc(stdin)) != EOF ; *p++ = c)
			if(c == '\n')
				break;
		if(c == EOF)
			return;
		*p = 0;
		do_file(lbuf);
	}
}






int main(argc, argv)
	int	argc ;
	char	**argv;
	{

	ARGV = argv ;
#ifdef	VSL	/* { */
#include	"../../include/vsl.h"
#endif		/* } */

	if (argc < 2){
		fprintf(stderr, "Usage: mailstrip [-] [files]\n");
		exit(1);
	}

	strcpy(tmp_name,TMP_NAME) ;
	signal(SIGINT, (void *)&cleanup);
	(void) mktemp(tmp_name) ;
	if (argc == 2 && strcmp(argv[1], "-") == 0)
		readstdin();
	else for(argv++; *argv ; argv++)
		do_file(*argv);
	exit(0);
}
