#ifdef	ournix
#include "ournix.h"
#endif
char sccsID[] =
 "@(#) filesize.c, V1.5, Copyright Julian H. Stacey, Munich, 23rd October 1988 - 2010.\n" ;

/* see manual for documentation */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
char	**ARGV ;
int	ARGC ;
char	bad_mode[]	= "bad mode" ;
typedef char	FLAG ;
FLAG	quiet	= 0 ;
FLAG	print	= 0 ;
FLAG	ignore	= 0 ;

#define NO_ERR		0
#define MATH_ERR	1
#define PROG_ERR	2

	int
usage(str)
	char *str ;
	{
	fprintf(stderr,"%s.\n",str);
	fprintf(stderr,
	 "Syntax:%s [-i] [-q] [-p] size +|+=|>|>=|-|-=|<|<=|=|== file[s].\n",
		*ARGV);
	exit(PROG_ERR) ;
	}

	void
zonk(char *p)
	{ // Later I might perhaps stack then print in a line with spaces ?
	if (print) printf("%s\n",p);
	}

	int
main(argc,argv)
	int	argc;
	char	**argv ;
	{
	long	reference ;	/* Comparison yardstick for file lengths */
	long	actual ;	/* Actual file lengths */
	char	mode ;		/* +, >, -, <, or = */
	char	second ;	/* = or \0 */
	struct stat	stat_buf ;
	extern long atol() ;
	char	*explain ;

	ARGV = argv ; ARGC = argc ;
#ifdef	VSL	/* { */
#include	"../../include/vsl.h"
#endif		/* } */

	while (**++argv == '-')
		{
		argc-- ;
		switch ( *++*argv)
			{
			case 'p':	print = 1	; break ;
			case 'q':	quiet = 1	; break ;
			case 'i':	ignore = 1	; break ;
			default :
				fprintf(stderr,"parameter %c not available\n",
					**argv) ;
				usage("") ;
				break ;
			}
		}
	argv--;
	if ( --argc <= 2) usage("insufficient parameters") ;
	if ( (reference = atol(*++argv) ) < 0L ) usage("-ve size") ;
	switch( (mode = **++argv) )
		{
		case '=' :	break ;
		case '+' :	mode = '>' ; break ;
		case '>' :	break ;
		case '-' :	mode = '<' ; break ;
		case '<' :	break ;
		default :	usage(bad_mode) ;
		}
	// Detect possible ">="
	if ((second = *++*argv) != '\0')
		{
		if (second != '=' ) usage(bad_mode) ;
		switch(mode)
			{
			case '=' :	break ;
			case '>' :	mode = '+' ; break ;	 /* >= */
			case '<' :	mode = '-' ; break ;	 /* <= */
			}
		}
	/* Could add code to allow:
	 *	le <=
	 *	ge >=
	 *	lt <
	 *	gt >
	 */

	argc -= 2 ;
	while (argc--)
		{
		if (stat(*++argv, &stat_buf) != 0)
			{
			fprintf(stderr,"%s: %sError stat failed on %s.\n",*ARGV,
				ignore? "Fatal " : "",
				*argv);
			if (!ignore) exit(PROG_ERR) ;
			}
		actual = stat_buf.st_size ;
		switch (mode)
			{
			/* Typical usage from /bin/sh script:
			 *	filesize 10000 \>= /var/log/wtmp
			 *		# Return 0 (=No Error) if file small,
			 *		# else returns non zero to $result,
			 *		# & truncates log.
			 *	if $result cp /dev/null /var/log/wtmp
			 */
			case '<': explain = "<" ;
				if (reference < actual )
					{
					zonk(*argv) ;
					continue ;
					}
				break ;
			case '-': explain = "<=" ;
				if (reference <= actual )
					{
					zonk(*argv) ;
					continue ;
					}
				break ;
			case '>': explain = ">" ;
				if (reference > actual )
					{
					zonk(*argv) ;
					continue ;
					}
				break ;
			case '+': explain = ">=" ;
				if (reference >= actual )
					{
					zonk(*argv) ;
					continue ;
					}
				break ;
			case '=': explain = "==" ;
				if (reference == actual )
					{
					zonk(*argv) ;
					continue ;
					}
				break ;
			}
		if (!quiet) fprintf(stderr,
			// pre 2014-02-14: "%s %sError: %s %ld %s '%ld %s %s'.\n",
			"%s %s%s %ld %s '%ld %s %s'.\n",
			*ARGV,
			// pre 2014-02-14: ignore? "Fatal " : "",
			ignore? "Fatal: " : "",
			*argv, actual,
			"bytes, fails requirement:",
			reference, explain, *argv ) ;
		if (!ignore) exit(MATH_ERR) ;
		}
	exit(NO_ERR) ;
	}
