#include "udev_version.h"
#define COMMENT_CHARACTER '#'
-#define PATH_TO_NAME_CHAR '@'
#define LINE_SIZE 512
#define PATH_SIZE 512
#define NAME_SIZE 128
/* 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);
#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)
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')
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);
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)
{
{
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;
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:
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);