/*
 * lsdel.c --- routines to try to help a user recover a deleted file.
 *
 * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
 * 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>
#include <sys/stat.h>

#include "debugfs.h"

struct deleted_info {
	ext2_ino_t	ino;
	unsigned short	mode;
	__u32		uid;
	__u64		size;
	time_t		dtime;
	e2_blkcnt_t	num_blocks;
	e2_blkcnt_t	free_blocks;
};

struct lsdel_struct {
	ext2_ino_t		inode;
	e2_blkcnt_t		num_blocks;
	e2_blkcnt_t		free_blocks;
	e2_blkcnt_t		bad_blocks;
};

static int deleted_info_compare(const void *a, const void *b)
{
	const struct deleted_info *arg1, *arg2;

	arg1 = (const struct deleted_info *) a;
	arg2 = (const struct deleted_info *) b;

	return arg1->dtime - arg2->dtime;
}

static int lsdel_proc(ext2_filsys fs,
		      blk64_t	*block_nr,
		      e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
		      blk64_t ref_block EXT2FS_ATTR((unused)),
		      int ref_offset EXT2FS_ATTR((unused)),
		      void *private)
{
	struct lsdel_struct *lsd = (struct lsdel_struct *) private;

	lsd->num_blocks++;

	if (*block_nr < fs->super->s_first_data_block ||
	    *block_nr >= ext2fs_blocks_count(fs->super)) {
		lsd->bad_blocks++;
		return BLOCK_ABORT;
	}

	if (!ext2fs_test_block_bitmap2(fs->block_map,*block_nr))
		lsd->free_blocks++;

	return 0;
}

void do_lsdel(int argc, char **argv)
{
	struct lsdel_struct 	lsd;
	struct deleted_info	*delarray;
	int			num_delarray, max_delarray;
	ext2_inode_scan		scan = 0;
	ext2_ino_t		ino;
	struct ext2_inode	inode;
	errcode_t		retval;
	char			*block_buf;
	int			i;
 	long			secs = 0;
 	char			*tmp;
	time_t			now;
	FILE			*out;

	if (common_args_process(argc, argv, 1, 2, "list_deleted_inodes",
				"[secs]", 0))
		return;

	if (argc > 1) {
		secs = strtol(argv[1],&tmp,0);
		if (*tmp) {
			com_err(argv[0], 0, "Bad time - %s",argv[1]);
			return;
		}
	}

	now = current_fs->now ? current_fs->now : time(0);
	max_delarray = 100;
	num_delarray = 0;
	delarray = malloc(max_delarray * sizeof(struct deleted_info));
	if (!delarray) {
		com_err("ls_deleted_inodes", ENOMEM,
			"while allocating deleted information storage");
		exit(1);
	}

	block_buf = malloc(current_fs->blocksize * 3);
	if (!block_buf) {
		com_err("ls_deleted_inodes", ENOMEM, "while allocating block buffer");
		goto error_out;
	}

	retval = ext2fs_open_inode_scan(current_fs, 0, &scan);
	if (retval) {
		com_err("ls_deleted_inodes", 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("ls_deleted_inodes", retval,
			"while starting inode scan");
		goto error_out;
	}

	while (ino) {
		if ((inode.i_dtime == 0) ||
		    (secs && ((unsigned) abs(now - secs) > inode.i_dtime)))
			goto next;

		lsd.inode = ino;
		lsd.num_blocks = 0;
		lsd.free_blocks = 0;
		lsd.bad_blocks = 0;

		retval = ext2fs_block_iterate3(current_fs, ino,
					       BLOCK_FLAG_READ_ONLY, block_buf,
					       lsdel_proc, &lsd);
		if (retval) {
			com_err("ls_deleted_inodes", retval,
				"while calling ext2fs_block_iterate2");
			goto next;
		}
		if (lsd.free_blocks && !lsd.bad_blocks) {
			if (num_delarray >= max_delarray) {
				max_delarray += 50;
				delarray = realloc(delarray,
			   max_delarray * sizeof(struct deleted_info));
				if (!delarray) {
					com_err("ls_deleted_inodes",
						ENOMEM,
						"while reallocating array");
					exit(1);
				}
			}

			delarray[num_delarray].ino = ino;
			delarray[num_delarray].mode = inode.i_mode;
			delarray[num_delarray].uid = inode_uid(inode);
			delarray[num_delarray].size = EXT2_I_SIZE(&inode);
			delarray[num_delarray].dtime = inode.i_dtime;
			delarray[num_delarray].num_blocks = lsd.num_blocks;
			delarray[num_delarray].free_blocks = lsd.free_blocks;
			num_delarray++;
		}

	next:
		do {
			retval = ext2fs_get_next_inode(scan, &ino, &inode);
		} while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE);
		if (retval) {
			com_err("ls_deleted_inodes", retval,
				"while doing inode scan");
			goto error_out;
		}
	}

	out = open_pager();

	fprintf(out, " Inode  Owner  Mode    Size      Blocks   Time deleted\n");

	qsort(delarray, num_delarray, sizeof(struct deleted_info),
	      deleted_info_compare);

	for (i = 0; i < num_delarray; i++) {
		fprintf(out, "%6u %6d %6o %6llu %6lld/%6lld %s",
			delarray[i].ino,
			delarray[i].uid, delarray[i].mode, delarray[i].size,
			delarray[i].free_blocks, delarray[i].num_blocks,
			time_to_string(delarray[i].dtime));
	}
	fprintf(out, "%d deleted inodes found.\n", num_delarray);
	close_pager(out);

error_out:
	free(block_buf);
	free(delarray);
	if (scan)
		ext2fs_close_inode_scan(scan);
	return;
}



