/* Find the file whose name matches that passed as first argument.
 * Print the filename and its volume:path to the screen
 */
#include <stdio.h>
#include <ctype.h>
#include <exec/types.h>
#include <devices/keymap.h>
#include <intuition/intuition.h>
#include <libraries/dosextens.h>

#define BELL 0x07
/*
 *                 F U N C T I O N     D E C L A R A T I O N S
 */
extern struct FileLock * Lock();

BOOL ifoundit;
/* home grown subrs: */
void close_things();

/*
 *                  M A I N     P R O G R A M     M O D U L E
 */
void
main( argc,argv)
int argc;
char * argv[];
{
	void scan_directory ();
	struct FileLock * Lock ();
	void UnLock ();
	char * strcpy ();

	struct FileLock * dir;
	struct FileInfoBlock * fb;
	char path[130];			/* hold volume name */
	char devname[32];
	char searchfile[32];
	char * ch;
	UBYTE i;

	if ((argc > 3) || (argc == 1))
		printf ("usage: whereis <filename> <devname>\n");
	else
		{
		ifoundit = FALSE;
		/* devname not specified */
		if (argc == 2)
			devname[0] = '\0';
		else
			{
			for (i=0;i<32;i++)
				devname[i] = '\0';
			strncpy (devname,argv[2],31);
			}
		strcpy (searchfile, argv[1]);
		/* upcase input string, simplify matching process */
		for (ch=searchfile; *ch != '\0'; ch++)
			*ch = toupper (*ch);
		/* Get Lock on disk */
		if ( (dir = Lock (devname,ACCESS_READ)) == NULL)
			{
			printf ("Could not obtain lock on device %s\n",
				devname);
			printf ("Then Die Ceasar\n");
			close_things ();
			exit (5);
			}
		else
			strcpy (path, devname);
		/* DO IT TO IT! */
		scan_directory (searchfile,path);
		}
	close_things ();
} /* end main */

/*
.page.index close_index
Do whatever final clean up is needed to leave the program.
 */
void
close_things()
{
	if (!ifoundit)
		printf ("Sorry, couldn't find it.\n");
	return;
} /* end close_things */


/*
.page.index scan_directory
 */
void
scan_directory (searchfile,path)
char * searchfile;
char * path;
	{
	char * strcpy ();
	void UnLock ();
	struct FileLock * dir;
	struct FileInfoBlock * fb;
	char * adddir ();

	/* WE GOTTA BE STINGY WITH LOCAL STORAGE, THIS IS RECURSING!
	 * CAN'T EAT TOO MUCH STACK.
	 */
#	define MAXSUB 50
	char * subdir [MAXSUB];	/* Pointer area for Sub-Directories */
	char pathname[130];	/* Pointers to AmigaDOS sub-directories */
	UBYTE countdir,indexdir,i;
	char testname[32];
	char * ch;

	if (ifoundit)
		return;
	/* Get Lock on this directory */
	if ( (dir = Lock (path,ACCESS_READ)) == NULL)
		{
		printf ("%cCould not obtain lock on directory %s\n",
			BELL, path);
		printf ("Then Die Ceasar\n");
		close_things ();
		exit (4);
		}

	/* Examine lock and obtain FileInfoBlock */
	fb=(struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock),0);
	if (!Examine (dir,fb))
		{
		printf ("%cCouldn't Examine files assoc with lock\n",BELL);
		printf ("Then Die Ceasar\n");
		UnLock (dir);
		FreeMem ((char *)fb, sizeof (struct FileInfoBlock));
		close_things ();
		exit (4);
		}
	/* we now have dir and fb set up, 
	 * scan all files at this level 
	 * (remembering subdirectories)
	 */
	countdir = 0;
	while ((ExNext(dir,fb),IoErr() != ERROR_NO_MORE_ENTRIES) 
		&& (countdir <= MAXSUB)
		&& (!ifoundit)
		) 
		{
		if (fb->fib_DirEntryType > 0)
			{
			/* we have a subdirectory here... */
			if (countdir < MAXSUB)
				subdir[countdir] = 
					adddir (fb->fib_FileName);
			else
				printf ("%cToo few subdirectory slots\n",
					BELL);
			countdir++;
			}
		else
			{
			/* compare fb->filename with searchfile */
			for (i=0;i<32;i++)
				testname[i] = '\0';
			strncpy (testname,fb->fib_FileName, 32);
			testname[31] = '\0';
			for (i = 0,ch=testname; (ch != '\0')&&(i<32); 
				i++,ch++)
				*ch = toupper (*ch);
#			if 0
			printf ("%s =?= %s\n",testname, searchfile);
#			endif
			if (strcmp (testname,searchfile)==0)
				{
				printf ("%s\t%s\n",testname,path);
				ifoundit = TRUE;
				}
			}
		} /* end while */
	/* return these now, we're done, thank you. */
	UnLock (dir);
	FreeMem ((char *)fb, sizeof (struct FileInfoBlock));

	/* finished with this level, try one level down */
	indexdir = 0;
	while ((indexdir < countdir)&&(!ifoundit))
		{
		strcpy (pathname,path);
		/* if no path delimiter, add one */
		if (       (path[strlen(path)-1] != ':') 
			&& (path[strlen(path)-1] != '/') 
			&& (strlen(path) > 0))
          		strcat (pathname,"/");
		strcat (pathname,subdir[indexdir]);

		scan_directory (searchfile,pathname);

		/* and pick up litter left by adddir() */
		FreeMem ((char *)subdir[indexdir],
			strlen(subdir[indexdir])+1);
		subdir[indexdir] = NULL;
		indexdir++;
		}

	return;
}	/* end scan_directory */

/*
.page.index adddir
 ----------------------------------------------------------------------------
	Allocate some memory and then copy string into it.
 */
char * adddir (string)
char * string;
{
	char * nameadd;    /* Address of the directory name */

	nameadd = (char *) AllocMem (strlen(string)+1,0);
	if (nameadd == NULL)
		{
		printf ("Not Enough Memory for Directories!!!\n");
		/* run away! run away! */
		close_things ();
		exit (7);
		}
	strcpy (nameadd, string);

	/* return address of string you just alloated. */
	return (nameadd);

}	/*end adddir*/
