commit 24284ee0dcbbe18246633b903585afe40728c770
parent de28e91664d7cb3aab511b0bb853859b2ed66a30
Author: Christoph Lohmann <20h@r-36.net>
Date: Fri, 6 Apr 2012 23:37:32 +0200
Removing libudev dependency.
Diffstat:
README.md | | | 11 | ----------- |
config.mk | | | 2 | +- |
nlmon.c | | | 186 | ++++++++++++++++++++++++++++++++----------------------------------------------- |
3 files changed, 76 insertions(+), 123 deletions(-)
diff --git a/README.md b/README.md
@@ -1,11 +0,0 @@
-# NetLink MONitor
-
-This simple utility is a replacement for udevadm monitor, which
-is full of bugs. It will listen on either the kernel (-k) or the
-udev (-u) events and print out the standard device parameters,
-the properties (-p), the tags (-t) and the devlinks (-l). You
-can filter (-f $subsystem) for the subsystem you only want to
-see events for.
-
-Have fun!
-
diff --git a/config.mk b/config.mk
@@ -10,7 +10,7 @@ MANPREFIX = ${PREFIX}/share/man
# includes and libs
INCS = -I. -I/usr/include
-LIBS = -L/usr/lib -lc -ludev
+LIBS = -L/usr/lib -lc
# flags
CPPFLAGS = -DVERSION=\"${VERSION}\"
diff --git a/nlmon.c b/nlmon.c
@@ -6,162 +6,126 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
-#include <libudev.h>
+#include <stdarg.h>
#include <poll.h>
#include <ctype.h>
#include <string.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <linux/types.h>
+#include <linux/netlink.h>
#include "arg.h"
char *argv0;
void
-printdevice(struct udev_device *dev)
+edie(char *fmt, ...)
{
- char *s;
+ va_list fmtargs;
-#define PRINTELEM(NAME) \
- s = (char *)udev_device_get_##NAME(dev); \
- if (s != NULL) \
- printf(#NAME "=%s\n", udev_device_get_##NAME(dev));
+ va_start(fmtargs, fmt);
+ vfprintf(stderr, fmt, fmtargs);
+ va_end(fmtargs);
+ fprintf(stderr, ": ");
- PRINTELEM(devpath)
- PRINTELEM(subsystem)
- PRINTELEM(devtype)
- PRINTELEM(syspath)
- PRINTELEM(sysnum)
- PRINTELEM(devnode)
- PRINTELEM(driver)
+ perror(NULL);
- printf("devnum=%d\n", (int)udev_device_get_devnum(dev));
-
- PRINTELEM(action)
- fflush(stdout);
+ exit(1);
}
void
-printproperties(struct udev_device *dev)
+die(char *fmt, ...)
{
- struct udev_list_entry *props, *prop;
-
- props = udev_device_get_properties_list_entry(dev);
- udev_list_entry_foreach(prop, props) {
- printf("%s=%s\n", udev_list_entry_get_name(prop), \
- udev_list_entry_get_value(prop));
- }
- fflush(stdout);
-}
+ va_list fmtargs;
-void
-printtags(struct udev_device *dev)
-{
- struct udev_list_entry *tags, *tag;
+ va_start(fmtargs, fmt);
+ vfprintf(stderr, fmt, fmtargs);
+ va_end(fmtargs);
- tags = udev_device_get_tags_list_entry(dev);
- udev_list_entry_foreach(tag, tags) {
- printf("%s=%s\n", udev_list_entry_get_name(tag), \
- udev_list_entry_get_value(tag));
- }
- fflush(stdout);
-}
-
-void
-printdevlinks(struct udev_device *dev)
-{
- struct udev_list_entry *devlinks, *devlink;
-
- devlinks = udev_device_get_devlinks_list_entry(dev);
- udev_list_entry_foreach(devlink, devlinks) {
- printf("%s=%s\n", udev_list_entry_get_name(devlink), \
- udev_list_entry_get_value(devlink));
- }
- fflush(stdout);
+ exit(1);
}
void
usage(void)
{
- fprintf(stderr, "usage: %s [-ptl] [-ku] [-f filter]\n", argv0);
- fflush(stderr);
- exit(EXIT_FAILURE);
+ die("usage: %s [-h] [-ku] [-f subsystem]\n", argv0);
}
int
main(int argc, char *argv[])
{
- char *filter, *rtlink;
- struct udev *udev;
- struct udev_monitor *mon;
- struct udev_device *dev;
- struct pollfd fds[1];
- int ret, doprops, dotags, dolinks;
-
- filter = NULL;
- doprops = 0;
- dotags = 0;
- dolinks = 0;
- rtlink = "kernel";
+ struct sockaddr_nl nls;
+ struct pollfd fds;
+ char buf[4097], obuf[4098], *subsystem;
+ int i, len, olen, slen, showudev, showkernel;
+
+ showkernel = 1;
+ showudev = 1;
+ subsystem = NULL;
ARGBEGIN {
case 'f':
- filter = EARGF(usage());
- break;
- case 'p':
- doprops = 1;
- break;
- case 'l':
- dolinks = 1;
- break;
- case 't':
- dotags = 1;
+ subsystem = EARGF(usage());
break;
case 'k':
- rtlink = "kernel";
+ showudev = 0;
break;
case 'u':
- rtlink = "udev";
+ showkernel = 0;
break;
default:
usage();
} ARGEND;
- udev = udev_new();
- if (!udev) {
- perror("udev_new");
- exit(EXIT_FAILURE);
- }
+ memset(&nls, 0, sizeof(nls));
+ nls.nl_family = AF_NETLINK;
+ nls.nl_pid = getpid();
+ nls.nl_groups = -1;
+
+ fds.events = POLLIN;
+ fds.fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
+ if (fds.fd < 0)
+ edie("socket");
+
+ if (bind(fds.fd, (void *)&nls, sizeof(nls)))
+ edie("bind");
+
+ buf[sizeof(buf)-1] = '\0';
+ while (poll(&fds, 1, -1) > -1) {
+ len = recv(fds.fd, buf, sizeof(buf)-1, MSG_DONTWAIT);
+ if (len < 0)
+ edie("recv");
+
+ if (strstr(buf, "libudev")) {
+ if (!showudev)
+ continue;
+ } else {
+ if (!showkernel)
+ continue;
+ }
- mon = udev_monitor_new_from_netlink(udev, rtlink);
- if (filter != NULL)
- udev_monitor_filter_add_match_subsystem_devtype(mon, \
- filter, NULL);
- udev_monitor_enable_receiving(mon);
-
- fds[0].fd = udev_monitor_get_fd(mon);
- fds[0].events = POLLIN|POLLPRI;
-
- for(;;) {
- ret = poll(fds, 1, -1);
- if (ret > 0) {
- if ((fds[0].revents & POLLIN) \
- || (fds[0].revents & POLLPRI)) {
- dev = udev_monitor_receive_device(mon);
- if (dev) {
- printdevice(dev);
- if (doprops)
- printproperties(dev);
- if (dotags)
- printtags(dev);
- if (dolinks)
- printdevlinks(dev);
- printf("\n");
- fflush(stdout);
- udev_device_unref(dev);
- }
+ for (i = 0, olen = 0; i < len; i += slen + 1) {
+ slen = strlen(buf+i);
+ if (!slen || !strchr(buf+i, '='))
+ continue;
+ if (subsystem && !strncmp(buf+i, "SUBSYSTEM=", 10)
+ && !strstr(buf+i+10, subsystem)) {
+ olen = 0;
+ break;
}
+
+ snprintf(obuf+olen, sizeof(obuf)-olen-2,
+ "%s\n", buf+i);
+ olen += slen + 1;
+ }
+ if (olen > 0) {
+ obuf[olen] = '\n';
+ write(0, obuf, olen+1);
}
}
- exit(EXIT_SUCCESS);
+ exit(0);
}