#ifdef	ournix
#include "ournix.h"
#endif
char sccsID[] =
 "@(#) 8fr.c V3.1 Copyright Julian H. Stacey, Munich, 1996-03-01 & 2011\n";
/*
WARNING This Prog is starting to be rewritten/converted, 
 It is NOT ready for use.
It derives from my 8f.
*/

#include <stdio.h>
#include <stdlib.h>

/* Searches for strings such as		ÿÿÿÿÿÿÿÿ
   produced by a [faulty cache chip?] in a bad scsi disc controller */

typedef	char	FLAG ;
FLAG no_lines	= 0 ;	/* 1 = dont print each matching line */
FLAG no_files	= 0 ;	/* 1 = dont print each matching file name */
FLAG no_count	= 0 ;	/* 1 = dont print count of matching blocks per file */
int exit_code	= 0 ;
int length	= 8 ;
			/* Looking for how many bytes
			 * adjacent (8 for 1542A Adaptec 2nd
			 * drive in 1996, 2048 for bad
			 * .avi from DVD in 2011 )
			 */
unsigned value = 0xFF ;
			/* Looking for what value of bytes
			 * ( 0xFF for 1542A Adaptec 2nd drive in 1996,
			 * 0x00 for bad .avi from DVD in 2011 )
			 */
char	**ARGV ;

	void
syntax()
	{
	fprintf(stderr,
 "Syntax Error: %s [-p] [-n number_of_bytes] [-b byte_value] [-c] [files]\n",
		*ARGV,*ARGV);
	exit(-1) ;
	}

/* Scan for sequences of length 0xFFs within each line of a file,
	remember there might be more than one sequence within a line. */
	int
do_file(fp,name)
	register FILE	*fp ;
	char	*name ;
	{
	register int	this_ch ;
	long	line_count = 1 ;
	long	block_count = 0 ;
	unsigned char_count = 0 ; /* number of character within the line,
					where the string of 0xFFs starts */
	long byte_count = 0 ;
	int	i ;

	while((this_ch = getc(fp)) != EOF)
		{
		/* Fetching one character at a time is inefficient,
		 * but I didnt know if these sequences of burts of
		 * error extended across block boundaries. though
		 * of course I suspected they would not.
		 */
		char_count++ ;
		byte_count++ ;
		if ( this_ch == value )
			{
			for ( i = length - 1 ;
				i-- &&
				byte_count++ &&
				((this_ch = getc(fp)) == value) ;
				) ;
			if ( i <= 0 )
				{
				if (!no_lines)
					{
					byte_count -= length ;
					if (name != (char *)0)
						printf("%s: ", name ) ;
					printf(
		"ByteInFile: %ld 0x%lx 0%lo; Line:%ld, CharInLine: %u\n",
						byte_count, byte_count,
						byte_count,
						line_count, char_count) ;
					byte_count += length ;
					}
				char_count += length ;
				block_count++ ;
				}
			}
		else if ( this_ch == '\n' ) { line_count++ ; char_count = 0 ; }
		}
	(void) fflush(stdout) ;
	if ( block_count )
		{
		if ( !no_files )
			printf("%s\n", ( name == (char *) 0 ? "Pipe" : name ) );
		if ( !no_count )
			printf("%s\t%ld\n",
				( name == (char *) 0 ? "Pipe" : name ),
				block_count ) ;
		}
	return( block_count ? 1 : 0);
	}

	int
main(argc, argv)
	int	argc ;
	char	**argv ;
	{
	FILE	*fp ;
	char	*p ;
	char	*name ;
	int	rslt ;

	ARGV = argv ;

#ifdef	VSL	/* { */
#include	"../../include/vsl.h"
#endif		/* } */

	for (argc--, argv++ ; argc ; argv++, argc--)
		{
		if (**argv != '-') break ;
		p = *argv + 1 ;
		while(*p) switch(*p++)
			{
			case 'l': /* Turn off print of each matching line */
				no_lines = 1 ;
				break ;
			case 'f': /* Turn off print of each matching file */
				no_files = 1 ;
				break ;
			case 'n': /* Number of adjacent identical bytes */
				length = atoi(*++argv) ;
				argc-- ;
				break ;
			case 'b': /* Value of adjacent identical bytes */
				rslt = sscanf(*++argv, "%x", &value) ;
				if ((rslt != 1 ) || ( value > 255 )) syntax() ;
				// printf("value is %d\n",value);
				argc-- ;
				break ;
			case 'c': /* Turn off print count of matching blocks */
				no_count = 1 ;
				break ;
			default:
				fprintf(stderr, "Unknown flag %c\n", *(p-1)) ;
				syntax() ;
				break ;
			}
		}

	// printf("debug2 %d %s\n", argc, *argv );

	/* like grep, could print name only if >= 2 files */
	// if (argc <= 2 ) no_files = 1 ;

	if (argc == 0) exit(do_file(stdin,(char *)0)) ;
	else do {
		name = *argv++ ;
		fp = fopen(name, "r") ;
		if (fp == (FILE *)0)
			{
			fprintf(stderr, "Cannot open '%s'\n",name) ;
			exit_code += 1 ;
			continue ;
			}
		exit_code += do_file(fp, name ) ;
		(void) fclose(fp) ;
		} while (--argc) ;
	exit(exit_code) ;
	}
