/*
 * blockdev implementation for busybox
 *
 * Copyright (C) 2010 Sergey Naumov <sknaumov@gmail.com>
 *
 * Licensed under GPLv2, see file LICENSE in this source tree.
 */

//applet:IF_BLOCKDEV(APPLET(blockdev, BB_DIR_SBIN, BB_SUID_DROP))

//kbuild:lib-$(CONFIG_BLOCKDEV) += blockdev.o

//config:config BLOCKDEV
//config:	bool "blockdev"
//config:	default y
//config:	help
//config:	  Performs some ioctls with block devices.

//usage:#define blockdev_trivial_usage
//usage:	"OPTION BLOCKDEV"
//usage:#define blockdev_full_usage "\n\n"
//usage:       "	--setro		Set ro"
//usage:     "\n	--setrw		Set rw"
//usage:     "\n	--getro		Get ro"
//usage:     "\n	--getss		Get sector size"
//usage:     "\n	--getbsz	Get block size"
//usage:     "\n	--setbsz BYTES	Set block size"
//usage:     "\n	--getsz		Get device size in 512-byte sectors"
/*//usage:     "\n	--getsize	Get device size in sectors (deprecated)"*/
//usage:     "\n	--getsize64	Get device size in bytes"
//usage:     "\n	--flushbufs	Flush buffers"
//usage:     "\n	--rereadpt	Reread partition table"


#include "libbb.h"
#include <linux/fs.h>

enum {
	ARG_NONE   = 0,
	ARG_INT    = 1,
	ARG_ULONG  = 2,
	/* Yes, BLKGETSIZE64 takes pointer to uint64_t, not ullong! */
	ARG_U64    = 3,
	ARG_MASK   = 3,

	FL_USRARG   = 4, /* argument is provided by user */
	FL_NORESULT = 8,
	FL_SCALE512 = 16,
};

struct bdc {
	uint32_t   ioc;                       /* ioctl code */
	const char name[sizeof("flushbufs")]; /* "--setfoo" wothout "--" */
	uint8_t    flags;
	int8_t     argval;                    /* default argument value */
};

static const struct bdc bdcommands[] = {
	{
		.ioc = BLKROSET,
		.name = "setro",
		.flags = ARG_INT + FL_NORESULT,
		.argval = 1,
	},{
		.ioc = BLKROSET,
		.name = "setrw",
		.flags = ARG_INT + FL_NORESULT,
		.argval = 0,
	},{
		.ioc = BLKROGET,
		.name = "getro",
		.flags = ARG_INT,
		.argval = -1,
	},{
		.ioc = BLKSSZGET,
		.name = "getss",
		.flags = ARG_INT,
		.argval = -1,
	},{
		.ioc = BLKBSZGET,
		.name = "getbsz",
		.flags = ARG_INT,
		.argval = -1,
	},{
		.ioc = BLKBSZSET,
		.name = "setbsz",
		.flags = ARG_INT + FL_NORESULT + FL_USRARG,
		.argval = 0,
	},{
		.ioc = BLKGETSIZE64,
		.name = "getsz",
		.flags = ARG_U64 + FL_SCALE512,
		.argval = -1,
	},{
		.ioc = BLKGETSIZE,
		.name = "getsize",
		.flags = ARG_ULONG,
		.argval = -1,
	},{
		.ioc = BLKGETSIZE64,
		.name = "getsize64",
		.flags = ARG_U64,
		.argval = -1,
	},{
		.ioc = BLKFLSBUF,
		.name = "flushbufs",
		.flags = ARG_NONE + FL_NORESULT,
		.argval = 0,
	},{
		.ioc = BLKRRPART,
		.name = "rereadpt",
		.flags = ARG_NONE + FL_NORESULT,
		.argval = 0,
	}
};

static const struct bdc *find_cmd(const char *s)
{
	const struct bdc *bdcmd = bdcommands;
	if (s[0] == '-' && s[1] == '-') {
		s += 2;
		do {
			if (strcmp(s, bdcmd->name) == 0)
				return bdcmd;
			bdcmd++;
		} while (bdcmd != bdcommands + ARRAY_SIZE(bdcommands));
	}
	bb_show_usage();
}

int blockdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int blockdev_main(int argc UNUSED_PARAM, char **argv)
{
	const struct bdc *bdcmd;
	int fd;
	uint64_t u64;
	union {
		int i;
		unsigned long lu;
		uint64_t u64;
	} ioctl_val_on_stack;

	argv++;
	if (!argv[0] || !argv[1]) /* must have at least 2 args */
		bb_show_usage();

	bdcmd = find_cmd(*argv);

	u64 = (int)bdcmd->argval;
	if (bdcmd->flags & FL_USRARG)
		u64 = xatoi_positive(*++argv);

	argv++;
	if (!argv[0] || argv[1])
		bb_show_usage();
	fd = xopen(argv[0], O_RDONLY);

	ioctl_val_on_stack.u64 = u64;
#if BB_BIG_ENDIAN
	/* Store data properly wrt data size.
	 * (1) It's no-op for little-endian.
	 * (2) it's no-op for 0 and -1. Only --setro uses arg != 0 and != -1,
	 * and it is ARG_INT. --setbsz USER_VAL is also ARG_INT.
	 * Thus, we don't need to handle ARG_ULONG.
	 */
	switch (bdcmd->flags & ARG_MASK) {
	case ARG_INT:
		ioctl_val_on_stack.i = (int)u64;
		break;
# if 0 /* unused */
	case ARG_ULONG:
		ioctl_val_on_stack.lu = (unsigned long)u64;
		break;
# endif
	}
#endif

	if (ioctl(fd, bdcmd->ioc, &ioctl_val_on_stack.u64) == -1)
		bb_simple_perror_msg_and_die(*argv);

	/* Fetch it into register(s) */
	u64 = ioctl_val_on_stack.u64;

	if (bdcmd->flags & FL_SCALE512)
		u64 >>= 9;

	/* Zero- or one-extend the value if needed, then print */
	switch (bdcmd->flags & (ARG_MASK+FL_NORESULT)) {
	case ARG_INT:
		/* Smaller code when we use long long
		 * (gcc tail-merges printf call)
		 */
		printf("%lld\n", (long long)(int)u64);
		break;
	case ARG_ULONG:
		u64 = (unsigned long)u64;
		/* FALLTHROUGH */
	case ARG_U64:
		printf("%llu\n", (unsigned long long)u64);
		break;
	}

	if (ENABLE_FEATURE_CLEAN_UP)
		close(fd);
	return EXIT_SUCCESS;
}
