chiark / gitweb /
analyze: improve output
[elogind.git] / src / dbus.c
index d7b80ba01d17c9bbe8d31ad368b179784c349f11..31b1ce6ee0706ec825892378eaf615e86cfffe70 100644 (file)
@@ -418,7 +418,7 @@ static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBus
                                         goto oom;
                         }
 
-                        /* On success we don't do anything, the service will be spwaned now */
+                        /* On success we don't do anything, the service will be spawned now */
                 }
         }
 
@@ -955,7 +955,8 @@ static int bus_init_private(Manager *m) {
         if (getpid() != 1)
                 return 0;
 
-        if (!(m->private_bus = dbus_server_listen("unix:abstract=/org/freedesktop/systemd1/private", &error))) {
+        unlink("/run/systemd/private");
+        if (!(m->private_bus = dbus_server_listen("unix:path=/run/systemd/private", &error))) {
                 log_error("Failed to create private D-Bus server: %s", error.message);
                 r = -EIO;
                 goto fail;
@@ -1213,12 +1214,20 @@ oom:
         return -ENOMEM;
 }
 
-DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBusMessage *message, const char*introspection, const BusProperty *properties) {
+DBusHandlerResult bus_default_message_handler(
+                Manager *m,
+                DBusConnection *c,
+                DBusMessage *message,
+                const char *introspection,
+                const char *interfaces,
+                const BusProperty *properties) {
+
         DBusError error;
         DBusMessage *reply = NULL;
         int r;
 
         assert(m);
+        assert(c);
         assert(message);
 
         dbus_error_init(&error);
@@ -1269,6 +1278,13 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBu
 
                         if (!dbus_message_iter_close_container(&iter, &sub))
                                 goto oom;
+                } else {
+                        if (!nulstr_contains(interfaces, interface))
+                                dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface");
+                        else
+                                dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property");
+
+                        return bus_send_error_reply(m, c, message, &error, -EINVAL);
                 }
 
         } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "GetAll") && properties) {
@@ -1283,6 +1299,11 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBu
                             DBUS_TYPE_INVALID))
                         return bus_send_error_reply(m, c, message, &error, -EINVAL);
 
+                if (interface[0] && !nulstr_contains(interfaces, interface)) {
+                        dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface");
+                        return bus_send_error_reply(m, c, message, &error, -EINVAL);
+                }
+
                 if (!(reply = dbus_message_new_method_return(message)))
                         goto oom;
 
@@ -1316,6 +1337,71 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBu
 
                 if (!dbus_message_iter_close_container(&iter, &sub))
                         goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set") && properties) {
+                const char *interface, *property;
+                DBusMessageIter iter;
+                const BusProperty *p;
+
+                if (!dbus_message_iter_init(message, &iter) ||
+                    dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+                        return bus_send_error_reply(m, c, message, NULL, -EINVAL);
+
+                dbus_message_iter_get_basic(&iter, &interface);
+
+                if (!dbus_message_iter_next(&iter) ||
+                    dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+                        return bus_send_error_reply(m, c, message, NULL, -EINVAL);
+
+                dbus_message_iter_get_basic(&iter, &property);
+
+                if (!dbus_message_iter_next(&iter) ||
+                    dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT ||
+                    dbus_message_iter_has_next(&iter))
+                        return bus_send_error_reply(m, c, message, NULL, -EINVAL);
+
+                for (p = properties; p->property; p++)
+                        if (streq(p->interface, interface) && streq(p->property, property))
+                                break;
+
+                if (p->set) {
+                        DBusMessageIter sub;
+                        char *sig;
+
+                        dbus_message_iter_recurse(&iter, &sub);
+
+                        if (!(sig = dbus_message_iter_get_signature(&sub)))
+                                goto oom;
+
+                        if (!streq(sig, p->signature)) {
+                                dbus_free(sig);
+                                return bus_send_error_reply(m, c, message, NULL, -EINVAL);
+                        }
+
+                        dbus_free(sig);
+
+                        if ((r = p->set(m, &sub, property)) < 0) {
+                                if (r == -ENOMEM)
+                                        goto oom;
+                                return bus_send_error_reply(m, c, message, NULL, r);
+                        }
+
+                        if (!(reply = dbus_message_new_method_return(message)))
+                                goto oom;
+                } else {
+                        if (p->property)
+                                dbus_set_error_const(&error, DBUS_ERROR_PROPERTY_READ_ONLY, "Property read-only");
+                        else if (!nulstr_contains(interfaces, interface))
+                                dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface");
+                        else
+                                dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property");
+
+                        return bus_send_error_reply(m, c, message, &error, -EINVAL);
+                }
+
+        } else if (!nulstr_contains(interfaces, dbus_message_get_interface(message))) {
+                dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface");
+                return bus_send_error_reply(m, c, message, &error, -EINVAL);
         }
 
         if (reply) {
@@ -1361,6 +1447,7 @@ static const char *error_to_dbus(int error) {
                 return DBUS_ERROR_FILE_EXISTS;
 
         case -ETIMEDOUT:
+        case -ETIME:
                 return DBUS_ERROR_TIMEOUT;
 
         case -EIO: