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

Where.c - V1.0 - testo sorgente in linguaggio C di Steve Poling (USA)

Rintraccia un file indicato per nome e stampa la posizione sul video

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

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

Compilazione Lattice: LC -vbr -L Where
Compilazione Aztec : cc +L where.c ------ ln where 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;

/* Funzione di termine e rientro pulito */

void close_things()
{
	if (!ifoundit)
		printf ("Sorry, non l'ho trovato!\n");
	return;
} /* end close_things */

void scan_directory (searchfile,path)
char * searchfile;
char * path;
	{
	struct FileInfoBlock *dir;
	struct FileInfoBlock *fb;
	char *adddir ();
	char *subdir [MAXSUB];	/* Puntatore area di Sub-Directories */
	char pathname[130];	/* Puntatori a sub-directories AmigaDOS*/
	UBYTE countdir,indexdir,i;
	char testname[32];
	char *ch;

	if (ifoundit)
		return;
	/* Ottiene il lock della directory */

	if ( ( dir = (struct FileInfoBLock *)Lock (path,ACCESS_READ)) == NULL)
		{
		printf ("%cNon ho ottenuto il lock %s\n",
			BELL, path);
		printf ("\nMuori Cesare!n");
		close_things ();
		exit (4);
		}

	/* Examine() del lock e lettura  FileInfoBlock */

	fb = (struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock),0);

	if (!Examine ( (BPTR)dir, fb) )
		{
		printf ("%cNon ho potuto esaminare lock associato a \n",BELL);
		printf ("\nAllora muori, Cesare\n");
		UnLock ((BPTR)dir);
		FreeMem ( (char *)fb, sizeof (struct FileInfoBlock));
		close_things ();
		exit (4);
		}
	/* dir e fb a posto, scandiamo il livello ricordando subdirectories */

	countdir = 0;
	while ((ExNext((BPTR)dir,fb),IoErr() != ERROR_NO_MORE_ENTRIES) 
		&& (countdir <= MAXSUB)
		&& (!ifoundit)
		) 
		{
		if (fb->fib_DirEntryType > 0)
			{
			/* abbiamo una subdirectory qui */
			if (countdir < MAXSUB)
				subdir[countdir] = 
					adddir (fb->fib_FileName);
			else
				printf ("%cTroppo pochi subdirectory slots\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 ( (BPTR) dir);
	FreeMem ((char *)fb, sizeof (struct FileInfoBlock));

	/* finito a questo livello, scendiamo di uno */

	indexdir = 0;
	while ((indexdir < countdir)&&(!ifoundit))
		{
		strcpy (pathname,path);

		/* se non c'e' delimitatore di path, aggiungiamolo */
		if (       (path[strlen(path)-1] != ':') 
			&& (path[strlen(path)-1] != '/') 
			&& (strlen(path) > 0))
          		strcat (pathname,"/");
		strcat (pathname,subdir[indexdir]);

		scan_directory (searchfile,pathname);

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

	return;
}	/* end scan_directory */

/*	Alloca memoria e vi salva la stringa */

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

	nameadd = (char *) AllocMem (strlen(string)+1,0);
	if (nameadd == NULL)
		{
		printf ("Non c'e' abbastanza memoria per le directory!\n");
		close_things ();
		exit (7);
		}
	strcpy (nameadd, string);

	/* ritorna indirizzo strnga allocata */
	return (nameadd);

}	/*end adddir*/

void main( argc,argv)
int argc;
char * argv[];
{
	void scan_directory ();
	void UnLock ();

	struct FileLock * dir;
	char path[130];			/* nome del volume */
	char devname[32];
	char searchfile[32];
	char * ch;
	UBYTE i;

	if ((argc > 3) || (argc == 1))
		printf ("Uso: where <filename> <devname>\n");
	else
		{
		ifoundit = FALSE;
		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]);
		
		for (ch = searchfile; *ch != '\0'; ch++)
			*ch = toupper (*ch);
		/* Get Lock on disk */
		if ((dir = (struct FileLock *)Lock (devname,ACCESS_READ)) == NULL)
			{
			printf ("Non ho ottenuto il lock del device %s\n",
				devname);
			printf ("Muori Cesare!\n");
			close_things ();
			exit (5);
			}
		else
			strcpy (path, devname);
		/* DO IT TO IT! */
		scan_directory (searchfile,path);
		}
	close_things ();
} /* end main */

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