/*
 * e2undo.c - Replay an undo log onto an ext2/3/4 filesystem
 *
 * Copyright IBM Corporation, 2007
 * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
 *
 * %Begin-Header%
 * This file may be redistributed under the terms of the GNU Public
 * License.
 * %End-Header%
 */

#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#include <fcntl.h>
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#include "ext2fs/tdb.h"
#include "ext2fs/ext2fs.h"
#include "nls-enable.h"

unsigned char mtime_key[] = "filesystem MTIME";
unsigned char uuid_key[] = "filesystem UUID";
unsigned char blksize_key[] = "filesystem BLKSIZE";

char *prg_name;

static void usage(char *prg_name)
{
	fprintf(stderr,
		_("Usage: %s <transaction file> <filesystem>\n"), prg_name);
	exit(1);

}

static int check_filesystem(TDB_CONTEXT *tdb, io_channel channel)
{
	__u32   s_mtime;
	__u8    s_uuid[16];
	errcode_t retval;
	TDB_DATA tdb_key, tdb_data;
	struct ext2_super_block super;

	io_channel_set_blksize(channel, SUPERBLOCK_OFFSET);
	retval = io_channel_read_blk64(channel, 1, -SUPERBLOCK_SIZE, &super);
	if (retval) {
		com_err(prg_name,
			retval, _("Failed to read the file system data \n"));
		return retval;
	}

	tdb_key.dptr = mtime_key;
	tdb_key.dsize = sizeof(mtime_key);
	tdb_data = tdb_fetch(tdb, tdb_key);
	if (!tdb_data.dptr) {
		retval = EXT2_ET_TDB_SUCCESS + tdb_error(tdb);
		com_err(prg_name, retval,
			_("Failed tdb_fetch %s\n"), tdb_errorstr(tdb));
		return retval;
	}

	s_mtime = *(__u32 *)tdb_data.dptr;
	if (super.s_mtime != s_mtime) {

		com_err(prg_name, 0,
			_("The file system Mount time didn't match %u\n"),
			s_mtime);

		return  -1;
	}


	tdb_key.dptr = uuid_key;
	tdb_key.dsize = sizeof(uuid_key);
	tdb_data = tdb_fetch(tdb, tdb_key);
	if (!tdb_data.dptr) {
		retval = EXT2_ET_TDB_SUCCESS + tdb_error(tdb);
		com_err(prg_name, retval,
			_("Failed tdb_fetch %s\n"), tdb_errorstr(tdb));
		return retval;
	}
	memcpy(s_uuid, tdb_data.dptr, sizeof(s_uuid));
	if (memcmp(s_uuid, super.s_uuid, sizeof(s_uuid))) {
		com_err(prg_name, 0,
			_("The file system UUID didn't match \n"));
		return -1;
	}

	return 0;
}

static int set_blk_size(TDB_CONTEXT *tdb, io_channel channel)
{
	int block_size;
	errcode_t retval;
	TDB_DATA tdb_key, tdb_data;

	tdb_key.dptr = blksize_key;
	tdb_key.dsize = sizeof(blksize_key);
	tdb_data = tdb_fetch(tdb, tdb_key);
	if (!tdb_data.dptr) {
		retval = EXT2_ET_TDB_SUCCESS + tdb_error(tdb);
		com_err(prg_name, retval,
			_("Failed tdb_fetch %s\n"), tdb_errorstr(tdb));
		return retval;
	}

	block_size = *(int *)tdb_data.dptr;
#ifdef DEBUG
	printf("Block size %d\n", block_size);
#endif
	io_channel_set_blksize(channel, block_size);

	return 0;
}

int main(int argc, char *argv[])
{
	int c,force = 0;
	TDB_CONTEXT *tdb;
	TDB_DATA key, data;
	io_channel channel;
	errcode_t retval;
	int  mount_flags;
	blk64_t  blk_num;
	char *device_name, *tdb_file;
	io_manager manager = unix_io_manager;

#ifdef ENABLE_NLS
	setlocale(LC_MESSAGES, "");
	setlocale(LC_CTYPE, "");
	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
	textdomain(NLS_CAT_NAME);
#endif
	add_error_table(&et_ext2_error_table);

	prg_name = argv[0];
	while((c = getopt(argc, argv, "f")) != EOF) {
		switch (c) {
			case 'f':
				force = 1;
				break;
			default:
				usage(prg_name);
		}
	}

	if (argc != optind+2)
		usage(prg_name);

	tdb_file = argv[optind];
	device_name = argv[optind+1];

	tdb = tdb_open(tdb_file, 0, 0, O_RDONLY, 0600);

	if (!tdb) {
		com_err(prg_name, errno,
				_("Failed tdb_open %s\n"), tdb_file);
		exit(1);
	}

	retval = ext2fs_check_if_mounted(device_name, &mount_flags);
	if (retval) {
		com_err(prg_name, retval, _("Error while determining whether "
				"%s is mounted.\n"), device_name);
		exit(1);
	}

	if (mount_flags & EXT2_MF_MOUNTED) {
		com_err(prg_name, retval, _("e2undo should only be run on "
				"unmounted file system\n"));
		exit(1);
	}

	retval = manager->open(device_name,
				IO_FLAG_EXCLUSIVE | IO_FLAG_RW,  &channel);
	if (retval) {
		com_err(prg_name, retval,
				_("Failed to open %s\n"), device_name);
		exit(1);
	}

	if (!force && check_filesystem(tdb, channel)) {
		exit(1);
	}

	if (set_blk_size(tdb, channel)) {
		exit(1);
	}

	for (key = tdb_firstkey(tdb); key.dptr; key = tdb_nextkey(tdb, key)) {
		if (!strcmp((char *) key.dptr, (char *) mtime_key) ||
		    !strcmp((char *) key.dptr, (char *) uuid_key) ||
		    !strcmp((char *) key.dptr, (char *) blksize_key)) {
			continue;
		}

		data = tdb_fetch(tdb, key);
		if (!data.dptr) {
			com_err(prg_name, 0,
				_("Failed tdb_fetch %s\n"), tdb_errorstr(tdb));
			exit(1);
		}
		blk_num = *(unsigned long *)key.dptr;
		printf(_("Replayed transaction of size %zd at location %llu\n"),
							data.dsize, blk_num);
		retval = io_channel_write_blk64(channel, blk_num,
						-data.dsize, data.dptr);
		if (retval == -1) {
			com_err(prg_name, retval,
					_("Failed write %s\n"),
					strerror(errno));
			exit(1);
		}
	}
	io_channel_close(channel);
	tdb_close(tdb);

	return 0;
}
