/* A C Module of Miscellaneous Functions of General Utility.
 *
 * Containing:
 *	void filaray( c, a, sz )
 *	void xnl( a )
 *	int addnl( a, sz )
 *	int nl1( a, sz )
 *	int chrcnt( c, a )
 *	void until_lf()
 *	int flc( f )
 *	int nlnf( ar, sz, n, f )
 *	void nthldel( fl, n )
 *	void stolower( str, sz )
 *	void pgf( f )
 *	int System( s )
 *	char *mkidxstr( idxstr, idx )
 *	char *mkacctstr( acctstr, acctn )
 *	int eolcdate( fl, ln )
 *	int reseolcdate( fl, ln )
 *	int rescmp( rln, fline )
 *	int addcdts( fl, ln )
 *	int mkpristr( pstr, p )
 *	int mkbigpristr( pstr, p )
 *	FILE *Fopen( fn, fl, m, fptr )
 *	void adjstperms( f )
 *	char *getname( name, acctn )
 *	int mknulline( l ) 
 *	int isfdups( fname )
 *	char *strccpy( cpy, line, c )
 *	char *strpat( line, pattern )
 *	char *strxbrk( s1, s2 )
 *	int strchno( s, c )
 *	int issalpha( s )
 *	int issdigit( s )
 *	int issfloat( s )
 *	int filepat( lnoflg, pattern, filename )
 *	int dubakpat( pattern, filename )
 *	int patfound( pattern, line )
 *	int isstorecode( ch )
 *	int mvf( fromname, toname )
 *	int cpf( fromname, toname )
 *	int catf( fromname, toname )
 *	void zapoldnum( a )
 *	int replacel( lineno, fline, file )
 */

 #include "header.hh" 


/* Initialize or fill array with given char but leave final
 * array position NUL, a NUL terminating version of library function
 * memset().
 */
void filaray( c, a, sz ) /* Fill array with given char */
char c;
char *a;
int sz;
{
	int k;

	for( k = 0; k < (sz - 1); k++ )
		*a++ = c;
	*a = NUL;


} /* End filaray() */

/* Zap newline to NUL in an array usually gotten by fgets() */
void xnl( a ) /* Zap newline to NUL in an array */
char *a;
{
	while( *a != LF )    {
		if( *a == NUL )    {
			/* Safety insurance */
			return;
		}
		++a;
	}
	*a = NUL;

} /* End xnl() */

/* Add newline and array checking for possible overflow
 * which returns the length of the string
 */
int addnl( a, sz )
char *a;
int sz;
{
	int k = sz;
	while( *a != NUL && k )    {
		++a;
		--k;
	}
	if( k == 0 )    {
		printf( "array: (%s) not enough room for LF\n", a );
		return( ERROR );
	}
	*a = LF;
	*(a + 1) = NUL;
	return( (int)strlen( a ) );
}

/* Uniformize array so it terminates with one and only one LF char
 */
int nl1( a, sz )
char *a;
int sz;
{
	void xnl();
	int chrcnt();
	int addnl();

	int k;

	if( strchr( a, LF ) == NULL )    {
		/* There is no LF, add one */
		return( addnl( a, sz ) );
	}
	else    {
		/* There is at least one LF, delete until there is only one */
		while( chrcnt( LF, a ) > 1 )
			xnl( a );
		return( (int)strlen( a ) );
	}
}

/* Count the number of times c appears in string a
 */
int chrcnt( c, a )
char c;
char *a;
{
	int cnt = 0;

	while( *a != NUL )    {
		if( c == *a )
			++cnt;
		++a;
	}
	return( cnt );
}

void until_lf() /* Get chars until line feed is found */
{
	printf( "\n\n\t\t\t  - HIT ENTER TO CONTINUE -\n" );
	do    {
		;
	} while( getchar() != LF );
}



int flc( f ) /* File line count with error checking */
char *f;
{
	void until_lf();

	FILE *rptr;
	int c, lno;

	if( ( rptr = Fopen( "flc", f, "r", rptr ) ) == NULL )    {
		until_lf();
		return( ERROR );
	}
	lno = 0;
	while( (c = getc( rptr ) ) != EOF )    {
		if( c == LF )
			++lno;
	}
	fclose( rptr );
	return( lno );
}


/* Get the nth line from a named file, put it to array.
 * (size of array = sz)
 * Return length of the line gotten or negative for error.
 */
int nlnf( ar, sz, n, f ) /* Put nth line of named file in named array */
char *ar;
int sz, n;
char *f;
{
	void until_lf();

	FILE *rptr;
	int lno;

	if( (rptr = Fopen( "nlf", f, "r" , rptr )) == NULL )    {
		until_lf();
		return( ERROR );
	}
	lno = 0;
	while( fgets( ar, sz, rptr ) != NULL )    {
		++lno;
		if( n == lno )    {
			fclose( rptr );
			return( strlen( ar ) );
		}
	}
	putchar( BEL );
	printf( "FILE ERROR nlnf(): requested line number (%d) of %s\n                   exceeds file lines (%d)\n", n, f, lno );
	until_lf();
	fclose( rptr );
	return( ERROR );
}

/* Delete the nth line from a file */
void nthldel( fl, n ) /* Delete the nth line from a file */
char *fl;
int n;
{
	extern int getpid(), unlink();

	FILE *rptr, *wptr;
	char line[ BIGMAXLINE ], tfl[ BIGMAXLINE ];
	int lno;

	sprintf( tfl, "/tmp/%d", getpid() );
	if( (rptr = Fopen( "nthldel", fl, "r", rptr ) ) == NULL )    {
		until_lf();
		return;
	}
	if( (wptr = Fopen( "nthldel", tfl, "w", wptr ) ) == NULL )    {
		until_lf();
		return;
	}
	lno = 0;
	while( fgets( line, BIGMAXLINE, rptr ) != NULL )    {
		++lno;
		if( lno != n )    {
			fprintf( wptr, "%s", line );
		}
	}
	freopen( fl, "w", wptr );
	freopen( tfl, "r", rptr );
	while( fgets( line, BIGMAXLINE, rptr ) != NULL )    {
		fprintf( wptr, "%s", line );
	}
	fclose( rptr );
	fclose( wptr );
	unlink( tfl );
	return;
}


void stolower( str, sz ) /* String to lower */
char *str;
int sz;
{
	--sz;
	while( sz-- )
		str[ sz ] = (char)tolower( str[ sz ] );
}

void pgf( f ) /* Page a named file */
char *f;
{
	extern void until_lf();
	extern int getuid();

	char cmd[ MAXLINE ];

	if( getuid() == 0 )    {
		sprintf( cmd, "%s %s", ROOT_PAGEFILTER, f );
	}
	else    {
		sprintf( cmd, "%s %s", PAGEFILTER, f );
	}
	system( cmd );
	until_lf();
}

int System( s )
char *s;
{
	extern int fork(), wait();

	int status;
	int pid;

	if( ( pid =  fork() ) == 0 )    {
		SIGNALF( SIGINT, SIG_DFL );
		SIGNALF( SIGQUIT, SIG_DFL );
		execlp( "/bin/sh", "sh", "-c", s, NULL );
	}
	else if( pid == -1 )    {
		printf( "ERROR(%d): %s\n", errno, sys_errlist[ errno ] );
		status = -1;
	}
	else    {
		SIGNALF( SIGINT, SIG_IGN );
		SIGNALF( SIGQUIT, SIG_IGN );
		while( wait( &status ) != pid )
			;
	}
	return( status );
}

/* From idx, create in array idxstr, idx zero padded on the left
 * so length of digit string is always 4 digits.
 * Needless to say, max idx is 9999.
 */
char *mkidxstr( idxstr, idx ) /* make 0 padded len=4 idxstr */
char *idxstr;
int idx;
{
	if( idx > 999 && idx < 10000 )
		sprintf( idxstr, "%d\0", idx );
	else if( idx > 99 && idx < 1000 )
		sprintf( idxstr, "0%d\0", idx );
	else if( idx > 9 && idx < 100 )
		sprintf( idxstr, "00%d\0", idx );
	else
		sprintf( idxstr, "000%d\0", idx );

	return( idxstr );
}

/***********************************************************************
 * Although the above & below functions have exactly the same code,
 * we keep them because the structure of account numbers and index
 * numbers may not always turn out to be the same.
 ***********************************************************************/

/* From acctn, create in array acctstr, acctn zero padded on the left
 * so length of digit string is always 4 digits.
 * Needless to say, max acctn is 9999.
 */
char *mkacctstr( acctstr, acctn ) /* make 0 padded len=4 acctstr */
char *acctstr;
int acctn;
{
	if( acctn > 999 && acctn < 10000 )
		sprintf( acctstr, "%d\0", acctn );
	else if( acctn > 99 && acctn < 1000 )
		sprintf( acctstr, "0%d\0", acctn );
	else if( acctn > 9 && acctn < 100 )
		sprintf( acctstr, "00%d\0", acctn );
	else
		sprintf( acctstr, "000%d\0", acctn );

	return( acctstr );
}

/* Get ln in file fl edit file so current c_datestr is added with
 * preceding space to the end of ln.  Returns the number of matching
 * lines that have been appended.  Should be exactly 1.
 * Called always through lockedit().
 */
int eolcdate( fl, ln )
char *fl, *ln;
{
	extern int system(), getpid();
	extern int krfldpos(), kxfldpos();

	void adjstperms();

	FILE *rptr, *wptr;
	char line[ MAXLINE ], tfile[ MAXLINE ];
	int ret;
	int minlen;

	/* For adding return date in OXACTIONF */
	minlen = kxfldpos( OXRDATE );

	sprintf( tfile, "%s/%d\0", DBASEDIR, getpid() );
	if( (rptr = Fopen( "eolcdate", fl, "r", rptr )) == NULL )
		return( ERROR );
	if( (wptr = Fopen( "eolcdate", tfile, "w", rptr )) == NULL )
		return( ERROR );


	ret = 0;
	while( fgets( line, MAXLINE, rptr ) != NULL )    {
		/* Eliminate any possible blank lines */
		if( strlen( line ) == 1 )
			continue;
		if( (strcmp( ln, line ) == 0) && (strlen( line ) == minlen) )    {
#ifdef DEBUG
printf( "Debug eolcdate(): matching line found = %s", line );
#endif
			/* Over write the LF */
			sprintf( &line[ strlen( line ) - 1 ], " %s\n", c_datestr );
#ifdef DEBUG
printf( "Debug eolcdate(): line written = %s", line );
#endif
			++ret;
		}
		fprintf( wptr, "%s", line );

	} /* End while */

	fclose( rptr );
	fclose( wptr );
	sprintf( line, "mv %s %s", tfile, fl );
	system( line );
	adjstperms( fl );

	return( ret );

} /* End eolcdate */

/* Get ln in file fl edit file so current c_datestr is added with
 * preceding space to the end of ln.  Returns the number of matching
 * lines that have been appended.  Should be exactly 1.
 * Called always through lockedit().
 */
int reseolcdate( fl, ln )
char *fl, *ln;
{
	extern int system(), getpid();
	extern int krfldpos(), kxfldpos();

	void adjstperms();
	int rescmp();

	FILE *rptr, *wptr;
	char line[ MAXLINE ], tfile[ MAXLINE ];
	int ret;
	int minlen;

	/* For adding pickup date in RESERVEF */
	minlen = krfldpos( 4 );

	sprintf( tfile, "%s/%d\0", DBASEDIR, getpid() );
	if( (rptr = Fopen( "reseolcdate", fl, "r", rptr )) == NULL )
		return( ERROR );
	if( (wptr = Fopen( "reseolcdate", tfile, "w", rptr )) == NULL )
		return( ERROR );


	ret = 0;
	while( fgets( line, MAXLINE, rptr ) != NULL )    {
		/* Eliminate any possible blank lines */
		if( strlen( line ) == 1 )
			continue;
		if( (rescmp( ln, line ) == TRUE) && (strlen( line ) == minlen) )    {
#ifdef DEBUG
printf( "Debug reseolcdate(): matching line found = %s", line );
#endif
			/* Over write the LF */
			sprintf( &line[ strlen( line ) - 1 ], " %s\n", c_datestr );
#ifdef DEBUG
printf( "Debug reseolcdate(): line written = %s", line );
#endif
			++ret;
		}
		fprintf( wptr, "%s", line );

	} /* End while */

	fclose( rptr );
	fclose( wptr );
	sprintf( line, "mv %s %s", tfile, fl );
	system( line );
	adjstperms( fl );

	return( ret );

} /* End reseolcdate */

/* A reservation match does not include the the copy letter
 */
int rescmp( rln, fline )
char *rln, *fline;
{
	int resacctno, fresacctno, resindex, fresindex;
	char resdatestr[ DATELEN ], fresdatestr[ DATELEN ];

	sscanf( rln, "%d %d %*c %s", &resacctno, &resindex, resdatestr );
	sscanf( fline, "%d %d %*c %s", &fresacctno, &fresindex, fresdatestr );

	/* Note: both lines have newlines and DATELEN is large enough so the
	 * strcmp below will work.
	 */
	if( resacctno == fresacctno && resindex == fresindex
			&& strcmp( resdatestr, fresdatestr ) == 0 )    {
		return( TRUE );
	}
	else    {
		return( FALSE );
	}
}

int addcdts( fl, ln ) /* Add SPc_datestr to eol of ln in fl */
char *fl, *ln;
{
	extern int lockedit();

	int eolcdate();

	if( strcmp( fl, RESERVEF ) == 0 )
		return( lockedit( reseolcdate, fl, ln ) );

	/* Otherwise OXACTIONF */
	return( lockedit( eolcdate, fl, ln ) );
}

int mkpristr( pstr, p )
char *pstr;
float p;
{
	void until_lf();

	/* This allows a negative price */
	/*
	if( p < 10.00 )
		sprintf( pstr, "  %.2f", p );
	else if( p >= 10.00 && p < 100.00 )
		sprintf( pstr, " %.2f", p );
	else if( p >= 100.00 && p < 1000.00 )
		sprintf( pstr, "%.2f", p );
	else    {
		printf( "No room for price this large\n" );
		until_lf();
		return( ERROR );
	}
	*/

	if( p >= -999.00 && p < 1000.00 )
		sprintf( pstr, "%*.2f", (PRICELEN -2), p );
	else    {
		printf( "No room for price this large\n" );
		until_lf();
		return( ERROR );
	}

	return( 0 );
}


/* Assumes array of BIGPRICELEN size */
int mkbigpristr( pstr, p )
char *pstr;
float p;
{
	void until_lf();


	if( p <= -10000.00 )    {
		printf( "No room for negative dollar amount this large\n" );
		until_lf();
		return( ERROR );
	}
	if( p >= 100000.00 )    {
		printf( "No room for dollar amount this large\n" );
		until_lf();
		return( ERROR );
	}

	sprintf( pstr, "%*.2f", (BIGPRICELEN - 2), p );

	return( 0 );
}



/* A safer fopen and more detailed in error messages.
 *
 * Usage:
 *	if( ( fptr = Fopen( fn, fl, m, fptr ) ) == NULL )
 *		return( ERROR );
 */


/*
 *   fn: name of invoking function
 *   fl: name of file to be opened
 *    m: mode of opening
 * fptr: 
 *
 * Only accounts for the old modes r, w, a in error messages.
 */
FILE *Fopen( fn, fl, m, fptr )
char *fn, *fl, *m;
FILE *fptr;
{
	extern void perror();

	char msg[80];

 	if( ( fptr = fopen( fl, m ) ) == NULL )    {
		/* Can't open */
		if( *m == 'r' )
			printf( "Failed attempt to read %s\n", fl );
		else if( *m == 'w' )
			printf( "Failed attempt to write %s\n", fl );
		else if( *m == 'a' )
			printf( "Failed attempt to append %s\n", fl );
		else
			printf( "Failed attempt to \"%s\" %s\n", m, fl );
		sprintf( msg, "%s()", fn );
		perror( msg );
		return( NULL );
	}
	return( fptr );
}

void adjstperms( f )
char *f;
{
	extern int chmod(), chown();

	void until_lf();

	if( chmod( f, CREATIONMASK ) == ERROR )    {
		/*
		printf( "adjstperms(): Cannot set 666 permissions on %s\n", f );
		until_lf();
		*/
	}
	if( chown( f, ULTRAUID, ULTRAGID ) == ERROR )    {
		/*
		printf( "adjstperms(): Cannot set ultra owner & group on %s\n", f );
		until_lf();
		*/
	}
}


char *getname( name, acctn ) /* Put customer name into name given acctn */
char *name;
int acctn;
{
	void xnl(), zapoldnum(), until_lf();
	int nlnf();

	char line[ MAXLINE ];
	int lacctn;

	nlnf( line, MAXLINE, CUSTLINE( acctn ), custlist[0] );
	sprintf( name, "%s", &line[ ACCTNOLEN - 1 ] );
	xnl( name );
	zapoldnum( name );
	sscanf( line, "%d", &lacctn );
	if( lacctn != acctn )    {
		printf( "getname(): FORM ERROR IN %s\n", custlist[0] );
		printf( "Line %d should have acct# %d; it has %d\n", CUSTLINE( acctn ), acctn, lacctn );
		until_lf();
	}
	return( name );
}

int mknulline( l )  /* erase a line putting eol as first element */
char *l;
{
	*l = NULL;
	return( TRUE );
}

/* We use this in main at startup on reserve and xaction files, and on the
 * reserve file whenever reservations is enetered from the main menu.
 */
int isfdups( fname ) /* Check for duplicate lines in a file */
char *fname;
{
	extern int kxfldpos();

	void until_lf();

	FILE *rptr1, *rptr2;
	char line1[ MAXLINE ], line2[ MAXLINE ];
	int ln1, ln2, cnt;
	int oxactf, xt;

	if( strcmp( OXACTIONF, fname ) == 0 )
		oxactf = TRUE;
	else
		oxactf = FALSE;

	if( (rptr1 = Fopen( "isdups", fname, "r", rptr1 )) == NULL )    {
		until_lf();
		return( ERROR );
	}
	if( (rptr2 = Fopen( "isdups", fname, "r", rptr2 )) == NULL )    {
		until_lf();
		return( ERROR );
	}
	ln1 = 0;
	ln2 = 0;
	cnt = 0;
	while( fgets( line1, MAXLINE, rptr1 ) != NULL )    {
		++ln1;
		if( oxactf )    {
			sscanf( &line1[ kxfldpos( OXXTYP ) ], "%d", &xt );
			if( xt != VGTYPE_VIDEO && xt != VGTYPE_VIDEO + 1 &&
			    xt != VGTYPE_GAME && xt != VGTYPE_GAME + 1 )
				/* Interest is only in rentals & late charges:
				 * other dups are ok.
				 */
				continue;
		}
		/* Align the two file pointers */
		fseek( rptr2, ftell( rptr1 ), 0 );

		ln2 = ln1;
		while( fgets( line2, MAXLINE, rptr2 ) != NULL )    {
			++ln2;
			if( oxactf )    {
				if( strncmp( line1, line2, kxfldpos( OXTIME ) ) == 0 &&
				    strcmp( &line1[ kxfldpos( OXWKDAY ) ], &line2[ kxfldpos( OXWKDAY ) ] ) == 0 )    {
					++cnt;
					putchar( BEL );
					printf( "FILE ERROR (%s): lines %d and %d are duplicates.\n", fname, ln1, ln2 );
					until_lf();
				}
			}
			else    {
				/* The reservation file */
				if( strcmp( line1, line2 ) == 0 )    {
					++cnt;
					putchar( BEL );
					printf( "FILE ERROR (%s): lines %d and %d are duplicates.\n", fname, ln1, ln2 );
					until_lf();
				}
			}
		}
	}
	fclose( rptr1 );
	fclose( rptr2 );

	/* Number of duplicates found */
	return( cnt );
}

/* Copy line from beginning to first occurance of c into cpy;
 * return pointer to next character in line, after c, NULL if c is NUL.
 */
char *strccpy( cpy, line, c )
char *cpy, *line;
char c;
{
	while( *cpy = *line  )    {
		if( *cpy == c )    {
			++cpy;
			++line;
			break;
		}
		++cpy;
		++line;
	}

	if( *cpy == NUL )
		/* Entire string has been copied either because c was given
		 * as NUL or because c was not found in the string.
		 */
		return( NULL );

	/* This return is possibly to a NUL character, if the character
	 * c is found to be the last nonNUL character in line
	 */
	return( ++line );
}

/* Returns pointer to position where first occurance of pattern begins
 * on line or NULL for absence of pattern.
 */
char *strpat( line, pattern ) /* Find pattern on a line */
char *line, *pattern;
{

        unsigned int patlen, lnlen;
        int i, j, k;
	char *lpos;

        patlen = strlen( pattern );
	lnlen = strlen( line );

	if( lnlen < patlen )
		return( NULL );

	if( lnlen == patlen )    {
		if( strcmp( pattern, line ) == 0 )
			return( line );
		else
			return( NULL );
	}

        k = 0;		/* line index */
        i = 0;
        j = 0;

	lpos = line;
        while( k < ( lnlen - patlen ) )    {

                while( *( pattern + j++ ) == *( line + i++ ) )   
                        ;
                if( j <= patlen )   {
                        ++k;
                        i = k;
                        j = 0;
                }
                else    {
			/* A match has been found */
                        return( lpos + k );

                }


        } /* end while */

        /* no pattern match on this line */

        return( NULL );

} /* End strpat() */

/* Return pointer to first occurance of a character in s1 that is not
 * in s2
 */
char *strxbrk( s1, s2 )
char *s1, *s2;
{
	/* Check each char in s1 to see if it is contained in s2.
	 * We want a pointer to the first occurance of failure.
	 */
	while( strchr( s2, *s1 ) !=  NULL && *s1 != NUL )
		++s1;

	/* If there is no failure, s1 will be null */
	return( s1 );

} /* End strxbrk() */

/* NB unused untested: Sun Feb 19 13:37:31 EST 1995 */

/* Return the number of occurances of character in string;
 * Zero if c is NUL.
 */
int strchno( s, c )
char *s;
int c;
{
	int n = 0;
	while( strchr( s, c ) !=  NULL && c != NUL )    {
		++n;
	}
	return( n );
}

int issalpha( s ) /* Boolean: is an entire string alphabetic? */
char *s;
{
	char *t;

	t = s;
	while( *t != NUL )    {
		if( !isalpha( *t ) )
			return( FALSE );
		++t;
	}
	return( TRUE );

} /* End issalpha() */

int issdigit( s ) /* Boolean: is an entire string numeric? */
char *s;
{
	char *t;

	t = s;
	while( *t != NUL )    {
		if( !isdigit( *t ) )
			return( FALSE );
		++t;
	}
	return( TRUE );

} /* End issdigit() */

int issfloat( s ) /* Boolean: is a string float-numeric? */
char *s;
{
	char *t;

	t = s;
	while( *t != NUL )    {
		if( !isdigit( *t ) && *t != '.' && *t != '+' && *t != '-' )
			return( FALSE );
		++t;
	}
	/* There are no illegal chars */

	if( strchr( s, '+' ) )    {
		if( strchr( s, '-' ) )
			/* Can't have both + and - */
			return( FALSE );
		if( *s != '+' )
			/* Must have sign at the beginning */
			return( FALSE );
		if( strchr( s, '+' ) != strrchr( s, '+' ) )
			/* First occurrence must also be the last */
			return( FALSE );
	}
	if( strchr( s, '-' ) )    {
		if( strchr( s, '+' ) )
			/* Can't have both + and - */
			return( FALSE );
		if( *s != '-' )
			/* Must have sign at the beginning */
			return( FALSE );
		if( strchr( s, '-' ) != strrchr( s, '-' ) )
			/* First occurrence must also be the last */
			return( FALSE );
	}

	/* Restrictions on special cases */
	if( strlen( s ) == 1 )    {
		/* '.', '+', '-' alone is not allowed; 0, 1, ... is allowed */
		if( isdigit( *s ) )
			return( TRUE );
		else
			return( FALSE );
	}
	if( strlen( s ) == 2 )    {
		/* Must have at least one digit */
		if( strpbrk( s, "0123456789" ) == NULL )
			return( FALSE );
	}

	return( TRUE );

} /* End issfloat() */

/* If lnoflg = TRUE, print the line numbers
 */
int filepat( lnoflg, pattern, filename ) /* Print line with pattern found */
int lnoflg;
char *pattern, *filename;
{
	FILE *rptr;
	char line[ 2*MAXLINE + 1 ];
	int pats;
	int lno;

	int patfound();

	if( ( rptr = Fopen( "filepat", filename, "r", rptr ) ) == NULL )    {
		until_lf();
		return( ERROR );
	}
	pats = 0;
	lno = 0;
	putchar( LF );
	while( fgets( line, 2*MAXLINE, rptr ) != NULL )    {
		++lno;
		if( patfound( pattern, line ) == TRUE )    {
			if( lnoflg == TRUE )    {
				printf( "%4d: %s", lno, line );
			}
			else    {
				printf( "%s", line );
			}
			++pats;
		}
	}
	fclose( rptr );
	return( pats );
}


int dubakpat( pattern, filename ) /* Print file line where pattern is found */
char *pattern, *filename;
{
	FILE *rptr;
	char line1[ MAXLINE ], line2[ MAXLINE ];
	int pats;

	int patfound();

	if( ( rptr = Fopen( "dubakpat", filename, "r", rptr ) ) == NULL )    {
		until_lf();
		return( ERROR );
	}
	pats = 0;
	while( fgets( line2, MAXLINE, rptr ) != NULL )    {
		if( patfound( pattern, line2 ) == TRUE )    {
			printf( "%s", line1 );
			printf( "%s\n", line2 );
			++pats;
		}
		strcpy( line1, line2 );
	}
	fclose( rptr );
	return( pats );
}

/* Returns BOOLEAN for found or not found
 */
int patfound( pattern, line ) /* Find pattern on a line */
char *pattern, *line;
{
	extern char *strchr();

        int patlen, lnlen;
        int i, j, k;

        patlen = strlen( pattern );
	lnlen = strlen( line );

	if( lnlen < patlen )
		return( FALSE );
	if( lnlen == patlen )    {
		if( strcmp( pattern, line ) == 0 )
			return( TRUE );
		else
			return( FALSE );
	}

        k = 0;
        i = 0;
        j = 0;

        while( k < ( lnlen - patlen ) )    {

                while( *( pattern + j++ ) == *( line + i++ ) )   
                        ;
                if( j <= patlen )   {
                        ++k;
                        i = k;
                        j = 0;
                }
                else    {
			/* A match has been found */
                        return( TRUE );

                }


        } /* end while */

        /* no pattern match on this line */

        return( FALSE );

} /* End patfound */

int isstorecode( ch )
char ch;
{
	int k;

	for( k = 0; k < STORENUM; k++ )    {
		if( ch == uvstorecodes[ k ] )
			return( k );
	}
	return( ERROR );
}

/* Move file
 */
int mvf( fromname, toname )
char *fromname, *toname;
{
	char cmd[ MAXLINE ];

	sprintf( cmd, "mv %s %s", fromname, toname );
	return( system( cmd ) );

} /* End mvf() */

/* Copy file
 */
int cpf( fromname, toname )
char *fromname, *toname;
{
	char cmd[ MAXLINE ];

	sprintf( cmd, "cp %s %s", fromname, toname );
	return( system( cmd ) );

} /* End cpf() */


/* Cat file
 * Copy a file to or cat onto if preexisting.
 */
int catf( fromname, toname )
char *fromname, *toname;
{
	char cmd[ MAXLINE ];

	if( access( toname, 0 ) == 0 )
		sprintf( cmd, "cat %s >> %s", fromname, toname );
	else
		sprintf( cmd, "cp %s %s", fromname, toname );
	return( system( cmd ) );

} /* End catf() */


/* Used for eliminating old account account numbers on customer list lines
 * and old index numbers on vlist lines.  These always have a space before
 * the LB and should have only one space.
 */
void zapoldnum( a )
char *a;
{
	while( *a != NUL )    {
		if( *a == '[' )    {
			*(a - 1) = NUL;
			return;
		}
		++a;
	}
}

/* Replace nth line in file with fline
 * Assumption: the line comes with its new line.
 */
int replacel( lineno, fline, file )
int lineno;
char *fline, *file;
{
	extern int getpid();
	void adjstperms();
	int mvf();

	FILE *rptr, *wptr;
	char tempf[ MAXLINE ];
	char line[ 2*MAXLINE + 1 ];
	int ln;

	sprintf( tempf, "%s/T%d", UVTMPDIR, getpid() );
	if( (wptr = fopen( tempf, "w" )) == NULL )    {
		printf( "recplacel(): cannot write %s.\n", tempf );
		return( FALSE );
	}
	if( (rptr = fopen( file, "r" )) == NULL )    {
		printf( "recplacel(): cannot read %s.\n", file );
		return( FALSE );
	}

	/* Copy file to a tempf up to line for replacement;
	 * write the file line to the tempf,
	 * continue copying.
	 */
	ln = 0;
	while( fgets( line, 2*MAXLINE, rptr ) != NULL )    {
		if( ++ln == lineno )
			break;
		else
			fprintf( wptr, "%s", line );
		
	}

	/* The replacement */
	fprintf( wptr, "%s", fline );

	while( fgets( line, 2*MAXLINE, rptr ) != NULL )    {
		fprintf( wptr, "%s", line );
		
	}
	fclose( rptr );
	fclose( wptr );
	

	/* Move tempf back to original file */
	adjstperms( tempf );
	if( mvf( tempf, file ) != 0 )    {
		putchar( BEL );
		printf( "\n\nCannot move %s to %s\n\n", tempf, file );
		until_lf();
		return( FALSE );
	}

	return( TRUE );

} /* End replacel() */


Return to Home Page Return to Metayoga Page Return to C Language Page


The URL for this document is:
http://graham.main.nc.us/~bhammel/graham/CPROGS/funcs.html
Created: 1997
Last Updated: May 28, 2000 Email me, Bill Hammel at
bhammel@graham.main.nc.us
READ WARNING BEFORE SENDING E-MAIL