/*
 * ncheck.c --- given a list of inodes, generate a list of names
 *
 * Copyright (C) 1994 Theodore Ts'o.  This file may be redistributed
 * under the terms of the GNU Public License.
 */

#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"

struct inode_walk_struct {
	ext2_ino_t		dir;
	ext2_ino_t		*iarray;
	int			inodes_left;
	int			num_inodes;
	int			position;
	char			*parent;
	unsigned int		get_pathname_failed:1;
	unsigned int		check_dirent:1;
};

static int ncheck_proc(struct ext2_dir_entry *dirent,
		       int	offset EXT2FS_ATTR((unused)),
		       int	blocksize EXT2FS_ATTR((unused)),
		       char	*buf EXT2FS_ATTR((unused)),
		       void	*private)
{
	struct inode_walk_struct *iw = (struct inode_walk_struct *) private;
	struct ext2_inode inode;
	errcode_t	retval;
	int		filetype = dirent->name_len >> 8;
	int		i;

	iw->position++;
	if (iw->position <= 2)
		return 0;
	for (i=0; i < iw->num_inodes; i++) {
		if (iw->iarray[i] == dirent->inode) {
			if (!iw->parent && !iw->get_pathname_failed) {
				retval = ext2fs_get_pathname(current_fs,
							     iw->dir,
							     0, &iw->parent);
				if (retval) {
					com_err("ncheck", retval,
		"while calling ext2fs_get_pathname for inode #%u", iw->dir);
					iw->get_pathname_failed = 1;
				}
			}
			if (iw->parent)
				printf("%u\t%s/%.*s", iw->iarray[i],
				       iw->parent,
				       (dirent->name_len & 0xFF), dirent->name);
			else
				printf("%u\t<%u>/%.*s", iw->iarray[i],
				       iw->dir,
				       (dirent->name_len & 0xFF), dirent->name);
			if (iw->check_dirent && filetype) {
				if (!debugfs_read_inode(dirent->inode, &inode,
							"ncheck") &&
				    filetype != ext2_file_type(inode.i_mode)) {
					printf("  <--- BAD FILETYPE");
				}
			}
			putc('\n', stdout);
		}
	}
	if (!iw->inodes_left)
		return DIRENT_ABORT;

	return 0;
}

void do_ncheck(int argc, char **argv)
{
	struct inode_walk_struct iw;
	int			c, i;
	ext2_inode_scan		scan = 0;
	ext2_ino_t		ino;
	struct ext2_inode	inode;
	errcode_t		retval;
	char			*tmp;

	iw.check_dirent = 0;

	reset_getopt();
	while ((c = getopt (argc, argv, "c")) != EOF) {
		switch (c) {
		case 'c':
			iw.check_dirent = 1;
			break;
		default:
			goto print_usage;
		}
	}
	argc -= optind;
	argv += optind;

	if (argc < 1) {
	print_usage:
		com_err(argv[0], 0, "Usage: ncheck [-c] <inode number> ...");
		return;
	}
	if (check_fs_open(argv[0]))
		return;

	iw.iarray = malloc(sizeof(ext2_ino_t) * argc);
	if (!iw.iarray) {
		com_err("ncheck", ENOMEM,
			"while allocating inode number array");
		return;
	}
	memset(iw.iarray, 0, sizeof(ext2_ino_t) * argc);

	for (i=0; i < argc; i++) {
		iw.iarray[i] = strtol(argv[i], &tmp, 0);
		if (*tmp) {
			com_err(argv[0], 0, "Bad inode - %s", argv[i]);
			goto error_out;
		}
	}

	iw.num_inodes = iw.inodes_left = argc;

	retval = ext2fs_open_inode_scan(current_fs, 0, &scan);
	if (retval) {
		com_err("ncheck", retval, "while opening inode scan");
		goto error_out;
	}

	do {
		retval = ext2fs_get_next_inode(scan, &ino, &inode);
	} while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE);
	if (retval) {
		com_err("ncheck", retval, "while starting inode scan");
		goto error_out;
	}

	printf("Inode\tPathname\n");
	while (ino) {
		if (!inode.i_links_count)
			goto next;
		/*
		 * To handle filesystems touched by 0.3c extfs; can be
		 * removed later.
		 */
		if (inode.i_dtime)
			goto next;
		/* Ignore anything that isn't a directory */
		if (!LINUX_S_ISDIR(inode.i_mode))
			goto next;

		iw.position = 0;
		iw.parent = 0;
		iw.dir = ino;
		iw.get_pathname_failed = 0;

		retval = ext2fs_dir_iterate(current_fs, ino, 0, 0,
					    ncheck_proc, &iw);
		ext2fs_free_mem(&iw.parent);
		if (retval) {
			com_err("ncheck", retval,
				"while calling ext2_dir_iterate");
			goto next;
		}

		if (iw.inodes_left == 0)
			break;

	next:
		do {
			retval = ext2fs_get_next_inode(scan, &ino, &inode);
		} while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE);

		if (retval) {
			com_err("ncheck", retval,
				"while doing inode scan");
			goto error_out;
		}
	}

error_out:
	free(iw.iarray);
	if (scan)
		ext2fs_close_inode_scan(scan);
	return;
}



