From e41245cb256231ef6954b3cbf45f0635d01501ed Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 23 Feb 2004 19:31:14 -0800 Subject: [PATCH] [PATCH] udev - allow all files in a directory as the config I was on the train for 5 hours today and the TODO is almost empty :) So, at least four people wanted this feature, then here is a actual working patch. We may specify now in udev.conf: udev_rules="/etc/udev/" and udev will scan the whole directory for files ending with *.rules, sort it in lexical order and create our rule list from all of the files. A plain given file will still work and the same applies to the *.permissions. I sort the files in our usual linked list, cause klibc has no scandir(). --- namedev.h | 4 +- namedev_parse.c | 107 ++++++++++++++++++++++++++++++++++++++++++++---- udev.c | 8 +++- 3 files changed, 107 insertions(+), 12 deletions(-) diff --git a/namedev.h b/namedev.h index 10a5dcaf..ffdde83c 100644 --- a/namedev.h +++ b/namedev.h @@ -48,10 +48,12 @@ struct sysfs_class_device; #define ATTR_PARTITIONS "all_partitions" #define PARTITIONS_COUNT 15 - #define PROGRAM_MAXARG 10 #define MAX_SYSFS_PAIRS 5 +#define RULEFILE_EXT ".rules" +#define PERMFILE_EXT ".permissions" + struct sysfs_pair { char file[FILE_SIZE]; char value[VALUE_SIZE]; diff --git a/namedev_parse.c b/namedev_parse.c index d5d2181c..013878c6 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -33,12 +33,16 @@ #include #include #include +#include +#include #include #include "udev.h" #include "logging.h" #include "namedev.h" +LIST_HEAD(file_list); + static int add_config_dev(struct config_device *new_dev) { struct config_device *tmp_dev; @@ -114,7 +118,7 @@ static char *get_key_attribute(char *str) return NULL; } -int namedev_init_rules(void) +static int namedev_parse_rules(char *filename) { char line[255]; int lineno; @@ -127,11 +131,11 @@ int namedev_init_rules(void) int retval = 0; struct config_device dev; - fd = fopen(udev_rules_filename, "r"); + fd = fopen(filename, "r"); if (fd != NULL) { - dbg("reading '%s' as rules file", udev_rules_filename); + dbg("reading '%s' as rules file", filename); } else { - dbg("can't open '%s' as a rules file", udev_rules_filename); + dbg("can't open '%s' as a rules file", filename); return -ENODEV; } @@ -262,7 +266,7 @@ int namedev_init_rules(void) continue; error: dbg("%s:%d:%d: parse error, rule skipped", - udev_rules_filename, lineno, temp - line); + filename, lineno, temp - line); } } exit: @@ -270,7 +274,7 @@ exit: return retval; } -int namedev_init_permissions(void) +static int namedev_parse_permissions(char *filename) { char line[255]; char *temp; @@ -279,11 +283,11 @@ int namedev_init_permissions(void) int retval = 0; struct perm_device dev; - fd = fopen(udev_permissions_filename, "r"); + fd = fopen(filename, "r"); if (fd != NULL) { - dbg("reading '%s' as permissions file", udev_permissions_filename); + dbg("reading '%s' as permissions file", filename); } else { - dbg("can't open '%s' as permissions file", udev_permissions_filename); + dbg("can't open '%s' as permissions file", filename); return -ENODEV; } @@ -352,3 +356,88 @@ exit: return retval; } +struct files { + struct list_head list; + char name[NAME_SIZE]; +}; + +/* sort files in lexical order */ +static int file_list_insert(char *filename) +{ + struct files *loop_file; + struct files *new_file; + + list_for_each_entry(loop_file, &file_list, list) { + if (strcmp(loop_file->name, filename) > 0) { + break; + } + } + + new_file = malloc(sizeof(struct files)); + if (new_file == NULL) { + dbg("error malloc"); + return -ENOMEM; + } + + strfieldcpy(new_file->name, filename); + list_add_tail(&new_file->list, &loop_file->list); + return 0; +} + +/* calls function for file or every file found in directory */ +static int call_foreach_file(int parser (char *f) , char *filename, char *extension) +{ + struct dirent *ent; + DIR *dir; + char *ext; + char file[NAME_SIZE]; + struct stat stats; + struct files *loop_file; + struct files *tmp_file; + + /* look if we have a plain file or a directory to scan */ + stat(filename, &stats); + if ((stats.st_mode & S_IFMT) != S_IFDIR) + return parser(filename); + + /* sort matching filename into list */ + dbg("open config as directory '%s'", filename); + dir = opendir(filename); + while (1) { + ent = readdir(dir); + if (ent == NULL || ent->d_name[0] == '\0') + break; + + dbg("found file '%s'", ent->d_name); + ext = strrchr(ent->d_name, '.'); + if (ext == NULL) + continue; + + if (strcmp(ext, extension) == 0) { + dbg("put file in list '%s'", ent->d_name); + file_list_insert(ent->d_name); + } + } + + /* parse every file in the list */ + list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) { + strfieldcpy(file, filename); + strcat(file, loop_file->name); + parser(file); + list_del(&loop_file->list); + free(loop_file); + } + + closedir(dir); + return 0; +} + +int namedev_init_rules() +{ + return call_foreach_file(namedev_parse_rules, udev_rules_filename, RULEFILE_EXT); +} + +int namedev_init_permissions() +{ + return call_foreach_file(namedev_parse_permissions, udev_permissions_filename, PERMFILE_EXT); +} diff --git a/udev.c b/udev.c index 8c91ac62..1c65f2e5 100644 --- a/udev.c +++ b/udev.c @@ -111,13 +111,13 @@ static int udev_hotplug(int argc, char **argv) action = get_action(); if (!action) { - dbg ("no action?"); + dbg("no action?"); goto exit; } devpath = get_devpath(); if (!devpath) { - dbg ("no devpath?"); + dbg("no devpath?"); goto exit; } dbg("looking at '%s'", devpath); @@ -131,6 +131,10 @@ static int udev_hotplug(int argc, char **argv) /* skip blacklisted subsystems */ subsystem = argv[1]; + if (!subsystem) { + dbg("no subsystem?"); + goto exit; + } i = 0; while (subsystem_blacklist[i][0] != '\0') { if (strcmp(subsystem, subsystem_blacklist[i]) == 0) { -- 2.39.5