/*
 * htree.c --- hash tree routines
 *
 * Copyright (C) 2002 Theodore Ts'o.  This file may be redistributed
 * under the terms of the GNU Public License.
 */

#include "config.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <sys/types.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
extern int optind;
extern char *optarg;
#endif

#include "debugfs.h"
#include "uuid/uuid.h"
#include "e2p/e2p.h"

static FILE *pager;

static void htree_dump_leaf_node(ext2_filsys fs, ext2_ino_t ino,
				 struct ext2_inode *inode,
				 struct ext2_dx_root_info * rootnode,
				 blk64_t blk, char *buf)
{
	errcode_t	errcode;
	struct ext2_dir_entry *dirent;
	int		thislen, col = 0;
	unsigned int	offset = 0;
	char		name[EXT2_NAME_LEN + 1];
	char		tmp[EXT2_NAME_LEN + 64];
	blk64_t		pblk;
	ext2_dirhash_t 	hash, minor_hash;
	unsigned int	rec_len;
	int		hash_alg;
	int		csum_size = 0;

	if (ext2fs_has_feature_metadata_csum(fs->super))
		csum_size = sizeof(struct ext2_dir_entry_tail);

	errcode = ext2fs_bmap2(fs, ino, inode, buf, 0, blk, 0, &pblk);
	if (errcode) {
		com_err("htree_dump_leaf_node", errcode,
			"while mapping logical block %llu\n", blk);
		return;
	}

	fprintf(pager, "Reading directory block %llu, phys %llu\n", blk, pblk);
	errcode = ext2fs_read_dir_block4(current_fs, pblk, buf, 0, ino);
	if (errcode) {
		com_err("htree_dump_leaf_node", errcode,
			"while reading block %llu (%llu)\n",
			blk, pblk);
		return;
	}
	hash_alg = rootnode->hash_version;
	if ((hash_alg <= EXT2_HASH_TEA) &&
	    (fs->super->s_flags & EXT2_FLAGS_UNSIGNED_HASH))
		hash_alg += 3;

	while (offset < fs->blocksize) {
		dirent = (struct ext2_dir_entry *) (buf + offset);
		errcode = ext2fs_get_rec_len(fs, dirent, &rec_len);
		if (errcode) {
			com_err("htree_dump_leaf_inode", errcode,
				"while getting rec_len for block %lu",
				(unsigned long) blk);
			return;
		}
		thislen = ext2fs_dirent_name_len(dirent);
		if (((offset + rec_len) > fs->blocksize) ||
		    (rec_len < 8) ||
		    ((rec_len % 4) != 0) ||
		    ((unsigned) thislen + 8 > rec_len)) {
			fprintf(pager, "Corrupted directory block (%llu)!\n",
				blk);
			break;
		}
		strncpy(name, dirent->name, thislen);
		name[thislen] = '\0';
		errcode = ext2fs_dirhash(hash_alg, name,
					 thislen, fs->super->s_hash_seed,
					 &hash, &minor_hash);
		if (errcode)
			com_err("htree_dump_leaf_node", errcode,
				"while calculating hash");
		if ((offset == fs->blocksize - csum_size) &&
		    (dirent->inode == 0) &&
		    (dirent->rec_len == csum_size) &&
		    (dirent->name_len == EXT2_DIR_NAME_LEN_CSUM)) {
			struct ext2_dir_entry_tail *t;

			t = (struct ext2_dir_entry_tail *) dirent;

			snprintf(tmp, EXT2_NAME_LEN + 64,
				 "leaf block checksum: 0x%08x  ",
				 t->det_checksum);
		} else {
			snprintf(tmp, EXT2_NAME_LEN + 64,
				 "%u 0x%08x-%08x (%d) %s   ",
				 dirent->inode, hash, minor_hash,
				 rec_len, name);
		}
		thislen = strlen(tmp);
		if (col + thislen > 80) {
			fprintf(pager, "\n");
			col = 0;
		}
		fprintf(pager, "%s", tmp);
		col += thislen;
		offset += rec_len;
	}
	fprintf(pager, "\n");
}


static void htree_dump_int_block(ext2_filsys fs, ext2_ino_t ino,
				 struct ext2_inode *inode,
				 struct ext2_dx_root_info * rootnode,
				 blk64_t blk, char *buf, int level);


static void htree_dump_int_node(ext2_filsys fs, ext2_ino_t ino,
				struct ext2_inode *inode,
				struct ext2_dx_root_info * rootnode,
				struct ext2_dx_entry *ent,
				char *buf, int level)
{
	struct ext2_dx_countlimit	dx_countlimit;
	struct ext2_dx_tail		*tail;
	int				hash, i;
	int				limit, count;
	int				remainder;

	dx_countlimit = *((struct ext2_dx_countlimit *) ent);
	count = ext2fs_le16_to_cpu(dx_countlimit.count);
	limit = ext2fs_le16_to_cpu(dx_countlimit.limit);

	fprintf(pager, "Number of entries (count): %d\n", count);
	fprintf(pager, "Number of entries (limit): %d\n", limit);

	remainder = fs->blocksize - (limit * sizeof(struct ext2_dx_entry));
	if (ent == (struct ext2_dx_entry *)(rootnode + 1))
		remainder -= sizeof(struct ext2_dx_root_info) + 24;
	else
		remainder -= 8;
	if (ext2fs_has_feature_metadata_csum(fs->super) &&
	    remainder == sizeof(struct ext2_dx_tail)) {
		tail = (struct ext2_dx_tail *)(ent + limit);
		fprintf(pager, "Checksum: 0x%08x\n",
			ext2fs_le32_to_cpu(tail->dt_checksum));
	}

	for (i=0; i < count; i++) {
		hash = i ? ext2fs_le32_to_cpu(ent[i].hash) : 0;
		fprintf(pager, "Entry #%d: Hash 0x%08x%s, block %u\n", i,
			hash, (hash & 1) ? " (**)" : "",
			ext2fs_le32_to_cpu(ent[i].block));
		}

	fprintf(pager, "\n");

	for (i=0; i < count; i++) {
		unsigned int hashval, block;

		hashval = ext2fs_le32_to_cpu(ent[i].hash);
		block = ext2fs_le32_to_cpu(ent[i].block);
		fprintf(pager, "Entry #%d: Hash 0x%08x, block %u\n", i,
		       i ? hashval : 0, block);
		if (level)
			htree_dump_int_block(fs, ino, inode, rootnode,
					     block, buf, level-1);
		else
			htree_dump_leaf_node(fs, ino, inode, rootnode,
					     block, buf);
	}

	fprintf(pager, "---------------------\n");
}

static void htree_dump_int_block(ext2_filsys fs, ext2_ino_t ino,
				 struct ext2_inode *inode,
				 struct ext2_dx_root_info * rootnode,
				 blk64_t blk, char *buf, int level)
{
	char		*cbuf;
	errcode_t	errcode;
	blk64_t		pblk;

	cbuf = malloc(fs->blocksize);
	if (!cbuf) {
		fprintf(pager, "Couldn't allocate child block.\n");
		return;
	}

	errcode = ext2fs_bmap2(fs, ino, inode, buf, 0, blk, 0, &pblk);
	if (errcode) {
		com_err("htree_dump_int_block", errcode,
			"while mapping logical block %llu\n", blk);
		goto errout;
	}

	errcode = io_channel_read_blk64(current_fs->io, pblk, 1, buf);
	if (errcode) {
		com_err("htree_dump_int_block", errcode,
			"while 	reading block %llu\n", blk);
		goto errout;
	}

	htree_dump_int_node(fs, ino, inode, rootnode,
			    (struct ext2_dx_entry *) (buf+8),
			    cbuf, level);
errout:
	free(cbuf);
}



void do_htree_dump(int argc, char *argv[])
{
	ext2_ino_t	ino;
	struct ext2_inode inode;
	blk64_t		blk;
	char		*buf = NULL;
	struct 		ext2_dx_root_info  *rootnode;
	struct 		ext2_dx_entry *ent;
	errcode_t	errcode;

	if (check_fs_open(argv[0]))
		return;

	pager = open_pager();

	if (common_inode_args_process(argc, argv, &ino, 0))
		goto errout;

	if (debugfs_read_inode(ino, &inode, argv[1]))
		goto errout;

	if (!LINUX_S_ISDIR(inode.i_mode)) {
		com_err(argv[0], 0, "Not a directory");
		goto errout;
	}

	if ((inode.i_flags & EXT2_BTREE_FL) == 0) {
		com_err(argv[0], 0, "Not a hash-indexed directory");
		goto errout;
	}

	buf = malloc(2*current_fs->blocksize);
	if (!buf) {
		com_err(argv[0], 0, "Couldn't allocate htree buffer");
		goto errout;
	}

	errcode = ext2fs_bmap2(current_fs, ino, &inode, buf, 0, 0, 0, &blk);
	if (errcode) {
		com_err("do_htree_block", errcode,
			"while mapping logical block 0\n");
		goto errout;
	}

	errcode = io_channel_read_blk64(current_fs->io, blk,
					1, buf);
	if (errcode) {
		com_err(argv[0], errcode, "Error reading root node");
		goto errout;
	}

	rootnode = (struct ext2_dx_root_info *) (buf + 24);

	fprintf(pager, "Root node dump:\n");
	fprintf(pager, "\t Reserved zero: %u\n", rootnode->reserved_zero);
	fprintf(pager, "\t Hash Version: %d\n", rootnode->hash_version);
	fprintf(pager, "\t Info length: %d\n", rootnode->info_length);
	fprintf(pager, "\t Indirect levels: %d\n", rootnode->indirect_levels);
	fprintf(pager, "\t Flags: %d\n", rootnode->unused_flags);

	ent = (struct ext2_dx_entry *) (buf + 24 + rootnode->info_length);

	htree_dump_int_node(current_fs, ino, &inode, rootnode, ent,
			    buf + current_fs->blocksize,
			    rootnode->indirect_levels);

errout:
	free(buf);
	close_pager(pager);
}

/*
 * This function prints the hash of a given file.
 */
void do_dx_hash(int argc, char *argv[])
{
	ext2_dirhash_t hash, minor_hash;
	errcode_t	err;
	int		c;
	int		hash_version = 0;
	__u32		hash_seed[4];

	hash_seed[0] = hash_seed[1] = hash_seed[2] = hash_seed[3] = 0;

	reset_getopt();
	while ((c = getopt (argc, argv, "h:s:")) != EOF) {
		switch (c) {
		case 'h':
			hash_version = e2p_string2hash(optarg);
			if (hash_version < 0)
				hash_version = atoi(optarg);
			break;
		case 's':
			if (uuid_parse(optarg, (unsigned char *) hash_seed)) {
				fprintf(stderr, "Invalid UUID format: %s\n",
					optarg);
				return;
			}
			break;
		default:
			goto print_usage;
		}
	}
	if (optind != argc-1) {
	print_usage:
		com_err(argv[0], 0, "usage: dx_hash [-h hash_alg] "
			"[-s hash_seed] filename");
		return;
	}
	err = ext2fs_dirhash(hash_version, argv[optind], strlen(argv[optind]),
			     hash_seed, &hash, &minor_hash);
	if (err) {
		com_err(argv[0], err, "while caclulating hash");
		return;
	}
	printf("Hash of %s is 0x%0x (minor 0x%0x)\n", argv[optind],
	       hash, minor_hash);
}

/*
 * Search for particular directory entry (useful for debugging very
 * large hash tree directories that have lost some blocks from the
 * btree index).
 */
struct process_block_struct {
	char	*search_name;
	char	*buf;
	int	len;
};

static int search_dir_block(ext2_filsys fs, blk64_t *blocknr,
			    e2_blkcnt_t blockcnt, blk64_t ref_blk,
			    int ref_offset, void *priv_data);

void do_dirsearch(int argc, char *argv[])
{
	ext2_ino_t	inode;
	struct process_block_struct pb;

	if (check_fs_open(argv[0]))
		return;

	if (argc != 3) {
		com_err(0, 0, "Usage: dirsearch dir filename");
		return;
	}

	inode = string_to_inode(argv[1]);
	if (!inode)
		return;

	pb.buf = malloc(current_fs->blocksize);
	if (!pb.buf) {
		com_err("dirsearch", 0, "Couldn't allocate buffer");
		return;
	}
	pb.search_name = argv[2];
	pb.len = strlen(pb.search_name);

	ext2fs_block_iterate3(current_fs, inode, BLOCK_FLAG_READ_ONLY, 0,
			      search_dir_block, &pb);

	free(pb.buf);
}


static int search_dir_block(ext2_filsys fs, blk64_t *blocknr,
			    e2_blkcnt_t blockcnt,
			    blk64_t ref_blk EXT2FS_ATTR((unused)),
			    int ref_offset EXT2FS_ATTR((unused)),
			    void *priv_data)
{
	struct process_block_struct *p;
	struct ext2_dir_entry *dirent;
	errcode_t	       	errcode;
	unsigned int		offset = 0;
	unsigned int		rec_len;

	if (blockcnt < 0)
		return 0;

	p = (struct process_block_struct *) priv_data;

	errcode = io_channel_read_blk64(current_fs->io, *blocknr, 1, p->buf);
	if (errcode) {
		com_err("search_dir_block", errcode,
			"while reading block %lu", (unsigned long) *blocknr);
		return BLOCK_ABORT;
	}

	while (offset < fs->blocksize) {
		dirent = (struct ext2_dir_entry *) (p->buf + offset);
		errcode = ext2fs_get_rec_len(fs, dirent, &rec_len);
		if (errcode) {
			com_err("htree_dump_leaf_inode", errcode,
				"while getting rec_len for block %lu",
				(unsigned long) *blocknr);
			return BLOCK_ABORT;
		}
		if (dirent->inode &&
		    p->len == ext2fs_dirent_name_len(dirent) &&
		    strncmp(p->search_name, dirent->name,
			    p->len) == 0) {
			printf("Entry found at logical block %lld, "
			       "phys %llu, offset %u\n", (long long)blockcnt,
			       *blocknr, offset);
			printf("offset %u\n", offset);
			return BLOCK_ABORT;
		}
		offset += rec_len;
	}
	return 0;
}

