X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fudev%2Fudev-rules.c;h=b3b42fe98958611d98768327b95cb836b116ee30;hb=8a1733871ffe9bfc47958e9056fd53ce216b1802;hp=b5b54dd0431d5e021ef1cabac629869eb7203d4a;hpb=da5d4bf64f96d21c664bc6fea37f4f28927beb2c;p=elogind.git diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index b5b54dd04..b3b42fe98 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2010 Kay Sievers + * Copyright (C) 2003-2012 Kay Sievers * Copyright (C) 2008 Alan Jenkins * * This program is free software: you can redistribute it and/or modify @@ -202,7 +202,6 @@ struct token { unsigned int value_off; union { unsigned int attr_off; - int devlink_unique; unsigned int rule_goto; mode_t mode; uid_t uid; @@ -745,7 +744,7 @@ static int import_file_into_properties(struct udev_device *dev, const char *file FILE *f; char line[UTIL_LINE_SIZE]; - f = fopen(filename, "r"); + f = fopen(filename, "re"); if (f == NULL) return -1; while (fgets(line, sizeof(line), f) != NULL) @@ -1020,6 +1019,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type, case TK_A_OWNER: case TK_A_GROUP: case TK_A_MODE: + case TK_A_DEVLINK: case TK_A_NAME: case TK_A_GOTO: case TK_M_TAG: @@ -1039,10 +1039,6 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type, token->key.value_off = add_string(rule_tmp->rules, value); token->key.attr_off = add_string(rule_tmp->rules, attr); break; - case TK_A_DEVLINK: - token->key.value_off = add_string(rule_tmp->rules, value); - token->key.devlink_unique = *(int *)data; - break; case TK_M_TEST: token->key.value_off = add_string(rule_tmp->rules, value); if (data != NULL) @@ -1496,17 +1492,11 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (startswith(key, "SYMLINK")) { - if (op < OP_MATCH_MAX) { + if (streq(key, "SYMLINK")) { + if (op < OP_MATCH_MAX) rule_add_key(&rule_tmp, TK_M_DEVLINK, op, value, NULL); - } else { - int flag = 0; - - attr = get_key_attribute(rules->udev, key + sizeof("SYMLINK")-1); - if (attr != NULL && strstr(attr, "unique") != NULL) - flag = 1; - rule_add_key(&rule_tmp, TK_A_DEVLINK, op, value, &flag); - } + else + rule_add_key(&rule_tmp, TK_A_DEVLINK, op, value, NULL); rule_tmp.rule.rule.can_set_name = true; continue; } @@ -1645,7 +1635,7 @@ static int parse_file(struct udev_rules *rules, const char *filename) } log_debug("read rules file: %s\n", filename); - f = fopen(filename, "r"); + f = fopen(filename, "re"); if (f == NULL) return -1; @@ -1728,54 +1718,53 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) /* init token array and string buffer */ rules->tokens = malloc(PREALLOC_TOKEN * sizeof(struct token)); - if (rules->tokens == NULL) { - free(rules); - return NULL; - } + if (rules->tokens == NULL) + return udev_rules_unref(rules); + rules->token_max = PREALLOC_TOKEN; rules->buf = malloc(PREALLOC_STRBUF); - if (rules->buf == NULL) { - free(rules->tokens); - free(rules); - return NULL; - } + if (rules->buf == NULL) + return udev_rules_unref(rules); + rules->buf_max = PREALLOC_STRBUF; /* offset 0 is always '\0' */ rules->buf[0] = '\0'; rules->buf_cur = 1; rules->trie_nodes = malloc(PREALLOC_TRIE * sizeof(struct trie_node)); - if (rules->trie_nodes == NULL) { - free(rules->buf); - free(rules->tokens); - free(rules); - return NULL; - } + if (rules->trie_nodes == NULL) + return udev_rules_unref(rules); + rules->trie_nodes_max = PREALLOC_TRIE; /* offset 0 is the trie root, with an empty string */ memset(rules->trie_nodes, 0x00, sizeof(struct trie_node)); rules->trie_nodes_cur = 1; - rules->dirs = strv_new(TEST_PREFIX SYSCONFDIR "/udev/rules.d", - TEST_PREFIX "/run/udev/rules.d", - TEST_PREFIX UDEVLIBEXECDIR "/rules.d", + rules->dirs = strv_new(SYSCONFDIR "/udev/rules.d", + "/run/udev/rules.d", + UDEVLIBEXECDIR "/rules.d", NULL); if (!rules->dirs) { log_error("failed to build config directory array"); - return NULL; + return udev_rules_unref(rules); } if (!path_strv_canonicalize(rules->dirs)) { log_error("failed to canonicalize config directories\n"); - return NULL; + return udev_rules_unref(rules); } strv_uniq(rules->dirs); + + rules->dirs_ts_usec = calloc(strv_length(rules->dirs), sizeof(long long)); + if(!rules->dirs_ts_usec) + return udev_rules_unref(rules); + udev_rules_check_timestamp(rules); + r = conf_files_list_strv(&files, ".rules", (const char **)rules->dirs); if (r < 0) { log_error("failed to enumerate rules files: %s\n", strerror(-r)); - return NULL; + return udev_rules_unref(rules); } - rules->dirs_ts_usec = calloc(strv_length(rules->dirs), sizeof(long long)); /* * The offset value in the rules strct is limited; add all @@ -2059,7 +2048,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(event->dev)) { const char *devlink; - devlink = udev_list_entry_get_name(list_entry) + strlen(TEST_PREFIX "/dev/"); + devlink = udev_list_entry_get_name(list_entry) + strlen("/dev/"); if (match_key(rules, cur, devlink) == 0) { match = true; break; @@ -2322,7 +2311,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event FILE *f; bool imported = false; - f = fopen("/proc/cmdline", "r"); + f = fopen("/proc/cmdline", "re"); if (f != NULL) { char cmdline[4096]; @@ -2533,7 +2522,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event log_debug("%i character(s) replaced\n", count); } if (major(udev_device_get_devnum(event->dev)) && - (!streq(name_str, udev_device_get_devnode(event->dev) + strlen(TEST_PREFIX "/dev/")))) { + (!streq(name_str, udev_device_get_devnode(event->dev) + strlen("/dev/")))) { log_error("NAME=\"%s\" ignored, kernel device nodes " "can not be renamed; please fix it in %s:%u\n", name, &rules->buf[rule->rule.filename_off], rule->rule.filename_line); @@ -2578,8 +2567,8 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event next[0] = '\0'; log_debug("LINK '%s' %s:%u\n", pos, &rules->buf[rule->rule.filename_off], rule->rule.filename_line); - util_strscpyl(filename, sizeof(filename), TEST_PREFIX "/dev/", pos, NULL); - udev_device_add_devlink(event->dev, filename, cur->key.devlink_unique); + util_strscpyl(filename, sizeof(filename), "/dev/", pos, NULL); + udev_device_add_devlink(event->dev, filename); while (isspace(next[1])) next++; pos = &next[1]; @@ -2588,8 +2577,8 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event if (pos[0] != '\0') { log_debug("LINK '%s' %s:%u\n", pos, &rules->buf[rule->rule.filename_off], rule->rule.filename_line); - util_strscpyl(filename, sizeof(filename), TEST_PREFIX "/dev/", pos, NULL); - udev_device_add_devlink(event->dev, filename, cur->key.devlink_unique); + util_strscpyl(filename, sizeof(filename), "/dev/", pos, NULL); + udev_device_add_devlink(event->dev, filename); } break; } @@ -2607,7 +2596,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event log_debug("ATTR '%s' writing '%s' %s:%u\n", attr, value, &rules->buf[rule->rule.filename_off], rule->rule.filename_line); - f = fopen(attr, "w"); + f = fopen(attr, "we"); if (f != NULL) { if (fprintf(f, "%s", value) <= 0) log_error("error writing ATTR{%s}: %m\n", attr); @@ -2698,7 +2687,7 @@ void udev_rules_apply_static_dev_perms(struct udev_rules *rules) /* we assure, that the permissions tokens are sorted before the static token */ if (mode == 0 && uid == 0 && gid == 0) goto next; - util_strscpyl(filename, sizeof(filename), TEST_PREFIX "/dev/", + util_strscpyl(filename, sizeof(filename), "/dev/", &rules->buf[cur->key.value_off], NULL); if (stat(filename, &stats) != 0) goto next;