/* ************************************************************************

    WhereIs.c - V1.00 - testo sorgente in linguaggio C di Steve Poling

    Ricerca tutte le ricorrenze di un file in un disco o device logico

----------------------------------------------------------------------------

Traduzione ed adattamento a Lattice C V5.0 e Aztec C V3.6 di Luigi Callegari

Compilazione Lattice: LC -Lvdc Whereis
Compilazione Aztec: cc +L Whereis ----- ln whereis c32.lib

************************************************************************** */

#include <exec/types.h>
#include <devices/keymap.h>
#include <intuition/intuition.h>
#include <libraries/dosextens.h>
#include <ctype.h>
#include <stdio.h>

#ifndef AZTEC_C
#include <string.h>
#include <proto/dos.h>
#include <proto/exec.h>
#else
#include <functions.h>
#endif

#define BELL 0x07
#define MAXSUB 50

BOOL ifoundit;

void close_things()
{
	if (!ifoundit)
		printf ("Sorry, non ce l'ho fatta!\n");
	return;
}

void scan_directory (searchfile,path)
char * searchfile;
char * path;
	{
	struct FileLock * dir;
	struct FileInfoBlock * fb;
	char *adddir();

	char * subdir [MAXSUB];	/* Puntatore area sub-directory */
	char pathname[130];		/* Puntatore a subdirectories AmigaDOS */
	UBYTE countdir,indexdir,i;
	char testname[32];
	char * ch;

	/* Ottiene Lock sulla directory */
	if ( (dir = (struct FileLock *) Lock ( path, ACCESS_READ)) == NULL)
		{
		printf ("%cNon ho ottenuto il lock sulla directory %s\n",
			BELL, path);
		printf ("Devo finire!\n");
		close_things ();
		exit (4);
		}

	/* Esamina Lock e legge in FileInfoBlock */
	fb=(struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),0);
	if (!Examine ((BPTR)dir,fb))
		{
		printf ("%cNon ho potuto Examineare il file associato \n",BELL);
		printf ("Devo finire\n");
		UnLock ( (BPTR) dir);
		FreeMem ((char *)fb, sizeof (struct FileInfoBlock));
		close_things ();
		exit (4);
		}

/* Ora abbiamo dir e fb a posto, scandiamo i files di questo livello
tenendo a mente le subdirectory incontrate */

	countdir = 0;
	while ((ExNext( (BPTR) dir,fb),IoErr() != ERROR_NO_MORE_ENTRIES) 
		&& (countdir <= MAXSUB)
		) 
		{
		if (fb->fib_DirEntryType > 0)
			{

			/* ecco una bella sub-directory qui */
			if (countdir < MAXSUB)
				subdir[countdir] = 
					adddir (fb->fib_FileName);
			else
				printf ("%cTroppi pochi slots di subdirectory\n",
					BELL);
			countdir++;
			}
		else
			{

			/* compara fb->filename con file cercato */
			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 */
	/*
	UnLock (dir);
	FreeMem ((char *)fb, sizeof (struct FileInfoBlock));

	/* finito a questo livello, ora scendiamo di uno */
	indexdir = 0;
	while (indexdir < countdir)
		{
		strcpy (pathname,path);

		/* Nessun delimitatore di path, aggiungine uno */
		if (       (path[strlen(path)-1] != ':') 
			&& (path[strlen(path)-1] != '/') 
			&& (strlen(path) > 0))
          		strcat (pathname,"/");
		strcat (pathname,subdir[indexdir]);

		scan_directory (searchfile,pathname);

		/* e preleva lettera lasciata da adddir() */
		FreeMem ((char *)subdir[indexdir],
			strlen(subdir[indexdir])+1);
		subdir[indexdir] = NULL;
		indexdir++;
		}

	return;
}	/* end scan_directory */

/* Alloca della memoria e vi copia la stringa */

char * adddir (string)
char * string;
{
	char * nameadd;    /* Indirizzo nome directory */

	nameadd = (char *) AllocMem (strlen(string)+1,0);
	if (nameadd == NULL)
		{
		printf ("Manca memoria per le directory!!\n");

		/* Via, Via !!! */
		close_things ();
		exit (7);
		}
	strcpy (nameadd, string);

	/* ritorna l'indirizzo della stringa allocata */
	return (nameadd);

}	/*end adddir*/


void main( argc,argv)
int argc;
char *argv[];
{
	void closethings();
	struct FileLock * dir;
	char path[130];			/* hold volume name */
	char devname[32];
	char searchfile[32];
	char * ch;
	UBYTE i;

	if ((argc > 3) || (argc == 1))
		printf ("Uso: whereis <filename> <devname>\n");
	else
		{
		ifoundit = FALSE;

		/* devname non specificato */
		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]);

		/* Ricerca in maiuscolo, per semplificare */
		for ( ch = searchfile ; *ch != '\0' ; ch++)
			*ch = toupper (*ch);

		/* Ottiene Lock sul disco */
		if ((dir=(struct FileLock *) Lock( devname,ACCESS_READ)) == NULL)
			{
			printf ("Non si ottiene lock sul device %s\n",
				devname);
			printf ("Finiamo!\n");
			close_things ();
			exit (5);
			}
		else
			strcpy (path, devname);

		/* ************************************** */
		scan_directory (searchfile,path);
		}
	close_things ();
} /* end main */

/****************************** FINE DEL FILE ****************************/
