]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/shared/udev-util.c
device-util: Declare iterator variables inline
[thirdparty/systemd.git] / src / shared / udev-util.c
index a4b17be097929da24ee1566d737bff081d1eeca3..3e81234dc1f3d7e8815141f6070b1b374cdeedaf 100644 (file)
@@ -165,8 +165,8 @@ static int device_monitor_handler(sd_device_monitor *monitor, sd_device *device,
         if (data->devlink) {
                 const char *devlink;
 
-                FOREACH_DEVICE_DEVLINK(device, devlink)
-                        if (path_equal(devlink, data->devlink))
+                FOREACH_DEVICE_DEVLINK(device, link)
+                        if (path_equal(link, data->devlink))
                                 goto found;
 
                 if (sd_device_get_devname(device, &devlink) >= 0 && path_equal(devlink, data->devlink))
@@ -347,11 +347,10 @@ int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos) {
         str += is_escaped;
         if (str[0] != '"')
                 return -EINVAL;
-        str++;
 
         if (!is_escaped) {
                 /* unescape double quotation '\"'->'"' */
-                for (i = j = str; *i != '"'; i++, j++) {
+                for (j = str, i = str + 1; *i != '"'; i++, j++) {
                         if (*i == '\0')
                                 return -EINVAL;
                         if (i[0] == '\\' && i[1] == '"')
@@ -359,12 +358,17 @@ int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos) {
                         *j = *i;
                 }
                 j[0] = '\0';
+                /*
+                 * The return value must be terminated by two subsequent NULs
+                 * so it could be safely interpreted as nulstr.
+                 */
+                j[1] = '\0';
         } else {
                 _cleanup_free_ char *unescaped = NULL;
                 ssize_t l;
 
                 /* find the end position of value */
-                for (i = str; *i != '"'; i++) {
+                for (i = str + 1; *i != '"'; i++) {
                         if (i[0] == '\\')
                                 i++;
                         if (*i == '\0')
@@ -372,12 +376,17 @@ int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos) {
                 }
                 i[0] = '\0';
 
-                l = cunescape_length(str, i - str, 0, &unescaped);
+                l = cunescape_length(str + 1, i - (str + 1), 0, &unescaped);
                 if (l < 0)
                         return l;
 
-                assert(l <= i - str);
+                assert(l <= i - (str + 1));
                 memcpy(str, unescaped, l + 1);
+                /*
+                 * The return value must be terminated by two subsequent NULs
+                 * so it could be safely interpreted as nulstr.
+                 */
+                str[l + 1] = '\0';
         }
 
         *ret_value = str;
@@ -582,176 +591,6 @@ int udev_queue_init(void) {
         return TAKE_FD(fd);
 }
 
-static int device_is_power_sink(sd_device *device) {
-        _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
-        bool found_source = false, found_sink = false;
-        sd_device *parent, *d;
-        int r;
-
-        assert(device);
-
-        /* USB-C power supply device has two power roles: source or sink. See,
-         * https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-class-typec */
-
-        r = sd_device_enumerator_new(&e);
-        if (r < 0)
-                return r;
-
-        r = sd_device_enumerator_allow_uninitialized(e);
-        if (r < 0)
-                return r;
-
-        r = sd_device_enumerator_add_match_subsystem(e, "typec", true);
-        if (r < 0)
-                return r;
-
-        r = sd_device_get_parent(device, &parent);
-        if (r < 0)
-                return r;
-
-        r = sd_device_enumerator_add_match_parent(e, parent);
-        if (r < 0)
-                return r;
-
-        FOREACH_DEVICE(e, d) {
-                const char *val;
-
-                r = sd_device_get_sysattr_value(d, "power_role", &val);
-                if (r < 0) {
-                        if (r != -ENOENT)
-                                log_device_debug_errno(d, r, "Failed to read 'power_role' sysfs attribute, ignoring: %m");
-                        continue;
-                }
-
-                if (strstr(val, "[source]")) {
-                        found_source = true;
-                        log_device_debug(d, "The USB type-C port is in power source mode.");
-                } else if (strstr(val, "[sink]")) {
-                        found_sink = true;
-                        log_device_debug(d, "The USB type-C port is in power sink mode.");
-                }
-        }
-
-        if (found_sink)
-                log_device_debug(device, "The USB type-C device has at least one port in power sink mode.");
-        else if (!found_source)
-                log_device_debug(device, "The USB type-C device has no port in power source mode, assuming the device is in power sink mode.");
-        else
-                log_device_debug(device, "All USB type-C ports are in power source mode.");
-
-        return found_sink || !found_source;
-}
-
-static bool battery_is_discharging(sd_device *d) {
-        const char *val;
-        int r;
-
-        assert(d);
-
-        r = sd_device_get_sysattr_value(d, "scope", &val);
-        if (r < 0) {
-                if (r != -ENOENT)
-                        log_device_debug_errno(d, r, "Failed to read 'scope' sysfs attribute, ignoring: %m");
-        } else if (streq(val, "Device")) {
-                log_device_debug(d, "The power supply is a device battery, ignoring device.");
-                return false;
-        }
-
-        r = device_get_sysattr_bool(d, "present");
-        if (r < 0)
-                log_device_debug_errno(d, r, "Failed to read 'present' sysfs attribute, assuming the battery is present: %m");
-        else if (r == 0) {
-                log_device_debug(d, "The battery is not present, ignoring the power supply.");
-                return false;
-        }
-
-        /* Possible values: "Unknown", "Charging", "Discharging", "Not charging", "Full" */
-        r = sd_device_get_sysattr_value(d, "status", &val);
-        if (r < 0) {
-                log_device_debug_errno(d, r, "Failed to read 'status' sysfs attribute, assuming the battery is discharging: %m");
-                return true;
-        }
-        if (!streq(val, "Discharging")) {
-                log_device_debug(d, "The battery status is '%s', assuming the battery is not used as a power source of this machine.", val);
-                return false;
-        }
-
-        return true;
-}
-
-int on_ac_power(void) {
-        _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
-        bool found_ac_online = false, found_discharging_battery = false;
-        sd_device *d;
-        int r;
-
-        r = sd_device_enumerator_new(&e);
-        if (r < 0)
-                return r;
-
-        r = sd_device_enumerator_allow_uninitialized(e);
-        if (r < 0)
-                return r;
-
-        r = sd_device_enumerator_add_match_subsystem(e, "power_supply", true);
-        if (r < 0)
-                return r;
-
-        FOREACH_DEVICE(e, d) {
-                /* See
-                 * https://github.com/torvalds/linux/blob/4eef766b7d4d88f0b984781bc1bcb574a6eafdc7/include/linux/power_supply.h#L176
-                 * for defined power source types. Also see:
-                 * https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-class-power */
-
-                const char *val;
-                r = sd_device_get_sysattr_value(d, "type", &val);
-                if (r < 0) {
-                        log_device_debug_errno(d, r, "Failed to read 'type' sysfs attribute, ignoring device: %m");
-                        continue;
-                }
-
-                /* Ignore USB-C power supply in source mode. See issue #21988. */
-                if (streq(val, "USB")) {
-                        r = device_is_power_sink(d);
-                        if (r <= 0) {
-                                if (r < 0)
-                                        log_device_debug_errno(d, r, "Failed to determine the current power role, ignoring device: %m");
-                                else
-                                        log_device_debug(d, "USB power supply is in source mode, ignoring device.");
-                                continue;
-                        }
-                }
-
-                if (streq(val, "Battery")) {
-                        if (battery_is_discharging(d)) {
-                                found_discharging_battery = true;
-                                log_device_debug(d, "The power supply is a battery and currently discharging.");
-                        }
-                        continue;
-                }
-
-                r = device_get_sysattr_unsigned(d, "online", NULL);
-                if (r < 0) {
-                        log_device_debug_errno(d, r, "Failed to query 'online' sysfs attribute, ignoring device: %m");
-                        continue;
-                } else if (r > 0)  /* At least 1 and 2 are defined as different types of 'online' */
-                        found_ac_online = true;
-
-                log_device_debug(d, "The power supply is currently %s.", r > 0 ? "online" : "offline");
-        }
-
-        if (found_ac_online) {
-                log_debug("Found at least one online non-battery power supply, system is running on AC.");
-                return true;
-        } else if (found_discharging_battery) {
-                log_debug("Found at least one discharging battery and no online power sources, assuming system is running from battery.");
-                return false;
-        } else {
-                log_debug("No power supply reported online and no discharging battery found, assuming system is running on AC.");
-                return true;
-        }
-}
-
 bool udev_available(void) {
         static int cache = -1;