1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-10-28 20:25:25 +03:00

udev-event: replace udev_device in subst_format_var() by sd_device

This commit is contained in:
Yu Watanabe 2018-10-25 13:59:03 +09:00
parent a315999de6
commit 4cade7a15b
2 changed files with 111 additions and 110 deletions

View File

@ -21,6 +21,7 @@
#include "path-util.h" #include "path-util.h"
#include "process-util.h" #include "process-util.h"
#include "signal-util.h" #include "signal-util.h"
#include "stdio-util.h"
#include "string-util.h" #include "string-util.h"
#include "udev-builtin.h" #include "udev-builtin.h"
#include "udev-node.h" #include "udev-node.h"
@ -121,71 +122,76 @@ static const struct subst_map_entry map[] = {
{ .name = "sys", .fmt = 'S', .type = SUBST_SYS }, { .name = "sys", .fmt = 'S', .type = SUBST_SYS },
}; };
static size_t subst_format_var(struct udev_event *event, static ssize_t subst_format_var(struct udev_event *event,
const struct subst_map_entry *entry, char *attr, const struct subst_map_entry *entry, char *attr,
char *dest, size_t l) { char *dest, size_t l) {
struct udev_device *dev = event->dev; sd_device *parent, *dev = event->dev->device;
const char *val = NULL;
char *s = dest; char *s = dest;
dev_t devnum;
int r;
assert(entry); assert(entry);
switch (entry->type) { switch (entry->type) {
case SUBST_DEVPATH: case SUBST_DEVPATH:
l = strpcpy(&s, l, udev_device_get_devpath(dev)); r = sd_device_get_devpath(dev, &val);
if (r < 0)
return r;
l = strpcpy(&s, l, val);
break; break;
case SUBST_KERNEL: case SUBST_KERNEL:
l = strpcpy(&s, l, udev_device_get_sysname(dev)); r = sd_device_get_sysname(dev, &val);
if (r < 0)
return r;
l = strpcpy(&s, l, val);
break; break;
case SUBST_KERNEL_NUMBER: case SUBST_KERNEL_NUMBER:
if (udev_device_get_sysnum(dev) == NULL) r = sd_device_get_sysnum(dev, &val);
break; if (r < 0)
l = strpcpy(&s, l, udev_device_get_sysnum(dev)); return r == -ENOENT ? 0 : r;
l = strpcpy(&s, l, val);
break; break;
case SUBST_ID: case SUBST_ID:
if (event->dev_parent == NULL) if (!event->dev_parent)
break; return 0;
l = strpcpy(&s, l, udev_device_get_sysname(event->dev_parent)); r = sd_device_get_sysname(event->dev_parent->device, &val);
if (r < 0)
return r;
l = strpcpy(&s, l, val);
break; break;
case SUBST_DRIVER: { case SUBST_DRIVER:
const char *driver; if (!event->dev_parent)
return 0;
if (event->dev_parent == NULL) r = sd_device_get_driver(event->dev_parent->device, &val);
break; if (r < 0)
return r == -ENOENT ? 0 : r;
driver = udev_device_get_driver(event->dev_parent); l = strpcpy(&s, l, val);
if (driver == NULL)
break;
l = strpcpy(&s, l, driver);
break; break;
} case SUBST_MAJOR:
case SUBST_MAJOR: {
char num[UTIL_PATH_SIZE];
sprintf(num, "%u", major(udev_device_get_devnum(dev)));
l = strpcpy(&s, l, num);
break;
}
case SUBST_MINOR: { case SUBST_MINOR: {
char num[UTIL_PATH_SIZE]; char buf[DECIMAL_STR_MAX(unsigned)];
sprintf(num, "%u", minor(udev_device_get_devnum(dev))); r = sd_device_get_devnum(dev, &devnum);
l = strpcpy(&s, l, num); if (r < 0 && r != -ENOENT)
return r;
xsprintf(buf, "%u", r < 0 ? 0 : entry->type == SUBST_MAJOR ? major(devnum) : minor(devnum));
l = strpcpy(&s, l, buf);
break; break;
} }
case SUBST_RESULT: { case SUBST_RESULT: {
char *rest; char *rest;
int i; int i;
if (event->program_result == NULL) if (!event->program_result)
break; return 0;
/* get part of the result string */ /* get part of the result string */
i = 0; i = 0;
if (attr != NULL) if (attr)
i = strtoul(attr, &rest, 10); i = strtoul(attr, &rest, 10);
if (i > 0) { if (i > 0) {
char result[UTIL_PATH_SIZE]; char result[UTIL_PATH_SIZE], tmp[UTIL_PATH_SIZE], *cpos;
char tmp[UTIL_PATH_SIZE];
char *cpos;
strscpy(result, sizeof(result), event->program_result); strscpy(result, sizeof(result), event->program_result);
cpos = result; cpos = result;
@ -209,88 +215,79 @@ static size_t subst_format_var(struct udev_event *event,
cpos[0] = '\0'; cpos[0] = '\0';
} }
l = strpcpy(&s, l, tmp); l = strpcpy(&s, l, tmp);
} else { } else
l = strpcpy(&s, l, event->program_result); l = strpcpy(&s, l, event->program_result);
}
break; break;
} }
case SUBST_ATTR: { case SUBST_ATTR: {
const char *value = NULL;
char vbuf[UTIL_NAME_SIZE]; char vbuf[UTIL_NAME_SIZE];
size_t len; size_t len;
int count; int count;
if (attr == NULL) { if (!attr)
log_error("missing file parameter for attr"); return -EINVAL;
break;
}
/* try to read the value specified by "[dmi/id]product_name" */ /* try to read the value specified by "[dmi/id]product_name" */
if (util_resolve_subsys_kernel(attr, vbuf, sizeof(vbuf), 1) == 0) if (util_resolve_subsys_kernel(attr, vbuf, sizeof(vbuf), 1) == 0)
value = vbuf; val = vbuf;
/* try to read the attribute the device */ /* try to read the attribute the device */
if (value == NULL) if (!val)
value = udev_device_get_sysattr_value(event->dev, attr); (void) sd_device_get_sysattr_value(dev, attr, &val);
/* try to read the attribute of the parent device, other matches have selected */ /* try to read the attribute of the parent device, other matches have selected */
if (value == NULL && event->dev_parent != NULL && event->dev_parent != event->dev) if (!val && event->dev_parent && event->dev_parent->device != dev)
value = udev_device_get_sysattr_value(event->dev_parent, attr); (void) sd_device_get_sysattr_value(event->dev_parent->device, attr, &val);
if (value == NULL) if (!val)
break; return 0;
/* strip trailing whitespace, and replace unwanted characters */ /* strip trailing whitespace, and replace unwanted characters */
if (value != vbuf) if (val != vbuf)
strscpy(vbuf, sizeof(vbuf), value); strscpy(vbuf, sizeof(vbuf), val);
len = strlen(vbuf); len = strlen(vbuf);
while (len > 0 && isspace(vbuf[--len])) while (len > 0 && isspace(vbuf[--len]))
vbuf[len] = '\0'; vbuf[len] = '\0';
count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT); count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT);
if (count > 0) if (count > 0)
log_debug("%i character(s) replaced" , count); log_device_debug(dev, "%i character(s) replaced", count);
l = strpcpy(&s, l, vbuf); l = strpcpy(&s, l, vbuf);
break; break;
} }
case SUBST_PARENT: { case SUBST_PARENT:
struct udev_device *dev_parent; r = sd_device_get_parent(dev, &parent);
const char *devnode; if (r < 0)
return r == -ENODEV ? 0 : r;
dev_parent = udev_device_get_parent(event->dev); r = sd_device_get_devname(parent, &val);
if (dev_parent == NULL) if (r < 0)
break; return r == -ENOENT ? 0 : r;
devnode = udev_device_get_devnode(dev_parent); l = strpcpy(&s, l, val + STRLEN("/dev/"));
if (devnode != NULL)
l = strpcpy(&s, l, devnode + STRLEN("/dev/"));
break; break;
}
case SUBST_DEVNODE: case SUBST_DEVNODE:
if (udev_device_get_devnode(dev) != NULL) r = sd_device_get_devname(dev, &val);
l = strpcpy(&s, l, udev_device_get_devnode(dev)); if (r < 0)
return r == -ENOENT ? 0 : r;
l = strpcpy(&s, l, val);
break; break;
case SUBST_NAME: case SUBST_NAME:
if (event->name != NULL) if (event->name)
l = strpcpy(&s, l, event->name); l = strpcpy(&s, l, event->name);
else if (udev_device_get_devnode(dev) != NULL) else if (sd_device_get_devname(dev, &val) >= 0)
l = strpcpy(&s, l, l = strpcpy(&s, l, val + STRLEN("/dev/"));
udev_device_get_devnode(dev) + STRLEN("/dev/")); else {
else r = sd_device_get_sysname(dev, &val);
l = strpcpy(&s, l, udev_device_get_sysname(dev)); if (r < 0)
return r;
l = strpcpy(&s, l, val);
}
break; break;
case SUBST_LINKS: { case SUBST_LINKS:
struct udev_list_entry *list_entry; FOREACH_DEVICE_DEVLINK(dev, val)
if (s == dest)
list_entry = udev_device_get_devlinks_list_entry(dev); l = strpcpy(&s, l, val + STRLEN("/dev/"));
if (list_entry == NULL) else
break; l = strpcpyl(&s, l, " ", val + STRLEN("/dev/"), NULL);
l = strpcpy(&s, l,
udev_list_entry_get_name(list_entry) + STRLEN("/dev/"));
udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
l = strpcpyl(&s, l, " ",
udev_list_entry_get_name(list_entry) + STRLEN("/dev/"),
NULL);
break; break;
}
case SUBST_ROOT: case SUBST_ROOT:
l = strpcpy(&s, l, "/dev"); l = strpcpy(&s, l, "/dev");
break; break;
@ -298,17 +295,13 @@ static size_t subst_format_var(struct udev_event *event,
l = strpcpy(&s, l, "/sys"); l = strpcpy(&s, l, "/sys");
break; break;
case SUBST_ENV: case SUBST_ENV:
if (attr == NULL) { if (!attr)
break; return 0;
} else { r = sd_device_get_property_value(dev, attr, &val);
const char *value; if (r < 0)
return r == -ENOENT ? 0 : r;
value = udev_device_get_property_value(event->dev, attr); l = strpcpy(&s, l, val);
if (value == NULL) break;
break;
l = strpcpy(&s, l, value);
break;
}
default: default:
assert_not_reached("Unknown format substitution type"); assert_not_reached("Unknown format substitution type");
} }
@ -316,9 +309,9 @@ static size_t subst_format_var(struct udev_event *event,
return s - dest; return s - dest;
} }
size_t udev_event_apply_format(struct udev_event *event, ssize_t udev_event_apply_format(struct udev_event *event,
const char *src, char *dest, size_t size, const char *src, char *dest, size_t size,
bool replace_whitespace) { bool replace_whitespace) {
const char *from; const char *from;
char *s; char *s;
size_t l; size_t l;
@ -335,9 +328,9 @@ size_t udev_event_apply_format(struct udev_event *event,
for (;;) { for (;;) {
const struct subst_map_entry *entry = NULL; const struct subst_map_entry *entry = NULL;
char attrbuf[UTIL_PATH_SIZE]; char attrbuf[UTIL_PATH_SIZE], *attr;
char *attr = NULL; bool format_dollar = false;
size_t subst_len; ssize_t subst_len;
while (from[0] != '\0') { while (from[0] != '\0') {
if (from[0] == '$') { if (from[0] == '$') {
@ -353,6 +346,7 @@ size_t udev_event_apply_format(struct udev_event *event,
if (startswith(&from[1], map[i].name)) { if (startswith(&from[1], map[i].name)) {
entry = &map[i]; entry = &map[i];
from += strlen(map[i].name)+1; from += strlen(map[i].name)+1;
format_dollar = true;
goto subst; goto subst;
} }
} }
@ -402,11 +396,18 @@ subst:
attrbuf[i] = '\0'; attrbuf[i] = '\0';
from += i+1; from += i+1;
attr = attrbuf; attr = attrbuf;
} else { } else
attr = NULL; attr = NULL;
}
subst_len = subst_format_var(event, entry, attr, s, l); subst_len = subst_format_var(event, entry, attr, s, l);
if (subst_len < 0) {
if (format_dollar)
log_device_warning_errno(event->dev->device, subst_len, "Failed to substitute variable '$%s', ignoring: %m", entry->name);
else
log_device_warning_errno(event->dev->device, subst_len, "Failed to apply format '%%%c', ignoring: %m", entry->fmt);
continue;
}
/* SUBST_RESULT handles spaces itself */ /* SUBST_RESULT handles spaces itself */
if (replace_whitespace && entry->type != SUBST_RESULT) if (replace_whitespace && entry->type != SUBST_RESULT)

View File

@ -62,9 +62,9 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules);
/* udev-event.c */ /* udev-event.c */
struct udev_event *udev_event_new(struct udev_device *dev); struct udev_event *udev_event_new(struct udev_device *dev);
struct udev_event *udev_event_free(struct udev_event *event); struct udev_event *udev_event_free(struct udev_event *event);
size_t udev_event_apply_format(struct udev_event *event, ssize_t udev_event_apply_format(struct udev_event *event,
const char *src, char *dest, size_t size, const char *src, char *dest, size_t size,
bool replace_whitespace); bool replace_whitespace);
int udev_event_spawn(struct udev_event *event, int udev_event_spawn(struct udev_event *event,
usec_t timeout_usec, usec_t timeout_usec,
usec_t timeout_warn_usec, usec_t timeout_warn_usec,