diff options
author | kay.sievers@vrfy.org <kay.sievers@vrfy.org> | 2004-02-23 19:31:14 -0800 |
---|---|---|
committer | Greg KH <gregkh@suse.de> | 2005-04-26 21:32:30 -0700 |
commit | e41245cb256231ef6954b3cbf45f0635d01501ed (patch) | |
tree | 132c1a400dadb4ccc902bcae5e79109178b5cfcc | |
parent | 82962619c626edfc68d39f0b179a909dd3dd0a6b (diff) |
[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().
-rw-r--r-- | namedev.h | 4 | ||||
-rw-r--r-- | namedev_parse.c | 107 | ||||
-rw-r--r-- | udev.c | 8 |
3 files changed, 107 insertions, 12 deletions
@@ -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 d5d2181cb6..013878c679 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -33,12 +33,16 @@ #include <fcntl.h> #include <ctype.h> #include <unistd.h> +#include <sys/stat.h> +#include <dirent.h> #include <errno.h> #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); +} @@ -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) { |