/*\
 *
 * RDBList_Prep «Freeware» © Steven Norburn <sndev@bigfoot.com>.
 *
 *	This converts and writes a RDB List into real Rigid Disk Blocks.
 *
 *	It requires OS 3.5+ hdwrench.library !
 *
 * History,
 *
 * 0.90	(30.12.00)
 *	First release.
 *
\*/

#define __USE_SYSBASE

#include <proto/exec.h>
#include <proto/dos.h>

#include	<libraries/HDWrench.h>
#include	<pragmas/HDWrench_pragmas.h>
#define	USE_SUGGESTED_MESSAGES

#define PROG "RDBList_Prep"
#define VERSION "«Freeware» 0.90ß"
#define DATE "30.12.00"
#define COPYRIGHT "© Steven Norburn <sndev@bigfoot.com>"

static char version_string[] =
"$VER: "PROG" "VERSION" ("DATE") " COPYRIGHT;

static char template[] =
"D=DEVICE/K/A,U=UNIT/K/A/N,F=FILE/A";

enum
{
	ARG_DEVICE,
	ARG_BU,
	ARG_FILE,
	NUM_ARGS
};

LONG arg_array[NUM_ARGS];

struct ExecBase *SysBase;
struct DosLibrary *DOSBase;
struct HDWLibrary	*HDWBase;

int Main(void);

 /*--------------*\
<*> Startup Code <*>
 \*--------------*/

int __saveds main(void) /* __saveds Restore Globel Data Pointer ! */
{
int ret = RETURN_FAIL;
struct RDArgs *rdargs;

	SysBase = (*(struct ExecBase **) 4);

	if((DOSBase = (struct DosLibrary *)OpenLibrary(DOSNAME, 37L)))
	{
		Printf
		(
			"\n%s\n\n"
			"*** WARNING ***, This is a Rigid Disk Block Writing program !\n"
			"\n"
			,&version_string[6]
		);

		if(!(rdargs = ReadArgs(template, arg_array, NULL))){
			Printf("Usage: "PROG" %s\n", template);
			ret = RETURN_WARN;
		}
		else{
			ret = Main();
			FreeArgs(rdargs);
		}
		CloseLibrary((struct Library *)DOSBase);
	}
	return(ret);
}

 /*--------------*\
<*> HDW_WriteRDB <*>
 \*--------------*/

/*\
 *	Description:
 *		Traverse "BootBlocks" RDB structures given.
 *		Write them to disk in the order the structures exist in the structure
 *		linked list.
 *
 *	Code:
 * 	Based on code provided by Joanne Dow, Wizardess Designs, Jan 1999
\*/

void HDW_WriteRDBs (char *devicename, ULONG baseunit, char *filename)
{
ULONG		rsuccess;
USHORT	rwsuccess;
BOOL		deviceopen;
char		diskname[32];
ULONG		capacity;
ULONG		blocksize;

	Printf ( "Reading RDB list from %s.\n\n", filename );

	rsuccess = ReadMountfile ( baseunit, filename, devicename );
	if ( rsuccess != 0 )
	{
		Printf ( "Mountfile read failed: %lu\n", rsuccess );
		return;
	}

	Printf ( "Attempting to open: %s:%lu\n", devicename, baseunit );

	deviceopen = HDWOpenDevice ( devicename, baseunit );

	if ( !deviceopen )
	{
		Printf ( "No device was opened !\n");
		return;
	}

	if ( FindDiskName ( diskname ))
		Printf ("Name\t\t= %.28s.\n", diskname);
	else
		Printf ( "FindDiskName failed !\n" );

	if ( QueryCapacity ( &capacity, &blocksize ))
		Printf ( "Capacity\t= %ld blocks of %ld bytes.\n",
				 capacity, blocksize );
	else
		Printf ( "Capacity read failed !\n" );

	Printf("\nEnter 'y' to write this new RDB ? ");
	Flush( Output() );

	if( FGetC( Input() ) != 'y' ) return;

	if(SetSignal(0,0) & SIGBREAKF_CTRL_C) return;

	Printf ( "\nBeginning to write RDB.\n\n" );

	rwsuccess = WriteRDBs();

	if ( rwsuccess == 0 )
		Printf ( "You should now have a new RDB waiting.\n" );
	else if ( rwsuccess == 0xffff )
		Printf ( "RDB Write failed because this version does not have it supported.\n" );
	else
		Printf ( "DOODOO CITY! RDB Write failed: %d\n", rwsuccess );

	HDWCloseDevice();
	return;
}

 /*------*\
<*> MAIN <*>
 \*------*/

int Main(void)
{
char	*filename;
char	*devicename;
ULONG	baseunit;

	devicename	= (char *)	arg_array [ ARG_DEVICE];
	baseunit	= *(ULONG*) arg_array [ ARG_BU ];
	filename	= (char *) arg_array [ ARG_FILE ];

	if (!(SetSignal(0,0) & SIGBREAKF_CTRL_C))
	{
		Printf ("Device Name\t= %s\n", devicename);
		Printf ("Base Unit\t= %lu\n", baseunit);
		Printf ("File Name\t= %s\n\n", filename);

		if (( HDWBase = ( struct HDWLibrary *) OpenLibrary ( HDWBaseName, 0)) == NULL )
		{
			Printf( "Failed to open %s !\n", HDWBaseName);
			return (RETURN_FAIL);
		}
		else
		{
			HDW_WriteRDBs (devicename, baseunit, filename );
			CloseLibrary ( ( struct Library *) HDWBase );
		}
	}
	if(SetSignal(0,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
	{
		Printf("***Break\n");
		return(RETURN_FAIL);
	}
	return(RETURN_OK);
}
