chiark / gitweb /
Prep v225: Applying various fixes and changes to src/libelogind/sd-bus that got lost...
[elogind.git] / src / libelogind / sd-bus / bus-match.c
index 53c231331d4500e7e0add28bbee28a2639063463..8ef30f55e74e16d43e19b0a06ca22e966b935167 100644 (file)
  */
 
 static inline bool BUS_MATCH_IS_COMPARE(enum bus_match_node_type t) {
-        return t >= BUS_MATCH_SENDER && t <= BUS_MATCH_ARG_NAMESPACE_LAST;
+        return t >= BUS_MATCH_SENDER && t <= BUS_MATCH_ARG_HAS_LAST;
 }
 
 static inline bool BUS_MATCH_CAN_HASH(enum bus_match_node_type t) {
         return (t >= BUS_MATCH_MESSAGE_TYPE && t <= BUS_MATCH_PATH) ||
-                (t >= BUS_MATCH_ARG && t <= BUS_MATCH_ARG_LAST);
+                (t >= BUS_MATCH_ARG && t <= BUS_MATCH_ARG_LAST) ||
+                (t >= BUS_MATCH_ARG_HAS && t <= BUS_MATCH_ARG_HAS_LAST);
 }
 
 static void bus_match_node_free(struct bus_match_node *node) {
@@ -179,12 +180,16 @@ static bool value_node_test(
         case BUS_MATCH_INTERFACE:
         case BUS_MATCH_MEMBER:
         case BUS_MATCH_PATH:
-        case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST: {
-                char **i;
+        case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST:
 
                 if (value_str)
                         return streq_ptr(node->value.str, value_str);
 
+                return false;
+
+        case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST: {
+                char **i;
+
                 STRV_FOREACH(i, value_strv)
                         if (streq_ptr(node->value.str, *i))
                                 return true;
@@ -192,33 +197,20 @@ static bool value_node_test(
                 return false;
         }
 
-        case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST: {
-                char **i;
-
+        case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST:
                 if (value_str)
                         return namespace_simple_pattern(node->value.str, value_str);
 
-                STRV_FOREACH(i, value_strv)
-                        if (namespace_simple_pattern(node->value.str, *i))
-                                return true;
                 return false;
-        }
 
         case BUS_MATCH_PATH_NAMESPACE:
                 return path_simple_pattern(node->value.str, value_str);
 
-        case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST: {
-                char **i;
-
+        case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST:
                 if (value_str)
                         return path_complex_pattern(node->value.str, value_str);
 
-                STRV_FOREACH(i, value_strv)
-                        if (path_complex_pattern(node->value.str, *i))
-                                return true;
-
                 return false;
-        }
 
         default:
                 assert_not_reached("Invalid node type");
@@ -249,6 +241,7 @@ static bool value_node_same(
         case BUS_MATCH_MEMBER:
         case BUS_MATCH_PATH:
         case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST:
+        case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST:
         case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST:
         case BUS_MATCH_PATH_NAMESPACE:
         case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST:
@@ -372,15 +365,19 @@ int bus_match_run(
                 break;
 
         case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST:
-                (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG, &test_str, &test_strv);
+                (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG, &test_str);
                 break;
 
         case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST:
-                (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_PATH, &test_str, &test_strv);
+                (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_PATH, &test_str);
                 break;
 
         case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST:
-                (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_NAMESPACE, &test_str, &test_strv);
+                (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_NAMESPACE, &test_str);
+                break;
+
+        case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST:
+                (void) bus_message_get_arg_strv(m, node->type - BUS_MATCH_ARG_HAS, &test_strv);
                 break;
 
         default:
@@ -743,6 +740,32 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n
                 return t;
         }
 
+        if (n == 7 && startswith(k, "arg") && startswith(k + 4, "has")) {
+                int j;
+
+                j = undecchar(k[3]);
+                if (j < 0)
+                        return -EINVAL;
+
+                return BUS_MATCH_ARG_HAS + j;
+        }
+
+        if (n == 8 && startswith(k, "arg") && startswith(k + 5, "has")) {
+                enum bus_match_node_type t;
+                int a, b;
+
+                a = undecchar(k[3]);
+                b = undecchar(k[4]);
+                if (a <= 0 || b < 0)
+                        return -EINVAL;
+
+                t = BUS_MATCH_ARG_HAS + a * 10 + b;
+                if (t > BUS_MATCH_ARG_HAS_LAST)
+                        return -EINVAL;
+
+                return t;
+        }
+
         return -EINVAL;
 }
 
@@ -861,8 +884,7 @@ int bus_match_parse(
                         if (r < 0)
                                 goto fail;
 
-                        free(value);
-                        value = NULL;
+                        value = mfree(value);
                 } else
                         u = 0;
 
@@ -944,8 +966,8 @@ char *bus_match_to_string(struct bus_match_component *components, unsigned n_com
                 fputc('\'', f);
         }
 
-        fflush(f);
-        if (ferror(f))
+        r = fflush_and_check(f);
+        if (r < 0)
                 return NULL;
 
         return buffer;
@@ -1114,6 +1136,10 @@ const char* bus_match_node_type_to_string(enum bus_match_node_type t, char buf[]
                 snprintf(buf, l, "arg%inamespace", t - BUS_MATCH_ARG_NAMESPACE);
                 return buf;
 
+        case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST:
+                snprintf(buf, l, "arg%ihas", t - BUS_MATCH_ARG_HAS);
+                return buf;
+
         default:
                 return NULL;
         }