/*
 * blockdev implementation for busybox
 *
 * Copyright (C) 2010 Sergey Naumov <sknaumov@gmail.com>
 *
 * Licensed under GPLv2, see file LICENSE in this source tree.
 */
//config:config BLOCKDEV
//config:	bool "blockdev (2.3 kb)"
//config:	default y
//config:	help
//config:	Performs some ioctls with block devices.

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

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

//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"
// util-linux 2.31 also has:
//	--getdiscardzeroes	BLKDISCARDZEROES	Get discard zeroes support status
//	--getpbsz		BLKPBSZGET	Get physical block (sector) size
//	--getiomin		BLKIOMIN	Get minimum I/O size
//	--getioopt		BLKIOOPT	Get optimal I/O size
//	--getalignoff		BLKALIGNOFF	Get alignment offset in bytes
//	--getmaxsect		BLKSECTGET	Get max sectors per request
//	--setra SECTORS		BLKRASET	Set readahead
//	--getra			BLKRAGET	Get readahead
//	--setfra SECTORS	BLKFRASET	Set filesystem readahead
//	--getfra		BLKFRAGET	Get filesystem readahead

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

/* Takes less space is separate arrays than one array of struct */
static const char bdcmd_names[] ALIGN1 =
	"setro"     "\0"
#define CMD_SETRO 0
	"setrw"     "\0"
	"getro"     "\0"
	"getss"     "\0"
	"getbsz"    "\0"
	"setbsz"    "\0"
#define CMD_SETBSZ 5
	"getsz"     "\0"
	"getsize"   "\0"
	"getsize64" "\0"
	"flushbufs" "\0"
	"rereadpt"  "\0"
;
static const uint32_t bdcmd_ioctl[] = {
	BLKROSET,       //setro
	BLKROSET,       //setrw
	BLKROGET,       //getro
	BLKSSZGET,      //getss
	BLKBSZGET,      //getbsz
	BLKBSZSET,      //setbsz
	BLKGETSIZE64,   //getsz
	BLKGETSIZE,     //getsize
	BLKGETSIZE64,   //getsize64
	BLKFLSBUF,      //flushbufs
	BLKRRPART,      //rereadpt
};
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,
};
static const uint8_t bdcmd_flags[] ALIGN1 = {
	ARG_INT + FL_NORESULT,             //setro
	ARG_INT + FL_NORESULT,             //setrw
	ARG_INT,                           //getro
	ARG_INT,                           //getss
	ARG_INT,                           //getbsz
	ARG_INT + FL_NORESULT + FL_USRARG, //setbsz
	ARG_U64 + FL_SCALE512,             //getsz
	ARG_ULONG,                         //getsize
	ARG_U64,                           //getsize64
	ARG_NONE + FL_NORESULT,            //flushbufs
	ARG_NONE + FL_NORESULT,            //rereadpt
};

static unsigned find_cmd(const char *s)
{
	if (s[0] == '-' && s[1] == '-') {
		int n = index_in_strings(bdcmd_names, s + 2);
		if (n >= 0)
			return n;
	}
	bb_show_usage();
}

int blockdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int blockdev_main(int argc UNUSED_PARAM, char **argv)
{
	unsigned bdcmd;
	unsigned flags;
	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);
	/* setrw translates to BLKROSET(0), most other ioctls don't care... */
	/* ...setro will do BLKROSET(1) */
	u64 = (bdcmd == CMD_SETRO);
	if (bdcmd == CMD_SETBSZ) {
		/* ...setbsz is BLKBSZSET(bytes) */
		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;
	flags = bdcmd_flags[bdcmd];
#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 (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_ioctl[bdcmd], &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 (flags & FL_SCALE512)
		u64 >>= 9;

	/* Zero- or one-extend the value if needed, then print */
	switch (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;
}
