/*
 * 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[] ALIGN4 = {
	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;
}
