commit da6383d0b4d1c2843dba3115c7cadfa8137c158c
Author: Christoph Lohmann <20h@r-36.net>
Date: Sat, 26 Feb 2011 17:20:49 +0100
Initial commit of nlmon.
Diffstat:
LICENSE | | | 21 | +++++++++++++++++++++ |
Makefile | | | 50 | ++++++++++++++++++++++++++++++++++++++++++++++++++ |
README.md | | | 11 | +++++++++++ |
arg.h | | | 19 | +++++++++++++++++++ |
config.mk | | | 23 | +++++++++++++++++++++++ |
nlmon.c | | | 167 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
6 files changed, 291 insertions(+), 0 deletions(-)
diff --git a/LICENSE b/LICENSE
@@ -0,0 +1,21 @@
+MIT/X Consortium License
+
+© 2011 Christoph Lohmann <20h@r-36.net>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/Makefile b/Makefile
@@ -0,0 +1,50 @@
+# nlmon - dynamic window manager
+# See LICENSE file for copyright and license details.
+
+include config.mk
+
+SRC = ${NAME}.c
+OBJ = ${SRC:.c=.o}
+
+all: options ${NAME}
+
+options:
+ @echo ${NAME} build options:
+ @echo "CFLAGS = ${CFLAGS}"
+ @echo "LDFLAGS = ${LDFLAGS}"
+ @echo "CC = ${CC}"
+
+.c.o:
+ @echo CC $<
+ @${CC} -c ${CFLAGS} $<
+
+${OBJ}: config.mk
+
+${NAME}: ${OBJ}
+ @echo CC -o $@
+ @${CC} -o $@ ${OBJ} ${LDFLAGS}
+
+clean:
+ @echo cleaning
+ @rm -f ${NAME} ${OBJ} ${NAME}-${VERSION}.tar.gz
+
+dist: clean
+ @echo creating dist tarball
+ @mkdir -p ${NAME}-${VERSION}
+ @cp -R LICENSE Makefile README.md config.mk \
+ ${SRC} *.h ${NAME}-${VERSION}
+ @tar -cf ${NAME}-${VERSION}.tar ${NAME}-${VERSION}
+ @gzip ${NAME}-${VERSION}.tar
+ @rm -rf ${NAME}-${VERSION}
+
+install: all
+ @echo installing executable file to ${DESTDIR}${PREFIX}/bin
+ @mkdir -p ${DESTDIR}${PREFIX}/bin
+ @cp -f ${NAME} ${DESTDIR}${PREFIX}/bin
+ @chmod 755 ${DESTDIR}${PREFIX}/bin/${NAME}
+
+uninstall:
+ @echo removing executable file from ${DESTDIR}${PREFIX}/bin
+ @rm -f ${DESTDIR}${PREFIX}/bin/${NAME}
+
+.PHONY: all options clean dist install uninstall
diff --git a/README.md b/README.md
@@ -0,0 +1,11 @@
+# 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/arg.h b/arg.h
@@ -0,0 +1,19 @@
+#ifndef ARG_H
+#define ARG_H
+
+#define USED(x) ((void)(x))
+
+extern char *argv0;
+
+#define ARGBEGIN for(argv0 = *argv, argv++, argc--;\
+ argv[0] && argv[0][0]=='-' && argv[0][1];\
+ argc--, argv++) {\
+ char _argc;\
+ _argc = argv[0][1];\
+ switch(_argc)
+#define ARGEND USED(_argc);} USED(argv);USED(argc);
+#define EARGF(x) ((argv[1] == NULL)? ((x), abort(), (char *)0) :\
+ (argc--, argv++, argv[0]))
+
+#endif
+
diff --git a/config.mk b/config.mk
@@ -0,0 +1,23 @@
+# nlmon metadata
+NAME = nlmon
+VERSION = 0.2
+
+# Customize below to fit your system
+
+# paths
+PREFIX = /usr
+MANPREFIX = ${PREFIX}/share/man
+
+# includes and libs
+INCS = -I. -I/usr/include
+LIBS = -L/usr/lib -lc -ludev
+
+# flags
+CPPFLAGS = -DVERSION=\"${VERSION}\"
+CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
+LDFLAGS = -g ${LIBS}
+#LDFLAGS = -s ${LIBS}
+
+# compiler and linker
+CC = cc
+
diff --git a/nlmon.c b/nlmon.c
@@ -0,0 +1,167 @@
+/*
+ * Copy me if you can.
+ * by 20h
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <libudev.h>
+#include <poll.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "arg.h"
+
+char *argv0;
+
+void
+printdevice(struct udev_device *dev)
+{
+ char *s;
+
+#define PRINTELEM(NAME) \
+ s = (char *)udev_device_get_##NAME(dev); \
+ if (s != NULL) \
+ printf(#NAME "=%s\n", udev_device_get_##NAME(dev));
+
+ PRINTELEM(devpath)
+ PRINTELEM(subsystem)
+ PRINTELEM(devtype)
+ PRINTELEM(syspath)
+ PRINTELEM(sysnum)
+ PRINTELEM(devnode)
+ PRINTELEM(driver)
+
+ printf("devnum=%d\n", (int)udev_device_get_devnum(dev));
+
+ PRINTELEM(action)
+ fflush(stdout);
+}
+
+void
+printproperties(struct udev_device *dev)
+{
+ 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);
+}
+
+void
+printtags(struct udev_device *dev)
+{
+ struct udev_list_entry *tags, *tag;
+
+ 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);
+}
+
+void
+usage(void)
+{
+ fprintf(stderr, "usage: %s [-ptl] [-ku] [-f filter]\n", argv0);
+ fflush(stderr);
+ exit(EXIT_FAILURE);
+}
+
+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";
+
+ ARGBEGIN {
+ case 'f':
+ filter = EARGF(usage());
+ break;
+ case 'p':
+ doprops = 1;
+ break;
+ case 'l':
+ dolinks = 1;
+ break;
+ case 't':
+ dotags = 1;
+ break;
+ case 'k':
+ rtlink = "kernel";
+ break;
+ case 'u':
+ rtlink = "udev";
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ udev = udev_new();
+ if (!udev) {
+ perror("udev_new");
+ exit(EXIT_FAILURE);
+ }
+
+ 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, 500);
+ 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);
+ }
+ }
+ }
+ }
+
+ exit(EXIT_SUCCESS);
+}
+