/*
 * 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, ss_argv_t argv, int sci_idx EXT2FS_ATTR((unused)),
	      void *infop EXT2FS_ATTR((unused)))
{
	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 && (labs(now - secs) > (long) inode.i_dtime)))
			goto next;

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

		if (ext2fs_inode_has_valid_blocks2(current_fs, &inode)) {
			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) ||
		    inode.i_flags & EXT4_INLINE_DATA_FL) {
			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 = (__s32) 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,
			(unsigned long long) delarray[i].size,
			(long long) delarray[i].free_blocks,
			(long long) 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;
}



