if [ "$DEV" = yes ]; then
echo "SRCS+= dev.c" >>$CONFIG_MK
echo "CPPFLAGS+= -DPLUGIN_DEV" >>$CONFIG_MK
- echo "LDFLAGS+= -Wl,--export-dynamic" >>$CONFIG_MK
echo "MKDIRS+= dev" >>$CONFIG_MK
fi
#include "common.h"
#include "dev.h"
+#include "eloop.h"
+#include "dhcpcd.h"
static struct dev *dev;
static void *handle;
+static int fd = -1;
+
+static struct dev_dhcpcd dev_dhcpcd = {
+ .handle_interface = &handle_interface
+};
int
dev_initialized(const char *ifname)
}
static int
-dev_start1(const char *name)
+dev_start2(const char *name)
{
char file[PATH_MAX];
void *h;
- void (*fptr)(struct dev *);
+ void (*fptr)(struct dev *, const struct dev_dhcpcd *);
+ int r;
snprintf(file, sizeof(file), DEVDIR "/%s", name);
h = dlopen(file, RTLD_LAZY);
syslog(LOG_ERR, "dlopen: %s", dlerror());
return -1;
}
- fptr = (void (*)(struct dev *))dlsym(h, "dev_init");
+ fptr = (void (*)(struct dev *, const struct dev_dhcpcd *))dlsym(h, "dev_init");
if (fptr == NULL) {
syslog(LOG_ERR, "dlsym: %s", dlerror());
dlclose(h);
return -1;
}
dev = calloc(1, sizeof(*dev));
- fptr(dev);
- if (dev->start == NULL || dev->start() == -1) {
+ fptr(dev, &dev_dhcpcd);
+ if (dev->start == NULL || (r = dev->start()) == -1) {
free(dev);
dev = NULL;
dlclose(h);
}
syslog(LOG_INFO, "dev: loaded %s", dev->name);
handle = h;
- return 0;
+ return r;
}
-int
-dev_start(const char *plugin)
+static int
+dev_start1(const char *plugin)
{
DIR *dp;
struct dirent *d;
}
if (plugin)
- return dev_start1(plugin);
+ return dev_start2(plugin);
dp = opendir(DEVDIR);
if (dp == NULL) {
if (d->d_name[0] == '.')
continue;
- r = dev_start1(d->d_name);
+ r = dev_start2(d->d_name);
if (r != -1)
break;
}
return r;
}
+
+int
+dev_start(const char *plugin)
+{
+
+ fd = dev_start1(plugin);
+ if (fd != -1) {
+ if (eloop_event_add(fd, dev->handle_data, NULL) == -1) {
+ syslog(LOG_ERR, "%s: eloop_event_add: %m", __func__);
+ dev_stop();
+ return -1;
+ }
+ }
+
+ return fd;
+}
const char *name;
int (*initialized)(const char *);
int (*listening)(void);
+ void (*handle_data)(void *);
int (*start)(void);
void (*stop)(void);
};
-int dev_init(struct dev *);
+
+struct dev_dhcpcd {
+ void (*handle_interface)(int, const char *);
+};
+
+int dev_init(struct dev *, const struct dev_dhcpcd *);
// hooks for dhcpcd
#ifdef PLUGIN_DEV
#include <syslog.h>
#include "../common.h"
-#include "../dhcpcd.h"
-#include "../eloop.h"
#include "../dev.h"
static const char udev_name[]="udev";
static struct udev *udev;
static struct udev_monitor *monitor;
-static int monitor_fd = -1;
+
+static const struct dev_dhcpcd *dhcpcd;
+
+static int
+udev_listening(void)
+{
+
+ return monitor ? 1 : 0;
+}
static int
udev_initialized(const char *ifname)
}
static void
-udev_handledata(__unused void *arg)
+udev_handle_data(__unused void *arg)
{
struct udev_device *device;
const char *subsystem, *ifname, *action;
if (strcmp(subsystem, "net") == 0) {
syslog(LOG_DEBUG, "%s: libudev: %s", ifname, action);
if (strcmp(action, "add") == 0 || strcmp(action, "move") == 0)
- handle_interface(1, ifname);
+ dhcpcd->handle_interface(1, ifname);
else if (strcmp(action, "remove") == 0)
- handle_interface(-1, ifname);
+ dhcpcd->handle_interface(-1, ifname);
}
udev_device_unref(device);
}
-static int
-udev_listening(void)
-{
-
- return monitor ? 1 : 0;
-}
-
static void
udev_stop(void)
{
- if (monitor_fd != -1) {
- eloop_event_delete(monitor_fd);
- monitor_fd = -1;
- }
-
if (monitor) {
udev_monitor_unref(monitor);
monitor = NULL;
static int
udev_start(void)
{
+ int fd;
if (udev) {
syslog(LOG_ERR, "udev: already started");
syslog(LOG_ERR, "udev_monitor_enable_receiving: %m");
goto bad;
}
- monitor_fd = udev_monitor_get_fd(monitor);
- if (monitor_fd == -1) {
+ fd = udev_monitor_get_fd(monitor);
+ if (fd == -1) {
syslog(LOG_ERR, "udev_monitor_get_fd: %m");
goto bad;
}
- if (eloop_event_add(monitor_fd, udev_handledata, NULL) == -1) {
- syslog(LOG_ERR, "%s: eloop_event_add: %m", __func__);
- goto bad;
- }
+ return fd;
- return monitor_fd;
bad:
-
udev_stop();
return -1;
}
int
-dev_init(struct dev *dev)
+dev_init(struct dev *dev, const struct dev_dhcpcd *dev_dhcpcd)
{
dev->name = udev_name;
dev->initialized = udev_initialized;
dev->listening = udev_listening;
- dev->start = udev_start;
+ dev->handle_data = udev_handle_data;
dev->stop = udev_stop;
+ dev->start = udev_start;
+
+ dhcpcd = dev_dhcpcd;
+
return 0;
}
#define eloop_timeouts_delete(a, ...) \
eloop_q_timeouts_delete(ELOOP_QUEUE, a, __VA_ARGS__)
-int eloop_event_add(int fd, void (*)(void *), void *);
-void eloop_event_delete(int fd);
+int eloop_event_add(int, void (*)(void *), void *);
+void eloop_event_delete(int);
int eloop_q_timeout_add_sec(int queue, time_t, void (*)(void *), void *);
int eloop_q_timeout_add_tv(int queue, const struct timeval *, void (*)(void *),
void *);