unfinished improvement started in england
#ifndef	LINT
char lib_replace[] =
	"@(#) lib/replace.c V1.0 Copyright Julian H. Stacey 89-10-04\n" ;
#endif
/* Symmetric implements char as signed char,
	hence the use of unsigned chars in some places,
	else a byte in a file such as 0xFF gets erroneously treated as EOF */

/* only valid way to use this file is by calling replace(),
	which does al necessary initialisations for you */
/* ----------------------------------------------------------------------- */
#include	<stdio.h>
#include	<sys/types.h>
#include	<sys/stat.h>
#ifdef ns32000	/* { */
#define BSD
#endif		/* } */
#ifdef	BSD
#include	<sys/file.h>
#include	<sys/signal.h>
#else
#include	<signal.h>
#endif
#ifndef	BSD	/* { */
#include	<fcntl.h>
#endif		/* } */
#include	"ms_exe.h"
/* ----------------------------------------------------------------------- */
typedef	int		FD ;
#define	FD_UNSET	-1
typedef	char		FLAG ;
#ifdef	MSDOS	/* { */
	typedef int	CKSUM ;
#endif		/* } */
#ifdef	ns32000	/* { */
	typedef	short	CKSUM ;
#endif		/* } */
/* ----------------------------------------------------------------------- */
#ifdef	MSDOS
#define MAXBUF	20000
			/* if MAXBUF = 30000, MSC compiler generating for
			small model produces a binary
			that complains not enough room for environment */
#else
#define MAXBUF	50000
#endif
/* ----------------------------------------------------------------------- */
extern	char **ARGV ;
extern	char *strcpy() ;
/* ----------------------------------------------------------------------- */
/* output/tmpfile variables	*/
static unsigned char	gbl_out_buf[MAXBUF] ;
static unsigned char	*gbl_out_buf_p ;	/* where to write next char */

/* input file variables	*/
static unsigned char	gbl_in_buf[MAXBUF] ;
static unsigned char	*gbl_in_buf_next_p ;
static unsigned char	*gbl_in_buf_end_p ;
					/* address of byte beyond buffer */
/* ----------------------------------------------------------------------- */
/* MSDOS .EXE Checksum to be written back:
					I dont know how msdos works out
					checksum, so i subtract
					each input word from the original
					checksum, and add each output word back
					to the original checksum */
static CKSUM	gbl_orig_cksum ;	/* checksum msdos file originally
					contains calculated by msdos linker */
static CKSUM	gbl_input_data_cksum ;	/*sum of words input from data segment*/
static CKSUM	gbl_output_data_cksum ;	/*sum of words output to data segment */
static CKSUM	gbl_input_tmp_cksum ;	/* byte/word buffering on input */
static CKSUM	gbl_output_tmp_cksum ;	/* byte/word buffering on output */
/* ----------------------------------------------------------------------- */
/* temporary file	*/
#ifdef	MSDOS	/* { */
#define	TMP_NAME	"/reXXXXXX.tmp"		/* put temp file in ram root */
#else		/* } { */
#define	TMP_NAME	"/tmp/replace.XXXXXX"	/* unix - dont try root */
#endif		/* } */
static	char	gbl_tmp_name[sizeof(TMP_NAME)+1] ;
/* ----------------------------------------------------------------------- */
static	long	gbl_in_count ;	/* read seek counter from start of file, used
					for checksum calculation, and 
					will be used to obviate
					redundant reads writes combinations */
static	long	gbl_out_count ; /* write seek counter from start of file, used
					for checksum calculation, and 
					will be used to obviate
					redundant writes combinations */
static	FD	gbl_tmp_fd ;
static	FD	gbl_orig_fd ;
static	FLAG	gbl_cksum_f ;
static	FLAG	gbl_binary_f ;
static	char	gbl_txt_nowrite[] =	"Write error on %s file.\n" ;
static	char	gbl_txt_temp[] =	"temporary" ;
/* ----------------------------------------------------------------------- */
static sick(str)
	char	*str ;
	{
	fprintf(stderr,"%s: failed %s, aborting.\n",*ARGV,str) ;
	perror(*ARGV) ;
	exit(1) ;
	}

/* 8 & 16 bit arithmetic simulator for larger machines */
#ifdef MSDOS	/* { was msdos , worked ok */
#define s_add(int_a,int_b,width) (int_a + int_b)
#else		/* } { */
	static int
s_add(int_a,int_b,bits)	/* signed 8 or 16 bit addition */
	int int_a, int_b ;	/* must not be passed values outside the scope
					of signed 8/16 bit values,
					but does not matter if compiler
					implements them as longs */
	int	bits ;
	{
	long				/* some hosts may treat ints as 8/16,
						& longs as 32, so stay safe
						with longs */
		long_a, long_b, tmp, max, min ;

	max = (( 1L << (bits - 1)) - 1L ) ;	/* ex 4 bit system 2^3-1 = 7 */
	min = (-( 1L << (bits - 1)) ) ;		/* ex 4 bit system -2^3 = -8 */
	long_a = int_a ;
	long_b = int_b ;
	tmp = long_a + long_b ;
	/* to understand the next bit, draw a circle with +7 down to 0 and
		further round to -8 marked on it */
	if ( tmp > max ) tmp -= (1L << bits) ; /* ex: 14 > 7 +14 - +16 = -2 */
	else if ( tmp < min ) tmp += (1L << bits) ; /* ex: -10 < -8+16+-10=+6 */
	return(tmp) ;
	}
#endif	/* } */
/* ----------------------------------------------------------------------- */
	static
clean_from_sig()
	{
	fprintf(stderr,"%s: Aborted on interrupt.\n",*ARGV);
	/* will a file be lost ? JJ */
	my_unlink() ;
	exit(1) ;
	}
/* ----------------------------------------------------------------------- */
	static int
in_c()
	{
	int	amount ;

	amount = read( gbl_orig_fd,  (char *)gbl_in_buf, (int)MAXBUF ) ;
	if ( amount <= 0 ) return( EOF ) ;
	gbl_in_buf_next_p = gbl_in_buf ;
	gbl_in_buf_end_p = gbl_in_buf + amount ;
	return( (int)*gbl_in_buf_next_p++ ) ;
	}
#define my_getchar()	(( gbl_in_buf_next_p < gbl_in_buf_end_p ) ? \
				(int)*gbl_in_buf_next_p++ : in_c())
/* ----------------------------------------------------------------------- */
#define my_putchar(c) 	{ *gbl_out_buf_p++ = c ; if (gbl_out_buf_p >= \
				&gbl_out_buf[MAXBUF-1] ) my_flush() ; }
	static
my_flush()
	{
	int	amount ;
	/* create temporary file */
	if (gbl_tmp_fd < 0 )
		{
		/* Open temp file if necessary - if buffer is big enough,
			temp file creation is never done, (thats why its
			done here, and not earlier) */
		if ( ( gbl_tmp_fd = open( gbl_tmp_name,
#ifdef	MSDOS	/* { */
				O_BINARY |
#endif	/* } */
				O_CREAT | O_TRUNC | O_RDWR, 0200 ) ) < 0 )
			{
			fprintf( stderr, "%s: Cannot create %s file '%s'\n",
						*ARGV,
						gbl_txt_temp, gbl_tmp_name ) ;
			fprintf(stderr,"Aborting.\n") ;
			exit(1) ;
			}
		}
	amount = gbl_out_buf_p - gbl_out_buf ;
	if ( write( gbl_tmp_fd, (char *)gbl_out_buf, amount ) != amount )
		{
		fprintf( stderr, gbl_txt_nowrite, gbl_txt_temp ) ;
		my_unlink() ;
		fprintf(stderr,"Aborting.\n") ;
		exit(1) ;
		}
	gbl_out_buf_p = gbl_out_buf ;
	}
/* ----------------------------------------------------------------------- */
	static int
getc_via_cksum()
	{
	int	byte ;

	byte = my_getchar() ;
	if (gbl_cksum_f)
		{ /* memorise msdos checksum in passing */
		if ((gbl_in_count % 2) == 0)	/* first (=high) byte of word */
			gbl_input_tmp_cksum = 0xFF00 & (byte << 8 ) ;
		else	{ /* trailing low byte */
			gbl_input_tmp_cksum |= 0xFF & byte ;
			if (gbl_in_count > MS_EXE_OVERLAY_LO)
				gbl_input_data_cksum =
					s_add(gbl_input_data_cksum,
						gbl_input_tmp_cksum,16) ;
			else if (gbl_in_count == MS_CKSUM_LO)
				gbl_orig_cksum = -gbl_input_tmp_cksum ;
			}
		}
	if (gbl_binary_f) gbl_in_count++ ;
	return(byte) ;
	}

	static
putchar_via_cksum(byte)
	char	byte ;
	{
	my_putchar(byte) ;
	if (gbl_cksum_f)
		{
		if (gbl_out_count > MS_EXE_OVERLAY_LO)
			{
			/* add data from checksum */
			if (gbl_out_count % 2)
				gbl_output_tmp_cksum = 0xFF00 & (byte << 8 ) ;
			else	{
				gbl_output_tmp_cksum |= 0xFF & byte ;
				gbl_output_data_cksum =
					s_add(gbl_output_data_cksum,
						gbl_output_tmp_cksum, 16) ;
				}
			}
		gbl_out_count++ ;
		}
	}
/* ----------------------------------------------------------------------- */
	static
my_unlink()
	{
	if ( gbl_tmp_fd >= 0)
		{
		(void) signal(SIGINT,SIG_IGN) ;
		if (close(gbl_tmp_fd)) sick("close");
		if (unlink( gbl_tmp_name ) < 0 ) sick("unlink") ;
		gbl_tmp_fd = FD_UNSET ;
		(void) signal(SIGINT,SIG_DFL) ;
		}
	}
	static 
name_off_screen(name)
	char	*name ;
	{
	int	i, j ;

	i = strlen( name) ;
	for ( j = i ; j-- ; ) (void)putchar( '\b') ;
	for ( j = i ; j-- ; ) (void)putchar( ' ') ;
	for ( j = i ; j-- ; ) (void)putchar( '\b') ;
	}
/* ----------------------------------------------------------------------- */
	static
buf_flush(P_buf_p, P_buf_count_u, P_remove_u, P_replace_u, P_found_u,
	P_occur_max_i, P_fill_c, P_binary_f, P_replace_p )
/* Flushes initial portion, then pad portion, then extension portion.
   Code outside this routine must copy every byte received into P_buf_p
	+-----------------------------------------------+
   In:	| REMOVE_______________________ | EXTENSION____	|
	+-----------------------------------------------+
   Out:	| REPLACE______________	| PAD__	| EXTENSION____	|
	+-----------------------------------------------+	*/
	char		*P_buf_p ;	
	unsigned	P_buf_count_u ;
	unsigned	P_remove_u ;		
	unsigned	P_replace_u;		
	unsigned	P_found_u ;
	int		P_occur_max_i ;
	char		P_fill_c ;
	FLAG		P_binary_f ;
	char		*P_replace_p ;
	{
	unsigned	L_out_u ;
	char 		*L_out_p ;
	FLAG		L_do_swap_f ;
#ifdef	DEBUG	/* { */
	printf("%s %s%d %s%d %s%d %s%d %s%d %s%c %s%c %s%s\n",
		"debug buf_flush: ",
		"|P_buf_count_u:",	P_buf_count_u,
		"|P_remove_u:",		P_remove_u,
		"|P_replace_u:",	P_replace_u,
		"|P_found_u:",		P_found_u,
		"|P_occur_max_i:",	P_occur_max_i,
		"|P_fill_c:",		P_fill_c,
		"|P_binary_f:",		P_binary_f + '0',
		"|P_replace_p:",	P_replace_p ) ;
#endif		/* } */

	if (P_buf_count_u == 0) return ;	/* erroneous call */
	/* flush initial portion (same length as replace in diagram above) */
	if (L_do_swap_f = ((P_buf_count_u >= P_remove_u) && 
		!((P_found_u > P_occur_max_i) && (P_occur_max_i != -1))	) )
		{	/* do a replacement */
		L_out_p = P_replace_p ;
		L_out_u = P_replace_u ;
		}
	else	{	/* only partial match, flush input stream */
		L_out_p = P_buf_p ;
		L_out_u = P_buf_count_u ;
		}
	while(L_out_u--) putchar_via_cksum(*L_out_p++) ;

	if (P_buf_count_u <= P_replace_u) return ;

	/* flush padding portion */
	L_out_p = P_buf_p + P_replace_u ;
	L_out_u = (P_buf_count_u > P_remove_u) ? 
		P_remove_u - P_replace_u : P_buf_count_u - P_replace_u ;
	while(L_out_u--)
		{
		if (P_binary_f)
			putchar_via_cksum((L_do_swap_f) ?
				P_fill_c : *L_out_p++);
		else	{
			if (!L_do_swap_f) /* discard */ L_out_p++ ;
			else putchar_via_cksum(*L_out_p++) ;
			}
		}
	if (P_buf_count_u <= P_remove_u) return ;

	/* flush extension portion */
	L_out_u = P_buf_count_u - P_remove_u ;
	while(L_out_u--) 
		putchar_via_cksum((L_do_swap_f) ? P_fill_c : *L_out_p++);
	}

/* ----------------------------------------------------------------------- */
/* Replace strings in a file, returns 0 if dont care how many occurences done,
   else returns (number requested - number replaced); exit(1) on any error */
	int
replace(P_name_p, P_remove_p, P_replace_p, P_extra_u, P_fill_c,
		P_occur_max_i, P_exact_f, P_binary_f, P_cksum_f, P_verbose_f )
	char		*P_name_p ;	/* file name */
	char		*P_remove_p ;	/* string to be removed */
	char		*P_replace_p ; 	/* string to be added */
	unsigned	P_extra_u ;	/* up to so many trailing extra chars
					possibly occuring, to be removed
					or converted to fill chars */
	char		P_fill_c ;	/* fill/pad character */
	int		P_occur_max_i ;	/* occurences:
						-1 == any no, 0==none 1==1 */
	FLAG 		P_exact_f ;	/* err exit if P_occur_max_i != no of
						occurences detected */
	FLAG		P_binary_f ;	/* 0==text, 1 == binary */
 	FLAG		P_cksum_f ;	/* 0==no ms_checksums, else 1 */
	FLAG 		P_verbose_f ;	/* announce file name */
	{
	extern	char *mktemp() ;
	extern	char *malloc() ;
	extern	syntax() ;

	unsigned L_remove_u, L_replace_u ;
	int	L_length_i	;
	FLAG	L_write_fail_f = 0 ;
	unsigned L_found_u = 0 ;
	int	L_byte_i ;		/* current byte from input file */
	char	*L_scan_p ;		/* general purpose I/O pointer */
	unsigned L_buf_count_u ;		/* input count (increments on a
						character basis till a full
						match is detected) */
	unsigned L_max_u ;
	CKSUM	L_new_cksum ;
	char	L_cksum_buf[2] ;
	char	*L_in_buf_p, *L_in_buf_base_p ;
	/* ------------------------------------------------------------------ */
#ifdef	DEBUG	/* { */
	printf("%s%s%s\n%s%s%s%s\n%s%u%s%c%s%d\n%s%c%s%c%s%c%s%c\n",
		"debug replace ",
		"|P_name_p:", P_name_p,
		"|P_remove_p:", P_remove_p,
		"|P_replace_p:", P_replace_p,
		"|P_extra_u:", P_extra_u,
		"|P_fill_c:", P_fill_c,
		"|P_occur_max_i:", P_occur_max_i,
		"|P_exact_f:", P_exact_f + '0',
		"|P_binary_f:", P_binary_f + '0',
		"|P_cksum_f:", P_cksum_f + '0',
		"|P_verbose_f:", P_verbose_f + '0') ;
#endif		/* } */
	gbl_cksum_f = P_cksum_f ;	/* export for other procedures */
	gbl_binary_f = P_binary_f ;	/* export for other procedures */

	/* check parameters */
	if (	( P_name_p == (char *)0 ) || ( *P_name_p == '\0' ) ||
		( P_remove_p == (char *)0 ) || ( *P_remove_p == '\0' )
		)	{ syntax() ; sick("parameters"); }
	if ( P_replace_p == (char *)0) P_replace_p = "\0" ;
	if ( P_occur_max_i < -1) sick("occurence count") ;
	if ((P_occur_max_i == -1) && P_exact_f)	{ syntax() ; exit(1) ; }
	L_remove_u = strlen( (char *)P_remove_p ) ;
	L_replace_u = strlen( (char *)P_replace_p ) ;
	/* check for replacement string too long */
	if ( ( L_replace_u > L_remove_u ) && P_binary_f )
		{
		*(P_replace_p + L_remove_u ) = '\0' ;
		fprintf( stderr,
	"%s: Warning: %s is binary, so replacement string truncated to %s\n",
			*ARGV, P_name_p, P_replace_p ) ;
		L_replace_u = L_remove_u ;
		}
	if (P_cksum_f && !P_binary_f) { syntax() ; exit(1) ; }
	/* determine number of pad characters to append after replacement
		string to remove tail of old string */
	L_max_u = L_remove_u + P_extra_u ;
	/* ------------------------------------------------------------------ */
	/* PREPARE TEMPORARY FILE AND POINTERS */
	if ( (gbl_orig_fd = open(P_name_p,
#ifdef	MSDOS	/* { */
			O_BINARY |
#endif	/* } */
			( (!P_binary_f) ? O_RDONLY :
			O_RDWR /* fixed size so lseek will be sufficient
				later */
			) ) ) < 0 )
		{
		fprintf( stderr, "%s: Cannot open %s\n", *ARGV, P_name_p);
		return(-10000) ;
		}
	/* copy (and change) data from P_name_p to gbl_tmp_name (or buffer) */
	if (P_verbose_f) { printf( "%s", P_name_p ) ; (void)fflush( stdout) ; }
	/* orig_to_tmp */
	gbl_tmp_fd = FD_UNSET ;	/* unset, may not need to be created */
	/* mktemp manual says the caller gets changed from XXXXXX,
		we call it once for each file, so use of strcpy protects
		original XXXXXX for subsequent invocations. */
	(void) strcpy(gbl_tmp_name,TMP_NAME);
	(void) mktemp(gbl_tmp_name) ;
	/* initialise buffers */
	gbl_in_buf_next_p = gbl_in_buf ;
	gbl_in_buf_end_p = gbl_in_buf ;
	gbl_out_buf_p = gbl_out_buf ;
	if ((L_in_buf_base_p = malloc(L_max_u)) == (char *)0)
		{
		fprintf(stderr,"%s: Couldnt allocate space pad memory\n",
			*ARGV ) ;
		perror(*ARGV) ;
		exit(1) ;
		}
	if (gbl_cksum_f)
		{
		gbl_input_data_cksum = gbl_output_data_cksum = (CKSUM)0 ;
		gbl_in_count = gbl_out_count = 0L ;
		}
	/* ------------------------------------------------------------------ */
	/* START SCANNING INPUT - this section within these brackets can
		conceptually be read seperately as a smaller unit than the total
		procedure, in order to aid comprehension.	*/
	{
#define	INIT_BUF	{				\
			L_buf_count_u = 0 ;		\
			L_scan_p = P_remove_p ;		\
			L_in_buf_p = L_in_buf_base_p ;	\
			}
	INIT_BUF
	if (signal( SIGINT, clean_from_sig) < 0 ) sick("signal") ;
	while(1){
		if ( (L_byte_i = getc_via_cksum() ) == EOF)
			{
#define	BUF_FLUSH	buf_flush(L_in_buf_base_p,L_buf_count_u, L_remove_u, \
				L_replace_u, L_found_u, P_occur_max_i,	\
				P_fill_c, P_binary_f, P_replace_p )
			BUF_FLUSH ;
			break ;
			}
		L_byte_i &= 0xFF ;
		if ( gbl_cksum_f && (gbl_in_count <= (MS_EXE_OVERLAY_LO + 1)))
			{
			putchar_via_cksum((char)L_byte_i) ;
			continue ;
			}
		/* Cant do a a putchar if already detected enough occurences,
			because we want to scan input stream to detect an 
			unexpectedly high number of input occurences */
		*L_in_buf_p++ = L_byte_i ;
		if ((++L_buf_count_u > L_remove_u) || (*L_scan_p++ == L_byte_i))
				/* access *L_scan_p after detect_f to avoid
				incrementing when not needed (MMU might
				interrupt if we go over end) */
			{ /* possible partial, full, or extended match,
				(including full or extended match not to be
				changed but merely noted) */
			if (L_buf_count_u == L_remove_u)
				{ /* matching string in 'P_name_p' and
					'P_remove_p' */
				if ((++L_found_u > P_occur_max_i) && P_exact_f)
					{
					fprintf(stderr,
				"%s: Error %d occurences in %s, Aborting.\n",
						*ARGV, L_found_u, P_name_p ) ;
					my_unlink() ;
					exit(1) ;
					}
				}
			if (L_buf_count_u == L_max_u) 
				{
				BUF_FLUSH ;
				INIT_BUF
				}
			}
		else	{	/* no recognisable match, flush 
				Note if single char in input buffer, we avoid
				calling flush with its time consuming 9 
				parameters for each byte in the file!	*/
			if (L_buf_count_u == 1) 
				putchar_via_cksum((char)L_byte_i) ; 
				else BUF_FLUSH ;
			INIT_BUF
			}
		}
	(void) free(L_in_buf_base_p) ;
	}
	/* ------------------------------------------------------------------ */

	/* look for odd bytes at end (not belonging to an input word) */
	if (gbl_cksum_f && (--gbl_in_count > MS_EXE_OVERLAY_LO) &&
						((gbl_in_count % 2) == 0))
		/* lone high byte in data segment */
		gbl_input_data_cksum = s_add(gbl_input_data_cksum,
						gbl_input_tmp_cksum ,16);
	if ((P_occur_max_i != -1) && (P_occur_max_i != L_found_u))
		fprintf(stderr,
			"%s: Warning: in %s, %d requested, %d detected.\n",
			*ARGV, P_name_p, P_occur_max_i, (int)L_found_u ) ;
	/* ------------------------------------------------------------------ */
	/* RE OPEN ORIGINAL PRIOR TO RETURNING DATA */
	if (signal( SIGINT, SIG_IGN) < 0) sick("signal") ;
	if ((P_binary_f) && (lseek( gbl_orig_fd, (off_t)0, 0 ) < 0) )
		sick("lseek") ;
	else	{
		if (close(gbl_orig_fd)) sick("close") ;
		/* if in text mode we may want to shorten the file,
			so gbl_orig_fd can not be opened just once as
			read+write, as read & writes wont shorten file,
			spare bytes will hang around unchanged at end of file */
		if ((gbl_orig_fd = open( P_name_p,
#ifdef	MSDOS	/* { */
			O_BINARY |
#endif	/* } */
			O_WRONLY | O_CREAT | O_TRUNC, 0200 ) ) < 0 )
			{
			fprintf( stderr, "%s: Cannot recreate '%s' %s %s.\n",
				*ARGV, P_name_p,
				",data lost (unless file was",
				"previously write protected), aborting.\n"
				) ;
			my_unlink() ;
			exit(1) ;
			}
		}
	/* ------------------------------------------------------------------ */
	/* WRITE DATA TO ORIGINAL FILE */
	if (gbl_tmp_fd >= 0)
		{
		if (lseek( gbl_tmp_fd, (off_t)0, 0 ) < 0) sick("lseek") ;
		/* go back to beginning */
		while ( ( L_length_i = read( gbl_tmp_fd, (char *) gbl_in_buf,
			(int)MAXBUF ) ) > 0 )
			if ( write( gbl_orig_fd, (char *)gbl_in_buf,
				L_length_i ) != L_length_i )
				{
				L_write_fail_f = 1 ;
				break ;
				}
		(void) close(gbl_tmp_fd) ;
		}
	/* remaining buffer */
	L_length_i = gbl_out_buf_p - gbl_out_buf ;
	if ( L_length_i && (write( gbl_orig_fd, (char *)gbl_out_buf, 
		L_length_i ) != L_length_i )) L_write_fail_f = 1;
	if ( L_write_fail_f )
		{
		fprintf( stderr, gbl_txt_nowrite, "source" ) ;
		fprintf( stderr, "Aborting.\n" ) ;
		my_unlink() ;
		exit(1) ;
		}
	/* ------------------------------------------------------------------ */
	/* OVERLAY NEW MSDOS .EXE CHECKSUM */
	if (gbl_cksum_f)
		{
		if ((--gbl_out_count > MS_EXE_OVERLAY_LO) &&
			((gbl_out_count % 2) == 0))
			/* lone high byte with no matching low byte */
			gbl_output_data_cksum = s_add(gbl_output_data_cksum,
				gbl_output_tmp_cksum, 16) ;
#ifdef	MSDOS	/* { */
#define	L_SET	0
#endif		/* } */
		if ( (lseek(gbl_orig_fd,(off_t)MS_CKSUM_HI,L_SET) ) < 0 )
			sick("lseek");
		L_new_cksum = gbl_orig_cksum ;
		L_new_cksum = s_add(L_new_cksum, -gbl_input_data_cksum, 16);
		L_new_cksum = s_add(L_new_cksum, gbl_output_data_cksum, 16);
		L_new_cksum = -L_new_cksum ;
		L_cksum_buf[0] = ( L_new_cksum & 0xFF00 ) >> 8 ;
		L_cksum_buf[1] = L_new_cksum & 0xFF ;
		if (write(gbl_orig_fd,(char *)L_cksum_buf,2) != 2 )
			sick("write");
		}
	if (close(gbl_orig_fd)) sick("close") ;
	my_unlink() ;
	if (P_verbose_f) name_off_screen(P_name_p) ;
	return( (P_exact_f) ? (P_occur_max_i - L_found_u) : 0) ;
	}
