/*
 * Copyright (C) 2003 ASANO Masahiro
 */

#include <unistd.h>
#include "crash.h"

/* BEGIN fs/lockd/svcsubs.c */
#define FILE_HASH_BITS		5
#define FILE_NRHASH		(1<<FILE_HASH_BITS)
/* END fs/lockd/svcsubs.c*/

PRIVATE addr_t nlm_rqst();
const commandtable_t command_nlm_rqst =
	{"nlm_rqst", nlm_rqst, "address", "print nlm_rqst table which is used by lockd"};
extern void prhead_nlm_rqst();
extern addr_t print_nlm_rqst();

PRIVATE addr_t nlm_file();
const commandtable_t command_nlm_file =
	{"nlm_file", nlm_file, "[address]", "print nlm_file table which is used by lockd"};
extern void prhead_nlm_file();
extern addr_t print_nlm_file();

PRIVATE addr_t nlm_block();
const commandtable_t command_nlm_block =
	{"nlm_block", nlm_block, "[address]", "print nlm_block table which is used by lockd"};
extern void prhead_nlm_block();
extern addr_t print_nlm_block();

addr_t nlm_blocked_addr;
addr_t nlm_files_addr;

PRIVATE addr_t
nlm_rqst()
{
	int c;
	int full = 0;
	addr_t addr = 0;

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

	if (argcnt == optind) {
		THROW(usage);
	} else {
		prhead_nlm_rqst();
		while (args[optind]) {
			addr = print_nlm_rqst(getvalue(args[optind]), full);
			optind++;
		}
	}

	return 0;
}

PRIVATE addr_t
nlm_file()
{
	int c;
	int full = 0;
	addr_t addr = 0;

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

	if (argcnt == optind) {
		int i;
		GETADDR(nlm_files);
		prhead_nlm_file();
		for (i = 0; i < FILE_NRHASH; i++) {
			memread(nlm_files_addr + sizeof(addr) * i, sizeof(addr),
				&addr, "nlm_files");
			while (addr) {
				addr = print_nlm_file(addr, full);
			}
		}

	} else {
		prhead_nlm_file();
		while (args[optind]) {
			addr = print_nlm_file(getvalue(args[optind]), full);
			optind++;
		}
	}

	return 0;
}

PRIVATE addr_t
nlm_block()
{
	int c;
	int full = 0;
	addr_t addr = 0;

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

	if (argcnt == optind) {
		/* nlm_blocked is both on fs/lockd/clntlock.c and
		   fs/lockd/svclock.c. We expect server side at this point */
		GETADDR(nlm_blocked);
		memread(nlm_blocked_addr, sizeof(addr), &addr, "nlm_blocked");

		prhead_nlm_block();
		while (addr) {
			addr = print_nlm_block(addr, full);
		}

	} else {
		prhead_nlm_block();
		while (args[optind]) {
			addr = print_nlm_block(getvalue(args[optind]), full);
			optind++;
		}
	}

	return 0;
}
