mirror of
https://github.com/systemd/systemd.git
synced 2024-10-29 21:55:36 +03:00
udev: make parser for attribute of $result harder
This commit is contained in:
parent
13cd553f91
commit
ce4f94b8e9
@ -20,6 +20,7 @@
|
|||||||
#include "format-util.h"
|
#include "format-util.h"
|
||||||
#include "libudev-util.h"
|
#include "libudev-util.h"
|
||||||
#include "netlink-util.h"
|
#include "netlink-util.h"
|
||||||
|
#include "parse-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "process-util.h"
|
#include "process-util.h"
|
||||||
#include "rlimit-util.h"
|
#include "rlimit-util.h"
|
||||||
@ -204,6 +205,26 @@ static int get_subst_type(const char **str, FormatSubstitutionType *ret_type, ch
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int safe_atou_optional_plus(const char *s, unsigned *ret) {
|
||||||
|
const char *p;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
/* Returns 1 if plus, 0 if no plus, negative on error */
|
||||||
|
|
||||||
|
p = endswith(s, "+");
|
||||||
|
if (p)
|
||||||
|
s = strndupa(s, p - s);
|
||||||
|
|
||||||
|
r = safe_atou(s, ret);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return !!p;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t udev_event_subst_format(
|
static ssize_t udev_event_subst_format(
|
||||||
UdevEvent *event,
|
UdevEvent *event,
|
||||||
FormatSubstitutionType type,
|
FormatSubstitutionType type,
|
||||||
@ -267,43 +288,50 @@ static ssize_t udev_event_subst_format(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FORMAT_SUBST_RESULT: {
|
case FORMAT_SUBST_RESULT: {
|
||||||
char *rest;
|
unsigned index = 0; /* 0 means whole string */
|
||||||
int i;
|
bool has_plus;
|
||||||
|
|
||||||
if (!event->program_result)
|
if (!event->program_result)
|
||||||
goto null_terminate;
|
goto null_terminate;
|
||||||
|
|
||||||
/* get part of the result string */
|
if (!isempty(attr)) {
|
||||||
i = 0;
|
r = safe_atou_optional_plus(attr, &index);
|
||||||
if (!isempty(attr))
|
if (r < 0)
|
||||||
i = strtoul(attr, &rest, 10);
|
return r;
|
||||||
if (i > 0) {
|
|
||||||
char result[UTIL_PATH_SIZE], tmp[UTIL_PATH_SIZE], *cpos;
|
|
||||||
|
|
||||||
strscpy(result, sizeof(result), event->program_result);
|
has_plus = r;
|
||||||
cpos = result;
|
|
||||||
while (--i) {
|
|
||||||
while (cpos[0] != '\0' && !isspace(cpos[0]))
|
|
||||||
cpos++;
|
|
||||||
while (isspace(cpos[0]))
|
|
||||||
cpos++;
|
|
||||||
if (cpos[0] == '\0')
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (i > 0) {
|
|
||||||
log_error("requested part of result string not found");
|
if (index == 0)
|
||||||
break;
|
|
||||||
}
|
|
||||||
strscpy(tmp, sizeof(tmp), cpos);
|
|
||||||
/* %{2+}c copies the whole string from the second part on */
|
|
||||||
if (rest[0] != '+') {
|
|
||||||
cpos = strchr(tmp, ' ');
|
|
||||||
if (cpos)
|
|
||||||
cpos[0] = '\0';
|
|
||||||
}
|
|
||||||
l = strpcpy(&s, l, tmp);
|
|
||||||
} else
|
|
||||||
l = strpcpy(&s, l, event->program_result);
|
l = strpcpy(&s, l, event->program_result);
|
||||||
|
else {
|
||||||
|
const char *start, *p;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
p = skip_leading_chars(event->program_result, NULL);
|
||||||
|
|
||||||
|
for (i = 1; i < index; i++) {
|
||||||
|
while (p[0] != '\0' && !strchr(WHITESPACE, p[0]))
|
||||||
|
p++;
|
||||||
|
p = skip_leading_chars(p, NULL);
|
||||||
|
if (*p == '\0')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i != index) {
|
||||||
|
log_device_debug(dev, "requested part of result string not found");
|
||||||
|
goto null_terminate;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = p;
|
||||||
|
/* %c{2+} copies the whole string from the second part on */
|
||||||
|
if (has_plus)
|
||||||
|
l = strpcpy(&s, l, start);
|
||||||
|
else {
|
||||||
|
while (p[0] != '\0' && !strchr(WHITESPACE, p[0]))
|
||||||
|
p++;
|
||||||
|
l = strnpcpy(&s, l, start, p - start);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FORMAT_SUBST_ATTR: {
|
case FORMAT_SUBST_ATTR: {
|
||||||
|
Loading…
Reference in New Issue
Block a user