cd; /*	Auto-Compile + Link
lc -l ff12
blink with SRC:linkff12
quit


    FF.C will search all directories on a disk for occurances of a
		particular file.

	Version 1.1: Now will support the more-popular MSDOS wildcard character: *
					Also: smaller code and a little quicker execution.

	Version 1.2: Uses AmigaDOS' Lock(), Examine() & ExNext() instead of
					Lattice's dfind() & dnext(). AmigaDOS' routines are
					much faster and can be used recursively so it is not
					neccesary to use the heap to make a list of directories.
					Lattice's stcpm() is used to compare filenames that are
					found to the user-supplied wildcard. If stcpm() says that
					a filename matches, then the name is displayed. This
					change increases the speed of this routine by an average
					of 55%!!! One additional mod allows the user to specify
					a directory to look in. This effectively defines a branch
					of the directory tree to search in, rather than starting
					with the root and scanning all directories on the disk.
						4-10-88		Finished....  4-22-88
	
    Copyright 1988 Ray Lambert
*/

#define VERSION "1.2\n"

#include <dos.h>	
#include <stdio.h>
#include <libraries/dosextens.h>
#include <exec/memory.h>
#include <stdlib.h>
#include <string.h>
#include <proto/dos.h>

#define MAX_PATH_LEN 108

char
	str[MAX_PATH_LEN],
  *ptr,
  *ArgPtr,
	file_mask[MAX_PATH_LEN],
  drive[MAX_PATH_LEN];

int
	Level,
	status,
	count;

/****/

void amiga_write(St)
char *St;
{
	Write(Output(),St,strlen(St));
}

/****/

void amiga_write_int(num)
int num;
{
	char st[10];
	char *p;
	register int j;
	p = st;
	for (j=10000; ( (j>num) && (j>1) ); j/=10);	/* Find beginning divisor */
	do
		{
			*p = (num/j) + 0x30;
			num%=j;
			j/=10;
			p++;
		}
	while (j>=1);
	*p = '\0';
	amiga_write(st);
}

/****/

void dtree(Root)
char *Root;
{
	BPTR lock;
	struct FileInfoBlock *info;
	int status;
	char temp_str[MAX_PATH_LEN];

	info = (struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock),
		MEMF_CLEAR);
	if (!info)
		{
			amiga_write("Unable to allocate memory!\n");
			return;
		}
	lock = Lock(Root,ACCESS_READ);
	if (!lock)
		{
			FreeMem(info,sizeof(struct FileInfoBlock));
			return;
		}
	status = Examine(lock,info);
	if (!status)
		{
			UnLock(lock);
			FreeMem(info,sizeof(struct FileInfoBlock));
			return;
		}
	status = ExNext(lock,info);
	while (status)
		{
      strcpy(temp_str,Root);
      if (Level>0) strcat(temp_str,"/");
      strcat(temp_str,info->fib_FileName);
			if (info->fib_DirEntryType>0)
      	{		/* It is a directory */
					Level++;
					dtree(temp_str);
					Level--;
        }
			else
        {		/* It is a normal file */
					ptr = strupr(info->fib_FileName);
					if ( stcpma(info->fib_FileName,file_mask) )
						{
							amiga_write("Found: ");
							amiga_write(temp_str);
							amiga_write("\n");
							count++;
						}
				}
			status = ExNext(lock,info);
		}
	UnLock(lock);
	FreeMem(info,sizeof(struct FileInfoBlock));
}

/****/

void fixWC(St)
char *St;
{
	char *p;
	ptr = strupr(St);
	while( stcpm(St,"#\?",&ptr) )
		{
			*(ptr++) = '*';
			for(p=ptr+1; *ptr; ptr++, p++) *ptr = *p;
		}
}

/****/

void usage()
{
 	amiga_write("\nUsage: FF [DRIVE:[PATH/]]FILENAME ...\n\n");
  amiga_write("    [DRIVE:] = Optional drive to scan\n");
	amiga_write("    [PATH/]  = Optional path to begin scan at\n");
	amiga_write("    FILENAME = File to search for (Wildcards allowed)\n\n");
  exit(1);
}

/****/

void _main(Arg)
char *Arg;
{
  amiga_write("\nFileFind Amiga! Version ");
	amiga_write(VERSION);
	amiga_write("Copyright 1988 by Ray Lambert\n");
	ptr = strchr(Arg,'\n');	/* Change terminating newline to a NULL */
	if (ptr) *ptr = NULL;		
  ArgPtr = strchr(Arg,' ');	/* Skip over command "FF " */
  if (!ArgPtr) usage();	/* No Args */
	while (*ArgPtr==' ') ArgPtr++;	/* Check for no args some more */
	if (!*ArgPtr) usage();
	do
		{
			/* Skip over leading spaces */
			while (*ArgPtr==' ') ArgPtr++;
			if (!*ArgPtr) continue;		/* Check for NULL */
			for (ptr = drive; (*ArgPtr!=' ') && (*ArgPtr!=NULL); ptr++, ArgPtr++)
				*ptr = *ArgPtr;
			*ptr = '\0';
    	ptr = strchr(drive,':');	/* Check for user drive spec */
    	if (ptr)
      	{		/* Drive was supplied by user */
					while(*ptr) ptr++;	/* Get pointer to last xter */
						/* Find beginning of mask.... */
					while( (*ptr!='/') && (*ptr!=':') ) ptr--;
					strcpy(file_mask,++ptr);
					*ptr = '\0';
					if (*(--ptr)=='/') *ptr = '\0';
				}
			else			
      	{		/* Get drive from system */
					strcpy(file_mask,drive);
          ptr = getcwd(drive,MAX_PATH_LEN);
          if (ptr!=drive)
            {
              amiga_write("\nCan't read current directory!\nAborted.\n");
              exit(20);
            }
    			ptr = strchr(drive,':');	/* Cut path off */
    			if (ptr) *(++ptr)='\0';
      	}
			if (strlen(file_mask)==0) usage();
    	amiga_write("\nSearching for file '");
			amiga_write(file_mask);
			amiga_write("' on drive '");
			amiga_write(drive);
			amiga_write("'\n\n");
			count = 0;
    	ptr = strchr(drive,':');	/* Check for path */
			if (*(++ptr))
				Level = 1;
			else
				Level = 0;
			fixWC(file_mask);	/* Converts all instances of '#?' to '*' and... */
			dtree(drive);			/* ....makes file_mask all uppercase */
			if (count==0)
				amiga_write("No matches Found.\n");
	    else
				{
					amiga_write("\nFound ");
					amiga_write_int(count);
					amiga_write(" match");
					if (count==1)
						amiga_write(".\n");
					else
						amiga_write("es.\n");
				}
		}
	while(*ArgPtr);
	amiga_write("\n");
}

