/*
 * Copyright (C) 2007-2009 Kay Sievers <kay.sievers@vrfy.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>

#include "udev.h"

static int debug;

static void log_fn(struct udev *udev, int priority,
		   const char *file, int line, const char *fn,
		   const char *format, va_list args)
{
	if (debug) {
		fprintf(stderr, "%s: ", fn);
		vfprintf(stderr, format, args);
	} else {
		va_list args2;

		va_copy(args2, args);
		vfprintf(stderr, format, args2);
		va_end(args2);
		vsyslog(priority, format, args);
	}
}

struct command {
	const char *name;
	int (*cmd)(struct udev *udev, int argc, char *argv[]);
	const char *help;
	int debug;
};

static const struct command cmds[];

static int version(struct udev *udev, int argc, char *argv[])
{
	printf("%s\n", VERSION);
	return 0;
}

static int help(struct udev *udev, int argc, char *argv[])
{
	const struct command *cmd;

	printf("Usage: udevadm [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]\n");
	for (cmd = cmds; cmd->name != NULL; cmd++)
		if (cmd->help != NULL)
			printf("  %-12s %s\n", cmd->name, cmd->help);
	printf("\n");
	return 0;
}

static const struct command cmds[] = {
	{
		.name = "info",
		.cmd = udevadm_info,
		.help = "query sysfs or the udev database",
	},
	{
		.name = "trigger",
		.cmd = udevadm_trigger,
		.help = "request events from the kernel",
	},
	{
		.name = "settle",
		.cmd = udevadm_settle,
		.help = "wait for the event queue to finish",
	},
	{
		.name = "control",
		.cmd = udevadm_control,
		.help = "control the udev daemon",
	},
	{
		.name = "monitor",
		.cmd = udevadm_monitor,
		.help = "listen to kernel and udev events",
	},
	{
		.name = "test",
		.cmd = udevadm_test,
		.help = "simulation run",
		.debug = 1,
	},
	{
		.name = "version",
		.cmd = version,
	},
	{
		.name = "help",
		.cmd = help,
	},
	{}
};

static int run_command(struct udev *udev, const struct command *cmd, int argc, char *argv[])
{
	if (cmd->debug) {
		debug = 1;
		if (udev_get_log_priority(udev) < LOG_INFO)
			udev_set_log_priority(udev, LOG_INFO);
	}
	info(udev, "calling: %s\n", cmd->name);
	return cmd->cmd(udev, argc, argv);
}

int main(int argc, char *argv[])
{
	struct udev *udev;
	static const struct option options[] = {
		{ "debug", no_argument, NULL, 'd' },
		{ "help", no_argument, NULL, 'h' },
		{ "version", no_argument, NULL, 'V' },
		{}
	};
	const char *command;
	int i;
	int rc = 1;

	udev = udev_new();
	if (udev == NULL)
		goto out;

	udev_log_init("udevadm");
	udev_set_log_fn(udev, log_fn);
	udev_selinux_init(udev);

	for (;;) {
		int option;

		option = getopt_long(argc, argv, "+dhV", options, NULL);
		if (option == -1)
			break;

		switch (option) {
		case 'd':
			debug = 1;
			if (udev_get_log_priority(udev) < LOG_INFO)
				udev_set_log_priority(udev, LOG_INFO);
			break;
		case 'h':
			rc = help(udev, argc, argv);
			goto out;
		case 'V':
			rc = version(udev, argc, argv);
			goto out;
		default:
			goto out;
		}
	}
	command = argv[optind];

	if (command != NULL)
		for (i = 0; cmds[i].cmd != NULL; i++) {
			if (strcmp(cmds[i].name, command) == 0) {
				argc -= optind;
				argv += optind;
				optind = 0;
				rc = run_command(udev, &cmds[i], argc, argv);
				goto out;
			}
		}

	fprintf(stderr, "missing or unknown command\n\n");
	help(udev, argc, argv);
	rc = 2;
out:
	udev_selinux_exit(udev);
	udev_unref(udev);
	udev_log_close();
	return rc;
}
