From 9c6ad9fbbac82e517f5e748ddbe166f96f120afe Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 14 Mar 2007 21:41:33 +0100 Subject: [PATCH] encode db-file names, instead of just replacing '/' --- udev.h | 3 ++- udev_db.c | 40 ++++++++++------------------------------ udev_utils_string.c | 43 +++++++++++++++++++++++++++++++++++++++++++ udevd.c | 22 +++++----------------- udevtrigger.c | 13 +++---------- 5 files changed, 63 insertions(+), 58 deletions(-) diff --git a/udev.h b/udev.h index 849de9645..200d7e836 100644 --- a/udev.h +++ b/udev.h @@ -29,7 +29,6 @@ #include "udev_version.h" #define COMMENT_CHARACTER '#' -#define PATH_TO_NAME_CHAR '@' #define LINE_SIZE 512 #define PATH_SIZE 512 #define NAME_SIZE 128 @@ -144,6 +143,8 @@ extern gid_t lookup_group(const char *group); /* udev_utils_string.c */ extern int string_is_true(const char *str); extern void remove_trailing_chars(char *path, char c); +extern size_t path_encode(char *s, size_t len); +extern size_t path_decode(char *s); extern int utf8_encoded_valid_unichar(const char *str); extern int replace_untrusted_chars(char *str); diff --git a/udev_db.c b/udev_db.c index b1217d80e..9032eefb8 100644 --- a/udev_db.c +++ b/udev_db.c @@ -33,38 +33,22 @@ #include "udev.h" -static int devpath_to_db_path(const char *devpath, char *filename, size_t len) +static size_t devpath_to_db_path(const char *devpath, char *filename, size_t len) { - size_t start, end, i; + size_t start; /* add location of db files */ strlcpy(filename, udev_root, len); start = strlcat(filename, "/"DB_DIR, len); - end = strlcat(filename, devpath, len); - if (end > len) - end = len; - - /* replace '/' to transform path into a filename */ - for (i = start+1; i < end; i++) - if (filename[i] == '/') - filename[i] = PATH_TO_NAME_CHAR; - - return 0; + strlcat(filename, devpath, len); + return path_encode(&filename[start+1], len - (start+1)); } static int db_file_to_devpath(const char *filename, char *devpath, size_t len) { - size_t end, i; - strlcpy(devpath, "/", len); - end = strlcat(devpath, filename, len); - - /* replace PATH_TO_NAME_CHAR to transform name into devpath */ - for (i = 1; i < end; i++) - if (devpath[i] == PATH_TO_NAME_CHAR) - devpath[i] = '/'; - - return 0; + strlcat(devpath, filename, len); + return path_decode(devpath); } int udev_db_add_device(struct udevice *udev) @@ -338,8 +322,7 @@ int udev_db_get_all_entries(struct list_head *name_list) while (1) { struct dirent *ent; - char filename[PATH_SIZE] = "/"; - size_t end, i; + char device[PATH_SIZE]; ent = readdir(dir); if (ent == NULL || ent->d_name[0] == '\0') @@ -347,12 +330,9 @@ int udev_db_get_all_entries(struct list_head *name_list) if (ent->d_name[0] == '.') continue; - end = strlcat(filename, ent->d_name, sizeof(filename)); - for (i = 1; i < end; i++) - if (filename[i] == PATH_TO_NAME_CHAR) - filename[i] = '/'; - name_list_add(name_list, filename, 1); - dbg("added '%s'", filename); + db_file_to_devpath(ent->d_name, device, sizeof(device)); + name_list_add(name_list, device, 1); + dbg("added '%s'", device); } closedir(dir); diff --git a/udev_utils_string.c b/udev_utils_string.c index 8cda47272..b0641f002 100644 --- a/udev_utils_string.c +++ b/udev_utils_string.c @@ -50,6 +50,49 @@ void remove_trailing_chars(char *path, char c) path[--len] = '\0'; } +size_t path_encode(char *s, size_t len) +{ + char t[(len * 3)+1]; + size_t i, j; + + t[0] = '\0'; + for (i = 0, j = 0; s[i] != '\0'; i++) { + if (s[i] == '/') { + memcpy(&t[j], "%2f", 3); + j += 3; + } else if (s[i] == '%') { + memcpy(&t[j], "%25", 3); + j += 3; + } else { + t[j] = s[i]; + j++; + } + } + t[j] = '\0'; + strncpy(s, t, len); + return j; +} + +size_t path_decode(char *s) +{ + size_t i, j; + + for (i = 0, j = 0; s[i] != '\0'; j++) { + if (memcmp(&s[i], "%2f", 3) == 0) { + s[j] = '/'; + i += 3; + }else if (memcmp(&s[i], "%25", 3) == 0) { + s[j] = '%'; + i += 3; + } else { + s[j] = s[i]; + i++; + } + } + s[j] = '\0'; + return j; +} + /* count of characters used to encode one unicode char */ static int utf8_encoded_expected_len(const char *str) { diff --git a/udevd.c b/udevd.c index 961ceb587..07f1c4810 100644 --- a/udevd.c +++ b/udevd.c @@ -167,7 +167,7 @@ static void export_event_state(struct udevd_uevent_msg *msg, enum event_state st { char filename[PATH_SIZE]; char filename_failed[PATH_SIZE]; - size_t start, end, i; + size_t start; struct udevd_uevent_msg *loop_msg; int fd; @@ -175,27 +175,15 @@ static void export_event_state(struct udevd_uevent_msg *msg, enum event_state st strlcpy(filename, udev_root, sizeof(filename)); strlcat(filename, "/", sizeof(filename)); start = strlcat(filename, EVENT_QUEUE_DIR, sizeof(filename)); - end = strlcat(filename, msg->devpath, sizeof(filename)); - if (end > sizeof(filename)) - end = sizeof(filename); - - /* replace '/' to transform path into a filename */ - for (i = start+1; i < end; i++) - if (filename[i] == '/') - filename[i] = PATH_TO_NAME_CHAR; + strlcat(filename, msg->devpath, sizeof(filename)); + path_encode(&filename[start+1], sizeof(filename) - (start+1)); /* add location of failed files */ strlcpy(filename_failed, udev_root, sizeof(filename_failed)); strlcat(filename_failed, "/", sizeof(filename_failed)); start = strlcat(filename_failed, EVENT_FAILED_DIR, sizeof(filename_failed)); - end = strlcat(filename_failed, msg->devpath, sizeof(filename_failed)); - if (end > sizeof(filename_failed)) - end = sizeof(filename_failed); - - /* replace '/' to transform path into a filename */ - for (i = start+1; i < end; i++) - if (filename_failed[i] == '/') - filename_failed[i] = PATH_TO_NAME_CHAR; + strlcat(filename_failed, msg->devpath, sizeof(filename_failed)); + path_encode(&filename_failed[start+1], sizeof(filename) - (start+1)); switch (state) { case EVENT_QUEUED: diff --git a/udevtrigger.c b/udevtrigger.c index c809d2d47..2bdd0c8d0 100644 --- a/udevtrigger.c +++ b/udevtrigger.c @@ -407,22 +407,15 @@ static void scan_failed(void) if (dir != NULL) { for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { char device[PATH_SIZE]; - size_t start, end, i; + size_t start; if (dent->d_name[0] == '.') continue; strlcpy(device, sysfs_path, sizeof(device)); start = strlcat(device, "/", sizeof(device)); - end = strlcat(device, dent->d_name, sizeof(device)); - if (end > sizeof(device)) - end = sizeof(device); - - /* replace PATH_TO_NAME_CHAR with '/' */ - for (i = start; i < end; i++) - if (device[i] == PATH_TO_NAME_CHAR) - device[i] = '/'; - + strlcat(device, dent->d_name, sizeof(device)); + path_decode(&device[start]); device_list_insert(device); } closedir(dir); -- 2.30.2