chiark / gitweb /
bus: add convenience functions for constructing and sending method calls/signals...
[elogind.git] / src / libsystemd-bus / bus-message.c
index 22e64042099de8235f1eb415981915cb7ce68672..7acab50979336b4e464dc9f0b403bac6a221af05 100644 (file)
@@ -302,6 +302,7 @@ int bus_message_from_malloc(
         m->n_iovec = 1;
         m->iovec[0].iov_base = buffer;
         m->iovec[0].iov_len = length;
+        m->size = length;
 
         r = message_parse_fields(m);
         if (r < 0)
@@ -331,7 +332,7 @@ static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
         m->header->endian = SD_BUS_NATIVE_ENDIAN;
         m->header->type = type;
         m->header->version = bus ? bus->message_version : 1;
-        m->allow_fds = !bus || bus->can_fds;
+        m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
 
         return m;
 }
@@ -354,6 +355,8 @@ int sd_bus_message_new_signal(
                 return -EINVAL;
         if (!m)
                 return -EINVAL;
+        if (bus && bus->state == BUS_UNSET)
+                return -ENOTCONN;
 
         t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
         if (!t)
@@ -396,6 +399,8 @@ int sd_bus_message_new_method_call(
                 return -EINVAL;
         if (!m)
                 return -EINVAL;
+        if (bus && bus->state == BUS_UNSET)
+                return -ENOTCONN;
 
         t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
         if (!t)
@@ -445,6 +450,8 @@ static int message_new_reply(
                 return -EINVAL;
         if (!m)
                 return -EINVAL;
+        if (bus && bus->state == BUS_UNSET)
+                return -ENOTCONN;
 
         t = message_new(bus, type);
         if (!t)
@@ -778,12 +785,12 @@ static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
 
 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
         struct bus_container *c;
-        size_t sz, align;
+        ssize_t align, sz;
         uint32_t k;
         void *a;
         char *e = NULL;
         int fd = -1;
-        uint32_t fdi;
+        uint32_t fdi = 0;
         int r;
 
         if (!m)
@@ -1234,7 +1241,7 @@ int sd_bus_message_close_container(sd_bus_message *m) {
         return 0;
 }
 
-static int message_append_ap(
+int bus_message_append_ap(
                 sd_bus_message *m,
                 const char *types,
                 va_list ap) {
@@ -1320,7 +1327,7 @@ static int message_append_ap(
 
                                 n = va_arg(ap, unsigned);
                                 for (i = 0; i < n; i++) {
-                                        r = message_append_ap(m, s, ap);
+                                        r = bus_message_append_ap(m, s, ap);
                                         if (r < 0)
                                                 return r;
                                 }
@@ -1342,7 +1349,7 @@ static int message_append_ap(
                         if (r < 0)
                                 return r;
 
-                        r = message_append_ap(m, s, ap);
+                        r = bus_message_append_ap(m, s, ap);
                         if (r < 0)
                                 return r;
 
@@ -1370,7 +1377,7 @@ static int message_append_ap(
 
                                 t += k - 1;
 
-                                r = message_append_ap(m, s, ap);
+                                r = bus_message_append_ap(m, s, ap);
                                 if (r < 0)
                                         return r;
 
@@ -1400,10 +1407,10 @@ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
         if (m->sealed)
                 return -EPERM;
         if (!types)
-                return -EINVAL;
+                return 0;
 
         va_start(ap, types);
-        r = message_append_ap(m, types, ap);
+        r = bus_message_append_ap(m, types, ap);
         va_end(ap);
 
         return r;
@@ -1584,10 +1591,12 @@ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
         }
 
         default: {
-                size_t sz, align, rindex;
+                ssize_t sz, align;
+                size_t rindex;
 
                 align = bus_type_get_alignment(type);
                 sz = bus_type_get_size(type);
+                assert(align > 0 && sz > 0);
 
                 rindex = m->rindex;
                 r = message_peek_body(m, &rindex, align, sz, &q);
@@ -2386,10 +2395,11 @@ static int message_skip_fields(
                         (*signature)++;
 
                 } else if (bus_type_is_basic(t)) {
-                        size_t align, k;
+                        ssize_t align, k;
 
                         align = bus_type_get_alignment(t);
                         k = bus_type_get_size(t);
+                        assert(align > 0 && k > 0);
 
                         r = message_peek_fields(m, ri, align, k, NULL);
                         if (r < 0)
@@ -2996,3 +3006,38 @@ int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
 
         return 0;
 }
+
+const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
+        int r;
+        const char *t;
+        char type;
+
+        assert(m);
+
+        r = sd_bus_message_rewind(m, true);
+        if (r < 0)
+                return NULL;
+
+        while (i > 0) {
+                r = sd_bus_message_peek_type(m, &type, NULL);
+                if (r < 0)
+                        return NULL;
+
+                if (type != SD_BUS_TYPE_STRING &&
+                    type != SD_BUS_TYPE_OBJECT_PATH &&
+                    type != SD_BUS_TYPE_SIGNATURE)
+                        return NULL;
+
+                r = sd_bus_message_read_basic(m, type, &t);
+                if (r < 0)
+                        return NULL;
+
+                i--;
+        }
+
+        r = sd_bus_message_rewind(m, true);
+        if (r < 0)
+                return NULL;
+
+        return t;
+}