diff options
-rw-r--r-- | INSTALL | 2 | ||||
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | doc/index.html | 4 | ||||
-rw-r--r-- | doc/upgrade.html | 7 | ||||
-rw-r--r-- | package/info | 2 | ||||
-rw-r--r-- | src/mdevd/mdevd-coldplug.c | 2 | ||||
-rw-r--r-- | src/mdevd/mdevd-internal.h | 2 | ||||
-rw-r--r-- | src/mdevd/mdevd.c | 96 | ||||
-rw-r--r-- | src/mdevd/mdevd_uevent_getvar.c | 2 |
9 files changed, 73 insertions, 50 deletions
diff --git a/INSTALL b/INSTALL index 5ab7f15..c09d868 100644 --- a/INSTALL +++ b/INSTALL @@ -6,7 +6,7 @@ Build Instructions - A Linux-based system with a standard C development environment - GNU make version 3.81 or later - - skalibs version 2.14.2.0 or later: https://skarnet.org/software/skalibs/ + - skalibs version 2.14.2.1 or later: https://skarnet.org/software/skalibs/ - optional: nsss version 0.2.0.4 or later: https://skarnet.org/software/nsss/ - optional: execline version 2.9.6.0 or later: https://skarnet.org/software/execline/ diff --git a/NEWS b/NEWS index e16e018..da9a1ee 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,11 @@ Changelog for mdevd. +In 0.1.6.5 +---------- + + - Bugfixes. + + In 0.1.6.4 ---------- diff --git a/doc/index.html b/doc/index.html index 1d3236f..a9ff0f2 100644 --- a/doc/index.html +++ b/doc/index.html @@ -102,7 +102,7 @@ and does not pull in any unnecessary code. </li> The Linux kernel must be 2.6.10 or later. </li> <li> GNU make, version 3.81 or later </li> <li> <a href="//skarnet.org/software/skalibs/">skalibs</a> version -2.14.2.0 or later. It's a build-time requirement. It's also a run-time +2.14.2.1 or later. It's a build-time requirement. It's also a run-time requirement if you link against the shared version of the skalibs library. </li> <li> Optionally: <a href="//skarnet.org/software/execline/">nsss</a> @@ -127,7 +127,7 @@ if your <tt>mdev.conf</tt> file contains <tt>+</tt>, <tt>-</tt> or <ul> <li> The current released version of mdevd is -<a href="mdevd-0.1.6.4.tar.gz">0.1.6.4</a>. </li> +<a href="mdevd-0.1.6.5.tar.gz">0.1.6.5</a>. </li> <li> Alternatively, you can checkout a copy of the <a href="//git.skarnet.org/cgi-bin/cgit.cgi/mdevd/">mdevd git repository</a>: diff --git a/doc/upgrade.html b/doc/upgrade.html index aac1c6e..8933613 100644 --- a/doc/upgrade.html +++ b/doc/upgrade.html @@ -18,6 +18,13 @@ <h1> What has changed in mdevd </h1> +<h2> in 0.1.6.5 </h2> + +<ul> + <li> <a href="//skarnet.org/software/skalibs/">skalibs</a> +dependency bumped to 2.14.2.1. </li> +</ul> + <h2> in 0.1.6.4 </h2> <ul> diff --git a/package/info b/package/info index f7bb7d2..1b5e3f7 100644 --- a/package/info +++ b/package/info @@ -1,4 +1,4 @@ package=mdevd -version=0.1.6.4 +version=0.1.6.5 category=admin package_macro_name=MDEVD diff --git a/src/mdevd/mdevd-coldplug.c b/src/mdevd/mdevd-coldplug.c index 6edf3fc..6b8953f 100644 --- a/src/mdevd/mdevd-coldplug.c +++ b/src/mdevd/mdevd-coldplug.c @@ -147,7 +147,7 @@ int main (int argc, char const *const *argv, char const *const *envp) struct uevent_s event ; for (;;) if (mdevd_uevent_read(nlfd, &event, 0, verbosity)) { - char *x = mdevd_uevent_getvar(&event, "ACTION") ; + char const *x = mdevd_uevent_getvar(&event, "ACTION") ; if (strcmp(x, "add")) continue ; x = mdevd_uevent_getvar(&event, "SUBSYSTEM") ; if (strcmp(x, subsystem)) continue ; diff --git a/src/mdevd/mdevd-internal.h b/src/mdevd/mdevd-internal.h index cff7cdf..21ec713 100644 --- a/src/mdevd/mdevd-internal.h +++ b/src/mdevd/mdevd-internal.h @@ -20,6 +20,6 @@ struct uevent_s extern int mdevd_netlink_init (unsigned int, unsigned int) ; extern int mdevd_uevent_read (int, struct uevent_s *, uint32_t, unsigned int) ; -extern char *mdevd_uevent_getvar (struct uevent_s *, char const *) ; +extern char const *mdevd_uevent_getvar (struct uevent_s const *, char const *) ; #endif diff --git a/src/mdevd/mdevd.c b/src/mdevd/mdevd.c index dcd3198..bbef872 100644 --- a/src/mdevd/mdevd.c +++ b/src/mdevd/mdevd.c @@ -128,13 +128,14 @@ static scriptelem const scriptelem_catchall = typedef struct udata_s udata, *udata_ref ; struct udata_s { - char *devname ; + char const *devname ; mode_t devtype ; unsigned int action ; int mmaj ; int mmin ; pid_t pid ; unsigned short i ; + char sysdevpath[PATH_MAX] ; char buf[UEVENT_MAX_SIZE] ; } ; #define UDATA_ZERO { .devname = 0, .devtype = 0, .action = 0, .mmaj = -1, .mmin = -1, .pid = 0, .i = 0, .buf = "" } @@ -151,10 +152,13 @@ static inline void script_free (scriptelem *script, unsigned short scriptlen, st for (i = 0 ; i < envmatchlen ; i++) regfree(&envmatch[i].re) ; } -static inline int mkdirp (char *s) +static inline int mkdirp (char const *path) { - size_t n = strlen(s) ; + size_t n = strlen(path) ; + if (!n) return 1 ; + char s[n + 1] ; size_t i = 0 ; + memcpy(s, path, n+1) ; for (; i < n ; i++) { if (s[i] == '/') @@ -170,7 +174,7 @@ static inline int mkdirp (char *s) return i >= n ; } -static int makesubdirs (char *path) +static int makesubdirs (char const *path) { if (strrchr(path, '/') && !mkdirp(path)) { @@ -557,12 +561,18 @@ static inline ssize_t alias_format (char *out, size_t outmax, char const *in, ch return w ; } -static inline void spawn_command (char const *command, struct uevent_s const *event, int isel, udata *ud) +static inline void spawn_command (char const *command, struct uevent_s const *event, int isel, udata *ud, char const *extra) { char const *argv[4] = { isel ? "execlineb" : "/bin/sh", isel ? "-Pc" : "-c", command, 0 } ; size_t envlen = env_len((char const **)environ) ; - char const *envp[envlen + event->varn + 1] ; - env_merge(envp, envlen + event->varn + 1, (char const **)environ, envlen, event->buf + event->vars[1], event->len - event->vars[1]) ; + size_t n ; + char const *envp[envlen + event->varn + 1 + !!extra] ; + n = env_merge(envp, envlen + event->varn + 1, (char const **)environ, envlen, event->buf + event->vars[1], event->len - event->vars[1]) ; + if (extra) + { + envp[n - 1] = extra ; + envp[n++] = 0 ; + } ud->pid = cspawn(argv[0], argv, envp, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0) ; if (!ud->pid) { @@ -570,11 +580,12 @@ static inline void spawn_command (char const *command, struct uevent_s const *ev } } -static inline int run_scriptelem (struct uevent_s *event, scriptelem const *elem, char const *storage, struct envmatch_s const *envmatch, udata *ud) +static inline int run_scriptelem (struct uevent_s const *event, scriptelem const *elem, char const *storage, struct envmatch_s const *envmatch, udata *ud) { size_t devnamelen = strlen(ud->devname) ; size_t nodelen = 0 ; - char *node = event->buf + event->len + 5 ; + char nodebuf[PATH_MAX] = "MDEV=" ; + char *node = nodebuf + 5 ; regmatch_t off[10] ; unsigned short i = 0 ; for (; i < elem->envmatchlen ; i++) @@ -608,27 +619,28 @@ static inline int run_scriptelem (struct uevent_s *event, scriptelem const *elem case MOVEINFO_MOVE : case MOVEINFO_MOVEANDLINK : { - ssize_t r = alias_format(node, PATH_MAX, storage + elem->movepath, ud->devname, off) ; + ssize_t r = alias_format(node, PATH_MAX - 5, storage + elem->movepath, ud->devname, off) ; if (r <= 1) { if (verbosity) strerr_warnwu5sys("process expression \"", storage + elem->movepath, "\" with devname \"", ud->devname, "\"") ; return -1 ; } - if (node[r - 2] == '/') + nodelen = r - 1 ; + if (node[nodelen - 1] == '/') { - if (r + devnamelen >= PATH_MAX) + if (nodelen + devnamelen >= PATH_MAX - 6) { errno = ENAMETOOLONG ; if (verbosity) strerr_warnwu2sys("create alias for ", ud->devname) ; return -1 ; } - memcpy(node + r - 1, ud->devname, devnamelen + 1) ; - nodelen = r + devnamelen - 1 ; + memcpy(node + nodelen, ud->devname, devnamelen + 1) ; + nodelen += devnamelen ; } break ; } } - if (elem->movetype != MOVEINFO_NOCREATE && ud->action == ACTION_ADD && ud->mmaj >= 0) + if (nodelen && ud->action == ACTION_ADD && ud->mmaj >= 0) { if (!makesubdirs(node)) return -1 ; if (dryrun) @@ -684,12 +696,6 @@ static inline int run_scriptelem (struct uevent_s *event, scriptelem const *elem if (elem->cmdtype == ACTION_ANY || ud->action == elem->cmdtype) { - if (!mdevd_uevent_getvar(event, "MDEV")) - { - event->vars[event->varn++] = event->len ; - memcpy(event->buf + event->len, "MDEV=", 5) ; - event->len += 6 + nodelen ; - } if (dryrun) { strerr_warni4x("dry run: spawn ", elem->flagexecline ? "execlineb" : "/bin/sh", " for: ", storage + elem->command) ; @@ -705,12 +711,16 @@ static inline int run_scriptelem (struct uevent_s *event, scriptelem const *elem buf[j+len] = ' ' ; j += len+1 ; } + if (nodelen) + { + memcpy(buf + j, nodebuf, nodelen + 5) ; + j += nodelen + 6 ; + } buf[j-1] = 0 ; strerr_warni2x("dry run: added variables: ", buf) ; } } - else spawn_command(storage + elem->command, event, elem->flagexecline, ud) ; - event->varn-- ; event->len -= 6 + nodelen ; + else spawn_command(storage + elem->command, event, elem->flagexecline, ud, nodelen ? nodebuf : 0) ; } if (elem->movetype != MOVEINFO_NOCREATE && ud->action == ACTION_REMOVE && ud->mmaj >= 0) @@ -727,16 +737,17 @@ static inline int run_scriptelem (struct uevent_s *event, scriptelem const *elem return !elem->flagcont ; } -static int run_script (struct uevent_s *event, scriptelem const *script, unsigned short scriptlen, char const *storage, struct envmatch_s const *envmatch, udata *ud) +static int run_script (struct uevent_s const *event, scriptelem const *script, unsigned short scriptlen, char const *storage, struct envmatch_s const *envmatch, udata *ud) { for (; ud->i < scriptlen && !ud->pid ; ud->i++) if (run_scriptelem(event, script + ud->i, storage, envmatch, ud)) ud->i = scriptlen - 1 ; return ud->i >= scriptlen && !ud->pid ; } -static inline int act_on_event (struct uevent_s *event, char *sysdevpath, size_t sysdevpathlen, unsigned int action, scriptelem const *script, unsigned short scriptlen, char const *storage, struct envmatch_s const *envmatch, udata *ud) +static inline int act_on_event (struct uevent_s const *event, unsigned int action, scriptelem const *script, unsigned short scriptlen, char const *storage, struct envmatch_s const *envmatch, udata *ud) { ssize_t hasmajmin = 0 ; + size_t sysdevpathlen = strlen(ud->sysdevpath) ; unsigned int mmaj, mmin ; char const *x = mdevd_uevent_getvar(event, "MAJOR") ; ud->devtype = S_IFCHR ; @@ -750,9 +761,9 @@ static inline int act_on_event (struct uevent_s *event, char *sysdevpath, size_t } if (!hasmajmin) { - memcpy(sysdevpath + sysdevpathlen, "/dev", 5) ; - hasmajmin = openreadnclose(sysdevpath, ud->buf, UINT_FMT << 1) ; - sysdevpath[sysdevpathlen] = 0 ; + memcpy(ud->sysdevpath + sysdevpathlen, "/dev", 5) ; + hasmajmin = openreadnclose(ud->sysdevpath, ud->buf, UINT_FMT << 1) ; + ud->sysdevpath[sysdevpathlen] = 0 ; if (hasmajmin > 0) { size_t i = uint_scan(ud->buf, &mmaj) ; @@ -773,9 +784,9 @@ static inline int act_on_event (struct uevent_s *event, char *sysdevpath, size_t if (!ud->devname) { ssize_t r ; - memcpy(sysdevpath + sysdevpathlen, "/uevent", 8) ; - r = openreadnclose(sysdevpath, ud->buf, UEVENT_MAX_SIZE-1) ; - sysdevpath[sysdevpathlen] = 0 ; + memcpy(ud->sysdevpath + sysdevpathlen, "/uevent", 8) ; + r = openreadnclose(ud->sysdevpath, ud->buf, UEVENT_MAX_SIZE-1) ; + ud->sysdevpath[sysdevpathlen] = 0 ; if (r > 0) { ud->buf[r] = 0 ; @@ -786,14 +797,14 @@ static inline int act_on_event (struct uevent_s *event, char *sysdevpath, size_t *strchr(ud->devname, '\n') = 0 ; } } - if (!ud->devname) ud->devname = basename(sysdevpath) ; + if (!ud->devname) ud->devname = basename(ud->sysdevpath) ; } if (strlen(ud->devname) >= PATH_MAX - 1) { if (verbosity) strerr_warnwu2x("device name too long: ", ud->devname) ; return 1 ; } - if (strstr(sysdevpath, "/block/")) ud->devtype = S_IFBLK ; + if (strstr(ud->sysdevpath, "/block/")) ud->devtype = S_IFBLK ; else { x = mdevd_uevent_getvar(event, "SUBSYSTEM") ; @@ -803,10 +814,11 @@ static inline int act_on_event (struct uevent_s *event, char *sysdevpath, size_t return run_script(event, script, scriptlen, storage, envmatch, ud) ; } -static inline int on_event (struct uevent_s *event, scriptelem const *script, unsigned short scriptlen, char const *storage, struct envmatch_s const *envmatch, udata *ud) +static inline int on_event (struct uevent_s const *event, scriptelem const *script, unsigned short scriptlen, char const *storage, struct envmatch_s const *envmatch, udata *ud) { - unsigned int action ; + int done = 1 ; char const *x = mdevd_uevent_getvar(event, "ACTION") ; + unsigned int action ; if (!x) return 1 ; if (!strcmp(x, "add")) action = ACTION_ADD ; else if (!strcmp(x, "remove")) action = ACTION_REMOVE ; @@ -814,17 +826,15 @@ static inline int on_event (struct uevent_s *event, scriptelem const *script, un x = mdevd_uevent_getvar(event, "DEVPATH") ; if (!x) return 1 ; { - int done = 1 ; size_t devpathlen = strlen(x) ; size_t slashsyslen = strlen(slashsys) ; - char sysdevpath[devpathlen + slashsyslen + 8] ; /* act_on_event needs the extra storage */ - memcpy(sysdevpath, slashsys, slashsyslen) ; - memcpy(sysdevpath + slashsyslen, x, devpathlen + 1) ; - x = mdevd_uevent_getvar(event, "FIRMWARE") ; - if (action == ACTION_ADD || !x) done = act_on_event(event, sysdevpath, slashsyslen + devpathlen, action, script, scriptlen, storage, envmatch, ud) ; - if (action == ACTION_ADD && x) load_firmware(x, sysdevpath) ; - return done ; + memcpy(ud->sysdevpath, slashsys, slashsyslen) ; + memcpy(ud->sysdevpath + slashsyslen, x, devpathlen + 1) ; } + x = mdevd_uevent_getvar(event, "FIRMWARE") ; + if (action == ACTION_ADD || !x) done = act_on_event(event, action, script, scriptlen, storage, envmatch, ud) ; + if (action == ACTION_ADD && x) load_firmware(x, ud->sysdevpath) ; + return done ; } diff --git a/src/mdevd/mdevd_uevent_getvar.c b/src/mdevd/mdevd_uevent_getvar.c index 8eb8583..0e3fd47 100644 --- a/src/mdevd/mdevd_uevent_getvar.c +++ b/src/mdevd/mdevd_uevent_getvar.c @@ -4,7 +4,7 @@ #include "mdevd-internal.h" -char *mdevd_uevent_getvar (struct uevent_s *event, char const *var) +char const *mdevd_uevent_getvar (struct uevent_s const *event, char const *var) { size_t varlen = strlen(var) ; unsigned short i = 1 ; |