/*
 * Copyright (C) 1993, 1994 by Ralf Baechle (linux@uni-koblenz.de)
 *
 * This file is part of Minix-Handler, an AmigaDOS Filehandler to access
 * Minix filesystems via AmigaDOS.
 *
 * Minix-Handler is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * Minix-Handler is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <stdio.h>

#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <utility/tagitem.h>

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

#include "minix.h"

static	ULONG	Size;
static	APTR	RamDskBuff = NULL;

BOOL LoadRamDiskImage( char *name)
{
	BPTR			RamH = NULL;
	struct FileInfoBlock	*RamFIB = NULL;
	BOOL			Success = FALSE;
	ULONG			ReallyRead;

	if(!(RamFIB=AllocDosObject(DOS_FIB, TAG_DONE))) {
		printf("Can't allocate dosobject.\n");
		goto fail;
		}
	if(!(RamH = Open(name, MODE_OLDFILE))) {
		printf("Can't open %s.\n", name);
		goto fail;
		}
	if(ExamineFH( RamH, RamFIB ) != DOSTRUE) {
		printf("Can't examine filehandle.\n");
		goto fail;
		}
	Size = RamFIB->fib_Size;
//	Size = 262144;
//	Size = 901120;
	printf("Size of %s is %d bytes.\n", name, Size);
	if(!(RamDskBuff=AllocMem(Size, MEMF_ANY))) {
		printf("Can't Alloc DskBuff.\n");
		goto fail;
		}
	ReallyRead = Read( RamH, RamDskBuff, Size);
	if(ReallyRead != Size) {
		printf("Only read %d bytes.\n", ReallyRead);
		printf("IoError: %d.\n", IoErr());
		PrintFault(IoErr(), "DOS Error: ");
		printf("Can't read image.\n");
		goto fail;
		}
	Success = TRUE;

fail:
	if(RamFIB)			FreeDosObject(DOS_FIB, RamFIB);
	if(RamH)			Close(RamH);
	if(RamDskBuff && !Success)	FreeMem( RamDskBuff, Size);

	return Success;
}

void UnLoadRamDiskImage(void)
{
	if(RamDskBuff)	FreeMem( RamDskBuff, Size );
}

void PrintSuper(void)
{
	struct minix_super_block	*sp;

	sp = (struct minix_super_block *) ((UBYTE*)RamDskBuff + 1024);

	printf("s_ninodes      : %d\n", sp->s_ninodes       );
	printf("s_nzones       : %d\n", sp->s_nzones        );
	printf("s_imap_blocks  : %d\n", sp->s_imap_blocks   );
	printf("s_zmap_blocks  : %d\n", sp->s_zmap_blocks   );
	printf("s_firstdatazone: %d\n", sp->s_firstdatazone );
	printf("s_log_zone_size: %d\n", sp->s_log_zone_size );
	printf("s_max_size     : %d\n", sp->s_max_size      );
	printf("s_magic        : %d\n", sp->s_magic         );
	printf("s_magic must be: %d\n", MINIX_SUPER_MAGIC );
}

void PrintInodes(void)
{
	struct minix_super_block	*sp;
	struct minix_inode		*mi;
	ULONG				i, j;

	mi = (struct minix_inode *) ((UBYTE*)RamDskBuff + 4096);
	sp = (struct minix_super_block *) ((UBYTE*)RamDskBuff + 1024);

	for(i=0;i<sp->s_ninodes;i++) {
		printf("\nInode #%d\n", i+1 );
		printf("i_mode  : %o\n", mi[i].i_mode   );
		printf("i_uid   : %d\n", mi[i].i_uid    );
		printf("i_size  : %d\n", mi[i].i_size   );
		printf("i_time  : %d\n", mi[i].i_time   );
		printf("i_gid   : %d\n", mi[i].i_gid    );
		printf("i_nlinks: %d\n", mi[i].i_nlinks );
		printf("i_zone  : ");
		for(j=0;j<9;j++)
			printf("%d ", mi[i].i_zone[j]   );
		printf("\n");
		}
}

int main( int argc, char *argv[])
{
//	if(!LoadRamDiskImage("ramdisk.img")) goto fail;
//	if(!LoadRamDiskImage("flat:dr0")) goto fail;
	if(!LoadRamDiskImage("rt")) goto fail;

	PrintSuper();
	printf("\n\n\n");
	PrintInodes();

	UnLoadRamDiskImage();
fail:	return 0;
}
