summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-bus/bus-message.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-08-25 19:28:30 +0200
committerLennart Poettering <lennart@poettering.net>2015-08-25 19:28:30 +0200
commiteccd47c5beb72211ce33c9a33a1bb36366d43e22 (patch)
tree3efe52cf8e6cecdf358ae421752d70bb352165d4 /src/libsystemd/sd-bus/bus-message.c
parent33c1c9745ccc478c8eda72f8bae76945487076ae (diff)
sd-bus: introduce new match type "arg0has=" for matching arrays of strings
Previously, sd-bus inofficially already supported bus matches that tested a string against an array of strings ("as"). This was done via an enhanced way to interpret "arg0=" matches. This is problematic however, since clients have no way to determine if their respective implementation understood strv matches or not, thus allowing invalid matches to be installed without a way to detect that. This patch changes the logic to only allow such matches with a new "arg0has=" syntax. This has the benefit that non-conforming implementations will return a parse error and a client application may thus efficiently detect support for the match type. Matches of this type are useful for "udev"-like systems that "tag" objects with a number of strings, and clients need to be able to match against any of these "tags". The name "has" takes inspiration from Python's ".has_key()" construct.
Diffstat (limited to 'src/libsystemd/sd-bus/bus-message.c')
-rw-r--r--src/libsystemd/sd-bus/bus-message.c69
1 files changed, 48 insertions, 21 deletions
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index a212f0b398..970aaabdc2 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -5611,21 +5611,23 @@ _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
return 1;
}
-int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str, char ***strv) {
- const char *contents;
+static int bus_message_get_arg_skip(
+ sd_bus_message *m,
+ unsigned i,
+ char *_type,
+ const char **_contents) {
+
unsigned j;
- char type;
int r;
- assert(m);
- assert(str);
- assert(strv);
-
r = sd_bus_message_rewind(m, true);
if (r < 0)
return r;
for (j = 0;; j++) {
+ const char *contents;
+ char type;
+
r = sd_bus_message_peek_type(m, &type, &contents);
if (r < 0)
return r;
@@ -5637,31 +5639,56 @@ int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str, char **
!(type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")))
return -ENXIO;
- if (j >= i)
- break;
+ if (j >= i) {
+ if (_contents)
+ *_contents = contents;
+ if (_type)
+ *_type = type;
+ return 0;
+ }
r = sd_bus_message_skip(m, NULL);
if (r < 0)
return r;
}
- if (type == SD_BUS_TYPE_ARRAY) {
+}
- r = sd_bus_message_read_strv(m, strv);
- if (r < 0)
- return r;
+int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str) {
+ char type;
+ int r;
- *str = NULL;
+ assert(m);
+ assert(str);
- } else {
- r = sd_bus_message_read_basic(m, type, str);
- if (r < 0)
- return r;
+ r = bus_message_get_arg_skip(m, i, &type, NULL);
+ if (r < 0)
+ return r;
- *strv = NULL;
- }
+ if (!IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE))
+ return -ENXIO;
- return 0;
+ return sd_bus_message_read_basic(m, type, str);
+}
+
+int bus_message_get_arg_strv(sd_bus_message *m, unsigned i, char ***strv) {
+ const char *contents;
+ char type;
+ int r;
+
+ assert(m);
+ assert(strv);
+
+ r = bus_message_get_arg_skip(m, i, &type, &contents);
+ if (r < 0)
+ return r;
+
+ if (type != SD_BUS_TYPE_ARRAY)
+ return -ENXIO;
+ if (!STR_IN_SET(contents, "s", "o", "g"))
+ return -ENXIO;
+
+ return sd_bus_message_read_strv(m, strv);
}
_public_ int sd_bus_message_get_errno(sd_bus_message *m) {