chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
rules: static_node - use 0660 if group is given to get the cigar
[elogind.git]
/
udev
/
udev-rules.c
diff --git
a/udev/udev-rules.c
b/udev/udev-rules.c
index c24da0c4974e151922eb0e9a571b21308ca90fd4..56a258d8adb920638ccd511f4ec5b1579f697215 100644
(file)
--- a/
udev/udev-rules.c
+++ b/
udev/udev-rules.c
@@
-136,6
+136,7
@@
enum token_type {
TK_M_SUBSYSTEMS, /* val */
TK_M_DRIVERS, /* val */
TK_M_ATTRS, /* val, attr */
TK_M_SUBSYSTEMS, /* val */
TK_M_DRIVERS, /* val */
TK_M_ATTRS, /* val, attr */
+ TK_M_TAGS, /* val */
TK_M_PARENTS_MAX,
TK_M_TEST, /* val, mode_t */
TK_M_PARENTS_MAX,
TK_M_TEST, /* val, mode_t */
@@
-271,6
+272,7
@@
static const char *token_str(enum token_type type)
[TK_M_SUBSYSTEMS] = "M SUBSYSTEMS",
[TK_M_DRIVERS] = "M DRIVERS",
[TK_M_ATTRS] = "M ATTRS",
[TK_M_SUBSYSTEMS] = "M SUBSYSTEMS",
[TK_M_DRIVERS] = "M DRIVERS",
[TK_M_ATTRS] = "M ATTRS",
+ [TK_M_TAGS] = "M TAGS",
[TK_M_PARENTS_MAX] = "M PARENTS_MAX",
[TK_M_TEST] = "M TEST",
[TK_M_PARENTS_MAX] = "M PARENTS_MAX",
[TK_M_TEST] = "M TEST",
@@
-342,6
+344,7
@@
static void dump_token(struct udev_rules *rules, struct token *token)
case TK_M_KERNELS:
case TK_M_SUBSYSTEMS:
case TK_M_DRIVERS:
case TK_M_KERNELS:
case TK_M_SUBSYSTEMS:
case TK_M_DRIVERS:
+ case TK_M_TAGS:
case TK_M_PROGRAM:
case TK_M_IMPORT_FILE:
case TK_M_IMPORT_PROG:
case TK_M_PROGRAM:
case TK_M_IMPORT_FILE:
case TK_M_IMPORT_PROG:
@@
-1013,6
+1016,7
@@
static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
case TK_M_KERNELS:
case TK_M_SUBSYSTEMS:
case TK_M_DRIVERS:
case TK_M_KERNELS:
case TK_M_SUBSYSTEMS:
case TK_M_DRIVERS:
+ case TK_M_TAGS:
case TK_M_PROGRAM:
case TK_M_IMPORT_FILE:
case TK_M_IMPORT_PROG:
case TK_M_PROGRAM:
case TK_M_IMPORT_FILE:
case TK_M_IMPORT_PROG:
@@
-1342,6
+1346,15
@@
static int add_rule(struct udev_rules *rules, char *line,
continue;
}
continue;
}
+ if (strcmp(key, "TAGS") == 0) {
+ if (op > OP_MATCH_MAX) {
+ err(rules->udev, "invalid TAGS operation\n");
+ goto invalid;
+ }
+ rule_add_key(&rule_tmp, TK_M_TAGS, op, value, NULL);
+ continue;
+ }
+
if (strncmp(key, "SYSFS{", sizeof("SYSFS{")-1) == 0) {
if (!sysfs_warn) {
sysfs_warn = true;
if (strncmp(key, "SYSFS{", sizeof("SYSFS{")-1) == 0) {
if (!sysfs_warn) {
sysfs_warn = true;
@@
-2165,7
+2178,8
@@
int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
case TK_M_KERNELS:
case TK_M_SUBSYSTEMS:
case TK_M_DRIVERS:
case TK_M_KERNELS:
case TK_M_SUBSYSTEMS:
case TK_M_DRIVERS:
- case TK_M_ATTRS: {
+ case TK_M_ATTRS:
+ case TK_M_TAGS: {
struct token *next;
/* get whole sequence of parent matches */
struct token *next;
/* get whole sequence of parent matches */
@@
-2199,13
+2213,21
@@
int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
if (match_attr(rules, event->dev_parent, event, key) != 0)
goto try_parent;
break;
if (match_attr(rules, event->dev_parent, event, key) != 0)
goto try_parent;
break;
+ case TK_M_TAGS: {
+ bool match = udev_device_has_tag(event->dev_parent, &rules->buf[cur->key.value_off]);
+
+ if (match && key->key.op == OP_NOMATCH)
+ goto try_parent;
+ if (!match && key->key.op == OP_MATCH)
+ goto try_parent;
+ break;
+ }
default:
goto nomatch;
}
dbg(event->udev, "parent key matched\n");
}
dbg(event->udev, "all parent keys matched\n");
default:
goto nomatch;
}
dbg(event->udev, "parent key matched\n");
}
dbg(event->udev, "all parent keys matched\n");
- /* all keys matched */
break;
try_parent:
break;
try_parent:
@@
-2504,11
+2526,15
@@
int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
}
break;
}
}
break;
}
- case TK_A_TAG:
+ case TK_A_TAG: {
+ char tag[UTIL_PATH_SIZE];
+
+ udev_event_apply_format(event, &rules->buf[cur->key.value_off], tag, sizeof(tag));
if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL)
udev_device_cleanup_tags_list(event->dev);
if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL)
udev_device_cleanup_tags_list(event->dev);
- udev_device_add_tag(event->dev,
&rules->buf[cur->key.value_off]
);
+ udev_device_add_tag(event->dev,
tag
);
break;
break;
+ }
case TK_A_NAME: {
const char *name = &rules->buf[cur->key.value_off];
char name_str[UTIL_PATH_SIZE];
case TK_A_NAME: {
const char *name = &rules->buf[cur->key.value_off];
char name_str[UTIL_PATH_SIZE];
@@
-2683,8
+2709,9
@@
void udev_rules_apply_static_dev_perms(struct udev_rules *rules)
case TK_A_STATIC_NODE: {
char filename[UTIL_PATH_SIZE];
struct stat stats;
case TK_A_STATIC_NODE: {
char filename[UTIL_PATH_SIZE];
struct stat stats;
+
/* we assure, that the permissions tokens are sorted before the static token */
/* we assure, that the permissions tokens are sorted before the static token */
- if (
mode == 0 &&
uid == 0 && gid == 0)
+ if (uid == 0 && gid == 0)
goto next;
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(rules->udev), "/",
&rules->buf[cur->key.value_off], NULL);
goto next;
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(rules->udev), "/",
&rules->buf[cur->key.value_off], NULL);
@@
-2692,14
+2719,19
@@
void udev_rules_apply_static_dev_perms(struct udev_rules *rules)
goto next;
if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode))
goto next;
goto next;
if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode))
goto next;
- if (mode != 0 && mode != (stats.st_mode & 0777)) {
+
+ if (mode == 0 && gid > 0)
+ mode = 0660;
+ if (mode != (stats.st_mode & 0777)) {
chmod(filename, mode);
info(rules->udev, "chmod '%s' %#o\n", filename, mode);
}
chmod(filename, mode);
info(rules->udev, "chmod '%s' %#o\n", filename, mode);
}
+
if ((uid != 0 && uid != stats.st_uid) || (gid != 0 && gid != stats.st_gid)) {
chown(filename, uid, gid);
info(rules->udev, "chown '%s' %u %u\n", filename, uid, gid);
}
if ((uid != 0 && uid != stats.st_uid) || (gid != 0 && gid != stats.st_gid)) {
chown(filename, uid, gid);
info(rules->udev, "chown '%s' %u %u\n", filename, uid, gid);
}
+
utimensat(AT_FDCWD, filename, NULL, 0);
break;
}
utimensat(AT_FDCWD, filename, NULL, 0);
break;
}