chiark / gitweb /
cleanup /dev/.udev/queue on startup and exit
[elogind.git] / udev / udev-rules.c
index e07cd3264c4c0d5ae21ef961b5b76d78160941d0..c718ff04eb88f3e7d7d1b3db346b01ba90d99dbf 100644 (file)
@@ -141,23 +141,23 @@ enum token_type {
        TK_END,
 };
 
-/* we try to pack stuff in a way that we take only 16 bytes per token */
+/* we try to pack stuff in a way that we take only 12 bytes per token */
 struct token {
        union {
-               unsigned short type;            /* same as in rule and key */
+               unsigned char type;             /* same as in rule and key */
                struct {
-                       unsigned short type;
-                       unsigned short flags;
-                       unsigned int next_rule;
+                       unsigned char type;
+                       unsigned char flags;
+                       unsigned short token_count;
                        unsigned int label_off;
                        unsigned short filename_off;
                        unsigned short filename_line;
                } rule;
                struct {
-                       unsigned short type;
-                       unsigned short flags;
-                       unsigned short op;
-                       unsigned short glob;
+                       unsigned char type;
+                       unsigned char flags;
+                       unsigned char op;
+                       unsigned char glob;
                        unsigned int value_off;
                        union {
                                unsigned int attr_off;
@@ -274,10 +274,11 @@ static void dump_token(struct udev_rules *rules, struct token *token)
                        const char *tk_ptr = (char *)token;
                        unsigned int off = tk_ptr - tks_ptr;
 
-                       dbg(rules->udev, "* RULE %s:%u, off: %u(%u), next: %u, label: '%s', flags: 0x%02x\n",
+                       dbg(rules->udev, "* RULE %s:%u, off: %u(%u), token_count: %u(%u), label: '%s', flags: 0x%02x\n",
                            &rules->buf[token->rule.filename_off], token->rule.filename_line,
                            off / (unsigned int) sizeof(struct token), off,
-                           token->rule.next_rule,
+                           token->rule.token_count,
+                           token->rule.token_count * (unsigned int) sizeof(struct token),
                            &rules->buf[token->rule.label_off],
                            token->rule.flags);
                        break;
@@ -1439,12 +1440,14 @@ static int add_rule(struct udev_rules *rules, char *line,
                goto invalid;
 
        /* add rule token */
+       rule_tmp.rule.rule.token_count = 1 + rule_tmp.token_cur;
        if (add_token(rules, &rule_tmp.rule) != 0)
                goto invalid;
 
        /* add tokens to list, sorted by type */
        if (sort_token(rules, &rule_tmp) != 0)
                goto invalid;
+
        return 0;
 invalid:
        err(rules->udev, "invalid rule '%s:%u'\n", filename, lineno);
@@ -1525,7 +1528,6 @@ static int parse_file(struct udev_rules *rules, const char *filename, unsigned s
 
 static int add_matching_files(struct udev *udev, struct udev_list_node *file_list, const char *dirname, const char *suffix)
 {
-       struct dirent *ent;
        DIR *dir;
        char filename[UTIL_PATH_SIZE];
 
@@ -1537,26 +1539,28 @@ static int add_matching_files(struct udev *udev, struct udev_list_node *file_lis
        }
 
        while (1) {
-               ent = readdir(dir);
-               if (ent == NULL || ent->d_name[0] == '\0')
+               struct dirent *dent;
+
+               dent = readdir(dir);
+               if (dent == NULL || dent->d_name[0] == '\0')
                        break;
 
-               if ((ent->d_name[0] == '.') || (ent->d_name[0] == '#'))
+               if (dent->d_name[0] == '.')
                        continue;
 
                /* look for file matching with specified suffix */
                if (suffix != NULL) {
                        const char *ext;
 
-                       ext = strrchr(ent->d_name, '.');
+                       ext = strrchr(dent->d_name, '.');
                        if (ext == NULL)
                                continue;
                        if (strcmp(ext, suffix) != 0)
                                continue;
                }
-               dbg(udev, "put file '%s/%s' into list\n", dirname, ent->d_name);
+               dbg(udev, "put file '%s/%s' into list\n", dirname, dent->d_name);
 
-               snprintf(filename, sizeof(filename), "%s/%s", dirname, ent->d_name);
+               snprintf(filename, sizeof(filename), "%s/%s", dirname, dent->d_name);
                filename[sizeof(filename)-1] = '\0';
                udev_list_entry_add(udev, file_list, filename, NULL, 1, 1);
        }
@@ -1571,9 +1575,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names)
        struct stat statbuf;
        struct udev_list_node file_list;
        struct udev_list_entry *file_loop, *file_tmp;
-       unsigned int prev_rule;
        struct token end_token;
-       unsigned int i;
 
        rules = malloc(sizeof(struct udev_rules));
        if (rules == NULL)
@@ -1689,15 +1691,6 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names)
        end_token.type = TK_END;
        add_token(rules, &end_token);
 
-       /* link all TK_RULE tokens to be able to fast-forward to next TK_RULE */
-       prev_rule = 0;
-       for (i = 1; i < rules->token_cur; i++) {
-               if (rules->tokens[i].type == TK_RULE) {
-                       rules->tokens[prev_rule].rule.next_rule = i;
-                       prev_rule = i;
-               }
-       }
-
        /* shrink allocated token and string buffer */
        if (rules->token_cur < rules->token_max) {
                struct token *tokens;
@@ -1885,8 +1878,6 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
        cur = &rules->tokens[0];
        rule = cur;
        while (1) {
-               unsigned int idx;
-
                dump_token(rules, cur);
                switch (cur->type) {
                case TK_RULE:
@@ -2085,7 +2076,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
 
                                        util_remove_trailing_chars(result, '\n');
                                        if (esc == ESCAPE_UNSET || esc == ESCAPE_REPLACE) {
-                                               count = util_replace_chars(result, ALLOWED_CHARS_INPUT);
+                                               count = udev_util_replace_chars(result, UDEV_ALLOWED_CHARS_INPUT);
                                                if (count > 0)
                                                        info(event->udev, "%i character(s) replaced\n" , count);
                                        }
@@ -2284,7 +2275,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                                util_strlcpy(name_str, name, sizeof(name_str));
                                udev_event_apply_format(event, name_str, sizeof(name_str));
                                if (esc == ESCAPE_UNSET || esc == ESCAPE_REPLACE) {
-                                       count = util_replace_chars(name_str, ALLOWED_CHARS_FILE);
+                                       count = udev_util_replace_chars(name_str, "/");
                                        if (count > 0)
                                                info(event->udev, "%i character(s) replaced\n", count);
                                        free(event->name);
@@ -2316,9 +2307,9 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                                util_strlcpy(temp, &rules->buf[cur->key.value_off], sizeof(temp));
                                udev_event_apply_format(event, temp, sizeof(temp));
                                if (esc == ESCAPE_UNSET)
-                                       count = util_replace_chars(temp, ALLOWED_CHARS_FILE " ");
+                                       count = udev_util_replace_chars(temp, "/ ");
                                else if (esc == ESCAPE_REPLACE)
-                                       count = util_replace_chars(temp, ALLOWED_CHARS_FILE);
+                                       count = udev_util_replace_chars(temp, "/");
                                if (count > 0)
                                        info(event->udev, "%i character(s) replaced\n" , count);
                                dbg(event->udev, "rule applied, added symlink(s) '%s'\n", temp);
@@ -2426,10 +2417,8 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                continue;
        nomatch:
                /* fast-forward to next rule */
-               idx = rule->rule.next_rule;
-               if (idx == 0)
-                       return 0;
-               dbg(rules->udev, "forward to rule: %u\n", idx);
-               cur = &rules->tokens[idx];
+               cur = rule + rule->rule.token_count;
+               dbg(rules->udev, "forward to rule: %u\n",
+                                (unsigned int) (cur - rules->tokens));
        }
 }