#ifdef	ournix
#include "ournix.h"
#endif
char sccsID[] =
 "@(#) mailsplit.c V1.4 Copyright Julian H. Stacey, Munich, 10th April 1991 .\n";
/* Separate manual exists,program & source can be tabbed */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>	// for unlink

typedef char	FLAG;
#define LINE_LN 30000
        /* LINE_LN: maximum scannable length of a text line in a mail,
           I just picked a large number.  30+ years later, dumb
           shits pollute the internet, excreting mega long
           lines of HTML without a \n, so I increased to 30000
                See Also LINE_LN in mailname.c
        */

char	*cut_str = "From ";	/* what will cause a new file (when found
					at the beginning of a file) */
FILE	*fp_out;
char	**ARGV;

#undef		USE_STRCHR
#ifdef	vax	/* { */
#define 	USE_STRCHR
#endif		/* } */
#ifdef	MSDOS	/* { */
#define 	USE_STRCHR
#endif		/* } */
#ifdef	USE_STRCHR	/* { */
	extern	char *strchr();
#define index(s,c)	strchr(s,c)
#define rindex(s,c)	strrchr(s,c)
#else			/* } { */
	extern	char *index();
	extern	char *rindex();
#endif			/* } */
char		*in_name;
char		out_name[LINE_LN];
int	exit_count = 0;
int	rslt;
long	line_no ;
FLAG	over_write_f = 0;
FLAG		verbose_f = 0;
FLAG	pipe_f = 0;
int	file_number ;
// extern long getpid();	// now from unistd.h

#define strnequ(s1,s2,ln)	(0==strncmp(s1,s2,ln))
#define strequ(s1,s2)		(0==strcmp(s1,s2))

	int
get_line(fp,where,max_length)
	FILE	*fp;
	register char *where;
	register int max_length; /* max. size of array including null */
	{
	register int ch;
	char *orig;

	orig = where;
	max_length--; /* allow for \n */
	while (((ch = getc(fp)) != EOF) && ((char)ch != '\n'))
		{ if (--max_length <= 0 )
			{ fprintf(stderr,
		"%s: Warning in %s\t - Line %ld longer than %d.\n",
				*ARGV,in_name,line_no, LINE_LN );
			exit_count++;
			/* Return a line terminated with a '\0',
				with no preceeding '\n' 
			(a very long input line gets split into a number of
			shorter lines, that each have a \n (appended elswhere
			in this program)
			*/
			/* un-necessary: *where = '\0'; */
			ch = '\n' + 1 ;		/* ie not '\n' */
			break;
			}
		*where++ = (char)ch;
		}
	if ((char)ch == '\n') 
		{
		*where++ = '\n';
		line_no++ ;
		}
	*where = '\0';
	return(where - orig);
	}

void syntax(ex)
	int	ex;
	{
	fprintf(stdout,
		"Syntax: %s [-c cut_str] [-r] [-o] [-v] [-?] [-- or files]\n",
		*ARGV);
	exit(ex);
	}

void mk_file()
	{
	struct stat	stat_buf;

	sprintf(out_name,"ms_%ld_%d",(long)getpid(),file_number++);
	if (verbose_f) printf("%s%s%sWriting %s\n",
		(pipe_f) ? "\0" : "Reading ",
		(pipe_f) ? "\0" : in_name,
		(pipe_f) ? "\0" : ", ",
		out_name);
	if (!over_write_f && ( (rslt = stat(out_name,&stat_buf)) == 0))
		{ /* stat has detected a pre existing target file */
		fprintf(stderr,
		"%s: Error: Pre existant %s.\n", *ARGV,out_name);
		exit(++exit_count);
		}
	if ( ( fp_out = fopen(out_name,"w")) == (FILE *)0 )
		{ fprintf(stderr,
			"%s: Error: %s\t- Cannot create to write.\n",
			*ARGV,out_name);
		exit(++exit_count);
		}
	}

int main(argc,argv)
	int	argc;
	char	**argv;
	{
	struct stat	stat_buf;
	char		line_in[LINE_LN];
	char *p;
	FLAG		remove_f = 0;
	int		len ;
	FILE	*fp_in;
	FLAG	extant_f ;		/* 1 if an output file is open */

	fprintf(stderr,"Warning this program cuts too often, see BUGS in manual.\n");

	len = strlen(cut_str) ;

	ARGV = argv;
#ifdef	VSL	/* { */
#include	"../../include/vsl.h"
#endif		/* } */
	for (argc--,argv++; argc > 0; argv++ )
		{ if(**argv != '-') break /* no more parameters */;
		argc--;
		switch(*++*argv)
			{ /* option detect */
			case '-':	/* stdin mode */
				pipe_f = 1;
				break;
			case 'r':	/* zap input file mode */
				remove_f = 1;
				break;
			case 'c':	/* cut string */
				if (!--argc) syntax(1);
				cut_str = *++argv;
				break;
			case 'v':	/* verbose mode */
				verbose_f = 1;
				break;
			case 'o':	/* overwrite ouput files if they exist */
				over_write_f = 1;
				break;
			case '?': syntax(0) ;
				break ;
			default:
				fprintf(stderr,
					"%s: `%c' - Unavailable option.\n",
					*ARGV,**argv);
				syntax(1);
				break ;
			}
		} /* finished taking parameters */

	if (remove_f && pipe_f ) syntax(1);
	if (pipe_f && argc) /* pipe input or file input, not both */ syntax(1);
	if (pipe_f) argc = 1;
	while (argc--)
		{
		line_no = 1L ;
		if (!pipe_f)
			{
			in_name = *argv++;
			if ( ( fp_in = fopen(in_name,"r")) == (FILE *)0 )
				{ fprintf(stderr,
					"%s: Error: %s\t- Cannot read.\n",
					*ARGV,out_name);
				++exit_count;
				continue;
				}
			}
		else	{
			in_name = "<pipe input>" ;
			fp_in = stdin ;
			}
		extant_f = 0 ;
		while ( get_line(fp_in,line_in,LINE_LN) )
			{
			if (strnequ(line_in,cut_str,len))
				{
				if (extant_f) (void) fclose(fp_out);
				extant_f=0 ;
				}
			if (!extant_f)
				{
				mk_file() ;
				extant_f = 1 ;
				}
			fprintf(fp_out,"%s",line_in);
			}
		if ( fp_out != (FILE *)0)
			/* If we've read a zero size file, there's no output,
			    so don't close, otherwise close */ 
			(void) fclose(fp_out);
		(void) fclose(fp_in);
		if (remove_f) (void) unlink(in_name);
		}
	exit(exit_count);
	}
