commit 210bd07cd4bb0c41313fda721578a3ddbbd52493
parent 0534a1001fb7990c2837bc4cf76f7f4824a890c1
Author: sin <sin@2f30.org>
Date: Thu, 22 Aug 2013 14:06:42 +0100
Fix path parsing
Diffstat:
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->path[1]);
+
+ 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), "/dev/%s%s",
+ &Rule->path[1], devname);
+ } else {
+ dirc = strdup(&Rule->path[1]);
+ if (!dirc)
+ eprintf("strdup:");
+ snprintf(buf, sizeof(buf), "/dev/%s", dirname(dirc));
+ free(dirc);
+
+ basec = strdup(&Rule->path[1]);
+ if (!basec)
+ eprintf("strdup:");
+ strlcpy(devname, basename(basec), sizeof(devname));
+ free(basec);
+
+ snprintf(devpath, sizeof(devpath), "%s/%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(devname));
snprintf(devpath, sizeof(devpath), "/dev/%s", devname);
}
}
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;
+}