X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=udev_rules_parse.c;h=9a12d53816e59f4dfaa50d3add57e4c243f5c925;hb=2e23125e112c0a56e1ccee193c2cfe0e26af1bad;hp=5ce91df383dfdb5c924b7008549b6d7b8679d70c;hpb=7db33ac19c430c9a4c4af415e2febbd6b17aff2a;p=elogind.git diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 5ce91df38..9a12d5381 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -232,6 +232,7 @@ static int add_rule_key_pair(struct udev_rule *rule, struct key_pairs *pairs, static int add_to_rules(struct udev_rules *rules, char *line, const char *filename, unsigned int lineno) { + char buf[sizeof(struct udev_rule) + LINE_SIZE]; struct udev_rule *rule; size_t rule_size; int valid; @@ -241,15 +242,12 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena int physdev = 0; int retval; - /* get all the keys */ - rule = calloc(1, sizeof (struct udev_rule) + LINE_SIZE); - if (!rule) { - err("malloc failed"); - return -1; - } + memset(buf, 0x00, sizeof(buf)); + rule = (struct udev_rule *) buf; linepos = line; valid = 0; + /* get all the keys */ while (1) { char *key; char *value; @@ -298,7 +296,16 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena err("invalid SUBSYSTEM operation"); goto invalid; } - add_rule_key(rule, &rule->subsystem, operation, value); + /* bus, class, subsystem events should all be the same */ + if (strcmp(value, "subsystem") == 0 || + strcmp(value, "bus") == 0 || + strcmp(value, "class") == 0) { + if (strcmp(value, "bus") == 0 || strcmp(value, "class") == 0) + err("'%s' must be specified as 'subsystem' " + "please fix it in %s:%u", value, filename, lineno); + add_rule_key(rule, &rule->subsystem, operation, "subsystem|class|bus"); + } else + add_rule_key(rule, &rule->subsystem, operation, value); valid = 1; continue; } @@ -376,7 +383,7 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena if (strncmp(attr, "device/", 7) == 0) err("the 'device' link is deprecated and will be removed from a future kernel, " "please fix it in %s:%u", filename, lineno); - else if (strchr(attr, '/') != NULL) + else if (strstr(attr, "../") != NULL) err("do not reference parent sysfs directories directly, that may break with a future kernel, " "please fix it in %s:%u", filename, lineno); if (add_rule_key_pair(rule, &rule->attrs, operation, attr, value) != 0) @@ -461,6 +468,15 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena continue; } + if (strncasecmp(key, "TEST", sizeof("TEST")-1) == 0) { + attr = get_key_attribute(key + sizeof("TEST")-1); + if (attr != NULL) + rule->test_mode_mask = strtol(attr, NULL, 8); + add_rule_key(rule, &rule->test, operation, value); + valid = 1; + continue; + } + if (strcasecmp(key, "RUN") == 0) { add_rule_key(rule, &rule->run, operation, value); valid = 1; @@ -555,6 +571,8 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena } if (strcasecmp(key, "OPTIONS") == 0) { + const char *pos; + if (strstr(value, "last_rule") != NULL) { dbg("last rule to be applied"); rule->last_rule = 1; @@ -567,6 +585,19 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena dbg("remove event should be ignored"); rule->ignore_remove = 1; } + pos = strstr(value, "link_priority="); + if (pos != NULL) { + rule->link_priority = atoi(&pos[strlen("link_priority=")]); + info("link priority=%i", rule->link_priority); + } + pos = strstr(value, "string_escape="); + if (pos != NULL) { + pos = &pos[strlen("string_escape=")]; + if (strncmp(pos, "none", strlen("none")) == 0) + rule->string_escape = ESCAPE_NONE; + else if (strncmp(pos, "replace", strlen("replace")) == 0) + rule->string_escape = ESCAPE_REPLACE; + } if (strstr(value, "all_partitions") != NULL) { dbg("creation of partition nodes requested"); rule->partitions = DEFAULT_PARTITIONS_COUNT; @@ -602,11 +633,9 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena memcpy(rules->buf + rules->bufsize, rule, rule_size); rules->bufsize += rule_size; exit: - free(rule); return 0; invalid: - free(rule); err("invalid rule '%s:%u'", filename, lineno); return -1; }