/*
 * wipefs - utility to wipe filesystems from device
 *
 * Copyright (C) 2009 Red Hat, Inc. All rights reserved.
 * Written by Karel Zak <kzak@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include <sys/stat.h>
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include <limits.h>
#include <libgen.h>

#include <blkid.h>
#include <libsmartcols.h>

#include "nls.h"
#include "xalloc.h"
#include "strutils.h"
#include "all-io.h"
#include "match.h"
#include "c.h"
#include "closestream.h"
#include "optutils.h"
#include "blkdev.h"

struct wipe_desc {
	loff_t		offset;		/* magic string offset */
	size_t		len;		/* length of magic string */
	unsigned char	*magic;		/* magic string */

	char		*usage;		/* raid, filesystem, ... */
	char		*type;		/* FS type */
	char		*label;		/* FS label */
	char		*uuid;		/* FS uuid */

	struct wipe_desc	*next;

	unsigned int	on_disk : 1,
			is_parttable : 1;

};

struct wipe_control {
	char		*devname;
	const char	*type_pattern;		/* -t <pattern> */

	struct libscols_table *outtab;
	struct wipe_desc *offsets;		/* -o <offset> -o <offset> ... */

	size_t		ndevs;			/* number of devices to probe */

	char		**reread;		/* devices to BLKRRPART */
	size_t		nrereads;		/* size of reread */

	unsigned int	noact : 1,
			all : 1,
			quiet : 1,
			backup : 1,
			force : 1,
			json : 1,
			no_headings : 1,
			parsable : 1;
};


/* column IDs */
enum {
	COL_UUID = 0,
	COL_LABEL,
	COL_LEN,
	COL_TYPE,
	COL_OFFSET,
	COL_USAGE,
	COL_DEVICE
};

/* column names */
struct colinfo {
	const char *name;	/* header */
	double whint;		/* width hint (N < 1 is in percent of termwidth) */
	int flags;		/* SCOLS_FL_* */
	const char *help;
};

/* columns descriptions */
static const struct colinfo infos[] = {
	[COL_UUID]    = {"UUID",     4, 0, N_("partition/filesystem UUID")},
	[COL_LABEL]   = {"LABEL",    5, 0, N_("filesystem LABEL")},
	[COL_LEN]     = {"LENGTH",   6, 0, N_("magic string length")},
	[COL_TYPE]    = {"TYPE",     4, 0, N_("superblok type")},
	[COL_OFFSET]  = {"OFFSET",   5, 0, N_("magic string offset")},
	[COL_USAGE]   = {"USAGE",    5, 0, N_("type description")},
	[COL_DEVICE]  = {"DEVICE",   5, 0, N_("block device name")}
};

static int columns[ARRAY_SIZE(infos) * 2];
static size_t ncolumns;

static int column_name_to_id(const char *name, size_t namesz)
{
	size_t i;

	assert(name);

	for (i = 0; i < ARRAY_SIZE(infos); i++) {
		const char *cn = infos[i].name;
		if (!strncasecmp(name, cn, namesz) && !*(cn + namesz))
			return i;
	}
	warnx(_("unknown column: %s"), name);
	return -1;
}

static int get_column_id(size_t num)
{
	assert(num < ncolumns);
	assert(columns[num] < (int)ARRAY_SIZE(infos));
	return columns[num];
}

static const struct colinfo *get_column_info(int num)
{
	return &infos[get_column_id(num)];
}


static void init_output(struct wipe_control *ctl)
{
	struct libscols_table *tb;
	size_t i;

	scols_init_debug(0);
	tb = scols_new_table();
	if (!tb)
		err(EXIT_FAILURE, _("failed to allocate output table"));

	if (ctl->json) {
		scols_table_enable_json(tb, 1);
		scols_table_set_name(tb, "signatures");
	}
	scols_table_enable_noheadings(tb, ctl->no_headings);

	if (ctl->parsable) {
		scols_table_enable_raw(tb, 1);
		scols_table_set_column_separator(tb, ",");
	}

	for (i = 0; i < ncolumns; i++) {
		const struct colinfo *col = get_column_info(i);
		struct libscols_column *cl;

		cl = scols_table_new_column(tb, col->name, col->whint,
					    col->flags);
		if (!cl)
			err(EXIT_FAILURE,
			    _("failed to initialize output column"));
		if (ctl->json) {
			int id = get_column_id(i);

			if (id == COL_LEN)
				scols_column_set_json_type(cl, SCOLS_JSON_NUMBER);
		}
	}
	ctl->outtab = tb;
}

static void finalize_output(struct wipe_control *ctl)
{
	if (ctl->parsable && !ctl->no_headings
	    && !scols_table_is_empty(ctl->outtab)) {
		struct libscols_iter *itr = scols_new_iter(SCOLS_ITER_FORWARD);
		struct libscols_column *cl;
		int i = 0;

		if (!itr)
			err_oom();

		fputs("# ", stdout);
		while (scols_table_next_column(ctl->outtab, itr, &cl) == 0) {
			struct libscols_cell *hdr = scols_column_get_header(cl);
			const char *name = scols_cell_get_data(hdr);

			if (i)
				fputc(',', stdout);
			fputs(name, stdout);
			i++;
		}
		fputc('\n', stdout);
		scols_free_iter(itr);
	}
	scols_print_table(ctl->outtab);
	scols_unref_table(ctl->outtab);
}

static void fill_table_row(struct wipe_control *ctl, struct wipe_desc *wp)
{
	static struct libscols_line *ln;
	size_t i;

	ln = scols_table_new_line(ctl->outtab, NULL);
	if (!ln)
		errx(EXIT_FAILURE, _("failed to allocate output line"));

	for (i = 0; i < ncolumns; i++) {
		char *str = NULL;

		switch (get_column_id(i)) {
		case COL_UUID:
			if (wp->uuid)
				str = xstrdup(wp->uuid);
			break;
		case COL_LABEL:
			if (wp->label)
				str = xstrdup(wp->label);
			break;
		case COL_OFFSET:
			xasprintf(&str, "0x%jx", (intmax_t)wp->offset);
			break;
		case COL_LEN:
			xasprintf(&str, "%zu", wp->len);
			break;
		case COL_USAGE:
			if (wp->usage)
				str = xstrdup(wp->usage);
			break;
		case COL_TYPE:
			if (wp->type)
				str = xstrdup(wp->type);
			break;
		case COL_DEVICE:
			if (ctl->devname) {
				char *dev = xstrdup(ctl->devname);
				str = xstrdup(basename(dev));
				free(dev);
			}
			break;
		default:
			abort();
		}

		if (str && scols_line_refer_data(ln, i, str))
			errx(EXIT_FAILURE, _("failed to add output data"));
	}
}

static void add_to_output(struct wipe_control *ctl, struct wipe_desc *wp)
{
	for (/*nothing*/; wp; wp = wp->next)
		fill_table_row(ctl, wp);
}

/* Allocates a new wipe_desc and add to the wp0 if not NULL */
static struct wipe_desc *add_offset(struct wipe_desc **wp0, loff_t offset)
{
	struct wipe_desc *wp, *last = NULL;

	if (wp0) {
		/* check if already exists */
		for (wp = *wp0; wp; wp = wp->next) {
			if (wp->offset == offset)
				return wp;
			last = wp;
		}
	}

	wp = xcalloc(1, sizeof(struct wipe_desc));
	wp->offset = offset;
	wp->next = NULL;

	if (last)
		last->next = wp;
	if (wp0 && !*wp0)
		*wp0 = wp;
	return wp;
}

/* Read data from libblkid and if detected type pass -t and -o filters than:
 * - allocates a new wipe_desc
 * - add the new wipe_desc to wp0 list (if not NULL)
 *
 * The function always returns offset and len if libblkid detected something.
 */
static struct wipe_desc *get_desc_for_probe(struct wipe_control *ctl,
					    struct wipe_desc **wp0,
					    blkid_probe pr,
					    loff_t *offset,
					    size_t *len)
{
	const char *off, *type, *mag, *p, *usage = NULL;
	struct wipe_desc *wp;
	int rc, ispt = 0;

	*len = 0;

	/* superblocks */
	if (blkid_probe_lookup_value(pr, "TYPE", &type, NULL) == 0) {
		rc = blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &off, NULL);
		if (!rc)
			rc = blkid_probe_lookup_value(pr, "SBMAGIC", &mag, len);
		if (rc)
			return NULL;

	/* partitions */
	} else if (blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL) == 0) {
		rc = blkid_probe_lookup_value(pr, "PTMAGIC_OFFSET", &off, NULL);
		if (!rc)
			rc = blkid_probe_lookup_value(pr, "PTMAGIC", &mag, len);
		if (rc)
			return NULL;
		usage = N_("partition-table");
		ispt = 1;
	} else
		return NULL;

	*offset = strtoll(off, NULL, 10);

	/* Filter out by -t <type> */
	if (ctl->type_pattern && !match_fstype(type, ctl->type_pattern))
		return NULL;

	/* Filter out by -o <offset> */
	if (ctl->offsets) {
		struct wipe_desc *w = NULL;

		for (w = ctl->offsets; w; w = w->next) {
			if (w->offset == *offset)
				break;
		}
		if (!w)
			return NULL;

		w->on_disk = 1; /* mark as "found" */
	}

	wp = add_offset(wp0, *offset);
	if (!wp)
		return NULL;

	if (usage || blkid_probe_lookup_value(pr, "USAGE", &usage, NULL) == 0)
		wp->usage = xstrdup(usage);

	wp->type = xstrdup(type);
	wp->on_disk = 1;
	wp->is_parttable = ispt ? 1 : 0;

	wp->magic = xmalloc(*len);
	memcpy(wp->magic, mag, *len);
	wp->len = *len;

	if (blkid_probe_lookup_value(pr, "LABEL", &p, NULL) == 0)
		wp->label = xstrdup(p);

	if (blkid_probe_lookup_value(pr, "UUID", &p, NULL) == 0)
		wp->uuid = xstrdup(p);

	return wp;
}

static blkid_probe
new_probe(const char *devname, int mode)
{
	blkid_probe pr = NULL;

	if (!devname)
		return NULL;

	if (mode) {
		int fd = open(devname, mode);
		if (fd < 0)
			goto error;

		pr = blkid_new_probe();
		if (!pr || blkid_probe_set_device(pr, fd, 0, 0) != 0) {
			close(fd);
			goto error;
		}
	} else
		pr = blkid_new_probe_from_filename(devname);

	if (!pr)
		goto error;

	blkid_probe_enable_superblocks(pr, 1);
	blkid_probe_set_superblocks_flags(pr,
			BLKID_SUBLKS_MAGIC |	/* return magic string and offset */
			BLKID_SUBLKS_TYPE |	/* return superblock type */
			BLKID_SUBLKS_USAGE |	/* return USAGE= */
			BLKID_SUBLKS_LABEL |	/* return LABEL= */
			BLKID_SUBLKS_UUID |	/* return UUID= */
			BLKID_SUBLKS_BADCSUM);	/* accept bad checksums */

	blkid_probe_enable_partitions(pr, 1);
	blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC |
					     BLKID_PARTS_FORCE_GPT);
	return pr;
error:
	blkid_free_probe(pr);
	err(EXIT_FAILURE, _("error: %s: probing initialization failed"), devname);
}

static struct wipe_desc *read_offsets(struct wipe_control *ctl)
{
	blkid_probe pr = new_probe(ctl->devname, 0);
	struct wipe_desc *wp0 = NULL;

	if (!pr)
		return NULL;

	while (blkid_do_probe(pr) == 0) {
		size_t len = 0;
		loff_t offset = 0;

		/* add a new offset to wp0 */
		get_desc_for_probe(ctl, &wp0, pr, &offset, &len);

		/* hide last detected signature and scan again */
		if (len) {
			blkid_probe_hide_range(pr, offset, len);
			blkid_probe_step_back(pr);
		}
	}

	blkid_free_probe(pr);
	return wp0;
}

static void free_wipe(struct wipe_desc *wp)
{
	while (wp) {
		struct wipe_desc *next = wp->next;

		free(wp->usage);
		free(wp->type);
		free(wp->magic);
		free(wp->label);
		free(wp->uuid);
		free(wp);

		wp = next;
	}
}

static void do_wipe_real(struct wipe_control *ctl, blkid_probe pr,
			struct wipe_desc *w)
{
	size_t i;

	if (blkid_do_wipe(pr, ctl->noact) != 0)
		err(EXIT_FAILURE, _("%s: failed to erase %s magic string at offset 0x%08jx"),
		     ctl->devname, w->type, (intmax_t)w->offset);

	if (ctl->quiet)
		return;

	printf(P_("%s: %zd byte was erased at offset 0x%08jx (%s): ",
		  "%s: %zd bytes were erased at offset 0x%08jx (%s): ",
		  w->len),
	       ctl->devname, w->len, (intmax_t)w->offset, w->type);

	for (i = 0; i < w->len; i++) {
		printf("%02x", w->magic[i]);
		if (i + 1 < w->len)
			fputc(' ', stdout);
	}
	putchar('\n');
}

static void do_backup(struct wipe_desc *wp, const char *base)
{
	char *fname = NULL;
	int fd;

	xasprintf(&fname, "%s0x%08jx.bak", base, (intmax_t)wp->offset);

	fd = open(fname, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
	if (fd < 0)
		goto err;
	if (write_all(fd, wp->magic, wp->len) != 0)
		goto err;
	close(fd);
	free(fname);
	return;
err:
	err(EXIT_FAILURE, _("%s: failed to create a signature backup"), fname);
}

#ifdef BLKRRPART
static void rereadpt(int fd, const char *devname)
{
	struct stat st;
	int try = 0;

	if (fstat(fd, &st) || !S_ISBLK(st.st_mode))
		return;

	do {
		/*
		 * Unfortunately, it's pretty common that the first re-read
		 * without delay is uncuccesful. The reason is probably kernel
		 * and/or udevd.  Let's wait a moment and try more attempts.
		 */
		xusleep(25000);

		errno = 0;
		ioctl(fd, BLKRRPART);
		if (errno != EBUSY)
			break;
	} while (try++ < 4);

	printf(_("%s: calling ioctl to re-read partition table: %m\n"), devname);
}
#endif

static int do_wipe(struct wipe_control *ctl)
{
	int mode = O_RDWR, reread = 0, need_force = 0;
	blkid_probe pr;
	char *backup = NULL;
	struct wipe_desc *w;

	if (!ctl->force)
		mode |= O_EXCL;

	pr = new_probe(ctl->devname, mode);
	if (!pr)
		return -errno;

	if (ctl->backup) {
		const char *home = getenv ("HOME");
		char *tmp = xstrdup(ctl->devname);

		if (!home)
			errx(EXIT_FAILURE, _("failed to create a signature backup, $HOME undefined"));
		xasprintf (&backup, "%s/wipefs-%s-", home, basename(tmp));
		free(tmp);
	}

	while (blkid_do_probe(pr) == 0) {
		int wiped = 0;
		size_t len = 0;
		loff_t offset = 0;
		struct wipe_desc *wp;

		wp = get_desc_for_probe(ctl, NULL, pr, &offset, &len);
		if (!wp)
			goto done;

		if (!ctl->force
		    && wp->is_parttable
		    && !blkid_probe_is_wholedisk(pr)) {
			warnx(_("%s: ignoring nested \"%s\" partition table "
				"on non-whole disk device"), ctl->devname, wp->type);
			need_force = 1;
			goto done;
		}

		if (backup)
			do_backup(wp, backup);
		do_wipe_real(ctl, pr, wp);
		if (wp->is_parttable)
			reread = 1;
		wiped = 1;
	done:
		if (!wiped && len) {
			/* if the offset has not been wiped (probably because
			 * filtered out by -t or -o) we need to hide it for
			 * libblkid to try another magic string for the same
			 * superblock, otherwise libblkid will continue with
			 * another superblock. Don't forget that the same
			 * superblock could be detected by more magic strings
			 * */
			blkid_probe_hide_range(pr, offset, len);
			blkid_probe_step_back(pr);
		}
		free_wipe(wp);
	}

	for (w = ctl->offsets; w; w = w->next) {
		if (!w->on_disk && !ctl->quiet)
			warnx(_("%s: offset 0x%jx not found"),
					ctl->devname, (uintmax_t)w->offset);
	}

	if (need_force)
		warnx(_("Use the --force option to force erase."));

	fsync(blkid_probe_get_fd(pr));

#ifdef BLKRRPART
	if (reread && (mode & O_EXCL)) {
		if (ctl->ndevs > 1) {
			/*
			 * We're going to probe more device, let's postpone
			 * re-read PT ioctl until all is erased to avoid
			 * situation we erase PT on /dev/sda before /dev/sdaN
			 * devices are processed.
			 */
			if (!ctl->reread)
				ctl->reread = xcalloc(ctl->ndevs, sizeof(char *));

			ctl->reread[ctl->nrereads++] = ctl->devname;
		} else
			rereadpt(blkid_probe_get_fd(pr), ctl->devname);
	}
#endif

	close(blkid_probe_get_fd(pr));
	blkid_free_probe(pr);
	free(backup);
	return 0;
}


static void __attribute__((__noreturn__))
usage(void)
{
	size_t i;

	fputs(USAGE_HEADER, stdout);
	printf(_(" %s [options] <device>\n"), program_invocation_short_name);

	fputs(USAGE_SEPARATOR, stdout);
	puts(_("Wipe signatures from a device."));

	fputs(USAGE_OPTIONS, stdout);
	puts(_(" -a, --all           wipe all magic strings (BE CAREFUL!)"));
	puts(_(" -b, --backup        create a signature backup in $HOME"));
	puts(_(" -f, --force         force erasure"));
	puts(_(" -i, --noheadings    don't print headings"));
	puts(_(" -J, --json          use JSON output format"));
	puts(_(" -n, --no-act        do everything except the actual write() call"));
	puts(_(" -o, --offset <num>  offset to erase, in bytes"));
	puts(_(" -O, --output <list> COLUMNS to display (see below)"));
	puts(_(" -p, --parsable      print out in parsable instead of printable format"));
	puts(_(" -q, --quiet         suppress output messages"));
	puts(_(" -t, --types <list>  limit the set of filesystem, RAIDs or partition tables"));

	printf(USAGE_HELP_OPTIONS(21));

	fputs(USAGE_COLUMNS, stdout);
	for (i = 0; i < ARRAY_SIZE(infos); i++)
		fprintf(stdout, " %8s  %s\n", infos[i].name, _(infos[i].help));

	printf(USAGE_MAN_TAIL("wipefs(8)"));
	exit(EXIT_SUCCESS);
}


int
main(int argc, char **argv)
{
	struct wipe_control ctl = { .devname = NULL };
	int c;
	char *outarg = NULL;

	static const struct option longopts[] = {
	    { "all",       no_argument,       NULL, 'a' },
	    { "backup",    no_argument,       NULL, 'b' },
	    { "force",     no_argument,       NULL, 'f' },
	    { "help",      no_argument,       NULL, 'h' },
	    { "no-act",    no_argument,       NULL, 'n' },
	    { "offset",    required_argument, NULL, 'o' },
	    { "parsable",  no_argument,       NULL, 'p' },
	    { "quiet",     no_argument,       NULL, 'q' },
	    { "types",     required_argument, NULL, 't' },
	    { "version",   no_argument,       NULL, 'V' },
	    { "json",      no_argument,       NULL, 'J'},
	    { "noheadings",no_argument,       NULL, 'i'},
	    { "output",    required_argument, NULL, 'O'},
	    { NULL,        0, NULL, 0 }
	};

	static const ul_excl_t excl[] = {       /* rows and cols in ASCII order */
		{ 'O','a','o' },
		{ 0 }
	};
	int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	while ((c = getopt_long(argc, argv, "abfhiJnO:o:pqt:V", longopts, NULL)) != -1) {

		err_exclusive_options(c, longopts, excl, excl_st);

		switch(c) {
		case 'a':
			ctl.all = 1;
			break;
		case 'b':
			ctl.backup = 1;
			break;
		case 'f':
			ctl.force = 1;
			break;
		case 'h':
			usage();
			break;
		case 'J':
			ctl.json = 1;
			break;
		case 'i':
			ctl.no_headings = 1;
			break;
		case 'O':
			outarg = optarg;
			break;
		case 'n':
			ctl.noact = 1;
			break;
		case 'o':
			add_offset(&ctl.offsets, strtosize_or_err(optarg,
					 _("invalid offset argument")));
			break;
		case 'p':
			ctl.parsable = 1;
			ctl.no_headings = 1;
			break;
		case 'q':
			ctl.quiet = 1;
			break;
		case 't':
			ctl.type_pattern = optarg;
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			return EXIT_SUCCESS;
		default:
			errtryhelp(EXIT_FAILURE);
		}
	}

	if (optind == argc) {
		warnx(_("no device specified"));
		errtryhelp(EXIT_FAILURE);

	}

	if (ctl.backup && !(ctl.all || ctl.offsets))
		warnx(_("The --backup option is meaningless in this context"));

	if (!ctl.all && !ctl.offsets) {
		/*
		 * Print only
		 */
		if (ctl.parsable) {
			/* keep it backward compatible */
			columns[ncolumns++] = COL_OFFSET;
			columns[ncolumns++] = COL_UUID;
			columns[ncolumns++] = COL_LABEL;
			columns[ncolumns++] = COL_TYPE;
		} else {
			/* default, may be modified by -O <list> */
			columns[ncolumns++] = COL_DEVICE;
			columns[ncolumns++] = COL_OFFSET;
			columns[ncolumns++] = COL_TYPE;
			columns[ncolumns++] = COL_UUID;
			columns[ncolumns++] = COL_LABEL;
		}

		if (outarg
		    && string_add_to_idarray(outarg, columns, ARRAY_SIZE(columns),
					     &ncolumns, column_name_to_id) < 0)
			return EXIT_FAILURE;

		init_output(&ctl);

		while (optind < argc) {
			struct wipe_desc *wp;

			ctl.devname = argv[optind++];
			wp = read_offsets(&ctl);
			if (wp)
				add_to_output(&ctl, wp);
			free_wipe(wp);
		}
		finalize_output(&ctl);
	} else {
		/*
		 * Erase
		 */
		ctl.ndevs = argc - optind;

		while (optind < argc) {
			ctl.devname = argv[optind++];
			do_wipe(&ctl);
			ctl.ndevs--;
		}

#ifdef BLKRRPART
		/* Re-read partition tables on whole-disk devices. This is
		 * postponed until all is done to avoid conflicts.
		 */
		for (size_t i = 0; i < ctl.nrereads; i++) {
			char *devname = ctl.reread[i];
			int fd = open(devname, O_RDONLY);

			if (fd >= 0) {
				rereadpt(fd, devname);
				close(fd);
			}
		}
		free(ctl.reread);
#endif
	}
	return EXIT_SUCCESS;
}
