/* ********************************************************************
Programma ...... Enough.c
Versione ....... 1.01i - Luglio 1989
Autore ......... Bruce A. Barret
Software ....... Lattice C V5.02 / Aztec C V5.0a
Hardware ....... Amiga + Kickstart & WB V1.2/1.3
Sintassi ....... ENOUGH [{MEM|FAST|CHIP}| nnn[K] [EXISTS file]
                        DISK drv: fff[K]]   (per file script)
Note ........... Traduzione, debugging ed adattamento di L.Callegari
********************************************************************* */

#include <exec/types.h>
#include <ctype.h>
#include <exec/memory.h>
#include <libraries/dosextens.h>
#include <clib/macros.h>
#include <stdio.h>

#ifdef LATTICE
#include <string.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <stdlib.h>
#else
#include <functions.h>
#endif

/* Definizioni di costanti */

#define VERNO 1
#define RELNO 0
#define DATE  "13-May-86"
#define AUTHOR	Bruce A. Barrett

/*	Motivazioni di termine per cleanup()*/

#define	DIE_OK				0
#define	DIE_MEM				1
#define	DIE_NOOUTPUT		2
#define	DIE_BADARGS			3
#define	DIE_S_DIR			4
#define	DIE_D_DIR			5
#define	DIE_S_FILE			6
#define	DIE_D_FILE			7
#define	DIE_FIBOVERFLOW	8
#define	DIE_FIBUNDERFLOW 	9
#define	DIE_CTRL_C			10
#define	DIE_NOT_ENOUGH		11
#define MAX_KEYWD_LEN		12

/* Per debugging; se necessario porre a TRUE*/
#define FIX FALSE
#if FIX
#define	ROUTINE(foo)	kprintf(foo)	/* debug richiesto */
#else
#define	ROUTINE(foo)	/* negativo */
#endif

int		f_lock;
struct	FileInfoBlock *file_info_block;
int		cur_argc;
int		gl_argc;

/* Sopprime il requester "Please insert volume" */
APTR suppress_IO_err()
{
struct Process *my_proc;
APTR	old_window;
    
ROUTINE("suppress_IO_err\n");
my_proc = (struct Process *) FindTask("");
old_window = my_proc -> pr_WindowPtr;
my_proc -> pr_WindowPtr = (APTR) -1;
return( old_window );
}

/* Permette requester Please insert volume " */
    
void allow_IO_err( old_wind )
APTR	old_wind;
{
struct Process *my_proc;

ROUTINE("allow_IO_err\n");
my_proc = (struct Process *)FindTask("");
my_proc -> pr_WindowPtr = old_wind;
}
    
/* Dato un tipo di memoria, ne misura la quantità disponibile */

do_mem_type(argv, type)
char	*argv[]; int		type;
{
int		avail, need;
    
ROUTINE("do_mem_type\n" );
if ( cur_argc >= gl_argc )
	return(DIE_BADARGS);

avail = AvailMem(type);
sscanf(argv[cur_argc], "%d", &need);
cur_argc++;
if (need == 0)
	return( DIE_BADARGS );
if ( (need*1024) <= avail )
	return( DIE_OK );
else
	return( DIE_NOT_ENOUGH );
}

do_mem( argv )
char	*argv[];
{
ROUTINE("do_mem\n");
cur_argc++;
return( do_mem_type(argv, MEMF_LARGEST) );
}

do_chip(argv)
char	*argv[];
{
ROUTINE("do_chip\n");
cur_argc++;
return( do_mem_type(argv, MEMF_CHIP|MEMF_LARGEST) );
}

do_fast(argv)
char	*argv[];
{
ROUTINE("do_fast\n");
cur_argc++;
return( do_mem_type( argv, MEMF_FAST|MEMF_LARGEST) );
}

do_disk(argv)
char	*argv[];
{						/* do_disk */
int		need, ret_val;
LONG	my_lock, free;
BOOL	result;
APTR	old_ptr;
struct InfoData *info_data;
    
ROUTINE("do_disk\n");
info_data = 0;			/* Rimuove warning del Lattice */
cur_argc++;				/* Salta keyword DISK */
ret_val = DIE_NOT_ENOUGH;

/* Verifica il numero di argomenti sulla linea di comandi */
if ((cur_argc+1) >= gl_argc)
	return(DIE_BADARGS);

/* verifica l'esistenza del volume o del drive */
old_ptr = (APTR) suppress_IO_err();	/* Disabilita requester */
my_lock = Lock(argv[cur_argc], MODE_OLDFILE);
allow_IO_err(old_ptr);					/* Riabilita i requester */
cur_argc++;
if ( my_lock == 0 ) return( ret_val );

/* Legge informazioni sul volume */
info_data = (struct InfoData *) AllocMem(sizeof(*info_data), 0);
if (info_data == 0)
	{
	UnLock(my_lock);
	return(ret_val);
}

result = Info(my_lock, info_data);
if (!result)
{
	UnLock(my_lock);
	FreeMem(info_data, sizeof(*info_data));
	return(ret_val);
}
    
/* Legge l'ammontare di spazio sul disco necessario */

sscanf(argv[cur_argc], "%d", &need);
cur_argc++;
if (need == 0)
	{
	UnLock(my_lock);
	FreeMem(info_data, sizeof(*info_data));
	return(DIE_BADARGS);
	}
free = (info_data->id_NumBlocks - info_data->id_NumBlocksUsed) *
info_data -> id_BytesPerBlock;

UnLock(my_lock);
FreeMem(info_data, sizeof(*info_data));
if (free > (need*1024) ) ret_val = DIE_OK;
	return(ret_val); 
}

do_exists(argv)
char	*argv[];
{
	LONG	my_lock;
	APTR	old_ptr;

	ROUTINE("do_exists\n");
	cur_argc++;
	old_ptr = (APTR) suppress_IO_err();	/* Disabilita requester */
	if (cur_argc >= gl_argc)
		return(DIE_BADARGS);
	my_lock = Lock( argv[cur_argc], MODE_OLDFILE );
	allow_IO_err( old_ptr );
	cur_argc++;
	if ( my_lock == 0 )
		return( DIE_NOT_ENOUGH );
	UnLock( my_lock );
	return( DIE_OK );
}

/* Copia stringa trasformandola in maiuscolo */
void uc_copy(to, from)
char	*to,	*from;
{
ROUTINE("uc_copy\n");
while ( *to++ = toupper(*from++) )
	;
}

/* Verifica pressione di CTRL-C e chiama eventualmente cleanup() */
void testbreak(argv)
char	*argv[];
{
void cleanup();
LONG	newsigs,	oldsigs;
    
ROUTINE("testbreak\n");
newsigs = 0;
   
oldsigs = SetSignal( newsigs, SIGBREAKF_CTRL_C );
if (oldsigs & (SIGBREAKF_CTRL_C) )
	cleanup(argv, DIE_CTRL_C);
}

void cleanup( argv, cause )
int	cause;	char	*argv[];
{
ROUTINE("cleanup\n");

	switch (cause)
	{
		case DIE_OK:	
		case DIE_MEM:	
		case DIE_NOOUTPUT:
		case DIE_S_DIR:
		case DIE_D_DIR:	
		case DIE_S_FILE:
		case DIE_D_FILE:	
		case DIE_FIBOVERFLOW:	
		case DIE_FIBUNDERFLOW:
		case DIE_NOT_ENOUGH:
		break;
		case DIE_BADARGS:
		printf("Errore: Sintassi del comando scorretta!\n");
		printf("Sintassi: ENOUGH [{MEM|FAST|CHIP} nnn[K]] [EXISTS file\n");
		printf("                 [DISK drv: fff[K]]\n");
		printf("nnn è il numero di K RAM richieste, fff è il nome di K\n");
		printf("sul disco \"drv:\" richiesto, file è il numero di path\n");
		printf("del quale si desidera verificare l'esistenza.\n");
		break;
	case DIE_CTRL_C:
		printf("*BREAK* Fermato dall'utente.\n");
		break;
	}
		ROUTINE("exit\n");
		if (cause == DIE_OK)
			exit( 0L );
		else if (cause == DIE_BADARGS)
			exit( 20L );	/* Errore sintattico! */
		else
			exit( 5L );
	
}

void main( argc, argv )
int argc; char *argv[];
{
char		key_wd[MAX_KEYWD_LEN];
int		ret_val;

ROUTINE("main\n");
gl_argc = argc;

ret_val = DIE_OK;
cur_argc = 1;
while ( (cur_argc < argc) && (ret_val == DIE_OK))
	{
testbreak();
uc_copy(key_wd, argv[cur_argc]);

	if (0 == strcmp(&key_wd[0],"MEM"))
		ret_val = do_mem(argv);
	else if (0 == strcmp(&key_wd[0],"CHIP"))
		ret_val = do_chip(argv);
	else if (0 == strcmp(&key_wd[0],"FAST"))
		ret_val = do_fast(argv);

	else if (0 == strcmp(&key_wd[0],"DISK"))
		ret_val = do_disk(argv);
	else if (0 == strcmp(&key_wd[0],"EXISTS"))
		ret_val = do_exists(argv);
	else 
		{
		ret_val = DIE_BADARGS;
		printf("%s: Version %ld.%ld, %s\n", argv[0], VERNO, RELNO, DATE);
		}
	}
cleanup(argv, ret_val);
}
