/*
 * 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 <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,
		      blk_t	*block_nr,
		      e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
		      blk_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 >= fs->super->s_blocks_count) {
		lsd->bad_blocks++;
		return BLOCK_ABORT;
	}

	if (!ext2fs_test_block_bitmap(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, "ls_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_iterate2(current_fs, ino, 0, 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 = inode.i_size;
			if (!LINUX_S_ISDIR(inode.i_mode))
				delarray[num_delarray].size |= 
					((__u64) inode.i_size_high << 32);
			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;
}



