#ifdef	ournix
#include "ournix.h"
#endif
char sccsID[] =
 "@(#) linesplit.c V1.1 Copyright Julian H. Stacey, Munich, 4-1992\n" ;

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#ifdef	unix
#include <sys/file.h>
#include <sys/types.h>
#else
#include <sys/types.h>
#include <fcntl.h>
#endif
#ifdef	i386	/* { */
#include <sys/fcntl.h>
#endif		/* } */

#ifndef	O_BINARY
#define	O_BINARY	0
#endif
typedef	char	FLAG ;
FLAG	verbose = 0 ;
int	width = 80 ;	/* typically 80, must not be less than 1 */

char	**ARGV ;

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

#ifdef	MSDOS
#define MAXBUF	25000
#else
#define MAXBUF	250000
#endif

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

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

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

void out_c(c)
	char c;
	{
	int	i;
	if (tmp_fd == 0)	
		{
		/* no temporary file yet */
		tmp_fd = open(tmp_name, O_BINARY|O_CREAT|O_TRUNC|O_RDWR, 0200);
		if (tmp_fd < 0)	
			{
			fprintf(stderr,
				"%s: Cannot create temporary file '%s'\n",
				*ARGV, tmp_name);
			exit(3);
			}
		}
	i = out_p - out_buf;
	out_p = out_buf;
	if (write(tmp_fd, out_buf, i) != i)	
		{
		fprintf(stderr, "%s: Write failure on temporary file\n",*ARGV);
		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))
void strip_it(f)
	int	f;
	{
	register int	c;
	register int	col;

	col = 1;
	while((c = IN_C(f)) != EOF )
		{
#ifdef	MSDOS
		if (c == '\r') continue;
#endif
		if ( (col > width) && (c != '\n') )
			{
			OUTC('\n');
			col = 1 ;
			}
		OUTC((char)c);
		if (c == '\n') col = 1;  else col++ ;
		}
	}


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

void fls_tmp()
	{
	int	i, res;

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

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

	if (tmp_fd == 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(tmp_fd, out_buf, MAXBUF)) > 0)
			if (write(f, out_buf, i) != i)	{
				res = -1;
				break;
				}
		}
	if (res < 0)	
		{
		fprintf(stderr, "%s: Write failure on source file\n",*ARGV);
		clean();
		exit(2);
		}
	close(f);
	}

int main(argc, argv)
	char	**argv;
	{
	int	f;
	void	cleanup();
	int	dir = 0;

	ARGV = argv ;
#ifdef	VSL	/* { */
#include	"../../include/vsl.h"
#endif		/* } */
	if (argc < 2)
		{
		fprintf(stderr, "Usage: %s [files]\n",*ARGV);
		exit(1);
		}
	(void) signal(SIGINT, (void *)&cleanup);
	strcpy(tmp_name,TMP_NAME) ;
	(void) mktemp(tmp_name) ;
	for(argv++; *argv ; argv++){
		if (**argv == '-')
			{
			switch((*argv)[1])
				{
				default:
				fprintf(stderr, "%s: Unknown option - ignored\n",
				*ARGV);
				break;
				}
			continue;
			}
		f = open(*argv, O_BINARY|O_RDONLY);
		if (f < 0){
			fprintf(stderr, "%s: Cannot open '%s'\n",*ARGV, *argv);
			continue;
			}
		if (verbose) printf("%s\n", *argv);
		strip_it(f); 
		close(f);
		fls_tmp();
		signal(SIGINT, SIG_IGN);
		f = open(*argv, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, 0200);
		if (f < 0)
			{
			(void) signal(SIGINT, (void *)&cleanup);
			fprintf(stderr, "%s: Cannot recreate '%s'\n",*ARGV, *argv);
			clean();
			continue;
			}
		copyback(f);
		(void) signal(SIGINT, (void *)&cleanup);
		clean();
		}
	exit(0);
	}


