/*
 * Copyright (C) 2000-2002 ASANO Masahiro
 */

#include <sys/stat.h>
#include <unistd.h>
#include "crash.h"

PRIVATE addr_t inode();
const commandtable_t command_inode =
	{"inode", inode, "[-f] [address]", "print inode table"};

addr_t inode_hashtable_addr;
addr_t inode_unused_addr;

extern addr_t print_inode();

PRIVATE addr_t
inode()
{
	int i, c;
	int full = 0;
	addr_t addr = 0;
#define HASH_SIZE 256
	struct list_head inode_hashtable[HASH_SIZE];
	extern const char head_inode[];

	while ((c = getopt(argcnt, args, "f")) != EOF) {
		switch (c) {
		case 'f':
			full = 1;
			break;
		default:
			THROW(usage);
		}
	}

	GETADDR(inode_hashtable);
	GETADDR(inode_unused);

	if (argcnt > optind) {
		if (!full) mprintf(head_inode);
		for (i = optind; i < argcnt; i++) {
			addr = getvalue(args[i]);
			if (full) mprintf(head_inode);
			addr = print_inode(addr, full);
		}
	} else {
		memread(inode_hashtable_addr, sizeof(inode_hashtable), &inode_hashtable, "inode_hashtable");
		for (i = 0; i < HASH_SIZE; i++) {
			mprintf("\nHASH TABLE %d\n", i);
			if (!full) mprintf(head_inode);
			for (addr = (addr_t)inode_hashtable[i].next; addr != (addr_t)&((struct list_head *)inode_hashtable_addr)[i];) {
				if (full) mprintf(head_inode);
				addr = print_inode(addr, full);
			}
		}
	}
	return addr;
}
