chiark / gitweb /
treewide: use log_*_errno whenever %m is in the format string
[elogind.git] / src / udev / udev-rules.c
index 9514dde75144ac6b56c72e6349da35615a992120..d72362fcbd1218d396bf2e04542a33dcb2a9043a 100644 (file)
@@ -459,8 +459,9 @@ static int add_token(struct udev_rules *rules, struct token *token) {
 
 static uid_t add_uid(struct udev_rules *rules, const char *owner) {
         unsigned int i;
-        uid_t uid;
+        uid_t uid = 0;
         unsigned int off;
+        int r;
 
         /* lookup, if we know it already */
         for (i = 0; i < rules->uids_cur; i++) {
@@ -470,7 +471,13 @@ static uid_t add_uid(struct udev_rules *rules, const char *owner) {
                         return uid;
                 }
         }
-        uid = util_lookup_user(rules->udev, owner);
+        r = get_user_creds(&owner, &uid, NULL, NULL, NULL);
+        if (r < 0) {
+                if (r == -ENOENT || r == -ESRCH)
+                        log_error("specified user '%s' unknown", owner);
+                else
+                        log_error_errno(r, "error resolving user '%s': %m", owner);
+        }
 
         /* grow buffer if needed */
         if (rules->uids_cur+1 >= rules->uids_max) {
@@ -499,8 +506,9 @@ static uid_t add_uid(struct udev_rules *rules, const char *owner) {
 
 static gid_t add_gid(struct udev_rules *rules, const char *group) {
         unsigned int i;
-        gid_t gid;
+        gid_t gid = 0;
         unsigned int off;
+        int r;
 
         /* lookup, if we know it already */
         for (i = 0; i < rules->gids_cur; i++) {
@@ -510,7 +518,13 @@ static gid_t add_gid(struct udev_rules *rules, const char *group) {
                         return gid;
                 }
         }
-        gid = util_lookup_group(rules->udev, group);
+        r = get_group_creds(&group, &gid);
+        if (r < 0) {
+                if (r == -ENOENT || r == -ESRCH)
+                        log_error("specified group '%s' unknown", group);
+                else
+                        log_error_errno(r, "error resolving group '%s': %m", group);
+        }
 
         /* grow buffer if needed */
         if (rules->gids_cur+1 >= rules->gids_max) {
@@ -615,6 +629,7 @@ static int import_file_into_properties(struct udev_device *dev, const char *file
 
 static int import_program_into_properties(struct udev_event *event,
                                           usec_t timeout_usec,
+                                          usec_t timeout_warn_usec,
                                           const char *program, const sigset_t *sigmask) {
         struct udev_device *dev = event->dev;
         char **envp;
@@ -623,7 +638,7 @@ static int import_program_into_properties(struct udev_event *event,
         int err;
 
         envp = udev_device_get_properties_envp(dev);
-        err = udev_event_spawn(event, timeout_usec, program, envp, sigmask, result, sizeof(result));
+        err = udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, sigmask, result, sizeof(result));
         if (err < 0)
                 return err;
 
@@ -1057,8 +1072,7 @@ static int add_rule(struct udev_rules *rules, char *line,
                                 _cleanup_free_ char *tmp;
 
                                 tmp = cescape(buf);
-                                log_error("invalid key/value pair in file %s on line %u,"
-                                          "starting at character %tu ('%s')\n",
+                                log_error("invalid key/value pair in file %s on line %u, starting at character %tu ('%s')",
                                           filename, lineno, linepos - line + 1, tmp);
                                 if (linepos[1] == '#')
                                         log_error("hint: comments can only start at beginning of line");
@@ -1561,7 +1575,7 @@ invalid:
 }
 
 static int parse_file(struct udev_rules *rules, const char *filename) {
-        FILE *f;
+        _cleanup_fclose_ FILE *f = NULL;
         unsigned int first_token;
         unsigned int filename_off;
         char line[UTIL_LINE_SIZE];
@@ -1619,7 +1633,6 @@ static int parse_file(struct udev_rules *rules, const char *filename) {
                 }
                 add_rule(rules, key, filename, filename_off, line_nr);
         }
-        fclose(f);
 
         /* link GOTOs to LABEL rules in this file to be able to fast-forward */
         for (i = first_token+1; i < rules->token_cur; i++) {
@@ -1672,7 +1685,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) {
 
         r = conf_files_list_strv(&files, ".rules", NULL, rules_dirs);
         if (r < 0) {
-                log_error("failed to enumerate rules files: %s", strerror(-r));
+                log_error_errno(r, "failed to enumerate rules files: %m");
                 return udev_rules_unref(rules);
         }
 
@@ -1862,6 +1875,8 @@ enum escape_type {
 int udev_rules_apply_to_event(struct udev_rules *rules,
                               struct udev_event *event,
                               usec_t timeout_usec,
+                              usec_t timeout_warn_usec,
+                              struct udev_list *properties_list,
                               const sigset_t *sigmask) {
         struct token *cur;
         struct token *rule;
@@ -1927,7 +1942,18 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
                         const char *value;
 
                         value = udev_device_get_property_value(event->dev, key_name);
-                        if (value == NULL)
+
+                        /* check global properties */
+                        if (!value && properties_list) {
+                                struct udev_list_entry *list_entry;
+
+                                list_entry = udev_list_get_entry(properties_list);
+                                list_entry = udev_list_entry_get_by_name(list_entry, key_name);
+                                if (list_entry != NULL)
+                                        value = udev_list_entry_get_value(list_entry);
+                        }
+
+                        if (!value)
                                 value = "";
                         if (match_key(rules, cur, value))
                                 goto nomatch;
@@ -2070,7 +2096,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
                                   rules_str(rules, rule->rule.filename_off),
                                   rule->rule.filename_line);
 
-                        if (udev_event_spawn(event, timeout_usec, program, envp, sigmask, result, sizeof(result)) < 0) {
+                        if (udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, sigmask, result, sizeof(result)) < 0) {
                                 if (cur->key.op != OP_NOMATCH)
                                         goto nomatch;
                         } else {
@@ -2106,7 +2132,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
                                   rules_str(rules, rule->rule.filename_off),
                                   rule->rule.filename_line);
 
-                        if (import_program_into_properties(event, timeout_usec, import, sigmask) != 0)
+                        if (import_program_into_properties(event, timeout_usec, timeout_warn_usec, import, sigmask) != 0)
                                 if (cur->key.op != OP_NOMATCH)
                                         goto nomatch;
                         break;
@@ -2239,6 +2265,8 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
                         break;
                 case TK_A_OWNER: {
                         char owner[UTIL_NAME_SIZE];
+                        const char *ow = owner;
+                        int r;
 
                         if (event->owner_final)
                                 break;
@@ -2246,7 +2274,15 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
                                 event->owner_final = true;
                         udev_event_apply_format(event, rules_str(rules, cur->key.value_off), owner, sizeof(owner));
                         event->owner_set = true;
-                        event->uid = util_lookup_user(event->udev, owner);
+                        r = get_user_creds(&ow, &event->uid, NULL, NULL, NULL);
+                        if (r < 0) {
+                                if (r == -ENOENT || r == -ESRCH)
+                                        log_error("specified user '%s' unknown", owner);
+                                else
+                                        log_error_errno(r, "error resolving user '%s': %m", owner);
+
+                                event->uid = 0;
+                        }
                         log_debug("OWNER %u %s:%u",
                                   event->uid,
                                   rules_str(rules, rule->rule.filename_off),
@@ -2255,6 +2291,8 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
                 }
                 case TK_A_GROUP: {
                         char group[UTIL_NAME_SIZE];
+                        const char *gr = group;
+                        int r;
 
                         if (event->group_final)
                                 break;
@@ -2262,7 +2300,15 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
                                 event->group_final = true;
                         udev_event_apply_format(event, rules_str(rules, cur->key.value_off), group, sizeof(group));
                         event->group_set = true;
-                        event->gid = util_lookup_group(event->udev, group);
+                        r = get_group_creds(&gr, &event->gid);
+                        if (r < 0) {
+                                if (r == -ENOENT || r == -ESRCH)
+                                        log_error("specified group '%s' unknown", group);
+                                else
+                                        log_error_errno(r, "error resolving group '%s': %m", group);
+
+                                event->gid = 0;
+                        }
                         log_debug("GROUP %u %s:%u",
                                   event->gid,
                                   rules_str(rules, rule->rule.filename_off),
@@ -2489,10 +2535,10 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
                         f = fopen(attr, "we");
                         if (f != NULL) {
                                 if (fprintf(f, "%s", value) <= 0)
-                                        log_error("error writing ATTR{%s}: %m", attr);
+                                        log_error_errno(errno, "error writing ATTR{%s}: %m", attr);
                                 fclose(f);
                         } else {
-                                log_error("error opening ATTR{%s} for writing: %m", attr);
+                                log_error_errno(errno, "error opening ATTR{%s} for writing: %m", attr);
                         }
                         break;
                 }
@@ -2606,17 +2652,15 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) {
 
                                         strscpyl(tags_dir, sizeof(tags_dir), "/run/udev/static_node-tags/", *t, "/", NULL);
                                         r = mkdir_p(tags_dir, 0755);
-                                        if (r < 0) {
-                                                log_error("failed to create %s: %s", tags_dir, strerror(-r));
-                                                return r;
-                                        }
+                                        if (r < 0)
+                                                return log_error_errno(r, "failed to create %s: %m", tags_dir);
 
                                         unescaped_filename = xescape(rules_str(rules, cur->key.value_off), "/.");
 
                                         strscpyl(tag_symlink, sizeof(tag_symlink), tags_dir, unescaped_filename, NULL);
                                         r = symlink(device_node, tag_symlink);
                                         if (r < 0 && errno != EEXIST) {
-                                                log_error("failed to create symlink %s -> %s: %m", tag_symlink, device_node);
+                                                log_error_errno(errno, "failed to create symlink %s -> %s: %m", tag_symlink, device_node);
                                                 return -errno;
                                         } else
                                                 r = 0;