commit 1953099f5f153e6e6bb19db54bd334bc25e6f655
parent b30694187cbd260d08dfc38dd468d41938d5bff9
Author: Christoph Lohmann <20h@r-36.net>
Date: Sun, 12 Sep 2021 20:59:58 +0200
Push v0.4 with major changes.
* nltrigger in C instead of old script
* nltrigger.1 manpage
* make now follows bitreich simpler output rules
* there is now a config.h with selection of when to trigger commands
* this filters and speeds up the whole system init
Thanks Platon Ryzhikov <ihummer63@yandex.ru> for sending in
the proposal and giving me the motivation to renew nldev
to this stage.
Diffstat:
Makefile | | | 72 | +++++++++++++++++++++++++++++++++--------------------------------------- |
config.mk | | | 6 | +++--- |
nldev.c | | | 37 | +++++++++++++++++++++---------------- |
nltrigger | | | 83 | ------------------------------------------------------------------------------- |
nltrigger.1 | | | 48 | ++++++++++++++++++++++++++++++++++++++++++++++++ |
nltrigger.c | | | 160 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
6 files changed, 265 insertions(+), 141 deletions(-)
diff --git a/Makefile b/Makefile
@@ -3,20 +3,13 @@
include config.mk
-SRC = ${NAME}.c
+SRC = ${NAME}.c nltrigger.c
OBJ = ${SRC:.c=.o}
-all: options ${NAME}
-
-options:
- @echo ${NAME} build options:
- @echo "CFLAGS = ${CFLAGS}"
- @echo "LDFLAGS = ${LDFLAGS}"
- @echo "CC = ${CC}"
+all: ${NAME} nltrigger
.c.o:
- @echo CC $<
- @${CC} -c ${CFLAGS} $<
+ ${CC} -c ${CFLAGS} $<
${OBJ}: config.h config.mk
@@ -24,40 +17,41 @@ config.h:
cp config.def.h $@
${NAME}: ${OBJ}
- @echo CC -o $@
- @${CC} -o $@ ${OBJ} ${LDFLAGS}
+ ${CC} -o $@ $@.o ${LDFLAGS}
+
+nltrigger: ${OBJ}
+ ${CC} -o $@ $@.o ${LDFLAGS}
+
clean:
- @echo cleaning
- @rm -f ${NAME} ${OBJ} ${NAME}-${VERSION}.tar.gz
+ rm -f ${NAME} ${OBJ} nltrigger ${NAME}-${VERSION}.tar.gz
dist: clean
- @echo creating dist tarball
- @mkdir -p ${NAME}-${VERSION}
- @cp -R LICENSE Makefile README.md FIXES.md config.def.h config.mk \
- ${SRC} ${NAME}.8 *.h ${NAME}-${VERSION}
- @tar -cf ${NAME}-${VERSION}.tar ${NAME}-${VERSION}
- @gzip ${NAME}-${VERSION}.tar
- @rm -rf ${NAME}-${VERSION}
+ mkdir -p ${NAME}-${VERSION}
+ cp -R LICENSE Makefile README.md FIXES.md config.def.h config.mk \
+ ${SRC} ${NAME}.8 nltrigger.1 *.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
- @cp -f run_${NAME} ${DESTDIR}${PREFIX}/bin
- @cp -f nltrigger ${DESTDIR}${PREFIX}/bin
- @chmod 755 ${DESTDIR}${PREFIX}/bin/${NAME}
- @echo installing manual page to ${DESTDIR}${MANPREFIX}/man8
- @mkdir -p ${DESTDIR}${MANPREFIX}/man8
- @cp -f ${NAME}.8 ${DESTDIR}${MANPREFIX}/man8
- @chmod 644 ${DESTDIR}${MANPREFIX}/man8/${NAME}.8
+ mkdir -p ${DESTDIR}${PREFIX}/bin
+ cp -f ${NAME} ${DESTDIR}${PREFIX}/bin
+ cp -f run_${NAME} ${DESTDIR}${PREFIX}/bin
+ cp -f nltrigger ${DESTDIR}${PREFIX}/bin
+ chmod 755 ${DESTDIR}${PREFIX}/bin/${NAME}
+ mkdir -p ${DESTDIR}${MANPREFIX}/man8
+ cp -f ${NAME}.8 ${DESTDIR}${MANPREFIX}/man8
+ chmod 644 ${DESTDIR}${MANPREFIX}/man8/${NAME}.8
+ mkdir -p ${DESTDIR}${MANPREFIX}/man1
+ cp -f nltrigger.1 ${DESTDIR}${MANPREFIX}/man1
+ chmod 644 ${DESTDIR}${MANPREFIX}/man1/nltrigger.1
uninstall:
- @echo removing executable file from ${DESTDIR}${PREFIX}/bin
- @rm -f ${DESTDIR}${PREFIX}/bin/${NAME}
- @rm -f ${DESTDIR}${PREFIX}/bin/run_${NAME}
- @rm -f ${DESTDIR}${PREFIX}/bin/nltrigger
- @echo removing manual page from ${DESTDIR}${PREFIX}/man8
- @rm -f ${DESTDIR}${MANPREFIX}/man8/${NAME}.8
-
-.PHONY: all options clean dist install uninstall
+ rm -f ${DESTDIR}${PREFIX}/bin/${NAME}
+ rm -f ${DESTDIR}${PREFIX}/bin/run_${NAME}
+ rm -f ${DESTDIR}${PREFIX}/bin/nltrigger
+ rm -f ${DESTDIR}${MANPREFIX}/man8/${NAME}.8
+ rm -f ${DESTDIR}${MANPREFIX}/man1/nltrigger.1
+
+.PHONY: all clean dist install uninstall
diff --git a/config.mk b/config.mk
@@ -1,6 +1,6 @@
# nldev metadata
NAME = nldev
-VERSION = 0.3
+VERSION = 0.4
# Customize below to fit your system
@@ -14,8 +14,8 @@ LIBS = -L/usr/lib -lc
# flags
CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -D_GNU_SOURCE
-CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
-LDFLAGS = -static -g ${LIBS}
+CFLAGS = -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
+LDFLAGS = -static ${LIBS}
#LDFLAGS = -s ${LIBS}
# compiler and linker
diff --git a/nldev.c b/nldev.c
@@ -1,7 +1,4 @@
-/*
- * Copy me if you can.
- * by 20h
- */
+/* See LICENSE for copyright information. */
#include <unistd.h>
#include <stdio.h>
@@ -22,10 +19,10 @@
#include <linux/netlink.h>
typedef struct {
- const char *action; /* ACTION to run rule for */
- const char *subsystem; /* SUBSYSTEM to run the rule for, NULL for any */
- const char *envvar; /* other environment variable to run rule for, NULL for any */
- const char *runpath;
+ char *action; /* ACTION to run rule for */
+ char *subsystem; /* SUBSYSTEM to run the rule for, NULL for any */
+ char *envvar; /* other environment variable to run rule for, NULL for any */
+ char *runpath;
} Rule;
#include "arg.h"
@@ -336,20 +333,28 @@ main(int argc, char *argv[])
getenv("DEVPATH") != NULL &&
getenv("SUBSYSTEM") != NULL &&
getenv("SEQNUM") != NULL) {
- if (runpath)
+ if (runpath) {
child(runpath);
- else {
+ } else {
for (i = 0; i < LENGTH(rules); i+=1) {
- if (rules[i].action == NULL || rules[i].runpath == NULL) /* rule must have non-NULL action and runpath */
+ if (rules[i].action == NULL
+ || rules[i].runpath == NULL) {
continue;
- if (strcmp(getenv("ACTION"), rules[i].action))
+ }
+ if (strcmp(getenv("ACTION"), rules[i].action)) {
continue;
- if (rules[i].subsystem != NULL)
- if (strcmp(getenv("SUBSYSTEM"), rules[i].subsystem))
+ }
+ if (rules[i].subsystem != NULL) {
+ if (strcmp(getenv("SUBSYSTEM"),
+ rules[i].subsystem)) {
continue;
- if (rules[i].envvar != NULL)
- if (getenv(rules[i].envvar) == NULL)
+ }
+ }
+ if (rules[i].envvar != NULL) {
+ if (getenv(rules[i].envvar) == NULL) {
continue;
+ }
+ }
child(rules[i].runpath);
}
}
diff --git a/nltrigger b/nltrigger
@@ -1,83 +0,0 @@
-#!/bin/busybox ash
-
-usage() {
- printf "usage: %s [add|list|del|action] [subsystem]\n" "$(basename $1)" >&2
- exit 1
-}
-
-action="list"
-if [ $# -gt 0 ];
-then
- action="$1"
-fi
-
-if [ "$action" = "list" ];
-then
- printf "class:\n"
- for i in /sys/class/*;
- do
- printf "\t%s\n" $(basename $i)
- done
-
- printf "bus:\n"
- for i in /sys/bus/*;
- do
- printf "\t%s\n" $(basename $i)
- done
-
- printf "devices:\n"
- for i in /sys/devices/*;
- do
- printf "\t%s\n" $(basename $i)
- done
-
- exit 0
-fi
-
-if [ $# -lt 2 ];
-then
- usage "$0"
-fi
-subsystem="$2"
-
-if [ "$subsystem" != "all" ];
-then
- if [ -d /sys/class/$subsystem ];
- then
- for i in /sys/class/$subsystem/*/uevent;
- do
- echo $action > $i
- done
- exit 0
- fi
-
- if [ -d /sys/bus/$subsystem ];
- then
- for i in /sys/bus/$subsystem/devices/*/uevent;
- do
- echo $action > $i
- done
- exit 0
- fi
-
- if [ -d /sys/devices/$subsystem ];
- then
- for i in /sys/devices/$subsystem/*/uevent \
- /sys/devices/$subsystem/*/*/uevent;
- do
- echo $action > $i
- done
- exit 0
- fi
-
- printf "Could not find subsystem '%s'.\n" $i >&2
- exit 1
-fi
-
-for i in $(find /sys -name uevent -print | sed -e 's/ /,/g');
-do
- echo $action > "$(echo $i | sed -e 's/,/ /g')"
-done
-
-exit 0
-
diff --git a/nltrigger.1 b/nltrigger.1
@@ -0,0 +1,48 @@
+.Dd September 12, 2021
+.Dt NLTRIGGER 1
+.Os
+.
+.Sh NAME
+.Nm nltrigger
+.Nd a tool to trigger netlink device events
+.
+.Sh SYNOPSIS
+.Nm
+.Bk -words
+.Ar path
+.Op Ar add|list|del|action
+.Op Ar delay
+.Ek
+.
+.Sh DESCRIPTION
+.Bd -filled
+.Nm
+is a simple tool to trigger netlink device events at a certain
+.Ar path
+with a certain
+.Ar action
+and a certain
+.Ar delay.
+.
+.Sh OPTIONS
+.Pp
+.Bl -tag -width Ds
+.Ar Path
+to be used as target.
+.Ar Action
+of [add|list|del|action]
+should be triggered.
+.Ar Delay
+of usecs to wait after the
+.Ar action
+has been triggered.
+(Default is 1000 usecs.)
+.El
+.Sh AUTHORS
+See the LICENSE file for the authors of this software.
+.
+.Sh LICENSE
+.Nm
+is released under the MIT/X Consortium License.
+.
+
diff --git a/nltrigger.c b/nltrigger.c
@@ -0,0 +1,160 @@
+/* See LICENSE file for copyright. */
+/*
+ * Based on smdev -s code. Thanks for the prework!
+ */
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include "arg.h"
+
+char *argv0;
+static char *action = "add";
+static useconds_t delay = 1000;
+static void venprintf(int, const char *, va_list);
+
+void
+eprintf(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ venprintf(EXIT_FAILURE, fmt, ap);
+ va_end(ap);
+}
+
+void
+enprintf(int status, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ venprintf(status, fmt, ap);
+ va_end(ap);
+}
+
+void
+venprintf(int status, const char *fmt, va_list ap)
+{
+ vfprintf(stderr, fmt, ap);
+
+ if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
+ fputc(' ', stderr);
+ perror(NULL);
+ }
+
+ exit(status);
+}
+
+void
+apathmax(char **p, long *size)
+{
+ errno = 0;
+
+ if((*size = pathconf("/", _PC_PATH_MAX)) == -1) {
+ if(errno == 0) {
+ *size = BUFSIZ;
+ } else {
+ eprintf("pathconf:");
+ }
+ }
+
+ if(!(*p = malloc(*size)))
+ eprintf("malloc:");
+}
+
+char *
+agetcwd(void)
+{
+ char *buf;
+ long size;
+
+ apathmax(&buf, &size);
+ if(!getcwd(buf, size))
+ eprintf("getcwd:");
+
+ return buf;
+}
+
+void
+recurse(const char *path, void (*fn)(const char *))
+{
+ char *cwd;
+ struct dirent *d;
+ struct stat st;
+ DIR *dp;
+
+ if(lstat(path, &st) == -1 || !S_ISDIR(st.st_mode)) {
+ return;
+ } else if(!(dp = opendir(path))) {
+ eprintf("opendir %s:", path);
+ }
+
+ cwd = agetcwd();
+ if(chdir(path) == -1)
+ eprintf("chdir %s:", path);
+
+ while((d = readdir(dp))) {
+ if(strcmp(d->d_name, ".") && strcmp(d->d_name, ".."))
+ fn(d->d_name);
+ }
+
+ closedir(dp);
+ if(chdir(cwd) == -1)
+ eprintf("chdir %s:", cwd);
+
+ free(cwd);
+}
+
+void
+trigger(const char *path)
+{
+ int fd;
+
+ recurse(path, trigger);
+ if (strstr(path, "uevent")) {
+ if ((fd = open("uevent", O_WRONLY | O_CLOEXEC)) != -1) {
+ dprintf(fd, "%s\n", action);
+ close(fd);
+ usleep(delay);
+ }
+ }
+}
+
+void usage(void)
+{
+ eprintf("usage: %s path [add|list|del|action] [delay]\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *path = NULL;
+
+ ARGBEGIN {
+ default:
+ usage();
+ } ARGEND;
+
+ if (argc == 0)
+ usage();
+
+ path = argv[0];
+ if (argc > 0) {
+ action = argv[0];
+ argc--; argv++;
+ }
+ if (argc > 0)
+ delay = atol(argv[0]);
+
+ trigger(path);
+
+ return 0;
+}
+