[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().
This commit is contained in:
parent
82962619c6
commit
e41245cb25
|
@ -48,10 +48,12 @@ struct sysfs_class_device;
|
||||||
#define ATTR_PARTITIONS "all_partitions"
|
#define ATTR_PARTITIONS "all_partitions"
|
||||||
#define PARTITIONS_COUNT 15
|
#define PARTITIONS_COUNT 15
|
||||||
|
|
||||||
|
|
||||||
#define PROGRAM_MAXARG 10
|
#define PROGRAM_MAXARG 10
|
||||||
#define MAX_SYSFS_PAIRS 5
|
#define MAX_SYSFS_PAIRS 5
|
||||||
|
|
||||||
|
#define RULEFILE_EXT ".rules"
|
||||||
|
#define PERMFILE_EXT ".permissions"
|
||||||
|
|
||||||
struct sysfs_pair {
|
struct sysfs_pair {
|
||||||
char file[FILE_SIZE];
|
char file[FILE_SIZE];
|
||||||
char value[VALUE_SIZE];
|
char value[VALUE_SIZE];
|
||||||
|
|
107
namedev_parse.c
107
namedev_parse.c
|
@ -33,12 +33,16 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "udev.h"
|
#include "udev.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "namedev.h"
|
#include "namedev.h"
|
||||||
|
|
||||||
|
LIST_HEAD(file_list);
|
||||||
|
|
||||||
static int add_config_dev(struct config_device *new_dev)
|
static int add_config_dev(struct config_device *new_dev)
|
||||||
{
|
{
|
||||||
struct config_device *tmp_dev;
|
struct config_device *tmp_dev;
|
||||||
|
@ -114,7 +118,7 @@ static char *get_key_attribute(char *str)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int namedev_init_rules(void)
|
static int namedev_parse_rules(char *filename)
|
||||||
{
|
{
|
||||||
char line[255];
|
char line[255];
|
||||||
int lineno;
|
int lineno;
|
||||||
|
@ -127,11 +131,11 @@ int namedev_init_rules(void)
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
struct config_device dev;
|
struct config_device dev;
|
||||||
|
|
||||||
fd = fopen(udev_rules_filename, "r");
|
fd = fopen(filename, "r");
|
||||||
if (fd != NULL) {
|
if (fd != NULL) {
|
||||||
dbg("reading '%s' as rules file", udev_rules_filename);
|
dbg("reading '%s' as rules file", filename);
|
||||||
} else {
|
} 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;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +266,7 @@ int namedev_init_rules(void)
|
||||||
continue;
|
continue;
|
||||||
error:
|
error:
|
||||||
dbg("%s:%d:%d: parse error, rule skipped",
|
dbg("%s:%d:%d: parse error, rule skipped",
|
||||||
udev_rules_filename, lineno, temp - line);
|
filename, lineno, temp - line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exit:
|
exit:
|
||||||
|
@ -270,7 +274,7 @@ exit:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int namedev_init_permissions(void)
|
static int namedev_parse_permissions(char *filename)
|
||||||
{
|
{
|
||||||
char line[255];
|
char line[255];
|
||||||
char *temp;
|
char *temp;
|
||||||
|
@ -279,11 +283,11 @@ int namedev_init_permissions(void)
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
struct perm_device dev;
|
struct perm_device dev;
|
||||||
|
|
||||||
fd = fopen(udev_permissions_filename, "r");
|
fd = fopen(filename, "r");
|
||||||
if (fd != NULL) {
|
if (fd != NULL) {
|
||||||
dbg("reading '%s' as permissions file", udev_permissions_filename);
|
dbg("reading '%s' as permissions file", filename);
|
||||||
} else {
|
} else {
|
||||||
dbg("can't open '%s' as permissions file", udev_permissions_filename);
|
dbg("can't open '%s' as permissions file", filename);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,3 +356,88 @@ exit:
|
||||||
return retval;
|
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);
|
||||||
|
}
|
||||||
|
|
8
udev.c
8
udev.c
|
@ -111,13 +111,13 @@ static int udev_hotplug(int argc, char **argv)
|
||||||
|
|
||||||
action = get_action();
|
action = get_action();
|
||||||
if (!action) {
|
if (!action) {
|
||||||
dbg ("no action?");
|
dbg("no action?");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
devpath = get_devpath();
|
devpath = get_devpath();
|
||||||
if (!devpath) {
|
if (!devpath) {
|
||||||
dbg ("no devpath?");
|
dbg("no devpath?");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
dbg("looking at '%s'", devpath);
|
dbg("looking at '%s'", devpath);
|
||||||
|
@ -131,6 +131,10 @@ static int udev_hotplug(int argc, char **argv)
|
||||||
|
|
||||||
/* skip blacklisted subsystems */
|
/* skip blacklisted subsystems */
|
||||||
subsystem = argv[1];
|
subsystem = argv[1];
|
||||||
|
if (!subsystem) {
|
||||||
|
dbg("no subsystem?");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
while (subsystem_blacklist[i][0] != '\0') {
|
while (subsystem_blacklist[i][0] != '\0') {
|
||||||
if (strcmp(subsystem, subsystem_blacklist[i]) == 0) {
|
if (strcmp(subsystem, subsystem_blacklist[i]) == 0) {
|
||||||
|
|
Loading…
Reference in a new issue