summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--namedev.c58
-rw-r--r--namedev.h15
-rw-r--r--namedev_parse.c54
-rw-r--r--udev.84
4 files changed, 82 insertions, 49 deletions
diff --git a/namedev.c b/namedev.c
index 23d46518ea..1e424998f6 100644
--- a/namedev.c
+++ b/namedev.c
@@ -46,6 +46,7 @@ static struct sysfs_attribute *find_sysfs_attribute(struct sysfs_class_device *c
LIST_HEAD(config_device_list);
LIST_HEAD(perm_device_list);
+
/* compare string with pattern (supports * ? [0-9] [!A-Z]) */
static int strcmp_pattern(const char *p, const char *s)
{
@@ -99,39 +100,6 @@ static int strcmp_pattern(const char *p, const char *s)
return 1;
}
-#define copy_var(a, b, var) \
- if (b->var) \
- a->var = b->var;
-
-#define copy_string(a, b, var) \
- if (strlen(b->var)) \
- strcpy(a->var, b->var);
-
-int add_perm_dev(struct perm_device *new_dev)
-{
- struct perm_device *dev;
- struct perm_device *tmp_dev;
-
- /* update the values if we already have the device */
- list_for_each_entry(dev, &perm_device_list, node) {
- if (strcmp(new_dev->name, dev->name))
- continue;
- copy_var(dev, new_dev, mode);
- copy_string(dev, new_dev, owner);
- copy_string(dev, new_dev, group);
- return 0;
- }
-
- /* not found, add new structure to the perm list */
- tmp_dev = malloc(sizeof(*tmp_dev));
- if (!tmp_dev)
- return -ENOMEM;
- memcpy(tmp_dev, new_dev, sizeof(*tmp_dev));
- list_add_tail(&tmp_dev->node, &perm_device_list);
- //dump_perm_dev(tmp_dev);
- return 0;
-}
-
static struct perm_device *find_perm(char *name)
{
struct perm_device *perm;
@@ -865,22 +833,28 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud
goto done;
found:
- /* substitute placeholder */
apply_format(udev, udev->name, sizeof(udev->name),
class_dev, sysfs_device);
udev->partitions = dev->partitions;
+
done:
+ /* get permissions given in rule */
+ set_empty_perms(udev, dev->mode,
+ dev->owner,
+ dev->group);
+
+ /* get permissions given in config file or set defaults */
perm = find_perm(udev->name);
- if (perm) {
- udev->mode = perm->mode;
- strfieldcpy(udev->owner, perm->owner);
- strfieldcpy(udev->group, perm->group);
+ if (perm != NULL) {
+ set_empty_perms(udev, perm->mode,
+ perm->owner,
+ perm->group);
} else {
- /* no matching perms found :( */
- udev->mode = get_default_mode();
- strfieldcpy(udev->owner, get_default_owner());
- strfieldcpy(udev->group, get_default_group());
+ set_empty_perms(udev, get_default_mode(),
+ get_default_owner(),
+ get_default_group());
}
+
dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o",
udev->name, udev->owner, udev->group, udev->mode);
diff --git a/namedev.h b/namedev.h
index 7f875ed603..16a8bffe97 100644
--- a/namedev.h
+++ b/namedev.h
@@ -44,6 +44,9 @@ struct sysfs_class_device;
#define FIELD_KERNEL "KERNEL"
#define FIELD_NAME "NAME"
#define FIELD_SYMLINK "SYMLINK"
+#define FIELD_OWNER "OWNER"
+#define FIELD_GROUP "GROUP"
+#define FIELD_MODE "MODE"
#define ATTR_PARTITIONS "all_partitions"
#define PARTITIONS_COUNT 15
@@ -54,6 +57,14 @@ struct sysfs_class_device;
#define RULEFILE_EXT ".rules"
#define PERMFILE_EXT ".permissions"
+#define set_empty_perms(dev, m, o, g) \
+ if (dev->mode == 0) \
+ dev->mode = m; \
+ if (dev->owner[0] == '\0') \
+ strfieldcpy(dev->owner, o); \
+ if (dev->group[0] == '\0') \
+ strfieldcpy(dev->group, g);
+
struct sysfs_pair {
char file[FILE_SIZE];
char value[VALUE_SIZE];
@@ -71,6 +82,9 @@ struct config_device {
char name[NAME_SIZE];
char symlink[NAME_SIZE];
struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS];
+ char owner[OWNER_SIZE];
+ char group[GROUP_SIZE];
+ unsigned int mode;
int partitions;
char config_file[NAME_SIZE];
int config_line;
@@ -93,7 +107,6 @@ extern int namedev_name_device(struct sysfs_class_device *class_dev, struct udev
extern int namedev_init_permissions(void);
extern int namedev_init_rules(void);
-extern int add_perm_dev(struct perm_device *new_dev);
extern void dump_config_dev(struct config_device *dev);
extern void dump_config_dev_list(void);
extern void dump_perm_dev(struct perm_device *dev);
diff --git a/namedev_parse.c b/namedev_parse.c
index defb698b26..fba32a4983 100644
--- a/namedev_parse.c
+++ b/namedev_parse.c
@@ -43,6 +43,7 @@
LIST_HEAD(file_list);
+
static int add_config_dev(struct config_device *new_dev)
{
struct config_device *tmp_dev;
@@ -61,9 +62,11 @@ void dump_config_dev(struct config_device *dev)
dbg_parse("name='%s', symlink='%s', bus='%s', place='%s', id='%s', "
"sysfs_file[0]='%s', sysfs_value[0]='%s', "
"kernel='%s', program='%s', result='%s'",
+ "owner='%s', group='%s', mode=%#o",
dev->name, dev->symlink, dev->bus, dev->place, dev->id,
dev->sysfs_pair[0].file, dev->sysfs_pair[0].value,
- dev->kernel, dev->program, dev->result);
+ dev->kernel, dev->program, dev->result,;
+ dev->owner, dev->group, dev->mode);
}
void dump_config_dev_list(void)
@@ -74,6 +77,31 @@ void dump_config_dev_list(void)
dump_config_dev(dev);
}
+static int add_perm_dev(struct perm_device *new_dev)
+{
+ struct perm_device *dev;
+ struct perm_device *tmp_dev;
+
+ /* update the values if we already have the device */
+ list_for_each_entry(dev, &perm_device_list, node) {
+ if (strcmp(new_dev->name, dev->name) != 0)
+ continue;
+
+ set_empty_perms(dev, new_dev->mode, new_dev->owner, new_dev->group);
+ return 0;
+ }
+
+ /* not found, add new structure to the perm list */
+ tmp_dev = malloc(sizeof(*tmp_dev));
+ if (!tmp_dev)
+ return -ENOMEM;
+
+ memcpy(tmp_dev, new_dev, sizeof(*tmp_dev));
+ list_add_tail(&tmp_dev->node, &perm_device_list);
+ //dump_perm_dev(tmp_dev);
+ return 0;
+}
+
void dump_perm_dev(struct perm_device *dev)
{
dbg_parse("name='%s', owner='%s', group='%s', mode=%#o",
@@ -240,12 +268,26 @@ static int namedev_parse_rules(char *filename)
continue;
}
+ if (strcasecmp(temp2, FIELD_OWNER) == 0) {
+ strfieldcpy(dev.owner, temp3);
+ continue;
+ }
+
+ if (strcasecmp(temp2, FIELD_GROUP) == 0) {
+ strfieldcpy(dev.group, temp3);
+ continue;
+ }
+
+ if (strcasecmp(temp2, FIELD_MODE) == 0) {
+ dev.mode = strtol(temp3, NULL, 8);
+ continue;
+ }
+
dbg("unknown type of field '%s'", temp2);
- dbg("You might be using a rules file in the old format, please fix.");
goto error;
}
- /* simple plausibility check for given keys */
+ /* simple plausibility checks for given keys */
if ((dev.sysfs_pair[0].file[0] == '\0') ^
(dev.sysfs_pair[0].value[0] == '\0')) {
dbg("inconsistency in " FIELD_SYSFS " key");
@@ -336,14 +378,14 @@ static int namedev_parse_permissions(char *filename)
strfieldcpy(dev.group, temp2);
if (!temp) {
- dbg("cannot parse line: %s", line);
+ dbg("cannot parse line '%s'", line);
continue;
}
dev.mode = strtol(temp, NULL, 8);
dbg_parse("name='%s', owner='%s', group='%s', mode=%#o",
- dev.name, dev.owner, dev.group,
- dev.mode);
+ dev.name, dev.owner, dev.group, dev.mode);
+
retval = add_perm_dev(&dev);
if (retval) {
dbg("add_perm_dev returned with error %d", retval);
diff --git a/udev.8 b/udev.8
index 8ebcf7bd99..d5d9549113 100644
--- a/udev.8
+++ b/udev.8
@@ -220,6 +220,10 @@ to the symlink list of the rule which will create the node.
This makes it possible to specify additional symlinks in a possibly
separate rules file, while the device nodes are maintained by the
distribution provided rules file.
+.TP
+.B OWNER, GROUP, MODE
+The permissions for this device. Every specified value overwrites the value
+given in the permissions file.
.P
.RB "The " NAME " ," SYMLINK " and " PROGRAM
fields support simple printf-like string substitution: