/*
	rfind1.c
	lcc rfind -k'-s 2000'
*/
#define PROGRAM   "再帰処理ファイルファインダ"
#define VERSION   "V0.04"
#define FIRSTDATE "94/12/06"
#define FINALDATE "95/02/01"
#define USAGE     "Usage: rfind [drive:path] [-t] [-k[16|32]] [-f]\n" \
		  " (option) t: tiff check.  k: wall cg."

#define MAIN

#include "calo.h"
#include <dos.h>
#include <string.h>

/*
スタックチェック
#pragma checksp
*/

#define MAXFILES 500

struct find_t b[MAXFILES];

enum kabegami{ kabe_n = 0, kabe_16 , kabe_32 , kabe_a };

char delim[] = "/" ;

extern int tifck( char *fn, unsigned char p );

void ffind( const char *fd, int bs ){

	struct find_t b0;
	char buf[100];
	int bp=bs,j;

	strcpy(buf,fd);
	strcat(buf,delim);
	strcat(buf,"*.*");
/* findfirst */
	if( _dos_findfirst( buf,
	_A_NORMAL | _A_SUBDIR | _A_VOLID | _A_SYSTEM | _A_HIDDEN,
	&b0 ) != NULL ){
		fputs("not find",stderr);
		return;
	}
/* while */
/*  findnext */
	do{
		if( b0.attrib & _A_SUBDIR && b0.name[0] == '.' )
			continue;
		b[bp] = b0;
		if( ++bp >= MAXFILES ){
			fputs("too many files!",stderr);
			break;
		}
	} while( _dos_findnext( &b0 ) == NULL );
/* 	printf("%d file(s) find\n",i); */
/* for */
	for( j = bs ; j < bp ; j ++ ){
/*  attrib */
		b[j].reserved[0] = ( b[j].attrib & _A_VOLID  ) ? 'v' : '-' ;
		b[j].reserved[1] = ( b[j].attrib & _A_SUBDIR ) ? 'd' : '-' ;
		b[j].reserved[2] = ( b[j].attrib & _A_ARCH   ) ? 'a' : '-' ;
		b[j].reserved[3] = ( b[j].attrib & _A_SYSTEM ) ? 's' : '-' ;
		b[j].reserved[4] = ( b[j].attrib & _A_HIDDEN ) ? 'h' : '-' ;
		b[j].reserved[5] = ( b[j].attrib & _A_RDONLY ) ? 'r' : '-' ;
		b[j].reserved[6] = NULL ;
/*  printf */
		printf("%s%s%-12s %9lu %6s\n",
			fd, delim, b[j].name, b[j].size, b[j].reserved);
		if( b[j].reserved[1] == 'd' ){
			strcpy(buf,fd);
			strcat(buf,delim);
			strcat(buf,b[j].name);
			ffind(buf,bp);
		}
	}
	return;
}

/* 速いだけがとりえ？ ファイル名だけ出力 */
void sfind( const char *fd, int bs ){

	struct find_t b0;
	char buf[100];
	int bp=bs,j;

	strcpy(buf,fd);
	strcat(buf,delim);
	strcat(buf,"*.*");
/* findfirst */
	if( _dos_findfirst( buf,
	_A_NORMAL | _A_SUBDIR | _A_VOLID | _A_SYSTEM | _A_HIDDEN,
	&b0 ) != NULL ){
		fputs("not find",stderr);
		return;
	}
/* while */
/*  findnext */
	do{
		if( b0.attrib & _A_SUBDIR && b0.name[0] == '.' )
			continue;
		b[bp] = b0;
		if( ++bp >= MAXFILES ){
			fputs("too many files!",stderr);
			break;
		}
	} while( _dos_findnext( &b0 ) == NULL );
/* 	printf("%d file(s) find\n",i); */
/* for */
	for( j = bs ; j < bp ; j ++ ){
/*  printf */
		if( b[j].attrib & _A_SUBDIR ){
			strcpy(buf,fd);
			strcat(buf,delim);
			strcat(buf,b[j].name);
			sfind(buf,bp);
		} else
			puts( b[j].name );
	}
	return;
}

void tfind( const char *fd, int bs, enum kabegami k ){

/* ffind() と ほとんど同じ */

	struct find_t b0;
	char buf[100];
	int bp=bs,j;

	strcpy(buf,fd);
	strcat(buf,delim);
	strcat(buf,"*.*");
/* findfirst */
	if( _dos_findfirst( buf,
	_A_NORMAL | _A_SUBDIR | _A_VOLID | _A_SYSTEM | _A_HIDDEN,
	&b0 ) != NULL ){
		fputs("not find",stderr);
		return;
	}
/* while */
/*  findnext */
	do{
		if( b0.attrib & _A_SUBDIR && b0.name[0] == '.' )
			continue;
		b[bp] = b0;
		if( ++bp >= MAXFILES ){
			fputs("too many files!",stderr);
			break;
		}
	} while( _dos_findnext( &b0 ) == NULL );
/* 	printf("%d file(s) find\n",i); */
/* for */
	for( j = bs ; j < bp ; j ++ ){
/* ここのへんだけ ffind() と違う */
/*  printf */
		{
		char *s;
		for( s = b[j].name ; *s++ != '.' ; )
			if( *s == NULL ) goto noex;
		if( *s++ == 'T' && *s++ == 'I' && *s == 'F' ){
			strcpy(buf,fd);
			strcat(buf,delim);
			strcat(buf,b[j].name);
			if(( k & tifck( buf,( k == kabe_n ) ? 'p': '-' ))!=0)
				printf("%s%s%-12s\n", fd, delim, b[j].name );
		}
		}
		noex:
		if( b[j].attrib & _A_SUBDIR ){
			strcpy(buf,fd);
			strcat(buf,delim);
			strcat(buf,b[j].name);
			tfind(buf,bp,k);
		}
	}
	return;
}

void main( int argc, char *argv[] ){

	char path[80] = ".";
	int i,t=0;
	enum kabegami k = kabe_n;

	if( argc == 1 ) usage( argv[0] );

	for( i = 1 ; i < argc ; i++ ){
		if( argv[i][0] == '-' || argv[i][0] == '/' ){
			switch (argv[i][1]) {
			case 'K':
			case 'k':
				k = ( argv[i][2] == '1' ? kabe_16 :
				    ( argv[i][2] == '3' ? kabe_32 :
						          kabe_a ) );
			case 'T':
			case 't':
				t = 1;
				break;
			case 'F':
			case 'f':
				t = 2;
				break;
			case 'H':
			case 'h':
			case '?':
				usage( argv[0] );
			default:
				usage("option err.");
			}
		continue;
		}
		{
		/*
		strcpy( path,argv[i] );
		*/
			char *s,*d;
			d = path;
			s = argv[i];
			while( *s != NULL ){
				*d++ = *s++;
				if( *s == '/' || *s == '\\' ) *delim = *s;
			}
			if( *(--d) == *delim ) *d = NULL;
		}
	}

	switch (t) {
	case 0:
		ffind( path, 0 );
		break;
	case 1:
		tfind( path, 0, k );
		break;
	default:
		sfind( path, 0 );
	}
}
