Fix path parsing - smdev - suckless mdev | |
git clone git://git.suckless.org/smdev | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 210bd07cd4bb0c41313fda721578a3ddbbd52493 | |
parent 0534a1001fb7990c2837bc4cf76f7f4824a890c1 | |
Author: sin <[email protected]> | |
Date: Thu, 22 Aug 2013 14:06:42 +0100 | |
Fix path parsing | |
Diffstat: | |
M Makefile | 3 ++- | |
M smdev.c | 45 +++++++++++++++++++++++++----… | |
M util.h | 1 + | |
A util/strlcpy.c | 14 ++++++++++++++ | |
4 files changed, 53 insertions(+), 10 deletions(-) | |
--- | |
diff --git a/Makefile b/Makefile | |
@@ -10,7 +10,8 @@ LIB = \ | |
util/eprintf.o \ | |
util/estrtol.o \ | |
util/mkpath.o \ | |
- util/recurse.o | |
+ util/recurse.o \ | |
+ util/strlcpy.o | |
SRC = smdev.c | |
diff --git a/smdev.c b/smdev.c | |
@@ -11,6 +11,7 @@ | |
#include <string.h> | |
#include <limits.h> | |
#include <regex.h> | |
+#include <libgen.h> | |
#include "config.h" | |
#include "mkpath.h" | |
#include "util.h" | |
@@ -146,17 +147,19 @@ createdev(struct Event *ev) | |
struct Rule *Rule; | |
struct passwd *pw; | |
struct group *gr; | |
- char devpath[PATH_MAX], *devname; | |
+ char devpath[PATH_MAX]; | |
+ char devname[PATH_MAX]; | |
+ char *dirc, *basec; | |
char buf[BUFSIZ]; | |
int type; | |
- int i; | |
+ int i, j; | |
snprintf(buf, sizeof(buf), "%d:%d", ev->maj, ev->min); | |
type = devtype(buf); | |
if (type < 0) | |
return -1; | |
- devname = ev->devname; | |
+ strlcpy(devname, ev->devname, sizeof(devname)); | |
snprintf(devpath, sizeof(devpath), "/dev/%s", devname); | |
for (i = 0; i < LEN(Rules); i++) { | |
Rule = &Rules[i]; | |
@@ -167,16 +170,40 @@ createdev(struct Event *ev) | |
if (Rule->path) { | |
if (Rule->path[0] != '=' && Rule->path[0] != '>') | |
eprintf("Invalid path '%s'\n", Rule->path); | |
- if (Rule->path[strlen(Rule->path) - 1] == '/') { | |
- snprintf(buf, sizeof(buf), "/dev/%s", &Rule->p… | |
+ | |
+ for (j = 1; Rule->path[j]; j++) { | |
+ if (Rule->path[j] != '/') | |
+ continue; | |
+ if (Rule->path[strlen(Rule->path) - 1] == '/')… | |
+ snprintf(buf, sizeof(buf), "/dev/%s", | |
+ &Rule->path[1]); | |
+ snprintf(devpath, sizeof(devpath), "/d… | |
+ &Rule->path[1], devname); | |
+ } else { | |
+ dirc = strdup(&Rule->path[1]); | |
+ if (!dirc) | |
+ eprintf("strdup:"); | |
+ snprintf(buf, sizeof(buf), "/dev/%s", … | |
+ free(dirc); | |
+ | |
+ basec = strdup(&Rule->path[1]); | |
+ if (!basec) | |
+ eprintf("strdup:"); | |
+ strlcpy(devname, basename(basec), size… | |
+ free(basec); | |
+ | |
+ snprintf(devpath, sizeof(devpath), "%s… | |
+ buf, devname); | |
+ } | |
umask(022); | |
if (mkpath(buf, 0755) < 0) | |
eprintf("mkdir %s:", buf); | |
umask(0); | |
- snprintf(devpath, sizeof(devpath), "/dev/%s%s", | |
- &Rule->path[1], devname); | |
- } else { | |
- devname = &Rule->path[1]; | |
+ break; | |
+ } | |
+ | |
+ if (!Rule->path[j]) { | |
+ strlcpy(devname, &Rule->path[1], sizeof(devnam… | |
snprintf(devpath, sizeof(devpath), "/dev/%s", … | |
} | |
} | |
diff --git a/util.h b/util.h | |
@@ -13,3 +13,4 @@ void enprintf(int, const char *, ...); | |
void eprintf(const char *, ...); | |
long estrtol(const char *, int); | |
void recurse(const char *, void (*)(const char *)); | |
+size_t strlcpy(char *dest, const char *src, size_t size); | |
diff --git a/util/strlcpy.c b/util/strlcpy.c | |
@@ -0,0 +1,14 @@ | |
+#include <stdio.h> | |
+#include <string.h> | |
+ | |
+size_t strlcpy(char *dest, const char *src, size_t size) | |
+{ | |
+ size_t ret = strlen(src); | |
+ | |
+ if (size) { | |
+ size_t len = (ret >= size) ? size - 1 : ret; | |
+ memcpy(dest, src, len); | |
+ dest[len] = '\0'; | |
+ } | |
+ return ret; | |
+} |