/*
 * zap.c --- zap block
 *
 * Copyright (C) 2012 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>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
extern int optind;
extern char *optarg;
#endif

#include "debugfs.h"

void do_zap_block(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
		    void *infop EXT2FS_ATTR((unused)))
{
	unsigned long	pattern = 0;
	unsigned char	*buf;
	ext2_ino_t	inode;
	errcode_t	errcode;
	blk64_t		block;
	char		*file = NULL;
	int		c, err;
	int		offset = -1;
	int		length = -1;
	int		bit = -1;

	if (check_fs_open(argv[0]))
		return;
	if (check_fs_read_write(argv[0]))
		return;

	reset_getopt();
	while ((c = getopt (argc, argv, "b:f:l:o:p:")) != EOF) {
		switch (c) {
		case 'f':
			file = optarg;
			break;
		case 'b':
			bit = parse_ulong(optarg, argv[0],
					  "bit", &err);
			if (err)
				return;
			if (bit >= (int) current_fs->blocksize * 8) {
				com_err(argv[0], 0, "The bit to flip "
					"must be within a %d block\n",
					current_fs->blocksize);
				return;
			}
			break;
		case 'p':
			pattern = parse_ulong(optarg, argv[0],
					      "pattern", &err);
			if (err)
				return;
			if (pattern >= 256) {
				com_err(argv[0], 0, "The fill pattern must "
					"be an 8-bit value\n");
				return;
			}
			break;
		case 'o':
			offset = parse_ulong(optarg, argv[0],
					     "offset", &err);
			if (err)
				return;
			if (offset >= (int) current_fs->blocksize) {
				com_err(argv[0], 0, "The offset must be "
					"within a %d block\n",
					current_fs->blocksize);
				return;
			}
			break;

			break;
		case 'l':
			length = parse_ulong(optarg, argv[0],
					     "length", &err);
			if (err)
				return;
			break;
		default:
			goto print_usage;
		}
	}

	if (bit > 0 && offset > 0) {
		com_err(argv[0], 0, "The -o and -b options can not be mixed.");
		return;
	}

	if (offset < 0)
		offset = 0;
	if (length < 0)
		length = current_fs->blocksize - offset;
	if ((offset + length) > (int) current_fs->blocksize) {
		com_err(argv[0], 0, "The specified length is too bug\n");
		return;
	}

	if (argc != optind+1) {
	print_usage:
		com_err(0, 0, "Usage:\tzap_block [-f file] [-o offset] "
			"[-l length] [-p pattern] block_num");
		com_err(0, 0, "\tzap_block [-f file] [-b bit] "
			"block_num");
		return;
	}

	block = parse_ulonglong(argv[optind], argv[0], "block", &err);
	if (err)
		return;

	if (file) {
		inode = string_to_inode(file);
		if (!inode)
			return;
		errcode = ext2fs_bmap2(current_fs, inode, 0, 0, 0,
				       block, 0, &block);
		if (errcode) {
			com_err(argv[0], errcode,
				"while mapping logical block %llu\n", block);
			return;
		}
	}

	buf = malloc(current_fs->blocksize);
	if (!buf) {
		com_err(argv[0], 0, "Couldn't allocate block buffer");
		return;
	}

	errcode = io_channel_read_blk64(current_fs->io, block, 1, buf);
	if (errcode) {
		com_err(argv[0], errcode,
			"while reading block %llu\n", block);
		goto errout;
	}

	if (bit >= 0)
		buf[bit >> 3] ^= 1 << (bit & 7);
	else
		memset(buf+offset, pattern, length);

	errcode = io_channel_write_blk64(current_fs->io, block, 1, buf);
	if (errcode) {
		com_err(argv[0], errcode,
			"while write block %llu\n", block);
		goto errout;
	}

errout:
	free(buf);
	return;
}

void do_block_dump(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
		    void *infop EXT2FS_ATTR((unused)))
{
	unsigned char	*buf;
	ext2_ino_t	inode;
	errcode_t	errcode;
	blk64_t		block;
	char		*file = NULL;
	int		xattr_dump = 0;
	int		c, err;

	if (check_fs_open(argv[0]))
		return;

	reset_getopt();
	while ((c = getopt (argc, argv, "f:x")) != EOF) {
		switch (c) {
		case 'f':
			file = optarg;
			break;
		case 'x':
			xattr_dump = 1;
			break;
		default:
			goto print_usage;
		}
	}

	if (argc != optind + 1) {
	print_usage:
		com_err(0, 0, "Usage: block_dump [-x] [-f inode] block_num");
		return;
	}

	block = parse_ulonglong(argv[optind], argv[0], "block", &err);
	if (err)
		return;

	if (file) {
		inode = string_to_inode(file);
		if (!inode)
			return;
		errcode = ext2fs_bmap2(current_fs, inode, 0, 0, 0,
				       block, 0, &block);
		if (errcode) {
			com_err(argv[0], errcode,
				"while mapping logical block %llu\n", block);
			return;
		}
	}

	buf = malloc(current_fs->blocksize);
	if (!buf) {
		com_err(argv[0], 0, "Couldn't allocate block buffer");
		return;
	}

	errcode = io_channel_read_blk64(current_fs->io, block, 1, buf);
	if (errcode) {
		com_err(argv[0], errcode,
			"while reading block %llu\n", block);
		goto errout;
	}

	if (xattr_dump)
		block_xattr_dump(stdout, buf, current_fs->blocksize);
	else
		do_byte_hexdump(stdout, buf, current_fs->blocksize);
errout:
	free(buf);
}

void do_byte_hexdump(FILE *fp, unsigned char *buf, size_t bufsize)
{
	size_t		i, j, max;
	int		suppress = -1;

	for (i = 0; i < bufsize; i += 16) {
		max = (bufsize - i > 16) ? 16 : bufsize - i;
		if (suppress < 0) {
			if (i && memcmp(buf + i, buf + i - max, max) == 0) {
				suppress = i;
				fprintf(fp, "*\n");
				continue;
			}
		} else {
			if (memcmp(buf + i, buf + suppress, max) == 0)
				continue;
			suppress = -1;
		}
		fprintf(fp, "%04o  ", (unsigned int)i);
		for (j = 0; j < 16; j++) {
			if (j < max)
				fprintf(fp, "%02x", buf[i+j]);
			else
				fprintf(fp, "  ");
			if ((j % 2) == 1)
				fprintf(fp, " ");
		}
		fprintf(fp, " ");
		for (j = 0; j < max; j++)
			fprintf(fp, "%c", isprint(buf[i+j]) ? buf[i+j] : '.');
		fprintf(fp, "\n");
	}
	fprintf(fp, "\n");
}
