/*
 * raw.c: User mode tool to bind and query raw character devices.
 *
 * Stephen Tweedie, 1999, 2000
 *
 * This file may be redistributed under the terms of the GNU General
 * Public License, version 2.
 *
 * Copyright Red Hat Software, 1999, 2000
 *
 */

#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <linux/major.h>
#include <linux/raw.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <unistd.h>

#include "c.h"
#include "closestream.h"
#include "nls.h"
#include "pathnames.h"

#define EXIT_RAW_ACCESS 3
#define EXIT_RAW_IOCTL 4

#define RAW_NR_MINORS 8192

int do_query;
int do_query_all;

int master_fd;
int raw_minor;

void open_raw_ctl(void);
static int query(int minor_raw, const char *raw_name, int quiet);
static int bind(int minor_raw, int block_major, int block_minor);

static void __attribute__ ((__noreturn__)) usage(int err)
{
	FILE *out = err == EXIT_SUCCESS ? stdout : stderr;

	fputs(USAGE_HEADER, out);
	fprintf(out,
		_(" %1$s %2$srawN <major> <minor>\n"
		  " %1$s %2$srawN /dev/<blockdevice>\n"
		  " %1$s -q %2$srawN\n"
		  " %1$s -qa\n"), program_invocation_short_name,
		_PATH_RAWDEVDIR);

	fputs(USAGE_SEPARATOR, out);
	fputs(_("Bind a raw character device to a block device.\n"), out);

	fputs(USAGE_OPTIONS, out);
	fputs(_(" -q, --query    set query mode\n"), out);
	fputs(_(" -a, --all      query all raw devices\n"), out);
	fputs(USAGE_HELP, out);
	fputs(USAGE_VERSION, out);
	fprintf(out, USAGE_MAN_TAIL("raw(8)"));
	exit(err);
}

static long strtol_octal_or_err(const char *str, const char *errmesg)
{
	long num;
	char *end = NULL;

	if (str == NULL || *str == '\0')
		goto err;
	errno = 0;
	num = strtol(str, &end, 0);

	if (errno || str == end || (end && *end))
		goto err;

	return num;
 err:
	if (errno)
		err(EXIT_FAILURE, "%s: '%s'", errmesg, str);
	else
		errx(EXIT_FAILURE, "%s: '%s'", errmesg, str);
	return 0;
}

int main(int argc, char *argv[])
{
	int c;
	char *raw_name;
	char *block_name;
	int retval;
	int block_major, block_minor;
	int i, rc;

	struct stat statbuf;

	static const struct option longopts[] = {
		{"query", no_argument, 0, 'q'},
		{"all", no_argument, 0, 'a'},
		{"version", no_argument, 0, 'V'},
		{"help", no_argument, 0, 'h'},
		{NULL, no_argument, 0, '0'},
	};

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

	while ((c = getopt_long(argc, argv, "qaVh", longopts, NULL)) != -1)
		switch (c) {
		case 'q':
			do_query = 1;
			break;
		case 'a':
			do_query_all = 1;
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			return EXIT_SUCCESS;
		case 'h':
			usage(EXIT_SUCCESS);
		default:
			usage(EXIT_FAILURE);
		}

	/*
	 * Check for, and open, the master raw device, /dev/raw
	 */
	open_raw_ctl();

	if (do_query_all) {
		if (optind < argc)
			usage(EXIT_FAILURE);
		for (i = 1; i < RAW_NR_MINORS; i++)
			query(i, NULL, 1);
		exit(EXIT_SUCCESS);
	}

	/*
	 * It's a bind or a single query.  Either way we need a raw device.
	 */

	if (optind >= argc)
		usage(EXIT_FAILURE);
	raw_name = argv[optind++];

	/*
	 * try to check the device name before stat(), because on systems with
	 * udev the raw0 causes a create udev event for char 162/0, which
	 * causes udev to *remove* /dev/rawctl
	 */
	rc = sscanf(raw_name, _PATH_RAWDEVDIR "raw%d", &raw_minor);
	if (rc != 1)
		usage(EXIT_FAILURE);

	if (raw_minor == 0)
		errx(EXIT_RAW_ACCESS,
		     _("Device '%s' is the control raw device "
		       "(use raw<N> where <N> is greater than zero)"),
		     raw_name);

	if (do_query)
		return query(raw_minor, raw_name, 0);

	/*
	 * It's not a query, so we still have some parsing to do.  Have we been
	 * given a block device filename or a major/minor pair?
	 */
	switch (argc - optind) {
	case 1:
		block_name = argv[optind];
		retval = stat(block_name, &statbuf);
		if (retval)
			err(EXIT_RAW_ACCESS,
			    _("Cannot locate block device '%s'"), block_name);
		if (!S_ISBLK(statbuf.st_mode))
			errx(EXIT_RAW_ACCESS,
			     _("Device '%s' is not a block device"),
			     block_name);
		block_major = major(statbuf.st_rdev);
		block_minor = minor(statbuf.st_rdev);
		break;

	case 2:
		block_major =
		    strtol_octal_or_err(argv[optind],
					_("failed to parse argument"));
		block_minor =
		    strtol_octal_or_err(argv[optind + 1],
					_("failed to parse argument"));
		break;

	default:
		usage(EXIT_FAILURE);
	}

	return bind(raw_minor, block_major, block_minor);
}

void open_raw_ctl(void)
{
	master_fd = open(_PATH_RAWDEVCTL, O_RDWR, 0);
	if (master_fd < 0) {
		master_fd = open(_PATH_RAWDEVCTL_OLD, O_RDWR, 0);
		if (master_fd < 0)
			err(EXIT_RAW_ACCESS,
			    _("Cannot open master raw device '%s'"),
			    _PATH_RAWDEVCTL);
	}
}

static int query(int minor_raw, const char *raw_name, int quiet)
{
	struct raw_config_request rq;
	static int has_worked = 0;

	if (raw_name) {
		struct stat statbuf;

		if (stat(raw_name, &statbuf) != 0)
			err(EXIT_RAW_ACCESS,
			    _("Cannot locate raw device '%s'"), raw_name);
		if (!S_ISCHR(statbuf.st_mode))
			errx(EXIT_RAW_ACCESS,
			     _("Raw device '%s' is not a character dev"),
			     raw_name);
		if (major(statbuf.st_rdev) != RAW_MAJOR)
			errx(EXIT_RAW_ACCESS,
			     _("Device '%s' is not a raw dev"), raw_name);
		minor_raw = minor(statbuf.st_rdev);
	}

	rq.raw_minor = minor_raw;
	if (ioctl(master_fd, RAW_GETBIND, &rq) < 0) {
		if (quiet && errno == ENODEV)
			return 3;
		if (has_worked && errno == EINVAL)
			return 0;
		err(EXIT_RAW_IOCTL, _("Error querying raw device"));
	}

	/* If one query has worked, mark that fact so that we don't report
	 * spurious fatal errors if raw(8) has been built to support more raw
	 * minor numbers than the kernel has. */
	has_worked = 1;
	if (quiet && !rq.block_major && !rq.block_minor)
		return 0;
	printf(_("%sraw%d:  bound to major %d, minor %d\n"),
	       _PATH_RAWDEVDIR, minor_raw, (int)rq.block_major,
	       (int)rq.block_minor);
	return 0;
}

static int bind(int minor_raw, int block_major, int block_minor)
{
	struct raw_config_request rq;

	rq.raw_minor = minor_raw;
	rq.block_major = block_major;
	rq.block_minor = block_minor;
	if (ioctl(master_fd, RAW_SETBIND, &rq) < 0)
		err(EXIT_RAW_IOCTL, _("Error setting raw device"));
	printf(_("%sraw%d:  bound to major %d, minor %d\n"),
	       _PATH_RAWDEVDIR, raw_minor, (int)rq.block_major,
	       (int)rq.block_minor);
	return 0;
}
