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;
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;
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);
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];
}
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);
}
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)
if (sort_base == NULL)
continue;
-
+ /* sort entry into existing list */
udev_list_entry_foreach_safe(file_loop, file_tmp, udev_list_get_entry(&file_list)) {
const char *file_name = udev_list_entry_get_name(file_loop);
const char *file_base = strrchr(file_name, '/');
if (strcmp(file_base, sort_base) == 0) {
info(udev, "rule file basename '%s' already added, ignoring '%s'\n",
file_name, sort_name);
- udev_list_entry_remove(sort_loop);
+ udev_list_entry_delete(sort_loop);
sort_loop = NULL;
break;
}
- if (strcmp(file_base, sort_base) > 0)
+ if (strcmp(file_base, sort_base) > 0) {
+ /* found later file, insert before */
+ udev_list_entry_remove(sort_loop);
+ udev_list_entry_insert_before(sort_loop, file_loop);
+ sort_loop = NULL;
break;
+ }
}
- if (sort_loop != NULL)
- udev_list_entry_move_before(sort_loop, file_loop);
+ /* current file already handled */
+ if (sort_loop == NULL)
+ continue;
+ /* no later file, append to end of list */
+ udev_list_entry_remove(sort_loop);
+ udev_list_entry_append(sort_loop, &file_list);
}
}
parse_file(rules, filename, filename_off);
else
info(udev, "can not read '%s'\n", filename);
- udev_list_entry_remove(file_loop);
+ udev_list_entry_delete(file_loop);
}
memset(&end_token, 0x00, sizeof(struct token));
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;
cur = &rules->tokens[0];
rule = cur;
while (1) {
- unsigned int idx;
-
dump_token(rules, cur);
switch (cur->type) {
case TK_RULE:
util_strlcpy(program, &rules->buf[cur->key.value_off], sizeof(program));
udev_event_apply_format(event, program, sizeof(program));
envp = udev_device_get_properties_envp(event->dev);
+ info(event->udev, "PROGRAM '%s' %s:%u\n",
+ program,
+ &rules->buf[rule->rule.filename_off],
+ rule->rule.filename_line);
if (util_run_program(event->udev, program, envp, result, sizeof(result), NULL) != 0) {
if (cur->key.op != OP_NOMATCH)
goto nomatch;
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);
}
util_strlcpy(import, &rules->buf[cur->key.value_off], sizeof(import));
udev_event_apply_format(event, import, sizeof(import));
+ info(event->udev, "IMPORT '%s' %s:%u\n",
+ import,
+ &rules->buf[rule->rule.filename_off],
+ rule->rule.filename_line);
if (import_program_into_properties(event->dev, import) != 0)
if (cur->key.op != OP_NOMATCH)
goto nomatch;
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);
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);
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));
}
}