// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2016 Red Hat, Inc.
 * All Rights Reserved.
 */

#include "libxfs.h"
#include "addr.h"
#include "command.h"
#include "type.h"
#include "faddr.h"
#include "fprint.h"
#include "field.h"
#include "flist.h"
#include "io.h"
#include "init.h"
#include "output.h"
#include "bit.h"
#include "print.h"
#include "crc.h"

static int crc_f(int argc, char **argv);
static void crc_help(void);

static const cmdinfo_t crc_cmd =
	{ "crc", NULL, crc_f, 0, 1, 0, "[-i|-r|-v]",
	  N_("manipulate crc values for V5 filesystem structures"), crc_help };

void
crc_init(void)
{
	if (xfs_has_crc(mp))
		add_command(&crc_cmd);
}

static void
crc_help(void)
{
	dbprintf(_(
"\n"
" 'crc' validates, invalidates, or recalculates the crc value for\n"
" the current on-disk metadata structures in Version 5 filesystems.\n"
"\n"
" Usage:  \"crc [-i|-r|-v]\"\n"
"\n"
));

}

static int
crc_f(
	int		argc,
	char		**argv)
{
	const struct xfs_buf_ops *stashed_ops = NULL;
	struct xfs_buf_ops nowrite_ops;
	extern char	*progname;
	const field_t	*fields;
	const ftattr_t	*fa;
	flist_t		*fl;
	int		invalidate = 0;
	int		recalculate = 0;
	int		validate = 0;
	int		c;

	if (cur_typ == NULL) {
		dbprintf(_("no current type\n"));
		return 0;
	}

	if (cur_typ->fields == NULL) {
		dbprintf(_("current type (%s) is not a structure\n"),
			 cur_typ->name);
		return 0;
	}

	if (argc) while ((c = getopt(argc, argv, "irv")) != EOF) {
		switch (c) {
		case 'i':
			invalidate = 1;
			break;
		case 'r':
			recalculate = 1;
			break;
		case 'v':
			validate = 1;
			break;
		default:
			dbprintf(_("bad option for crc command\n"));
			return 0;
		}
	} else
		validate = 1;

	if (invalidate + recalculate + validate > 1) {
		dbprintf(_("crc command accepts only one option\n"));
		return 0;
	}

	if ((invalidate || recalculate) &&
	    ((x.flags & LIBXFS_ISREADONLY) || !expert_mode)) {
		dbprintf(_("%s not in expert mode, writing disabled\n"),
			progname);
		return 0;
	}

	fields = cur_typ->fields;

	/* if we're a root field type, go down 1 layer to get field list */
	if (fields->name[0] == '\0') {
		fa = &ftattrtab[fields->ftyp];
		ASSERT(fa->ftyp == fields->ftyp);
		fields = fa->subfld;
	}

	/* Search for a CRC field */
	fl = flist_find_ftyp(fields, FLDT_CRC, iocur_top->data, 0);
	if (!fl) {
		dbprintf(_("No CRC field found for type %s\n"), cur_typ->name);
		return 0;
	}

	/* run down the field list and set offsets into the data */
	if (!flist_parse(fields, fl, iocur_top->data, 0)) {
		flist_free(fl);
		dbprintf(_("parsing error\n"));
		return 0;
	}

	if (invalidate) {
		flist_t		*sfl;
		int		bit_length;
		int		parentoffset;
		uint32_t	crc;

		sfl = fl;
		parentoffset = 0;
		while (sfl->child) {
			parentoffset = sfl->offset;
			sfl = sfl->child;
		}
		ASSERT(sfl->fld->ftyp == FLDT_CRC);

		bit_length = fsize(sfl->fld, iocur_top->data, parentoffset, 0);
		bit_length *= fcount(sfl->fld, iocur_top->data, parentoffset);
		crc = getbitval(iocur_top->data, sfl->offset, bit_length,
				BVUNSIGNED);
		/* Off by one, ignore endianness - we're just corrupting it. */
		crc++;
		setbitval(iocur_top->data, sfl->offset, bit_length, &crc);

		/* Temporarily remove write verifier to write a bad CRC */
		stashed_ops = iocur_top->bp->b_ops;
		nowrite_ops.verify_read = stashed_ops->verify_read;
		nowrite_ops.verify_write = xfs_dummy_verify;
		iocur_top->bp->b_ops = &nowrite_ops;
	}

	if (invalidate || recalculate) {
		if (invalidate)
			dbprintf(_("Invalidating CRC:\n"));
		else
			dbprintf(_("Recalculating CRC:\n"));

		write_cur();
		if (stashed_ops)
			iocur_top->bp->b_ops = stashed_ops;
		/* re-verify to get proper b_error state */
		iocur_top->bp->b_ops->verify_read(iocur_top->bp);
	} else
		dbprintf(_("Verifying CRC:\n"));

	/* And show us what we've got! */
	flist_print(fl);
	print_flist(fl);
	flist_free(fl);
	return 0;
}
