chiark / gitweb /
builtin: apply format string
[elogind.git] / udev / udev-rules.c
index 75636d9bd6ee52685541356a1f5100d8078c6dee..4226d0b4e0ea801439765db624131ffeb960cf00 100644 (file)
@@ -364,7 +364,7 @@ static void dump_token(struct udev_rules *rules, struct token *token)
                    token_str(type), operation_str(op), value, string_glob_str(glob));
                break;
        case TK_M_IMPORT_BUILTIN:
                    token_str(type), operation_str(op), value, string_glob_str(glob));
                break;
        case TK_M_IMPORT_BUILTIN:
-               dbg(rules->udev, "%s %i\n", token_str(type), token->key.builtin_cmd);
+               dbg(rules->udev, "%s %i '%s'\n", token_str(type), token->key.builtin_cmd, value);
                break;
        case TK_M_ATTR:
        case TK_M_ATTRS:
                break;
        case TK_M_ATTR:
        case TK_M_ATTRS:
@@ -1039,6 +1039,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
                token->key.value_off = add_string(rule_tmp->rules, value);
                break;
        case TK_M_IMPORT_BUILTIN:
                token->key.value_off = add_string(rule_tmp->rules, value);
                break;
        case TK_M_IMPORT_BUILTIN:
+               token->key.value_off = add_string(rule_tmp->rules, value);
                token->key.builtin_cmd = *(enum udev_builtin_cmd *)data;
                break;
        case TK_M_ENV:
                token->key.builtin_cmd = *(enum udev_builtin_cmd *)data;
                break;
        case TK_M_ENV:
@@ -1396,18 +1397,13 @@ static int add_rule(struct udev_rules *rules, char *line,
                        if (strstr(attr, "program")) {
                                /* find known built-in command */
                                if (value[0] != '/') {
                        if (strstr(attr, "program")) {
                                /* find known built-in command */
                                if (value[0] != '/') {
-                                       char file[UTIL_PATH_SIZE];
-                                       char *pos;
                                        enum udev_builtin_cmd cmd;
 
                                        enum udev_builtin_cmd cmd;
 
-                                       util_strscpy(file, sizeof(file), value);
-                                       pos = strchr(file, ' ');
-                                       if (pos)
-                                               pos[0] = '\0';
-                                       cmd = udev_builtin_lookup(file);
+                                       cmd = udev_builtin_lookup(value);
                                        if (cmd < UDEV_BUILTIN_MAX) {
                                        if (cmd < UDEV_BUILTIN_MAX) {
-                                               info(rules->udev, "IMPORT found builtin '%s', replacing %s:%u\n", file, filename, lineno);
-                                               rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, NULL, &cmd);
+                                               info(rules->udev, "IMPORT found builtin '%s', replacing %s:%u\n",
+                                                    value, filename, lineno);
+                                               rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
                                                continue;
                                        }
                                }
                                                continue;
                                        }
                                }
@@ -1418,7 +1414,7 @@ static int add_rule(struct udev_rules *rules, char *line,
 
                                dbg(rules->udev, "IMPORT execute builtin\n");
                                if (cmd < UDEV_BUILTIN_MAX)
 
                                dbg(rules->udev, "IMPORT execute builtin\n");
                                if (cmd < UDEV_BUILTIN_MAX)
-                                       rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, NULL, &cmd);
+                                       rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
                                else
                                        err(rules->udev, "IMPORT{builtin}: '%s' unknown %s:%u\n", value, filename, lineno);
                        } else if (strstr(attr, "file")) {
                                else
                                        err(rules->udev, "IMPORT{builtin}: '%s' unknown %s:%u\n", value, filename, lineno);
                        } else if (strstr(attr, "file")) {
@@ -1612,7 +1608,9 @@ static int add_rule(struct udev_rules *rules, char *line,
 
                        continue;
                }
 
                        continue;
                }
+
                err(rules->udev, "unknown key '%s' in %s:%u\n", key, filename, lineno);
                err(rules->udev, "unknown key '%s' in %s:%u\n", key, filename, lineno);
+               goto invalid;
        }
 
        /* add rule token */
        }
 
        /* add rule token */
@@ -1796,13 +1794,13 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names)
        if (udev_get_rules_path(udev) == NULL) {
                char filename[UTIL_PATH_SIZE];
 
        if (udev_get_rules_path(udev) == NULL) {
                char filename[UTIL_PATH_SIZE];
 
-               /* /lib/udev -- default/package rules */
+               /* /usr/lib/udev -- system rules */
                add_matching_files(udev, &file_list, LIBEXECDIR "/rules.d", ".rules");
 
                add_matching_files(udev, &file_list, LIBEXECDIR "/rules.d", ".rules");
 
-               /* /etc/udev -- system-specific/user/admin rules */
+               /* /etc/udev -- local administration rules */
                add_matching_files(udev, &file_list, SYSCONFDIR "/udev/rules.d", ".rules");
 
                add_matching_files(udev, &file_list, SYSCONFDIR "/udev/rules.d", ".rules");
 
-               /* /run/udev -- throw-away/temporary rules */
+               /* /run/udev -- runtime rules */
                util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/rules.d", NULL);
                add_matching_files(udev, &file_list, filename, ".rules");
        } else {
                util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/rules.d", NULL);
                add_matching_files(udev, &file_list, filename, ".rules");
        } else {
@@ -2306,25 +2304,32 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                        break;
                }
                case TK_M_IMPORT_BUILTIN: {
                        break;
                }
                case TK_M_IMPORT_BUILTIN: {
-                       /* check if we ran already */
-                       if (event->builtin_run & (1 << cur->key.builtin_cmd)) {
-                               info(event->udev, "IMPORT builtin skip '%s' %s:%u\n",
-                                    udev_builtin_name(cur->key.builtin_cmd),
-                                    &rules->buf[rule->rule.filename_off],
-                                    rule->rule.filename_line);
-                               /* return the result from earlier run */
-                               if (event->builtin_ret & (1 << cur->key.builtin_cmd))
+                       char command[UTIL_PATH_SIZE];
+
+                       if (udev_builtin_run_once(cur->key.builtin_cmd)) {
+                               /* check if we ran already */
+                               if (event->builtin_run & (1 << cur->key.builtin_cmd)) {
+                                       info(event->udev, "IMPORT builtin skip '%s' %s:%u\n",
+                                            udev_builtin_name(cur->key.builtin_cmd),
+                                            &rules->buf[rule->rule.filename_off],
+                                            rule->rule.filename_line);
+                                       /* return the result from earlier run */
+                                       if (event->builtin_ret & (1 << cur->key.builtin_cmd))
                                        if (cur->key.op != OP_NOMATCH)
                                        if (cur->key.op != OP_NOMATCH)
-                                               goto nomatch;
-                               break;
+                                                       goto nomatch;
+                                       break;
+                               }
+                               /* mark as ran */
+                               event->builtin_run |= (1 << cur->key.builtin_cmd);
                        }
                        }
-                       /* mark as ran */
-                       event->builtin_run |= (1 << cur->key.builtin_cmd);
+
+                       udev_event_apply_format(event, &rules->buf[cur->key.value_off], command, sizeof(command));
                        info(event->udev, "IMPORT builtin '%s' %s:%u\n",
                             udev_builtin_name(cur->key.builtin_cmd),
                             &rules->buf[rule->rule.filename_off],
                             rule->rule.filename_line);
                        info(event->udev, "IMPORT builtin '%s' %s:%u\n",
                             udev_builtin_name(cur->key.builtin_cmd),
                             &rules->buf[rule->rule.filename_off],
                             rule->rule.filename_line);
-                       if (udev_builtin_run(event->dev, cur->key.builtin_cmd, false) != 0) {
+
+                       if (udev_builtin_run(event->dev, cur->key.builtin_cmd, command, false) != 0) {
                                /* remember failure */
                                info(rules->udev, "IMPORT builtin '%s' returned non-zero\n",
                                     udev_builtin_name(cur->key.builtin_cmd));
                                /* remember failure */
                                info(rules->udev, "IMPORT builtin '%s' returned non-zero\n",
                                     udev_builtin_name(cur->key.builtin_cmd));