/*
 * dhcpcd - DHCP client daemon
 * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifdef LIBUDEV_NOINIT
#  define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE
#  warning This version of udev is too old does not support
#  warning per device initialization checks.
#  warning As such, dhcpcd will need to depend on the
#  warning udev-settle service or similar if starting
#  warning in master mode.
#endif

#include <libudev.h>
#include <string.h>
#include <syslog.h>

#include "../common.h"
#include "../dev.h"

static const char udev_name[] = "udev";
static struct udev *udev;
static struct udev_monitor *monitor;

static struct dev_dhcpcd dhcpcd;

static int
udev_listening(void)
{

	return monitor ? 1 : 0;
}

static int
udev_initialized(const char *ifname)
{
	struct udev_device *device;
	int r;

	device = udev_device_new_from_subsystem_sysname(udev, "net", ifname);
	if (device) {
#ifndef LIBUDEV_NOINIT
		r = udev_device_get_is_initialized(device);
#else
		r = 1;
#endif
		udev_device_unref(device);
	} else
		r = 0;
	return r;
}

static int
udev_handle_device(void *ctx)
{
	struct udev_device *device;
	const char *subsystem, *ifname, *action;

	device = udev_monitor_receive_device(monitor);
	if (device == NULL) {
		syslog(LOG_ERR, "libudev: received NULL device");
		return -1;
	}

	subsystem = udev_device_get_subsystem(device);
	ifname = udev_device_get_sysname(device);
	action = udev_device_get_action(device);

	/* udev filter documentation says "usually" so double check */
	if (strcmp(subsystem, "net") == 0) {
		syslog(LOG_DEBUG, "%s: libudev: %s", ifname, action);
		if (strcmp(action, "add") == 0 || strcmp(action, "move") == 0)
			dhcpcd.handle_interface(ctx, 1, ifname);
		else if (strcmp(action, "remove") == 0)
			dhcpcd.handle_interface(ctx, -1, ifname);
	}

	udev_device_unref(device);
	return 1;
}

static void
udev_stop(void)
{

	if (monitor) {
		udev_monitor_unref(monitor);
		monitor = NULL;
	}

	if (udev) {
		udev_unref(udev);
		udev = NULL;
	}
}

static int
udev_start(void)
{
	int fd;

	if (udev) {
		syslog(LOG_ERR, "udev: already started");
		return -1;
	}

	syslog(LOG_DEBUG, "udev: starting");
	udev = udev_new();
	if (udev == NULL) {
		syslog(LOG_ERR, "udev_new: %m");
		return -1;
	}
	monitor = udev_monitor_new_from_netlink(udev, "udev");
	if (monitor == NULL) {
		syslog(LOG_ERR, "udev_monitor_new_from_netlink: %m");
		goto bad;
	}
#ifndef LIBUDEV_NOFILTER
	if (udev_monitor_filter_add_match_subsystem_devtype(monitor,
	    "net", NULL) != 0)
	{
		syslog(LOG_ERR,
		    "udev_monitor_filter_add_match_subsystem_devtype: %m");
		goto bad;
	}
#endif
	if (udev_monitor_enable_receiving(monitor) != 0) {
		syslog(LOG_ERR, "udev_monitor_enable_receiving: %m");
		goto bad;
	}
	fd = udev_monitor_get_fd(monitor);
	if (fd == -1) {
		syslog(LOG_ERR, "udev_monitor_get_fd: %m");
		goto bad;
	}
	return fd;

bad:
	udev_stop();
	return -1;
}

int
dev_init(struct dev *dev, const struct dev_dhcpcd *dev_dhcpcd)
{

	dev->name = udev_name;
	dev->initialized = udev_initialized;
	dev->listening = udev_listening;
	dev->handle_device = udev_handle_device;
	dev->stop = udev_stop;
	dev->start = udev_start;

	dhcpcd = *dev_dhcpcd;

	return 0;
}
