
/*
 * Copyright 2004 Jeff Garzik
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */

#include "blktool-config.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>

#include <linux/hdreg.h>
#include <scsi/sg.h>

#include <glib.h>
#include "blktool.h"


void pdie(const char *msg, int perr)
{
	if (perr)
		perror(msg);
	else
		fprintf(stderr, "%s", msg);
	if (blkdev >= 0)
		close(blkdev);
	exit(1);
}

void flag_push(const char *flag_str)
{
	g_ptr_array_add(flag_arr, (gpointer) flag_str);
}

void list_dump(const char *list_name, GPtrArray *arr)
{
	size_t name_start = strlen(list_name);
	int col = name_start;
	size_t len;
	int i;
	const char *s;

	if (arr->len > 0)
		printf("%s:", list_name);

	for (i = 0; i < arr->len; i++) {
		s = g_ptr_array_index(arr, i);
		len = strlen(s) + 1;

		if ((col + len) > 76) {
			printf("\n%s:", list_name);
			col = name_start;
		}

		printf(" %s", s);
		col += len;
	}

	if (arr->len > 0)
		printf("\n");
}

void ioctl_call(int cmd, const char *cmd_name, void *arg)
{
	if (ioctl(blkdev, cmd, arg))
		pdie(cmd_name, 1);
}

int parse_bool(int argc, char **argv, struct bool_command *bcm)
{
	const char *arg = argv[optind];

	if (!strcmp(arg, "1"))
		return 1;
	if (!strcmp(arg, "on"))
		return 1;
	if (!strcmp(arg, bcm->str_true))
		return 1;

	if (!strcmp(arg, "0"))
		return 0;
	if (!strcmp(arg, "off"))
		return 0;
	if (!strcmp(arg, bcm->str_false))
		return 0;

	fprintf(stderr, MSG_INVALID_ARG, arg, bcm->cmd.cmd);
	exit(1);
	return -1;
}

int parse_int(int argc, char **argv, struct command *cmd)
{
	const char *arg = argv[optind];
	char *endp = NULL;
	long tmp;

	errno = 0;

	tmp = strtol(arg, &endp, 10);
	if ((arg == endp) || (errno != 0))
		goto err_out;

	return tmp;

err_out:
	fprintf(stderr, MSG_INVALID_ARG, arg, cmd->cmd);
	exit(1);
	return -1;
}

void noread_arg_check(int argc, char **argv)
{
	if (optind == argc) {
		fprintf(stderr, MSG_INVALID_CMD_NOREAD, argv[optind - 1]);
		exit(1);
	}
	else if ((optind + 1) != argc) {
		fprintf(stderr, MSG_INVALID_CMD_ARGS, argv[optind - 1]);
		exit(1);
	}
}

int get_bool(int argc, char **argv, struct command *cmd)
{
	noread_arg_check(argc, argv);
	return parse_bool(argc, argv, (struct bool_command *) cmd);
}

int get_int(int argc, char **argv, struct command *cmd)
{
	noread_arg_check(argc, argv);
	return parse_int(argc, argv, cmd);
}

