chiark / gitweb /
dbus: more efficient implementation of properties
authorMichal Schmidt <mschmidt@redhat.com>
Sun, 15 Jan 2012 23:23:59 +0000 (00:23 +0100)
committerMichal Schmidt <mschmidt@redhat.com>
Mon, 16 Jan 2012 12:34:42 +0000 (13:34 +0100)
The way the various properties[] arrays are initialized is inefficient:
 - only the .data members change at runtime, yet the whole arrays of
   properties with all the fields are constructed on the stack one by
   one by the code.
 - there's duplication, eg. the properties of "org.freedesktop.systemd1.Unit"
   are repeated in several unit types.

Fix it by moving the information about properties into static const
sections. Instead of storing the .data directly in the property, store
a constant offset from a run-time base.
The small arrays of struct BusBoundProperties bind together the constant
information with the right runtime information (the base pointer).

On my system the code shrinks by 60 KB, data increases by 10 KB.

26 files changed:
configure.ac
src/dbus-automount.c
src/dbus-common.c
src/dbus-common.h
src/dbus-device.c
src/dbus-execute.c
src/dbus-execute.h
src/dbus-job.c
src/dbus-manager.c
src/dbus-mount.c
src/dbus-path.c
src/dbus-service.c
src/dbus-snapshot.c
src/dbus-socket.c
src/dbus-swap.c
src/dbus-target.c
src/dbus-timer.c
src/dbus-unit.c
src/dbus-unit.h
src/hostname/hostnamed.c
src/locale/localed.c
src/login/logind-dbus.c
src/login/logind-seat-dbus.c
src/login/logind-session-dbus.c
src/login/logind-user-dbus.c
src/timedate/timedated.c

index 194caa5..16365eb 100644 (file)
@@ -100,6 +100,7 @@ CC_CHECK_CFLAGS_APPEND([ \
         -Wno-unused-parameter \
         -Wno-missing-field-initializers \
         -Wno-unused-result \
+        -Werror=overflow \
         -Wp,-D_FORTIFY_SOURCE=2 \
         -ffast-math \
         -fno-common \
index 62e8a5f..938768b 100644 (file)
 
 const char bus_automount_interface[] _introspect_("Automount") = BUS_AUTOMOUNT_INTERFACE;
 
+static const BusProperty bus_automount_properties[] = {
+        { "Where",         bus_property_append_string, "s", offsetof(Automount, where),    true },
+        { "DirectoryMode", bus_property_append_mode,   "u", offsetof(Automount, directory_mode) },
+        { NULL, }
+};
+
 DBusHandlerResult bus_automount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
         Automount *am = AUTOMOUNT(u);
-        const BusProperty properties[] = {
-                BUS_UNIT_PROPERTIES,
-                { "org.freedesktop.systemd1.Automount", "Where", bus_property_append_string,       "s", am->where           },
-                { "org.freedesktop.systemd1.Automount", "DirectoryMode", bus_property_append_mode, "u", &am->directory_mode },
-                { NULL, NULL, NULL, NULL, NULL }
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit",      bus_unit_properties,      u  },
+                { "org.freedesktop.systemd1.Automount", bus_automount_properties, am },
+                { NULL, }
         };
 
-        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, properties);
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
 }
index 40754e1..50daedc 100644 (file)
@@ -259,7 +259,7 @@ DBusHandlerResult bus_default_message_handler(
                 DBusMessage *message,
                 const char *introspection,
                 const char *interfaces,
-                const BusProperty *properties) {
+                const BusBoundProperties *bound_properties) {
 
         DBusError error;
         DBusMessage *reply = NULL;
@@ -278,9 +278,12 @@ DBusHandlerResult bus_default_message_handler(
                 if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID))
                         goto oom;
 
-        } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Get") && properties) {
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Get") && bound_properties) {
                 const char *interface, *property;
+                const BusBoundProperties *bp;
                 const BusProperty *p;
+                void *data;
+                DBusMessageIter iter, sub;
 
                 if (!dbus_message_get_args(
                             message,
@@ -290,43 +293,51 @@ DBusHandlerResult bus_default_message_handler(
                             DBUS_TYPE_INVALID))
                         return bus_send_error_reply(c, message, &error, -EINVAL);
 
-                for (p = properties; p->property; p++)
-                        if (streq(p->interface, interface) && streq(p->property, property))
-                                break;
+                for (bp = bound_properties; bp->interface; bp++) {
+                        if (!streq(bp->interface, interface))
+                                continue;
 
-                if (p->property) {
-                        DBusMessageIter iter, sub;
+                        for (p = bp->properties; p->property; p++)
+                                if (streq(p->property, property))
+                                        goto get_prop;
+                }
 
-                        if (!(reply = dbus_message_new_method_return(message)))
-                                goto oom;
+                /* no match */
+                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");
 
-                        dbus_message_iter_init_append(reply, &iter);
+                return bus_send_error_reply(c, message, &error, -EINVAL);
 
-                        if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, p->signature, &sub))
-                                goto oom;
-
-                        if ((r = p->append(&sub, property, (void*) p->data)) < 0) {
+get_prop:
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
 
-                                if (r == -ENOMEM)
-                                        goto oom;
+                dbus_message_iter_init_append(reply, &iter);
 
-                                dbus_message_unref(reply);
-                                return bus_send_error_reply(c, message, NULL, r);
-                        }
+                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, p->signature, &sub))
+                        goto oom;
 
-                        if (!dbus_message_iter_close_container(&iter, &sub))
+                data = (char*)bp->base + p->offset;
+                if (p->indirect)
+                        data = *(void**)data;
+                r = p->append(&sub, property, data);
+                if (r < 0) {
+                        if (r == -ENOMEM)
                                 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(c, message, &error, -EINVAL);
+                        dbus_message_unref(reply);
+                        return bus_send_error_reply(c, message, NULL, r);
                 }
 
-        } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "GetAll") && properties) {
+                if (!dbus_message_iter_close_container(&iter, &sub))
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "GetAll") && bound_properties) {
                 const char *interface;
+                const BusBoundProperties *bp;
                 const BusProperty *p;
                 DBusMessageIter iter, sub, sub2, sub3;
 
@@ -350,36 +361,46 @@ DBusHandlerResult bus_default_message_handler(
                 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub))
                         goto oom;
 
-                for (p = properties; p->property; p++) {
-                        if (interface[0] && !streq(p->interface, interface))
+                for (bp = bound_properties; bp->interface; bp++) {
+                        if (interface[0] && !streq(bp->interface, interface))
                                 continue;
 
-                        if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, NULL, &sub2) ||
-                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &p->property) ||
-                            !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, p->signature, &sub3))
-                                goto oom;
+                        for (p = bp->properties; p->property; p++) {
+                                void *data;
 
-                        if ((r = p->append(&sub3, p->property, (void*) p->data)) < 0) {
-
-                                if (r == -ENOMEM)
+                                if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, NULL, &sub2) ||
+                                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &p->property) ||
+                                    !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, p->signature, &sub3))
                                         goto oom;
 
-                                dbus_message_unref(reply);
-                                return bus_send_error_reply(c, message, NULL, r);
-                        }
+                                data = (char*)bp->base + p->offset;
+                                if (p->indirect)
+                                        data = *(void**)data;
+                                r = p->append(&sub3, p->property, data);
+                                if (r < 0) {
+                                        if (r == -ENOMEM)
+                                                goto oom;
 
-                        if (!dbus_message_iter_close_container(&sub2, &sub3) ||
-                            !dbus_message_iter_close_container(&sub, &sub2))
-                                goto oom;
+                                        dbus_message_unref(reply);
+                                        return bus_send_error_reply(c, message, NULL, r);
+                                }
+
+                                if (!dbus_message_iter_close_container(&sub2, &sub3) ||
+                                    !dbus_message_iter_close_container(&sub, &sub2))
+                                        goto oom;
+                        }
                 }
 
                 if (!dbus_message_iter_close_container(&iter, &sub))
                         goto oom;
 
-        } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set") && properties) {
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set") && bound_properties) {
                 const char *interface, *property;
                 DBusMessageIter iter;
+                const BusBoundProperties *bp;
                 const BusProperty *p;
+                DBusMessageIter sub;
+                char *sig;
 
                 if (!dbus_message_iter_init(message, &iter) ||
                     dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
@@ -398,45 +419,52 @@ DBusHandlerResult bus_default_message_handler(
                     dbus_message_iter_has_next(&iter))
                         return bus_send_error_reply(c, message, NULL, -EINVAL);
 
-                for (p = properties; p->property; p++)
-                        if (streq(p->interface, interface) && streq(p->property, property))
-                                break;
+                for (bp = bound_properties; bp->interface; bp++) {
+                        if (!streq(bp->interface, interface))
+                                continue;
 
-                if (p->set) {
-                        DBusMessageIter sub;
-                        char *sig;
+                        for (p = bp->properties; p->property; p++)
+                                if (streq(p->property, property))
+                                        goto set_prop;
+                }
 
-                        dbus_message_iter_recurse(&iter, &sub);
+                /* no match */
+                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");
 
-                        if (!(sig = dbus_message_iter_get_signature(&sub)))
-                                goto oom;
+                return bus_send_error_reply(c, message, &error, -EINVAL);
 
-                        if (!streq(sig, p->signature)) {
-                                dbus_free(sig);
-                                return bus_send_error_reply(c, message, NULL, -EINVAL);
-                        }
+set_prop:
+                if (!p->set) {
+                        dbus_set_error_const(&error, DBUS_ERROR_PROPERTY_READ_ONLY, "Property read-only");
+                        return bus_send_error_reply(c, message, &error, -EINVAL);
+                }
 
+                dbus_message_iter_recurse(&iter, &sub);
+
+                sig = dbus_message_iter_get_signature(&sub);
+                if (!sig)
+                        goto oom;
+
+                if (!streq(sig, p->signature)) {
                         dbus_free(sig);
+                        return bus_send_error_reply(c, message, NULL, -EINVAL);
+                }
 
-                        if ((r = p->set(&sub, property)) < 0) {
-                                if (r == -ENOMEM)
-                                        goto oom;
-                                return bus_send_error_reply(c, message, NULL, r);
-                        }
+                dbus_free(sig);
 
-                        if (!(reply = dbus_message_new_method_return(message)))
+                r = p->set(&sub, property);
+                if (r < 0) {
+                        if (r == -ENOMEM)
                                 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(c, message, &error, -EINVAL);
+                        return bus_send_error_reply(c, message, NULL, r);
                 }
 
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
         } else {
                 const char *interface = dbus_message_get_interface(message);
 
index acd9208..c3499b9 100644 (file)
@@ -96,14 +96,22 @@ typedef int (*BusPropertyCallback)(DBusMessageIter *iter, const char *property,
 typedef int (*BusPropertySetCallback)(DBusMessageIter *iter, const char *property);
 
 typedef struct BusProperty {
-        const char *interface;           /* interface of the property */
         const char *property;            /* name of the property */
         BusPropertyCallback append;      /* Function that is called to serialize this property */
         const char *signature;
-        const void *data;                /* The data of this property */
+        const uint16_t offset;           /* Offset from BusBoundProperties::base address to the property data.
+                                          * uint16_t is sufficient, because we have no structs too big.
+                                          * -Werror=overflow will catch it if this does not hold. */
+        bool indirect;                   /* data is indirect, ie. not base+offset, but *(base+offset) */
         BusPropertySetCallback set;      /* Optional: Function that is called to set this property */
 } BusProperty;
 
+typedef struct BusBoundProperties {
+        const char *interface;           /* interface of the properties */
+        const BusProperty *properties;   /* array of properties, ended by a NULL-filled element */
+        const void *const base;          /* base pointer to which the offset must be added to reach data */
+} BusBoundProperties;
+
 DBusHandlerResult bus_send_error_reply(
                 DBusConnection *c,
                 DBusMessage *message,
@@ -115,7 +123,7 @@ DBusHandlerResult bus_default_message_handler(
                 DBusMessage *message,
                 const char *introspection,
                 const char *interfaces,
-                const BusProperty *properties);
+                const BusBoundProperties *bound_properties);
 
 int bus_property_append_string(DBusMessageIter *i, const char *property, void *data);
 int bus_property_append_strv(DBusMessageIter *i, const char *property, void *data);
index dd5d0e9..b39fb9d 100644 (file)
@@ -47,13 +47,19 @@ const char bus_device_interface[] _introspect_("Device") = BUS_DEVICE_INTERFACE;
 const char bus_device_invalidating_properties[] =
         "SysFSPath\0";
 
+static const BusProperty bus_device_properties[] = {
+        { "SysFSPath", bus_property_append_string, "s", offsetof(Device, sysfs), true },
+        { NULL, }
+};
+
+
 DBusHandlerResult bus_device_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
         Device *d = DEVICE(u);
-        const BusProperty properties[] = {
-                BUS_UNIT_PROPERTIES,
-                { "org.freedesktop.systemd1.Device", "SysFSPath", bus_property_append_string, "s", d->sysfs },
-                { NULL, NULL, NULL, NULL, NULL }
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit",   bus_unit_properties,   u },
+                { "org.freedesktop.systemd1.Device", bus_device_properties, d },
+                { NULL, }
         };
 
-        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, properties);
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
 }
index 201f6b5..caeaf77 100644 (file)
@@ -355,3 +355,66 @@ int bus_execute_append_command(DBusMessageIter *i, const char *property, void *d
 
         return 0;
 }
+
+const BusProperty bus_exec_context_properties[] = {
+        { "Environment",              bus_property_append_strv,             "as", offsetof(ExecContext, environment),            true },
+        { "EnvironmentFiles",         bus_execute_append_env_files,      "a(sb)", offsetof(ExecContext, environment_files),      true },
+        { "UMask",                    bus_property_append_mode,              "u", offsetof(ExecContext, umask)                        },
+        { "LimitCPU",                 bus_execute_append_rlimits,            "t", 0 },
+        { "LimitFSIZE",               bus_execute_append_rlimits,            "t", 0 },
+        { "LimitDATA",                bus_execute_append_rlimits,            "t", 0 },
+        { "LimitSTACK",               bus_execute_append_rlimits,            "t", 0 },
+        { "LimitCORE",                bus_execute_append_rlimits,            "t", 0 },
+        { "LimitRSS",                 bus_execute_append_rlimits,            "t", 0 },
+        { "LimitNOFILE",              bus_execute_append_rlimits,            "t", 0 },
+        { "LimitAS",                  bus_execute_append_rlimits,            "t", 0 },
+        { "LimitNPROC",               bus_execute_append_rlimits,            "t", 0 },
+        { "LimitMEMLOCK",             bus_execute_append_rlimits,            "t", 0 },
+        { "LimitLOCKS",               bus_execute_append_rlimits,            "t", 0 },
+        { "LimitSIGPENDING",          bus_execute_append_rlimits,            "t", 0 },
+        { "LimitMSGQUEUE",            bus_execute_append_rlimits,            "t", 0 },
+        { "LimitNICE",                bus_execute_append_rlimits,            "t", 0 },
+        { "LimitRTPRIO",              bus_execute_append_rlimits,            "t", 0 },
+        { "LimitRTTIME",              bus_execute_append_rlimits,            "t", 0 },
+        { "WorkingDirectory",         bus_property_append_string,            "s", offsetof(ExecContext, working_directory),      true },
+        { "RootDirectory",            bus_property_append_string,            "s", offsetof(ExecContext, root_directory),         true },
+        { "OOMScoreAdjust",           bus_execute_append_oom_score_adjust,   "i", 0 },
+        { "Nice",                     bus_execute_append_nice,               "i", 0 },
+        { "IOScheduling",             bus_execute_append_ioprio,             "i", 0 },
+        { "CPUSchedulingPolicy",      bus_execute_append_cpu_sched_policy,   "i", 0 },
+        { "CPUSchedulingPriority",    bus_execute_append_cpu_sched_priority, "i", 0 },
+        { "CPUAffinity",              bus_execute_append_affinity,          "ay", 0 },
+        { "TimerSlackNSec",           bus_execute_append_timer_slack_nsec,   "t", 0 },
+        { "CPUSchedulingResetOnFork", bus_property_append_bool,              "b", offsetof(ExecContext, cpu_sched_reset_on_fork)      },
+        { "NonBlocking",              bus_property_append_bool,              "b", offsetof(ExecContext, non_blocking)                 },
+        { "StandardInput",            bus_execute_append_input,              "s", offsetof(ExecContext, std_input)                    },
+        { "StandardOutput",           bus_execute_append_output,             "s", offsetof(ExecContext, std_output)                   },
+        { "StandardError",            bus_execute_append_output,             "s", offsetof(ExecContext, std_error)                    },
+        { "TTYPath",                  bus_property_append_string,            "s", offsetof(ExecContext, tty_path),               true },
+        { "TTYReset",                 bus_property_append_bool,              "b", offsetof(ExecContext, tty_reset)                    },
+        { "TTYVHangup",               bus_property_append_bool,              "b", offsetof(ExecContext, tty_vhangup)                  },
+        { "TTYVTDisallocate",         bus_property_append_bool,              "b", offsetof(ExecContext, tty_vt_disallocate)           },
+        { "SyslogPriority",           bus_property_append_int,               "i", offsetof(ExecContext, syslog_priority)              },
+        { "SyslogIdentifier",         bus_property_append_string,            "s", offsetof(ExecContext, syslog_identifier),      true },
+        { "SyslogLevelPrefix",        bus_property_append_bool,              "b", offsetof(ExecContext, syslog_level_prefix)          },
+        { "Capabilities",             bus_execute_append_capabilities,       "s", 0 },
+        { "SecureBits",               bus_property_append_int,               "i", offsetof(ExecContext, secure_bits)                  },
+        { "CapabilityBoundingSet",    bus_execute_append_capability_bs,      "t", offsetof(ExecContext, capability_bounding_set_drop) },
+        { "User",                     bus_property_append_string,            "s", offsetof(ExecContext, user),                   true },
+        { "Group",                    bus_property_append_string,            "s", offsetof(ExecContext, group),                  true },
+        { "SupplementaryGroups",      bus_property_append_strv,             "as", offsetof(ExecContext, supplementary_groups),   true },
+        { "TCPWrapName",              bus_property_append_string,            "s", offsetof(ExecContext, tcpwrap_name),           true },
+        { "PAMName",                  bus_property_append_string,            "s", offsetof(ExecContext, pam_name),               true },
+        { "ReadWriteDirectories",     bus_property_append_strv,             "as", offsetof(ExecContext, read_write_dirs),        true },
+        { "ReadOnlyDirectories",      bus_property_append_strv,             "as", offsetof(ExecContext, read_only_dirs),         true },
+        { "InaccessibleDirectories",  bus_property_append_strv,             "as", offsetof(ExecContext, inaccessible_dirs),      true },
+        { "MountFlags",               bus_property_append_ul,                "t", offsetof(ExecContext, mount_flags)                  },
+        { "PrivateTmp",               bus_property_append_bool,              "b", offsetof(ExecContext, private_tmp)                  },
+        { "PrivateNetwork",           bus_property_append_bool,              "b", offsetof(ExecContext, private_network)              },
+        { "SameProcessGroup",         bus_property_append_bool,              "b", offsetof(ExecContext, same_pgrp)                    },
+        { "KillMode",                 bus_execute_append_kill_mode,          "s", offsetof(ExecContext, kill_mode)                    },
+        { "KillSignal",               bus_property_append_int,               "i", offsetof(ExecContext, kill_signal)                  },
+        { "UtmpIdentifier",           bus_property_append_string,            "s", offsetof(ExecContext, utmp_id),                true },
+        { "ControlGroupModify",       bus_property_append_bool,              "b", offsetof(ExecContext, control_group_modify)         },
+        { NULL, }
+};
index 2e30679..4626acb 100644 (file)
@@ -25,6 +25,7 @@
 #include <dbus/dbus.h>
 
 #include "manager.h"
+#include "dbus-common.h"
 
 #define BUS_EXEC_STATUS_INTERFACE(prefix)                               \
         "  <property name=\"" prefix "StartTimestamp\" type=\"t\" access=\"read\"/>\n" \
 #define BUS_EXEC_COMMAND_INTERFACE(name)                             \
         "  <property name=\"" name "\" type=\"a(sasbttuii)\" access=\"read\"/>\n"
 
-#define BUS_EXEC_CONTEXT_PROPERTIES(interface, context)                 \
-        { interface, "Environment",                   bus_property_append_strv,   "as",    (context).environment                   }, \
-        { interface, "EnvironmentFiles",              bus_execute_append_env_files, "a(sb)", (context).environment_files           }, \
-        { interface, "UMask",                         bus_property_append_mode,   "u",     &(context).umask                        }, \
-        { interface, "LimitCPU",                      bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "LimitFSIZE",                    bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "LimitDATA",                     bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "LimitSTACK",                    bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "LimitCORE",                     bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "LimitRSS",                      bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "LimitNOFILE",                   bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "LimitAS",                       bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "LimitNPROC",                    bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "LimitMEMLOCK",                  bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "LimitLOCKS",                    bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "LimitSIGPENDING",               bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "LimitMSGQUEUE",                 bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "LimitNICE",                     bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "LimitRTPRIO",                   bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "LimitRTTIME",                   bus_execute_append_rlimits, "t",     &(context)                              }, \
-        { interface, "WorkingDirectory",              bus_property_append_string, "s",     (context).working_directory             }, \
-        { interface, "RootDirectory",                 bus_property_append_string, "s",     (context).root_directory                }, \
-        { interface, "OOMScoreAdjust",                bus_execute_append_oom_score_adjust, "i", &(context)                         }, \
-        { interface, "Nice",                          bus_execute_append_nice,    "i",     &(context)                              }, \
-        { interface, "IOScheduling",                  bus_execute_append_ioprio,  "i",     &(context)                              }, \
-        { interface, "CPUSchedulingPolicy",           bus_execute_append_cpu_sched_policy, "i", &(context)                         }, \
-        { interface, "CPUSchedulingPriority",         bus_execute_append_cpu_sched_priority, "i", &(context)                       }, \
-        { interface, "CPUAffinity",                   bus_execute_append_affinity,"ay",    &(context)                              }, \
-        { interface, "TimerSlackNSec",                bus_execute_append_timer_slack_nsec, "t", &(context)                         }, \
-        { interface, "CPUSchedulingResetOnFork",      bus_property_append_bool,   "b",     &(context).cpu_sched_reset_on_fork      }, \
-        { interface, "NonBlocking",                   bus_property_append_bool,   "b",     &(context).non_blocking                 }, \
-        { interface, "StandardInput",                 bus_execute_append_input,   "s",     &(context).std_input                    }, \
-        { interface, "StandardOutput",                bus_execute_append_output,  "s",     &(context).std_output                   }, \
-        { interface, "StandardError",                 bus_execute_append_output,  "s",     &(context).std_error                    }, \
-        { interface, "TTYPath",                       bus_property_append_string, "s",     (context).tty_path                      }, \
-        { interface, "TTYReset",                      bus_property_append_bool,   "b",     &(context).tty_reset                    }, \
-        { interface, "TTYVHangup",                    bus_property_append_bool,   "b",     &(context).tty_vhangup                  }, \
-        { interface, "TTYVTDisallocate",              bus_property_append_bool,   "b",     &(context).tty_vt_disallocate           }, \
-        { interface, "SyslogPriority",                bus_property_append_int,    "i",     &(context).syslog_priority              }, \
-        { interface, "SyslogIdentifier",              bus_property_append_string, "s",     (context).syslog_identifier             }, \
-        { interface, "SyslogLevelPrefix",             bus_property_append_bool,   "b",     &(context).syslog_level_prefix          }, \
-        { interface, "Capabilities",                  bus_execute_append_capabilities, "s",&(context)                              }, \
-        { interface, "SecureBits",                    bus_property_append_int,    "i",     &(context).secure_bits                  }, \
-        { interface, "CapabilityBoundingSet",         bus_execute_append_capability_bs, "t", &(context).capability_bounding_set_drop }, \
-        { interface, "User",                          bus_property_append_string, "s",     (context).user                          }, \
-        { interface, "Group",                         bus_property_append_string, "s",     (context).group                         }, \
-        { interface, "SupplementaryGroups",           bus_property_append_strv,   "as",    (context).supplementary_groups          }, \
-        { interface, "TCPWrapName",                   bus_property_append_string, "s",     (context).tcpwrap_name                  }, \
-        { interface, "PAMName",                       bus_property_append_string, "s",     (context).pam_name                      }, \
-        { interface, "ReadWriteDirectories",          bus_property_append_strv,   "as",    (context).read_write_dirs               }, \
-        { interface, "ReadOnlyDirectories",           bus_property_append_strv,   "as",    (context).read_only_dirs                }, \
-        { interface, "InaccessibleDirectories",       bus_property_append_strv,   "as",    (context).inaccessible_dirs             }, \
-        { interface, "MountFlags",                    bus_property_append_ul,     "t",     &(context).mount_flags                  }, \
-        { interface, "PrivateTmp",                    bus_property_append_bool,   "b",     &(context).private_tmp                  }, \
-        { interface, "PrivateNetwork",                bus_property_append_bool,   "b",     &(context).private_network              }, \
-        { interface, "SameProcessGroup",              bus_property_append_bool,   "b",     &(context).same_pgrp                    }, \
-        { interface, "KillMode",                      bus_execute_append_kill_mode, "s",   &(context).kill_mode                    }, \
-        { interface, "KillSignal",                    bus_property_append_int,    "i",     &(context).kill_signal                  }, \
-        { interface, "UtmpIdentifier",                bus_property_append_string, "s",     (context).utmp_id                       }, \
-        { interface, "ControlGroupModify",            bus_property_append_bool,   "b",     &(context).control_group_modify         }
+extern const BusProperty bus_exec_context_properties[];
 
-#define BUS_EXEC_STATUS_PROPERTIES(interface, estatus, prefix)           \
-        { interface, prefix "StartTimestamp",         bus_property_append_usec,   "t",     &(estatus).start_timestamp.realtime     }, \
-        { interface, prefix "StartTimestampMonotonic",bus_property_append_usec,   "t",     &(estatus).start_timestamp.monotonic    }, \
-        { interface, prefix "ExitTimestamp",          bus_property_append_usec,   "t",     &(estatus).start_timestamp.realtime     }, \
-        { interface, prefix "ExitTimestampMonotonic", bus_property_append_usec,   "t",     &(estatus).start_timestamp.monotonic    }, \
-        { interface, prefix "PID",                    bus_property_append_pid,    "u",     &(estatus).pid                          }, \
-        { interface, prefix "Code",                   bus_property_append_int,    "i",     &(estatus).code                         }, \
-        { interface, prefix "Status",                 bus_property_append_int,    "i",     &(estatus).status                       }
-
-#define BUS_EXEC_COMMAND_PROPERTY(interface, command, name)             \
-        { interface, name, bus_execute_append_command, "a(sasbttttuii)", (command) }
+#define BUS_EXEC_COMMAND_PROPERTY(name, command, indirect)             \
+        { name, bus_execute_append_command, "a(sasbttttuii)", (command), (indirect), NULL }
 
 int bus_execute_append_output(DBusMessageIter *i, const char *property, void *data);
 int bus_execute_append_input(DBusMessageIter *i, const char *property, void *data);
index 82a23a8..ab6d610 100644 (file)
@@ -85,15 +85,15 @@ static int bus_job_append_unit(DBusMessageIter *i, const char *property, void *d
         return 0;
 }
 
-static DBusHandlerResult bus_job_message_dispatch(Job *j, DBusConnection *connection, DBusMessage *message) {
-        const BusProperty properties[] = {
-                { "org.freedesktop.systemd1.Job", "Id",      bus_property_append_uint32, "u",    &j->id    },
-                { "org.freedesktop.systemd1.Job", "State",   bus_job_append_state,       "s",    &j->state },
-                { "org.freedesktop.systemd1.Job", "JobType", bus_job_append_type,        "s",    &j->type  },
-                { "org.freedesktop.systemd1.Job", "Unit",    bus_job_append_unit,        "(so)", j         },
-                { NULL, NULL, NULL, NULL, NULL }
-        };
+static const BusProperty bus_job_properties[] = {
+        { "Id",      bus_property_append_uint32, "u", offsetof(Job, id)    },
+        { "State",   bus_job_append_state,       "s", offsetof(Job, state) },
+        { "JobType", bus_job_append_type,        "s", offsetof(Job, type)  },
+        { "Unit",    bus_job_append_unit,     "(so)", 0 },
+        { NULL, }
+};
 
+static DBusHandlerResult bus_job_message_dispatch(Job *j, DBusConnection *connection, DBusMessage *message) {
         DBusMessage *reply = NULL;
 
         if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Job", "Cancel")) {
@@ -102,8 +102,13 @@ static DBusHandlerResult bus_job_message_dispatch(Job *j, DBusConnection *connec
 
                 job_finish_and_invalidate(j, JOB_CANCELED);
 
-        } else
-                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, properties);
+        } else {
+                const BusBoundProperties bps[] = {
+                        { "org.freedesktop.systemd1.Job", bus_job_properties, j },
+                        { NULL, }
+                };
+                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
+        }
 
         if (reply) {
                 if (!dbus_connection_send(connection, reply, NULL))
index 710cbcb..6d272cb 100644 (file)
@@ -491,46 +491,52 @@ static int bus_manager_send_unit_files_changed(Manager *m) {
         return r;
 }
 
-static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, DBusMessage *message, void *data) {
-        Manager *m = data;
+static const char systemd_property_string[] = PACKAGE_STRING "\0" DISTRIBUTION "\0" SYSTEMD_FEATURES;
 
-        const BusProperty properties[] = {
-                { "org.freedesktop.systemd1.Manager", "Version",       bus_property_append_string,    "s",  PACKAGE_STRING     },
-                { "org.freedesktop.systemd1.Manager", "Distribution",  bus_property_append_string,    "s",  DISTRIBUTION       },
-                { "org.freedesktop.systemd1.Manager", "Features",      bus_property_append_string,    "s",  SYSTEMD_FEATURES   },
-                { "org.freedesktop.systemd1.Manager", "RunningAs",     bus_manager_append_running_as, "s",  &m->running_as     },
-                { "org.freedesktop.systemd1.Manager", "Tainted",       bus_manager_append_tainted,    "s",  m                  },
-                { "org.freedesktop.systemd1.Manager", "InitRDTimestamp", bus_property_append_uint64,  "t",  &m->initrd_timestamp.realtime },
-                { "org.freedesktop.systemd1.Manager", "InitRDTimestampMonotonic", bus_property_append_uint64, "t", &m->initrd_timestamp.monotonic },
-                { "org.freedesktop.systemd1.Manager", "StartupTimestamp", bus_property_append_uint64, "t",  &m->startup_timestamp.realtime },
-                { "org.freedesktop.systemd1.Manager", "StartupTimestampMonotonic", bus_property_append_uint64, "t", &m->startup_timestamp.monotonic },
-                { "org.freedesktop.systemd1.Manager", "FinishTimestamp", bus_property_append_uint64,  "t",  &m->finish_timestamp.realtime },
-                { "org.freedesktop.systemd1.Manager", "FinishTimestampMonotonic", bus_property_append_uint64, "t",&m->finish_timestamp.monotonic },
-                { "org.freedesktop.systemd1.Manager", "LogLevel",      bus_manager_append_log_level,  "s",  m, bus_manager_set_log_level },
-                { "org.freedesktop.systemd1.Manager", "LogTarget",     bus_manager_append_log_target, "s",  m, bus_manager_set_log_target },
-                { "org.freedesktop.systemd1.Manager", "NNames",        bus_manager_append_n_names,    "u",  m                  },
-                { "org.freedesktop.systemd1.Manager", "NJobs",         bus_manager_append_n_jobs,     "u",  m                  },
-                { "org.freedesktop.systemd1.Manager", "NInstalledJobs",bus_property_append_uint32,    "u",  &m->n_installed_jobs },
-                { "org.freedesktop.systemd1.Manager", "NFailedJobs",   bus_property_append_uint32,    "u",  &m->n_failed_jobs  },
-                { "org.freedesktop.systemd1.Manager", "Progress",      bus_manager_append_progress,   "d",  m                  },
-                { "org.freedesktop.systemd1.Manager", "Environment",   bus_property_append_strv,      "as", m->environment     },
-                { "org.freedesktop.systemd1.Manager", "ConfirmSpawn",  bus_property_append_bool,      "b",  &m->confirm_spawn  },
-                { "org.freedesktop.systemd1.Manager", "ShowStatus",    bus_property_append_bool,      "b",  &m->show_status    },
-                { "org.freedesktop.systemd1.Manager", "UnitPath",      bus_property_append_strv,      "as", m->lookup_paths.unit_path },
-                { "org.freedesktop.systemd1.Manager", "NotifySocket",  bus_property_append_string,    "s",  m->notify_socket   },
-                { "org.freedesktop.systemd1.Manager", "ControlGroupHierarchy", bus_property_append_string, "s", m->cgroup_hierarchy },
-                { "org.freedesktop.systemd1.Manager", "MountAuto",     bus_property_append_bool,      "b",  &m->mount_auto     },
-                { "org.freedesktop.systemd1.Manager", "SwapAuto",      bus_property_append_bool,      "b",  &m->swap_auto      },
-                { "org.freedesktop.systemd1.Manager", "DefaultControllers", bus_property_append_strv, "as", m->default_controllers },
-                { "org.freedesktop.systemd1.Manager", "DefaultStandardOutput", bus_manager_append_exec_output, "s", &m->default_std_output },
-                { "org.freedesktop.systemd1.Manager", "DefaultStandardError",  bus_manager_append_exec_output, "s", &m->default_std_error  },
+static const BusProperty bus_systemd_properties[] = {
+        { "Version",       bus_property_append_string,    "s",  0                                             },
+        { "Distribution",  bus_property_append_string,    "s",  sizeof(PACKAGE_STRING)                        },
+        { "Features",      bus_property_append_string,    "s",  sizeof(PACKAGE_STRING) + sizeof(DISTRIBUTION) },
+        { NULL, }
+};
+
+static const BusProperty bus_manager_properties[] = {
+        { "RunningAs",     bus_manager_append_running_as,          "s", offsetof(Manager, running_as)                  },
+        { "Tainted",       bus_manager_append_tainted,             "s", 0 },
+        { "InitRDTimestamp", bus_property_append_uint64,           "t", offsetof(Manager, initrd_timestamp.realtime)   },
+        { "InitRDTimestampMonotonic", bus_property_append_uint64,  "t", offsetof(Manager, initrd_timestamp.monotonic)  },
+        { "StartupTimestamp", bus_property_append_uint64,          "t", offsetof(Manager, startup_timestamp.realtime)  },
+        { "StartupTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, startup_timestamp.monotonic) },
+        { "FinishTimestamp", bus_property_append_uint64,           "t", offsetof(Manager, finish_timestamp.realtime)   },
+        { "FinishTimestampMonotonic", bus_property_append_uint64,  "t", offsetof(Manager, finish_timestamp.monotonic)  },
+        { "LogLevel",      bus_manager_append_log_level,           "s", 0,                                             0, bus_manager_set_log_level },
+        { "LogTarget",     bus_manager_append_log_target,          "s", 0,                                             0, bus_manager_set_log_target },
+        { "NNames",        bus_manager_append_n_names,             "u", 0 },
+        { "NJobs",         bus_manager_append_n_jobs,              "u", 0 },
+        { "NInstalledJobs",bus_property_append_uint32,             "u", offsetof(Manager, n_installed_jobs)            },
+        { "NFailedJobs",   bus_property_append_uint32,             "u", offsetof(Manager, n_failed_jobs)               },
+        { "Progress",      bus_manager_append_progress,            "d", 0 },
+        { "Environment",   bus_property_append_strv,              "as", offsetof(Manager, environment),                true },
+        { "ConfirmSpawn",  bus_property_append_bool,               "b", offsetof(Manager, confirm_spawn)               },
+        { "ShowStatus",    bus_property_append_bool,               "b", offsetof(Manager, show_status)                 },
+        { "UnitPath",      bus_property_append_strv,              "as", offsetof(Manager, lookup_paths.unit_path),     true },
+        { "NotifySocket",  bus_property_append_string,             "s", offsetof(Manager, notify_socket),              true },
+        { "ControlGroupHierarchy", bus_property_append_string,     "s", offsetof(Manager, cgroup_hierarchy),           true },
+        { "MountAuto",     bus_property_append_bool,               "b", offsetof(Manager, mount_auto)                  },
+        { "SwapAuto",      bus_property_append_bool,               "b", offsetof(Manager, swap_auto)                   },
+        { "DefaultControllers", bus_property_append_strv,         "as", offsetof(Manager, default_controllers),        true },
+        { "DefaultStandardOutput", bus_manager_append_exec_output, "s", offsetof(Manager, default_std_output)          },
+        { "DefaultStandardError",  bus_manager_append_exec_output, "s", offsetof(Manager, default_std_error)           },
 #ifdef HAVE_SYSV_COMPAT
-                { "org.freedesktop.systemd1.Manager", "SysVConsole",   bus_property_append_bool,      "b",  &m->sysv_console   },
-                { "org.freedesktop.systemd1.Manager", "SysVInitPath",  bus_property_append_strv,      "as", m->lookup_paths.sysvinit_path },
-                { "org.freedesktop.systemd1.Manager", "SysVRcndPath",  bus_property_append_strv,      "as", m->lookup_paths.sysvrcnd_path },
+        { "SysVConsole",   bus_property_append_bool,               "b", offsetof(Manager, sysv_console)                },
+        { "SysVInitPath",  bus_property_append_strv,              "as", offsetof(Manager, lookup_paths.sysvinit_path), true },
+        { "SysVRcndPath",  bus_property_append_strv,              "as", offsetof(Manager, lookup_paths.sysvrcnd_path), true },
 #endif
-                { NULL, NULL, NULL, NULL, NULL }
-        };
+        { NULL, }
+};
+
+static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, DBusMessage *message, void *data) {
+        Manager *m = data;
 
         int r;
         DBusError error;
@@ -1416,8 +1422,14 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
                 if (!reply)
                         goto oom;
 
-        } else
-                return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, properties);
+        } else {
+                const BusBoundProperties bps[] = {
+                        { "org.freedesktop.systemd1.Manager", bus_systemd_properties, systemd_property_string },
+                        { "org.freedesktop.systemd1.Manager", bus_manager_properties, m },
+                        { NULL, }
+                };
+                return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, bps);
+        }
 
         if (job_type != _JOB_TYPE_INVALID) {
                 const char *name, *smode, *old_name = NULL;
index 60f1e92..17d29d6 100644 (file)
@@ -135,23 +135,29 @@ static int bus_mount_append_type(DBusMessageIter *i, const char *property, void
         return 0;
 }
 
+static const BusProperty bus_mount_properties[] = {
+        { "Where",         bus_property_append_string, "s", offsetof(Mount, where),    true },
+        { "What",          bus_mount_append_what,      "s", 0 },
+        { "Options",       bus_mount_append_options,   "s", 0 },
+        { "Type",          bus_mount_append_type,      "s", 0 },
+        { "TimeoutUSec",   bus_property_append_usec,   "t", offsetof(Mount, timeout_usec)   },
+        BUS_EXEC_COMMAND_PROPERTY("ExecMount",   offsetof(Mount, exec_command[MOUNT_EXEC_MOUNT]),   false),
+        BUS_EXEC_COMMAND_PROPERTY("ExecUnmount", offsetof(Mount, exec_command[MOUNT_EXEC_UNMOUNT]), false),
+        BUS_EXEC_COMMAND_PROPERTY("ExecRemount", offsetof(Mount, exec_command[MOUNT_EXEC_REMOUNT]), false),
+        { "ControlPID",    bus_property_append_pid,    "u", offsetof(Mount, control_pid)    },
+        { "DirectoryMode", bus_property_append_mode,   "u", offsetof(Mount, directory_mode) },
+        { NULL, }
+};
+
 DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
         Mount *m = MOUNT(u);
-        const BusProperty properties[] = {
-                BUS_UNIT_PROPERTIES,
-                { "org.freedesktop.systemd1.Mount", "Where",         bus_property_append_string, "s", m->where                 },
-                { "org.freedesktop.systemd1.Mount", "What",          bus_mount_append_what,      "s", u                        },
-                { "org.freedesktop.systemd1.Mount", "Options",       bus_mount_append_options,   "s", u                        },
-                { "org.freedesktop.systemd1.Mount", "Type",          bus_mount_append_type,      "s", u                        },
-                { "org.freedesktop.systemd1.Mount", "TimeoutUSec",   bus_property_append_usec,   "t", &m->timeout_usec         },
-                BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Mount", m->exec_command+MOUNT_EXEC_MOUNT,   "ExecMount"),
-                BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Mount", m->exec_command+MOUNT_EXEC_UNMOUNT, "ExecUnmount"),
-                BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Mount", m->exec_command+MOUNT_EXEC_REMOUNT, "ExecRemount"),
-                BUS_EXEC_CONTEXT_PROPERTIES("org.freedesktop.systemd1.Mount", m->exec_context),
-                { "org.freedesktop.systemd1.Mount", "ControlPID",    bus_property_append_pid,    "u", &m->control_pid          },
-                { "org.freedesktop.systemd1.Mount", "DirectoryMode", bus_property_append_mode,   "u", &m->directory_mode       },
-                { NULL, NULL, NULL, NULL, NULL }
+
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit",  bus_unit_properties,         u },
+                { "org.freedesktop.systemd1.Mount", bus_mount_properties,        m },
+                { "org.freedesktop.systemd1.Mount", bus_exec_context_properties, &m->exec_context },
+                { NULL, }
         };
 
-        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, properties);
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps );
 }
index 53a5b42..083ba9e 100644 (file)
@@ -92,16 +92,21 @@ static int bus_path_append_unit(DBusMessageIter *i, const char *property, void *
         return dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t) ? 0 : -ENOMEM;
 }
 
+static const BusProperty bus_path_properties[] = {
+        { "Unit",          bus_path_append_unit,      "s", 0 },
+        { "Paths",         bus_path_append_paths, "a(ss)", 0 },
+        { "MakeDirectory", bus_property_append_bool,  "b", offsetof(Path, make_directory) },
+        { "DirectoryMode", bus_property_append_mode,  "u", offsetof(Path, directory_mode) },
+        { NULL, }
+};
+
 DBusHandlerResult bus_path_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
         Path *p = PATH(u);
-        const BusProperty properties[] = {
-                BUS_UNIT_PROPERTIES,
-                { "org.freedesktop.systemd1.Path", "Unit",          bus_path_append_unit,     "s",     u                   },
-                { "org.freedesktop.systemd1.Path", "Paths",         bus_path_append_paths,    "a(ss)", u                   },
-                { "org.freedesktop.systemd1.Path", "MakeDirectory", bus_property_append_bool, "b",     &p->make_directory  },
-                { "org.freedesktop.systemd1.Path", "DirectoryMode", bus_property_append_mode, "u",     &p->directory_mode  },
-                { NULL, NULL, NULL, NULL, NULL }
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit", bus_unit_properties, u },
+                { "org.freedesktop.systemd1.Path", bus_path_properties, p },
+                { NULL, }
         };
 
-        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, properties);
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
 }
index 2157c2b..e1f6370 100644 (file)
@@ -94,40 +94,56 @@ static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_type, service_type, Se
 static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_restart, service_restart, ServiceRestart);
 static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_notify_access, notify_access, NotifyAccess);
 
-DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connection, DBusMessage *message) {
-        Service *s = SERVICE(u);
-        const BusProperty properties[] = {
-                BUS_UNIT_PROPERTIES,
-                { "org.freedesktop.systemd1.Service", "Type",                   bus_service_append_type,    "s", &s->type                      },
-                { "org.freedesktop.systemd1.Service", "Restart",                bus_service_append_restart, "s", &s->restart                   },
-                { "org.freedesktop.systemd1.Service", "PIDFile",                bus_property_append_string, "s", s->pid_file                   },
-                { "org.freedesktop.systemd1.Service", "NotifyAccess",           bus_service_append_notify_access, "s", &s->notify_access       },
-                { "org.freedesktop.systemd1.Service", "RestartUSec",            bus_property_append_usec,   "t", &s->restart_usec              },
-                { "org.freedesktop.systemd1.Service", "TimeoutUSec",            bus_property_append_usec,   "t", &s->timeout_usec              },
-                BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Service", s->exec_command[SERVICE_EXEC_START_PRE],  "ExecStartPre"),
-                BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Service", s->exec_command[SERVICE_EXEC_START],      "ExecStart"),
-                BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Service", s->exec_command[SERVICE_EXEC_START_POST], "ExecStartPost"),
-                BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Service", s->exec_command[SERVICE_EXEC_RELOAD],     "ExecReload"),
-                BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Service", s->exec_command[SERVICE_EXEC_STOP],       "ExecStop"),
-                BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Service", s->exec_command[SERVICE_EXEC_STOP_POST],  "ExecStopPost"),
-                BUS_EXEC_CONTEXT_PROPERTIES("org.freedesktop.systemd1.Service", s->exec_context),
-                { "org.freedesktop.systemd1.Service", "PermissionsStartOnly",   bus_property_append_bool,   "b", &s->permissions_start_only    },
-                { "org.freedesktop.systemd1.Service", "RootDirectoryStartOnly", bus_property_append_bool,   "b", &s->root_directory_start_only },
-                { "org.freedesktop.systemd1.Service", "RemainAfterExit",        bus_property_append_bool,   "b", &s->remain_after_exit         },
-                { "org.freedesktop.systemd1.Service", "GuessMainPID",           bus_property_append_bool,   "b", &s->guess_main_pid            },
-               BUS_EXEC_STATUS_PROPERTIES("org.freedesktop.systemd1.Service", s->main_exec_status, "ExecMain"),
-                { "org.freedesktop.systemd1.Service", "MainPID",                bus_property_append_pid,    "u", &s->main_pid                  },
-                { "org.freedesktop.systemd1.Service", "ControlPID",             bus_property_append_pid,    "u", &s->control_pid               },
-                { "org.freedesktop.systemd1.Service", "BusName",                bus_property_append_string, "s", s->bus_name                   },
-                { "org.freedesktop.systemd1.Service", "StatusText",             bus_property_append_string, "s", s->status_text                },
+static const BusProperty bus_exec_main_status_properties[] = {
+        { "ExecMainStartTimestamp",         bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.realtime)  },
+        { "ExecMainStartTimestampMonotonic",bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.monotonic) },
+        { "ExecMainExitTimestamp",          bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.realtime)  },
+        { "ExecMainExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.monotonic) },
+        { "ExecMainPID",                    bus_property_append_pid,  "u", offsetof(ExecStatus, pid)                       },
+        { "ExecMainCode",                   bus_property_append_int,  "i", offsetof(ExecStatus, code)                      },
+        { "ExecMainStatus",                 bus_property_append_int,  "i", offsetof(ExecStatus, status)                    },
+        { NULL, }
+};
+
+static const BusProperty bus_service_properties[] = {
+        { "Type",                   bus_service_append_type,          "s", offsetof(Service, type)                      },
+        { "Restart",                bus_service_append_restart,       "s", offsetof(Service, restart)                   },
+        { "PIDFile",                bus_property_append_string,       "s", offsetof(Service, pid_file),            true },
+        { "NotifyAccess",           bus_service_append_notify_access, "s", offsetof(Service, notify_access)             },
+        { "RestartUSec",            bus_property_append_usec,         "t", offsetof(Service, restart_usec)              },
+        { "TimeoutUSec",            bus_property_append_usec,         "t", offsetof(Service, timeout_usec)              },
+        BUS_EXEC_COMMAND_PROPERTY("ExecStartPre",  offsetof(Service, exec_command[SERVICE_EXEC_START_PRE]),  true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecStart",     offsetof(Service, exec_command[SERVICE_EXEC_START]),      true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecStartPost", offsetof(Service, exec_command[SERVICE_EXEC_START_POST]), true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecReload",    offsetof(Service, exec_command[SERVICE_EXEC_RELOAD]),     true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecStop",      offsetof(Service, exec_command[SERVICE_EXEC_STOP]),       true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecStopPost",  offsetof(Service, exec_command[SERVICE_EXEC_STOP_POST]),  true ),
+        { "PermissionsStartOnly",   bus_property_append_bool,         "b", offsetof(Service, permissions_start_only)    },
+        { "RootDirectoryStartOnly", bus_property_append_bool,         "b", offsetof(Service, root_directory_start_only) },
+        { "RemainAfterExit",        bus_property_append_bool,         "b", offsetof(Service, remain_after_exit)         },
+        { "GuessMainPID",           bus_property_append_bool,         "b", offsetof(Service, guess_main_pid)            },
+        { "MainPID",                bus_property_append_pid,          "u", offsetof(Service, main_pid)                  },
+        { "ControlPID",             bus_property_append_pid,          "u", offsetof(Service, control_pid)               },
+        { "BusName",                bus_property_append_string,       "s", offsetof(Service, bus_name),            true },
+        { "StatusText",             bus_property_append_string,       "s", offsetof(Service, status_text),         true },
 #ifdef HAVE_SYSV_COMPAT
-                { "org.freedesktop.systemd1.Service", "SysVRunLevels",          bus_property_append_string, "s", s->sysv_runlevels             },
-                { "org.freedesktop.systemd1.Service", "SysVStartPriority",      bus_property_append_int,    "i", &s->sysv_start_priority       },
-                { "org.freedesktop.systemd1.Service", "SysVPath",               bus_property_append_string, "s", s->sysv_path                  },
+        { "SysVRunLevels",          bus_property_append_string,       "s", offsetof(Service, sysv_runlevels),      true },
+        { "SysVStartPriority",      bus_property_append_int,          "i", offsetof(Service, sysv_start_priority)       },
+        { "SysVPath",               bus_property_append_string,       "s", offsetof(Service, sysv_path),           true },
 #endif
-                { "org.freedesktop.systemd1.Service", "FsckPassNo",             bus_property_append_int,    "i", &s->fsck_passno               },
-                { NULL, NULL, NULL, NULL, NULL }
+        { "FsckPassNo",             bus_property_append_int,          "i", offsetof(Service, fsck_passno)               },
+        { NULL, }
+};
+
+DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connection, DBusMessage *message) {
+        Service *s = SERVICE(u);
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit",    bus_unit_properties,             u },
+                { "org.freedesktop.systemd1.Service", bus_service_properties,          s },
+                { "org.freedesktop.systemd1.Service", bus_exec_context_properties,     &s->exec_context },
+                { "org.freedesktop.systemd1.Service", bus_exec_main_status_properties, &s->main_exec_status },
+                { NULL, }
         };
 
-        return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, properties);
+        return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
 }
index 0967034..e69388a 100644 (file)
 
 const char bus_snapshot_interface[] _introspect_("Snapshot") = BUS_SNAPSHOT_INTERFACE;
 
+static const BusProperty bus_snapshot_properties[] = {
+        { "Cleanup", bus_property_append_bool, "b", offsetof(Snapshot, cleanup) },
+        { NULL, }
+};
+
 DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
         Snapshot *s = SNAPSHOT(u);
-        const BusProperty properties[] = {
-                BUS_UNIT_PROPERTIES,
-                { "org.freedesktop.systemd1.Snapshot", "Cleanup", bus_property_append_bool, "b", &s->cleanup },
-                { NULL, NULL, NULL, NULL, NULL }
-        };
 
         DBusMessage *reply = NULL;
         DBusError error;
@@ -65,8 +65,14 @@ DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusConnection *c, DBusM
                 if (!(reply = dbus_message_new_method_return(message)))
                         goto oom;
 
-        } else
-                return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, properties);
+        } else {
+                const BusBoundProperties bps[] = {
+                        { "org.freedesktop.systemd1.Unit",     bus_unit_properties,     u },
+                        { "org.freedesktop.systemd1.Snapshot", bus_snapshot_properties, s },
+                        { NULL, }
+                };
+                return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
+        }
 
         if (reply) {
                 if (!dbus_connection_send(c, reply, NULL))
index 9caed55..995b672 100644 (file)
@@ -87,42 +87,47 @@ const char bus_socket_invalidating_properties[] =
 
 static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_bind_ipv6_only, socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
 
+static const BusProperty bus_socket_properties[] = {
+        { "BindIPv6Only",   bus_socket_append_bind_ipv6_only,  "s", offsetof(Socket, bind_ipv6_only)  },
+        { "Backlog",        bus_property_append_unsigned,      "u", offsetof(Socket, backlog)         },
+        { "TimeoutUSec",    bus_property_append_usec,          "t", offsetof(Socket, timeout_usec)    },
+        BUS_EXEC_COMMAND_PROPERTY("ExecStartPre",  offsetof(Socket, exec_command[SOCKET_EXEC_START_PRE]),  true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecStartPost", offsetof(Socket, exec_command[SOCKET_EXEC_START_POST]), true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecStopPre",   offsetof(Socket, exec_command[SOCKET_EXEC_STOP_PRE]),   true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecStopPost",  offsetof(Socket, exec_command[SOCKET_EXEC_STOP_POST]),  true ),
+        { "ControlPID",     bus_property_append_pid,           "u", offsetof(Socket, control_pid)     },
+        { "BindToDevice",   bus_property_append_string,        "s", offsetof(Socket, bind_to_device), true },
+        { "DirectoryMode",  bus_property_append_mode,          "u", offsetof(Socket, directory_mode)  },
+        { "SocketMode",     bus_property_append_mode,          "u", offsetof(Socket, socket_mode)     },
+        { "Accept",         bus_property_append_bool,          "b", offsetof(Socket, accept)          },
+        { "KeepAlive",      bus_property_append_bool,          "b", offsetof(Socket, keep_alive)      },
+        { "Priority",       bus_property_append_int,           "i", offsetof(Socket, priority)        },
+        { "ReceiveBuffer",  bus_property_append_size,          "t", offsetof(Socket, receive_buffer)  },
+        { "SendBuffer",     bus_property_append_size,          "t", offsetof(Socket, send_buffer)     },
+        { "IPTOS",          bus_property_append_int,           "i", offsetof(Socket, ip_tos)          },
+        { "IPTTL",          bus_property_append_int,           "i", offsetof(Socket, ip_ttl)          },
+        { "PipeSize",       bus_property_append_size,          "t", offsetof(Socket, pipe_size)       },
+        { "FreeBind",       bus_property_append_bool,          "b", offsetof(Socket, free_bind)       },
+        { "Transparent",    bus_property_append_bool,          "b", offsetof(Socket, transparent)     },
+        { "Broadcast",      bus_property_append_bool,          "b", offsetof(Socket, broadcast)       },
+        { "PassCredentials",bus_property_append_bool,          "b", offsetof(Socket, pass_cred)       },
+        { "Mark",           bus_property_append_int,           "i", offsetof(Socket, mark)            },
+        { "MaxConnections", bus_property_append_unsigned,      "u", offsetof(Socket, max_connections) },
+        { "NConnections",   bus_property_append_unsigned,      "u", offsetof(Socket, n_connections)   },
+        { "NAccepted",      bus_property_append_unsigned,      "u", offsetof(Socket, n_accepted)      },
+        { "MessageQueueMaxMessages", bus_property_append_long, "x", offsetof(Socket, mq_maxmsg)       },
+        { "MessageQueueMessageSize", bus_property_append_long, "x", offsetof(Socket, mq_msgsize)      },
+        { NULL, }
+};
+
 DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
         Socket *s = SOCKET(u);
-        const BusProperty properties[] = {
-                BUS_UNIT_PROPERTIES,
-                { "org.freedesktop.systemd1.Socket", "BindIPv6Only",   bus_socket_append_bind_ipv6_only, "s", &s->bind_ipv6_only  },
-                { "org.freedesktop.systemd1.Socket", "Backlog",        bus_property_append_unsigned,     "u", &s->backlog         },
-                { "org.freedesktop.systemd1.Socket", "TimeoutUSec",    bus_property_append_usec,         "t", &s->timeout_usec    },
-                BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Socket", s->exec_command[SOCKET_EXEC_START_PRE],  "ExecStartPre"),
-                BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Socket", s->exec_command[SOCKET_EXEC_START_POST], "ExecStartPost"),
-                BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Socket", s->exec_command[SOCKET_EXEC_STOP_PRE],   "ExecStopPre"),
-                BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Socket", s->exec_command[SOCKET_EXEC_STOP_POST],  "ExecStopPost"),
-                BUS_EXEC_CONTEXT_PROPERTIES("org.freedesktop.systemd1.Socket", s->exec_context),
-                { "org.freedesktop.systemd1.Socket", "ControlPID",     bus_property_append_pid,          "u", &s->control_pid     },
-                { "org.freedesktop.systemd1.Socket", "BindToDevice",   bus_property_append_string,       "s", s->bind_to_device   },
-                { "org.freedesktop.systemd1.Socket", "DirectoryMode",  bus_property_append_mode,         "u", &s->directory_mode  },
-                { "org.freedesktop.systemd1.Socket", "SocketMode",     bus_property_append_mode,         "u", &s->socket_mode     },
-                { "org.freedesktop.systemd1.Socket", "Accept",         bus_property_append_bool,         "b", &s->accept          },
-                { "org.freedesktop.systemd1.Socket", "KeepAlive",      bus_property_append_bool,         "b", &s->keep_alive      },
-                { "org.freedesktop.systemd1.Socket", "Priority",       bus_property_append_int,          "i", &s->priority        },
-                { "org.freedesktop.systemd1.Socket", "ReceiveBuffer",  bus_property_append_size,         "t", &s->receive_buffer  },
-                { "org.freedesktop.systemd1.Socket", "SendBuffer",     bus_property_append_size,         "t", &s->send_buffer     },
-                { "org.freedesktop.systemd1.Socket", "IPTOS",          bus_property_append_int,          "i", &s->ip_tos          },
-                { "org.freedesktop.systemd1.Socket", "IPTTL",          bus_property_append_int,          "i", &s->ip_ttl          },
-                { "org.freedesktop.systemd1.Socket", "PipeSize",       bus_property_append_size,         "t", &s->pipe_size       },
-                { "org.freedesktop.systemd1.Socket", "FreeBind",       bus_property_append_bool,         "b", &s->free_bind       },
-                { "org.freedesktop.systemd1.Socket", "Transparent",    bus_property_append_bool,         "b", &s->transparent     },
-                { "org.freedesktop.systemd1.Socket", "Broadcast",      bus_property_append_bool,         "b", &s->broadcast       },
-                { "org.freedesktop.systemd1.Socket", "PassCredentials",bus_property_append_bool,         "b", &s->pass_cred       },
-                { "org.freedesktop.systemd1.Socket", "Mark",           bus_property_append_int,          "i", &s->mark            },
-                { "org.freedesktop.systemd1.Socket", "MaxConnections", bus_property_append_unsigned,     "u", &s->max_connections },
-                { "org.freedesktop.systemd1.Socket", "NConnections",   bus_property_append_unsigned,     "u", &s->n_connections   },
-                { "org.freedesktop.systemd1.Socket", "NAccepted",      bus_property_append_unsigned,     "u", &s->n_accepted      },
-                { "org.freedesktop.systemd1.Socket", "MessageQueueMaxMessages", bus_property_append_long,"x", &s->mq_maxmsg       },
-                { "org.freedesktop.systemd1.Socket", "MessageQueueMessageSize", bus_property_append_long,"x", &s->mq_msgsize      },
-                { NULL, NULL, NULL, NULL, NULL }
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit",   bus_unit_properties,         u },
+                { "org.freedesktop.systemd1.Socket", bus_socket_properties,       s },
+                { "org.freedesktop.systemd1.Socket", bus_exec_context_properties, &s->exec_context },
+                { NULL, }
         };
 
-        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, properties);
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
 }
index 3002581..5ed33b5 100644 (file)
@@ -84,18 +84,23 @@ static int bus_swap_append_priority(DBusMessageIter *i, const char *property, vo
         return 0;
 }
 
+static const BusProperty bus_swap_properties[] = {
+        { "What",       bus_property_append_string, "s", offsetof(Swap, what),  true },
+        { "Priority",   bus_swap_append_priority,   "i", 0 },
+        BUS_EXEC_COMMAND_PROPERTY("ExecActivate",   offsetof(Swap, exec_command[SWAP_EXEC_ACTIVATE]),   false),
+        BUS_EXEC_COMMAND_PROPERTY("ExecDeactivate", offsetof(Swap, exec_command[SWAP_EXEC_DEACTIVATE]), false),
+        { "ControlPID", bus_property_append_pid,    "u", offsetof(Swap, control_pid) },
+        { NULL, }
+};
+
 DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
         Swap *s = SWAP(u);
-        const BusProperty properties[] = {
-                BUS_UNIT_PROPERTIES,
-                { "org.freedesktop.systemd1.Swap", "What",       bus_property_append_string, "s", s->what         },
-                { "org.freedesktop.systemd1.Swap", "Priority",   bus_swap_append_priority,   "i", u               },
-                BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Swap", s->exec_command+SWAP_EXEC_ACTIVATE,   "ExecActivate"),
-                BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Swap", s->exec_command+SWAP_EXEC_DEACTIVATE, "ExecDeactivate"),
-                BUS_EXEC_CONTEXT_PROPERTIES("org.freedesktop.systemd1.Swap", s->exec_context),
-                { "org.freedesktop.systemd1.Swap", "ControlPID", bus_property_append_pid,    "u", &s->control_pid },
-                { NULL, NULL, NULL, NULL, NULL }
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit", bus_unit_properties,         u },
+                { "org.freedesktop.systemd1.Swap", bus_swap_properties,         s },
+                { "org.freedesktop.systemd1.Swap", bus_exec_context_properties, &s->exec_context },
+                { NULL, }
         };
 
-        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, properties);
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
 }
index 1e00f2d..55cf862 100644 (file)
 const char bus_target_interface[] _introspect_("Target") = BUS_TARGET_INTERFACE;
 
 DBusHandlerResult bus_target_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
-        const BusProperty properties[] = {
-                BUS_UNIT_PROPERTIES,
-                { NULL, NULL, NULL, NULL, NULL }
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit", bus_unit_properties, u },
+                { NULL, }
         };
 
-        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, properties);
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
 }
index 0c4b4f3..0988b3e 100644 (file)
@@ -113,15 +113,20 @@ static int bus_timer_append_unit(DBusMessageIter *i, const char *property, void
         return dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t) ? 0 : -ENOMEM;
 }
 
+static const BusProperty bus_timer_properties[] = {
+        { "Unit",           bus_timer_append_unit,        "s", 0 },
+        { "Timers",         bus_timer_append_timers, "a(stt)", 0 },
+        { "NextElapseUSec", bus_property_append_usec,     "t", offsetof(Timer, next_elapse) },
+        { NULL, }
+};
+
 DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
         Timer *t = TIMER(u);
-        const BusProperty properties[] = {
-                BUS_UNIT_PROPERTIES,
-                { "org.freedesktop.systemd1.Timer", "Unit",           bus_timer_append_unit,      "s",      u               },
-                { "org.freedesktop.systemd1.Timer", "Timers",         bus_timer_append_timers,    "a(stt)", u               },
-                { "org.freedesktop.systemd1.Timer", "NextElapseUSec", bus_property_append_usec,   "t",      &t->next_elapse },
-                { NULL, NULL, NULL, NULL, NULL }
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit",  bus_unit_properties,  u },
+                { "org.freedesktop.systemd1.Timer", bus_timer_properties, t },
+                { NULL, }
         };
 
-        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, properties);
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
 }
index dc5321e..9591c58 100644 (file)
 
 const char bus_unit_interface[] _introspect_("Unit") = BUS_UNIT_INTERFACE;
 
+const BusProperty bus_unit_properties[] = {
+        { "Id",                   bus_property_append_string,         "s", offsetof(Unit, id),                                         true },
+        { "Names",                bus_unit_append_names,             "as", 0 },
+        { "Following",            bus_unit_append_following,          "s", 0 },
+        { "Requires",             bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_REQUIRES]),                true },
+        { "RequiresOverridable",  bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_REQUIRES_OVERRIDABLE]),    true },
+        { "Requisite",            bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_REQUISITE]),               true },
+        { "RequisiteOverridable", bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_REQUISITE_OVERRIDABLE]),   true },
+        { "Wants",                bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_WANTS]),                   true },
+        { "BindTo",               bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_BIND_TO]),                 true },
+        { "RequiredBy",           bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY]),             true },
+        { "RequiredByOverridable",bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY_OVERRIDABLE]), true },
+        { "WantedBy",             bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_WANTED_BY]),               true },
+        { "BoundBy",              bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_BOUND_BY]),                true },
+        { "Conflicts",            bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_CONFLICTS]),               true },
+        { "ConflictedBy",         bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_CONFLICTED_BY]),           true },
+        { "Before",               bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_BEFORE]),                  true },
+        { "After",                bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_AFTER]),                   true },
+        { "OnFailure",            bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_ON_FAILURE]),              true },
+        { "Triggers",             bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_TRIGGERS]),                true },
+        { "TriggeredBy",          bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]),            true },
+        { "PropagateReloadTo",    bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_PROPAGATE_RELOAD_TO]),     true },
+        { "PropagateReloadFrom",  bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_PROPAGATE_RELOAD_FROM]),   true },
+        { "Description",          bus_unit_append_description,        "s", 0 },
+        { "LoadState",            bus_unit_append_load_state,         "s", offsetof(Unit, load_state)                         },
+        { "ActiveState",          bus_unit_append_active_state,       "s", 0 },
+        { "SubState",             bus_unit_append_sub_state,          "s", 0 },
+        { "FragmentPath",         bus_property_append_string,         "s", offsetof(Unit, fragment_path),                              true },
+        { "UnitFileState",        bus_unit_append_file_state,         "s", 0 },
+        { "InactiveExitTimestamp",bus_property_append_usec,           "t", offsetof(Unit, inactive_exit_timestamp.realtime)   },
+        { "InactiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.monotonic)  },
+        { "ActiveEnterTimestamp", bus_property_append_usec,           "t", offsetof(Unit, active_enter_timestamp.realtime)    },
+        { "ActiveEnterTimestampMonotonic", bus_property_append_usec,  "t", offsetof(Unit, active_enter_timestamp.monotonic)   },
+        { "ActiveExitTimestamp",  bus_property_append_usec,           "t", offsetof(Unit, active_exit_timestamp.realtime)     },
+        { "ActiveExitTimestampMonotonic",  bus_property_append_usec,  "t", offsetof(Unit, active_exit_timestamp.monotonic)    },
+        { "InactiveEnterTimestamp", bus_property_append_usec,         "t", offsetof(Unit, inactive_enter_timestamp.realtime)  },
+        { "InactiveEnterTimestampMonotonic",bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.monotonic) },
+        { "CanStart",             bus_unit_append_can_start,          "b", 0 },
+        { "CanStop",              bus_unit_append_can_stop,           "b", 0 },
+        { "CanReload",            bus_unit_append_can_reload,         "b", 0 },
+        { "CanIsolate",           bus_unit_append_can_isolate,        "b", 0 },
+        { "Job",                  bus_unit_append_job,             "(uo)", 0 },
+        { "StopWhenUnneeded",     bus_property_append_bool,           "b", offsetof(Unit, stop_when_unneeded)                 },
+        { "RefuseManualStart",    bus_property_append_bool,           "b", offsetof(Unit, refuse_manual_start)                },
+        { "RefuseManualStop",     bus_property_append_bool,           "b", offsetof(Unit, refuse_manual_stop)                 },
+        { "AllowIsolate",         bus_property_append_bool,           "b", offsetof(Unit, allow_isolate)                      },
+        { "DefaultDependencies",  bus_property_append_bool,           "b", offsetof(Unit, default_dependencies)               },
+        { "OnFailureIsolate",     bus_property_append_bool,           "b", offsetof(Unit, on_failure_isolate)                 },
+        { "IgnoreOnIsolate",      bus_property_append_bool,           "b", offsetof(Unit, ignore_on_isolate)                  },
+        { "IgnoreOnSnapshot",     bus_property_append_bool,           "b", offsetof(Unit, ignore_on_snapshot)                 },
+        { "DefaultControlGroup",  bus_unit_append_default_cgroup,     "s", 0 },
+        { "ControlGroup",         bus_unit_append_cgroups,           "as", 0 },
+        { "ControlGroupAttributes", bus_unit_append_cgroup_attrs,"a(sss)", 0 },
+        { "NeedDaemonReload",     bus_unit_append_need_daemon_reload, "b", 0 },
+        { "JobTimeoutUSec",       bus_property_append_usec,           "t", offsetof(Unit, job_timeout)                        },
+        { "ConditionTimestamp",   bus_property_append_usec,           "t", offsetof(Unit, condition_timestamp.realtime)       },
+        { "ConditionTimestampMonotonic", bus_property_append_usec,    "t", offsetof(Unit, condition_timestamp.monotonic)      },
+        { "ConditionResult",      bus_property_append_bool,           "b", offsetof(Unit, condition_result)                   },
+        { "LoadError",            bus_unit_append_load_error,      "(ss)", 0 },
+        { NULL, }
+};
+
 #define INVALIDATING_PROPERTIES                 \
         "LoadState\0"                           \
         "ActiveState\0"                         \
index 6476c8a..5ae9d0c 100644 (file)
@@ -25,6 +25,7 @@
 #include <dbus/dbus.h>
 
 #include "manager.h"
+#include "dbus-common.h"
 
 #define BUS_UNIT_INTERFACE \
         " <interface name=\"org.freedesktop.systemd1.Unit\">\n"         \
         BUS_GENERIC_INTERFACES_LIST             \
         "org.freedesktop.systemd1.Unit\0"
 
-#define BUS_UNIT_PROPERTIES \
-        { "org.freedesktop.systemd1.Unit", "Id",                   bus_property_append_string,     "s",    u->id                        }, \
-        { "org.freedesktop.systemd1.Unit", "Names",                bus_unit_append_names,          "as",   u                                 }, \
-        { "org.freedesktop.systemd1.Unit", "Following",            bus_unit_append_following,      "s",    u                                 }, \
-        { "org.freedesktop.systemd1.Unit", "Requires",             bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_REQUIRES] }, \
-        { "org.freedesktop.systemd1.Unit", "RequiresOverridable",  bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_REQUIRES_OVERRIDABLE] }, \
-        { "org.freedesktop.systemd1.Unit", "Requisite",            bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_REQUISITE] }, \
-        { "org.freedesktop.systemd1.Unit", "RequisiteOverridable", bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_REQUISITE_OVERRIDABLE] }, \
-        { "org.freedesktop.systemd1.Unit", "Wants",                bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_WANTS]  }, \
-        { "org.freedesktop.systemd1.Unit", "BindTo",               bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_BIND_TO]  }, \
-        { "org.freedesktop.systemd1.Unit", "RequiredBy",           bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_REQUIRED_BY] }, \
-        { "org.freedesktop.systemd1.Unit", "RequiredByOverridable",bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE] }, \
-        { "org.freedesktop.systemd1.Unit", "WantedBy",             bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_WANTED_BY] }, \
-        { "org.freedesktop.systemd1.Unit", "BoundBy",              bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_BOUND_BY]  }, \
-        { "org.freedesktop.systemd1.Unit", "Conflicts",            bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_CONFLICTS] }, \
-        { "org.freedesktop.systemd1.Unit", "ConflictedBy",         bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_CONFLICTED_BY] }, \
-        { "org.freedesktop.systemd1.Unit", "Before",               bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_BEFORE] }, \
-        { "org.freedesktop.systemd1.Unit", "After",                bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_AFTER]  }, \
-        { "org.freedesktop.systemd1.Unit", "OnFailure",            bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_ON_FAILURE] }, \
-        { "org.freedesktop.systemd1.Unit", "Triggers",             bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_TRIGGERS] }, \
-        { "org.freedesktop.systemd1.Unit", "TriggeredBy",          bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_TRIGGERED_BY] }, \
-        { "org.freedesktop.systemd1.Unit", "PropagateReloadTo",    bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_PROPAGATE_RELOAD_TO] }, \
-        { "org.freedesktop.systemd1.Unit", "PropagateReloadFrom",  bus_unit_append_dependencies,   "as",   u->dependencies[UNIT_PROPAGATE_RELOAD_FROM] }, \
-        { "org.freedesktop.systemd1.Unit", "Description",          bus_unit_append_description,    "s",    u                                 }, \
-        { "org.freedesktop.systemd1.Unit", "LoadState",            bus_unit_append_load_state,     "s",    &u->load_state               }, \
-        { "org.freedesktop.systemd1.Unit", "ActiveState",          bus_unit_append_active_state,   "s",    u                                 }, \
-        { "org.freedesktop.systemd1.Unit", "SubState",             bus_unit_append_sub_state,      "s",    u                                 }, \
-        { "org.freedesktop.systemd1.Unit", "FragmentPath",         bus_property_append_string,     "s",    u->fragment_path             }, \
-        { "org.freedesktop.systemd1.Unit", "UnitFileState",        bus_unit_append_file_state,     "s",    u                                 }, \
-        { "org.freedesktop.systemd1.Unit", "InactiveExitTimestamp",bus_property_append_usec,       "t",    &u->inactive_exit_timestamp.realtime }, \
-        { "org.freedesktop.systemd1.Unit", "InactiveExitTimestampMonotonic",bus_property_append_usec, "t", &u->inactive_exit_timestamp.monotonic }, \
-        { "org.freedesktop.systemd1.Unit", "ActiveEnterTimestamp", bus_property_append_usec,       "t",    &u->active_enter_timestamp.realtime }, \
-        { "org.freedesktop.systemd1.Unit", "ActiveEnterTimestampMonotonic", bus_property_append_usec, "t", &u->active_enter_timestamp.monotonic }, \
-        { "org.freedesktop.systemd1.Unit", "ActiveExitTimestamp",  bus_property_append_usec,       "t",    &u->active_exit_timestamp.realtime }, \
-        { "org.freedesktop.systemd1.Unit", "ActiveExitTimestampMonotonic",  bus_property_append_usec, "t", &u->active_exit_timestamp.monotonic }, \
-        { "org.freedesktop.systemd1.Unit", "InactiveEnterTimestamp",bus_property_append_usec,      "t",    &u->inactive_enter_timestamp.realtime }, \
-        { "org.freedesktop.systemd1.Unit", "InactiveEnterTimestampMonotonic",bus_property_append_usec,"t", &u->inactive_enter_timestamp.monotonic }, \
-        { "org.freedesktop.systemd1.Unit", "CanStart",             bus_unit_append_can_start,      "b",    u                                 }, \
-        { "org.freedesktop.systemd1.Unit", "CanStop",              bus_unit_append_can_stop,       "b",    u                                 }, \
-        { "org.freedesktop.systemd1.Unit", "CanReload",            bus_unit_append_can_reload,     "b",    u                                 }, \
-        { "org.freedesktop.systemd1.Unit", "CanIsolate",           bus_unit_append_can_isolate,    "b",    u                                 }, \
-        { "org.freedesktop.systemd1.Unit", "Job",                  bus_unit_append_job,            "(uo)", u                                 }, \
-        { "org.freedesktop.systemd1.Unit", "StopWhenUnneeded",     bus_property_append_bool,       "b",    &u->stop_when_unneeded       }, \
-        { "org.freedesktop.systemd1.Unit", "RefuseManualStart",    bus_property_append_bool,       "b",    &u->refuse_manual_start      }, \
-        { "org.freedesktop.systemd1.Unit", "RefuseManualStop",     bus_property_append_bool,       "b",    &u->refuse_manual_stop       }, \
-        { "org.freedesktop.systemd1.Unit", "AllowIsolate",         bus_property_append_bool,       "b",    &u->allow_isolate            }, \
-        { "org.freedesktop.systemd1.Unit", "DefaultDependencies",  bus_property_append_bool,       "b",    &u->default_dependencies     }, \
-        { "org.freedesktop.systemd1.Unit", "OnFailureIsolate",     bus_property_append_bool,       "b",    &u->on_failure_isolate       }, \
-        { "org.freedesktop.systemd1.Unit", "IgnoreOnIsolate",      bus_property_append_bool,       "b",    &u->ignore_on_isolate        }, \
-        { "org.freedesktop.systemd1.Unit", "IgnoreOnSnapshot",     bus_property_append_bool,       "b",    &u->ignore_on_snapshot       }, \
-        { "org.freedesktop.systemd1.Unit", "DefaultControlGroup",  bus_unit_append_default_cgroup, "s",    u                                 }, \
-        { "org.freedesktop.systemd1.Unit", "ControlGroup",         bus_unit_append_cgroups,        "as",   u                                 }, \
-        { "org.freedesktop.systemd1.Unit", "ControlGroupAttributes", bus_unit_append_cgroup_attrs, "a(sss)", u                               }, \
-        { "org.freedesktop.systemd1.Unit", "NeedDaemonReload",     bus_unit_append_need_daemon_reload, "b", u                                }, \
-        { "org.freedesktop.systemd1.Unit", "JobTimeoutUSec",       bus_property_append_usec,       "t",    &u->job_timeout              }, \
-        { "org.freedesktop.systemd1.Unit", "ConditionTimestamp",   bus_property_append_usec,       "t",    &u->condition_timestamp.realtime }, \
-        { "org.freedesktop.systemd1.Unit", "ConditionTimestampMonotonic", bus_property_append_usec,"t",    &u->condition_timestamp.monotonic }, \
-        { "org.freedesktop.systemd1.Unit", "ConditionResult",      bus_property_append_bool,       "b",    &u->condition_result         }, \
-        { "org.freedesktop.systemd1.Unit", "LoadError",            bus_unit_append_load_error,     "(ss)", u                                 }
+extern const BusProperty bus_unit_properties[];
 
 int bus_unit_append_names(DBusMessageIter *i, const char *property, void *data);
 int bus_unit_append_following(DBusMessageIter *i, const char *property, void *data);
index f3b2c94..1340c29 100644 (file)
@@ -280,18 +280,24 @@ static int bus_hostname_append_icon_name(DBusMessageIter *i, const char *propert
         return bus_property_append_string(i, property, (void*) name);
 }
 
+static const BusProperty bus_hostname_properties[] = {
+        { "Hostname",       bus_property_append_string,    "s", sizeof(data[0])*PROP_HOSTNAME,        true },
+        { "StaticHostname", bus_property_append_string,    "s", sizeof(data[0])*PROP_STATIC_HOSTNAME, true },
+        { "PrettyHostname", bus_property_append_string,    "s", sizeof(data[0])*PROP_PRETTY_HOSTNAME, true },
+        { "IconName",       bus_hostname_append_icon_name, "s", sizeof(data[0])*PROP_ICON_NAME,       true },
+        { NULL, }
+};
+
+static const BusBoundProperties bps[] = {
+        { "org.freedesktop.hostname1", bus_hostname_properties, data },
+        { NULL, }
+};
+
 static DBusHandlerResult hostname_message_handler(
                 DBusConnection *connection,
                 DBusMessage *message,
                 void *userdata) {
 
-        const BusProperty properties[] = {
-                { "org.freedesktop.hostname1", "Hostname",       bus_property_append_string,    "s", data[PROP_HOSTNAME]},
-                { "org.freedesktop.hostname1", "StaticHostname", bus_property_append_string,    "s", data[PROP_STATIC_HOSTNAME]},
-                { "org.freedesktop.hostname1", "PrettyHostname", bus_property_append_string,    "s", data[PROP_PRETTY_HOSTNAME]},
-                { "org.freedesktop.hostname1", "IconName",       bus_hostname_append_icon_name, "s", data[PROP_ICON_NAME]},
-                { NULL, NULL, NULL, NULL, NULL }
-        };
 
         DBusMessage *reply = NULL, *changed = NULL;
         DBusError error;
@@ -470,7 +476,7 @@ static DBusHandlerResult hostname_message_handler(
                 }
 
         } else
-                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, properties);
+                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
 
         if (!(reply = dbus_message_new_method_return(message)))
                 goto oom;
index c6b48de..d46d91e 100644 (file)
@@ -129,8 +129,12 @@ static char *data[_PROP_MAX] = {
         NULL
 };
 
-static char *x11_layout = NULL, *x11_model = NULL, *x11_variant = NULL, *x11_options = NULL;
-static char *vc_keymap = NULL, *vc_keymap_toggle = NULL;
+typedef struct State {
+        char *x11_layout, *x11_model, *x11_variant, *x11_options;
+        char *vc_keymap, *vc_keymap_toggle;
+} State;
+
+static State state;
 
 static usec_t remain_until = 0;
 
@@ -160,19 +164,19 @@ static void free_data_locale(void) {
 }
 
 static void free_data_x11(void) {
-        free(x11_layout);
-        free(x11_model);
-        free(x11_variant);
-        free(x11_options);
+        free(state.x11_layout);
+        free(state.x11_model);
+        free(state.x11_variant);
+        free(state.x11_options);
 
-        x11_layout = x11_model = x11_variant = x11_options = NULL;
+        state.x11_layout = state.x11_model = state.x11_variant = state.x11_options = NULL;
 }
 
 static void free_data_vconsole(void) {
-        free(vc_keymap);
-        free(vc_keymap_toggle);
+        free(state.vc_keymap);
+        free(state.vc_keymap_toggle);
 
-        vc_keymap = vc_keymap_toggle = NULL;
+        state.vc_keymap = state.vc_keymap_toggle = NULL;
 }
 
 static void simplify(void) {
@@ -248,8 +252,8 @@ static int read_data_vconsole(void) {
         free_data_vconsole();
 
         r = parse_env_file("/etc/vconsole.conf", NEWLINE,
-                           "KEYMAP",        &vc_keymap,
-                           "KEYMAP_TOGGLE", &vc_keymap_toggle,
+                           "KEYMAP",        &state.vc_keymap,
+                           "KEYMAP_TOGGLE", &state.vc_keymap_toggle,
                            NULL);
 
         if (r < 0 && r != -ENOENT)
@@ -306,20 +310,20 @@ static int read_data_x11(void) {
                         if (strv_length(a) == 3) {
 
                                 if (streq(a[1], "XkbLayout")) {
-                                        free(x11_layout);
-                                        x11_layout = a[2];
+                                        free(state.x11_layout);
+                                        state.x11_layout = a[2];
                                         a[2] = NULL;
                                 } else if (streq(a[1], "XkbModel")) {
-                                        free(x11_model);
-                                        x11_model = a[2];
+                                        free(state.x11_model);
+                                        state.x11_model = a[2];
                                         a[2] = NULL;
                                 } else if (streq(a[1], "XkbVariant")) {
-                                        free(x11_variant);
-                                        x11_variant = a[2];
+                                        free(state.x11_variant);
+                                        state.x11_variant = a[2];
                                         a[2] = NULL;
                                 } else if (streq(a[1], "XkbOptions")) {
-                                        free(x11_options);
-                                        x11_options = a[2];
+                                        free(state.x11_options);
+                                        state.x11_options = a[2];
                                         a[2] = NULL;
                                 }
                         }
@@ -505,12 +509,12 @@ static int write_data_vconsole(void) {
         if (r < 0 && r != -ENOENT)
                 return r;
 
-        if (isempty(vc_keymap))
+        if (isempty(state.vc_keymap))
                 l = strv_env_unset(l, "KEYMAP");
         else {
                 char *s, **u;
 
-                s = strappend("KEYMAP=", vc_keymap);
+                s = strappend("KEYMAP=", state.vc_keymap);
                 if (!s) {
                         strv_free(l);
                         return -ENOMEM;
@@ -526,12 +530,12 @@ static int write_data_vconsole(void) {
                 l = u;
         }
 
-        if (isempty(vc_keymap_toggle))
+        if (isempty(state.vc_keymap_toggle))
                 l = strv_env_unset(l, "KEYMAP_TOGGLE");
         else  {
                 char *s, **u;
 
-                s = strappend("KEYMAP_TOGGLE=", vc_keymap_toggle);
+                s = strappend("KEYMAP_TOGGLE=", state.vc_keymap_toggle);
                 if (!s) {
                         strv_free(l);
                         return -ENOMEM;
@@ -567,10 +571,10 @@ static int write_data_x11(void) {
         char *temp_path;
         int r;
 
-        if (isempty(x11_layout) &&
-            isempty(x11_model) &&
-            isempty(x11_variant) &&
-            isempty(x11_options)) {
+        if (isempty(state.x11_layout) &&
+            isempty(state.x11_model) &&
+            isempty(state.x11_variant) &&
+            isempty(state.x11_options)) {
 
 #ifdef TARGET_FEDORA
                 unlink("/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf");
@@ -600,17 +604,17 @@ static int write_data_x11(void) {
               "        Identifier \"system-keyboard\"\n"
               "        MatchIsKeyboard \"on\"\n", f);
 
-        if (!isempty(x11_layout))
-                fprintf(f, "        Option \"XkbLayout\" \"%s\"\n", x11_layout);
+        if (!isempty(state.x11_layout))
+                fprintf(f, "        Option \"XkbLayout\" \"%s\"\n", state.x11_layout);
 
-        if (!isempty(x11_model))
-                fprintf(f, "        Option \"XkbModel\" \"%s\"\n", x11_model);
+        if (!isempty(state.x11_model))
+                fprintf(f, "        Option \"XkbModel\" \"%s\"\n", state.x11_model);
 
-        if (!isempty(x11_variant))
-                fprintf(f, "        Option \"XkbVariant\" \"%s\"\n", x11_variant);
+        if (!isempty(state.x11_variant))
+                fprintf(f, "        Option \"XkbVariant\" \"%s\"\n", state.x11_variant);
 
-        if (!isempty(x11_options))
-                fprintf(f, "        Option \"XkbOptions\" \"%s\"\n", x11_options);
+        if (!isempty(state.x11_options))
+                fprintf(f, "        Option \"XkbOptions\" \"%s\"\n", state.x11_options);
 
         fputs("EndSection\n", f);
         fflush(f);
@@ -742,13 +746,13 @@ static int convert_vconsole_to_x11(DBusConnection *connection) {
 
         assert(connection);
 
-        if (isempty(vc_keymap)) {
+        if (isempty(state.vc_keymap)) {
 
                 modified =
-                        !isempty(x11_layout) ||
-                        !isempty(x11_model) ||
-                        !isempty(x11_variant) ||
-                        !isempty(x11_options);
+                        !isempty(state.x11_layout) ||
+                        !isempty(state.x11_model) ||
+                        !isempty(state.x11_variant) ||
+                        !isempty(state.x11_options);
 
                 free_data_x11();
         } else {
@@ -772,20 +776,20 @@ static int convert_vconsole_to_x11(DBusConnection *connection) {
                         if (r == 0)
                                 break;
 
-                        if (!streq(vc_keymap, a[0])) {
+                        if (!streq(state.vc_keymap, a[0])) {
                                 strv_free(a);
                                 continue;
                         }
 
-                        if (!streq_ptr(x11_layout, strnulldash(a[1])) ||
-                            !streq_ptr(x11_model, strnulldash(a[2])) ||
-                            !streq_ptr(x11_variant, strnulldash(a[3])) ||
-                            !streq_ptr(x11_options, strnulldash(a[4]))) {
+                        if (!streq_ptr(state.x11_layout, strnulldash(a[1])) ||
+                            !streq_ptr(state.x11_model, strnulldash(a[2])) ||
+                            !streq_ptr(state.x11_variant, strnulldash(a[3])) ||
+                            !streq_ptr(state.x11_options, strnulldash(a[4]))) {
 
-                                if (free_and_set(&x11_layout, strnulldash(a[1])) < 0 ||
-                                    free_and_set(&x11_model, strnulldash(a[2])) < 0 ||
-                                    free_and_set(&x11_variant, strnulldash(a[3])) < 0 ||
-                                    free_and_set(&x11_options, strnulldash(a[4])) < 0) {
+                                if (free_and_set(&state.x11_layout, strnulldash(a[1])) < 0 ||
+                                    free_and_set(&state.x11_model, strnulldash(a[2])) < 0 ||
+                                    free_and_set(&state.x11_variant, strnulldash(a[3])) < 0 ||
+                                    free_and_set(&state.x11_options, strnulldash(a[4])) < 0) {
                                         strv_free(a);
                                         fclose(f);
                                         return -ENOMEM;
@@ -836,11 +840,11 @@ static int convert_x11_to_vconsole(DBusConnection *connection) {
 
         assert(connection);
 
-        if (isempty(x11_layout)) {
+        if (isempty(state.x11_layout)) {
 
                 modified =
-                        !isempty(vc_keymap) ||
-                        !isempty(vc_keymap_toggle);
+                        !isempty(state.vc_keymap) ||
+                        !isempty(state.vc_keymap_toggle);
 
                 free_data_x11();
         } else {
@@ -868,13 +872,13 @@ static int convert_x11_to_vconsole(DBusConnection *connection) {
                                 break;
 
                         /* Determine how well matching this entry is */
-                        if (streq_ptr(x11_layout, a[1]))
+                        if (streq_ptr(state.x11_layout, a[1]))
                                 /* If we got an exact match, this is best */
                                 matching = 10;
                         else {
                                 size_t x;
 
-                                x = strcspn(x11_layout, ",");
+                                x = strcspn(state.x11_layout, ",");
 
                                 /* We have multiple X layouts, look
                                  * for an entry that matches our key
@@ -882,7 +886,7 @@ static int convert_x11_to_vconsole(DBusConnection *connection) {
                                  * layout stripped off. */
                                 if (x > 0 &&
                                     strlen(a[1]) == x &&
-                                    strncmp(x11_layout, a[1], x) == 0)
+                                    strncmp(state.x11_layout, a[1], x) == 0)
                                         matching = 5;
                                 else  {
                                         size_t w;
@@ -894,19 +898,19 @@ static int convert_x11_to_vconsole(DBusConnection *connection) {
                                         w = strcspn(a[1], ",");
 
                                         if (x > 0 && x == w &&
-                                            memcmp(x11_layout, a[1], x) == 0)
+                                            memcmp(state.x11_layout, a[1], x) == 0)
                                                 matching = 1;
                                 }
                         }
 
                         if (matching > 0 &&
-                            streq_ptr(x11_model, a[2])) {
+                            streq_ptr(state.x11_model, a[2])) {
                                 matching++;
 
-                                if (streq_ptr(x11_variant, a[3])) {
+                                if (streq_ptr(state.x11_variant, a[3])) {
                                         matching++;
 
-                                        if (streq_ptr(x11_options, a[4]))
+                                        if (streq_ptr(state.x11_options, a[4]))
                                                 matching++;
                                 }
                         }
@@ -931,12 +935,12 @@ static int convert_x11_to_vconsole(DBusConnection *connection) {
 
                 fclose(f);
 
-                if (!streq_ptr(vc_keymap, new_keymap)) {
-                        free(vc_keymap);
-                        vc_keymap = new_keymap;
+                if (!streq_ptr(state.vc_keymap, new_keymap)) {
+                        free(state.vc_keymap);
+                        state.vc_keymap = new_keymap;
 
-                        free(vc_keymap_toggle);
-                        vc_keymap_toggle = NULL;
+                        free(state.vc_keymap_toggle);
+                        state.vc_keymap_toggle = NULL;
 
                         modified = true;
                 } else
@@ -1001,22 +1005,27 @@ static int append_locale(DBusMessageIter *i, const char *property, void *userdat
         return r;
 }
 
+static const BusProperty bus_locale_properties[] = {
+        { "Locale",               append_locale,             "as", 0 },
+        { "X11Layout",            bus_property_append_string, "s", offsetof(State, x11_layout),       true },
+        { "X11Model",             bus_property_append_string, "s", offsetof(State, x11_model),        true },
+        { "X11Variant",           bus_property_append_string, "s", offsetof(State, x11_variant),      true },
+        { "X11Options",           bus_property_append_string, "s", offsetof(State, x11_options),      true },
+        { "VConsoleKeymap",       bus_property_append_string, "s", offsetof(State, vc_keymap),        true },
+        { "VConsoleKeymapToggle", bus_property_append_string, "s", offsetof(State, vc_keymap_toggle), true },
+        { NULL, }
+};
+
+static const BusBoundProperties bps[] = {
+        { "org.freedesktop.locale1", bus_locale_properties, &state },
+        { NULL, }
+};
+
 static DBusHandlerResult locale_message_handler(
                 DBusConnection *connection,
                 DBusMessage *message,
                 void *userdata) {
 
-        const BusProperty properties[] = {
-                { "org.freedesktop.locale1", "Locale",               append_locale,              "as", NULL                   },
-                { "org.freedesktop.locale1", "X11Layout",            bus_property_append_string, "s",  x11_layout             },
-                { "org.freedesktop.locale1", "X11Model",             bus_property_append_string, "s",  x11_model              },
-                { "org.freedesktop.locale1", "X11Variant",           bus_property_append_string, "s",  x11_variant            },
-                { "org.freedesktop.locale1", "X11Options",           bus_property_append_string, "s",  x11_options            },
-                { "org.freedesktop.locale1", "VConsoleKeymap",       bus_property_append_string, "s",  vc_keymap              },
-                { "org.freedesktop.locale1", "VConsoleKeymapToggle", bus_property_append_string, "s",  vc_keymap_toggle       },
-                { NULL, NULL, NULL, NULL, NULL }
-        };
-
         DBusMessage *reply = NULL, *changed = NULL;
         DBusError error;
         int r;
@@ -1169,15 +1178,15 @@ static DBusHandlerResult locale_message_handler(
                 if (isempty(keymap_toggle))
                         keymap_toggle = NULL;
 
-                if (!streq_ptr(keymap, vc_keymap) ||
-                    !streq_ptr(keymap_toggle, vc_keymap_toggle)) {
+                if (!streq_ptr(keymap, state.vc_keymap) ||
+                    !streq_ptr(keymap_toggle, state.vc_keymap_toggle)) {
 
                         r = verify_polkit(connection, message, "org.freedesktop.locale1.set-keyboard", interactive, &error);
                         if (r < 0)
                                 return bus_send_error_reply(connection, message, &error, r);
 
-                        if (free_and_set(&vc_keymap, keymap) < 0 ||
-                            free_and_set(&vc_keymap_toggle, keymap_toggle) < 0)
+                        if (free_and_set(&state.vc_keymap, keymap) < 0 ||
+                            free_and_set(&state.vc_keymap_toggle, keymap_toggle) < 0)
                                 goto oom;
 
                         r = write_data_vconsole();
@@ -1186,7 +1195,7 @@ static DBusHandlerResult locale_message_handler(
                                 return bus_send_error_reply(connection, message, NULL, r);
                         }
 
-                        log_info("Changed virtual console keymap to '%s'", strempty(vc_keymap));
+                        log_info("Changed virtual console keymap to '%s'", strempty(state.vc_keymap));
 
                         r = load_vconsole_keymap(connection, NULL);
                         if (r < 0)
@@ -1237,19 +1246,19 @@ static DBusHandlerResult locale_message_handler(
                 if (isempty(options))
                         options = NULL;
 
-                if (!streq_ptr(layout, x11_layout) ||
-                    !streq_ptr(model, x11_model) ||
-                    !streq_ptr(variant, x11_variant) ||
-                    !streq_ptr(options, x11_options)) {
+                if (!streq_ptr(layout, state.x11_layout) ||
+                    !streq_ptr(model, state.x11_model) ||
+                    !streq_ptr(variant, state.x11_variant) ||
+                    !streq_ptr(options, state.x11_options)) {
 
                         r = verify_polkit(connection, message, "org.freedesktop.locale1.set-keyboard", interactive, &error);
                         if (r < 0)
                                 return bus_send_error_reply(connection, message, &error, r);
 
-                        if (free_and_set(&x11_layout, layout) < 0 ||
-                            free_and_set(&x11_model, model) < 0 ||
-                            free_and_set(&x11_variant, variant) < 0 ||
-                            free_and_set(&x11_options, options) < 0)
+                        if (free_and_set(&state.x11_layout, layout) < 0 ||
+                            free_and_set(&state.x11_model, model) < 0 ||
+                            free_and_set(&state.x11_variant, variant) < 0 ||
+                            free_and_set(&state.x11_options, options) < 0)
                                 goto oom;
 
                         r = write_data_x11();
@@ -1258,7 +1267,7 @@ static DBusHandlerResult locale_message_handler(
                                 return bus_send_error_reply(connection, message, NULL, r);
                         }
 
-                        log_info("Changed X11 keyboard layout to '%s'", strempty(x11_layout));
+                        log_info("Changed X11 keyboard layout to '%s'", strempty(state.x11_layout));
 
                         changed = bus_properties_changed_new(
                                         "/org/freedesktop/locale1",
@@ -1278,8 +1287,7 @@ static DBusHandlerResult locale_message_handler(
                         }
                 }
         } else
-                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, properties);
-
+                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
 
         if (!(reply = dbus_message_new_method_return(message)))
                 goto oom;
index efbc040..42dd54d 100644 (file)
@@ -706,6 +706,20 @@ static int flush_devices(Manager *m) {
         return trigger_device(m, NULL);
 }
 
+static const BusProperty bus_login_manager_properties[] = {
+        { "ControlGroupHierarchy",  bus_property_append_string,         "s",  offsetof(Manager, cgroup_path),        true },
+        { "Controllers",            bus_property_append_strv,           "as", offsetof(Manager, controllers),        true },
+        { "ResetControllers",       bus_property_append_strv,           "as", offsetof(Manager, reset_controllers),  true },
+        { "NAutoVTs",               bus_property_append_unsigned,       "u",  offsetof(Manager, n_autovts)           },
+        { "KillOnlyUsers",          bus_property_append_strv,           "as", offsetof(Manager, kill_only_users),    true },
+        { "KillExcludeUsers",       bus_property_append_strv,           "as", offsetof(Manager, kill_exclude_users), true },
+        { "KillUserProcesses",      bus_property_append_bool,           "b",  offsetof(Manager, kill_user_processes) },
+        { "IdleHint",               bus_manager_append_idle_hint,       "b",  0 },
+        { "IdleSinceHint",          bus_manager_append_idle_hint_since, "t",  0 },
+        { "IdleSinceHintMonotonic", bus_manager_append_idle_hint_since, "t",  0 },
+        { NULL, }
+};
+
 static DBusHandlerResult manager_message_handler(
                 DBusConnection *connection,
                 DBusMessage *message,
@@ -713,20 +727,6 @@ static DBusHandlerResult manager_message_handler(
 
         Manager *m = userdata;
 
-        const BusProperty properties[] = {
-                { "org.freedesktop.login1.Manager", "ControlGroupHierarchy",  bus_property_append_string,   "s",  m->cgroup_path          },
-                { "org.freedesktop.login1.Manager", "Controllers",            bus_property_append_strv,     "as", m->controllers          },
-                { "org.freedesktop.login1.Manager", "ResetControllers",       bus_property_append_strv,     "as", m->reset_controllers    },
-                { "org.freedesktop.login1.Manager", "NAutoVTs",               bus_property_append_unsigned, "u",  &m->n_autovts           },
-                { "org.freedesktop.login1.Manager", "KillOnlyUsers",          bus_property_append_strv,     "as", m->kill_only_users      },
-                { "org.freedesktop.login1.Manager", "KillExcludeUsers",       bus_property_append_strv,     "as", m->kill_exclude_users   },
-                { "org.freedesktop.login1.Manager", "KillUserProcesses",      bus_property_append_bool,     "b",  &m->kill_user_processes },
-                { "org.freedesktop.login1.Manager", "IdleHint",               bus_manager_append_idle_hint, "b",  m                       },
-                { "org.freedesktop.login1.Manager", "IdleSinceHint",          bus_manager_append_idle_hint_since, "t", m                  },
-                { "org.freedesktop.login1.Manager", "IdleSinceHintMonotonic", bus_manager_append_idle_hint_since, "t", m                  },
-                { NULL, NULL, NULL, NULL, NULL }
-        };
-
         DBusError error;
         DBusMessage *reply = NULL;
         int r;
@@ -1426,8 +1426,13 @@ static DBusHandlerResult manager_message_handler(
                 }
 
                 free(introspection);
-        } else
-                return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, properties);
+        } else {
+                const BusBoundProperties bps[] = {
+                        { "org.freedesktop.login1.Manager", bus_login_manager_properties, m },
+                        { NULL, }
+                };
+                return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, bps);
+        }
 
         if (reply) {
                 if (!dbus_connection_send(connection, reply, NULL))
index a15689b..95ef5ff 100644 (file)
@@ -207,22 +207,22 @@ static int get_seat_for_path(Manager *m, const char *path, Seat **_s) {
         return 0;
 }
 
+static const BusProperty bus_login_seat_properties[] = {
+        { "Id",                     bus_property_append_string,      "s", offsetof(Seat, id), true },
+        { "ActiveSession",          bus_seat_append_active,       "(so)", 0 },
+        { "CanMultiSession",        bus_seat_append_multi_session,   "b", 0 },
+        { "Sessions",               bus_seat_append_sessions,    "a(so)", 0 },
+        { "IdleHint",               bus_seat_append_idle_hint,       "b", 0 },
+        { "IdleSinceHint",          bus_seat_append_idle_hint_since, "t", 0 },
+        { "IdleSinceHintMonotonic", bus_seat_append_idle_hint_since, "t", 0 },
+        { NULL, }
+};
+
 static DBusHandlerResult seat_message_dispatch(
                 Seat *s,
                 DBusConnection *connection,
                 DBusMessage *message) {
 
-        const BusProperty properties[] = {
-                { "org.freedesktop.login1.Seat", "Id",                     bus_property_append_string,      "s",     s->id },
-                { "org.freedesktop.login1.Seat", "ActiveSession",          bus_seat_append_active,          "(so)",  s     },
-                { "org.freedesktop.login1.Seat", "CanMultiSession",        bus_seat_append_multi_session,   "b",     s     },
-                { "org.freedesktop.login1.Seat", "Sessions",               bus_seat_append_sessions,        "a(so)", s     },
-                { "org.freedesktop.login1.Seat", "IdleHint",               bus_seat_append_idle_hint,       "b",     s     },
-                { "org.freedesktop.login1.Seat", "IdleSinceHint",          bus_seat_append_idle_hint_since, "t",     s     },
-                { "org.freedesktop.login1.Seat", "IdleSinceHintMonotonic", bus_seat_append_idle_hint_since, "t",     s     },
-                { NULL, NULL, NULL, NULL, NULL }
-        };
-
         DBusError error;
         DBusMessage *reply = NULL;
         int r;
@@ -265,8 +265,13 @@ static DBusHandlerResult seat_message_dispatch(
                 reply = dbus_message_new_method_return(message);
                 if (!reply)
                         goto oom;
-        } else
-                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, properties);
+        } else {
+                const BusBoundProperties bps[] = {
+                        { "org.freedesktop.login1.Seat", bus_login_seat_properties, s },
+                        { NULL, }
+                };
+                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
+        }
 
         if (reply) {
                 if (!dbus_connection_send(connection, reply, NULL))
index cbd6d7f..dabb91c 100644 (file)
@@ -119,21 +119,21 @@ static int bus_session_append_seat(DBusMessageIter *i, const char *property, voi
 
 static int bus_session_append_user(DBusMessageIter *i, const char *property, void *data) {
         DBusMessageIter sub;
-        Session *s = data;
+        User *u = data;
         char *p = NULL;
 
         assert(i);
         assert(property);
-        assert(s);
+        assert(u);
 
         if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub))
                 return -ENOMEM;
 
-        p = user_bus_path(s->user);
+        p = user_bus_path(u);
         if (!p)
                 return -ENOMEM;
 
-        if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &s->user->uid) ||
+        if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &u->uid) ||
             !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) {
                 free(p);
                 return -ENOMEM;
@@ -222,39 +222,42 @@ static int get_session_for_path(Manager *m, const char *path, Session **_s) {
         return 0;
 }
 
+static const BusProperty bus_login_session_properties[] = {
+        { "Id",                     bus_property_append_string,         "s", offsetof(Session, id),                 true },
+        { "Timestamp",              bus_property_append_usec,           "t", offsetof(Session, timestamp.realtime)  },
+        { "TimestampMonotonic",     bus_property_append_usec,           "t", offsetof(Session, timestamp.monotonic) },
+        { "ControlGroupPath",       bus_property_append_string,         "s", offsetof(Session, cgroup_path),        true },
+        { "VTNr",                   bus_property_append_uint32,         "u", offsetof(Session, vtnr)                },
+        { "Seat",                   bus_session_append_seat,         "(so)", 0 },
+        { "TTY",                    bus_property_append_string,         "s", offsetof(Session, tty),                true },
+        { "Display",                bus_property_append_string,         "s", offsetof(Session, display),            true },
+        { "Remote",                 bus_property_append_bool,           "b", offsetof(Session, remote)              },
+        { "RemoteUser",             bus_property_append_string,         "s", offsetof(Session, remote_user),        true },
+        { "RemoteHost",             bus_property_append_string,         "s", offsetof(Session, remote_host),        true },
+        { "Service",                bus_property_append_string,         "s", offsetof(Session, service),            true },
+        { "Leader",                 bus_property_append_pid,            "u", offsetof(Session, leader)              },
+        { "Audit",                  bus_property_append_uint32,         "u", offsetof(Session, audit_id)            },
+        { "Type",                   bus_session_append_type,            "s", offsetof(Session, type)                },
+        { "Active",                 bus_session_append_active,          "b", 0 },
+        { "Controllers",            bus_property_append_strv,          "as", offsetof(Session, controllers),        true },
+        { "ResetControllers",       bus_property_append_strv,          "as", offsetof(Session, reset_controllers),  true },
+        { "KillProcesses",          bus_property_append_bool,           "b", offsetof(Session, kill_processes)      },
+        { "IdleHint",               bus_session_append_idle_hint,       "b", 0 },
+        { "IdleSinceHint",          bus_session_append_idle_hint_since, "t", 0 },
+        { "IdleSinceHintMonotonic", bus_session_append_idle_hint_since, "t", 0 },
+        { NULL, }
+};
+
+static const BusProperty bus_login_session_user_properties[] = {
+        { "User",                   bus_session_append_user,         "(uo)", 0 },
+        { "Name",                   bus_property_append_string,         "s", offsetof(User, name),                  true },
+};
+
 static DBusHandlerResult session_message_dispatch(
                 Session *s,
                 DBusConnection *connection,
                 DBusMessage *message) {
 
-        const BusProperty properties[] = {
-                { "org.freedesktop.login1.Session", "Id",                 bus_property_append_string,   "s",    s->id                   },
-                { "org.freedesktop.login1.Session", "User",               bus_session_append_user,      "(uo)", s                       },
-                { "org.freedesktop.login1.Session", "Name",               bus_property_append_string,   "s",    s->user->name           },
-                { "org.freedesktop.login1.Session", "Timestamp",          bus_property_append_usec,     "t",    &s->timestamp.realtime  },
-                { "org.freedesktop.login1.Session", "TimestampMonotonic", bus_property_append_usec,     "t",    &s->timestamp.monotonic },
-                { "org.freedesktop.login1.Session", "ControlGroupPath",   bus_property_append_string,   "s",    s->cgroup_path          },
-                { "org.freedesktop.login1.Session", "VTNr",               bus_property_append_uint32,   "u",    &s->vtnr                },
-                { "org.freedesktop.login1.Session", "Seat",               bus_session_append_seat,      "(so)", s                       },
-                { "org.freedesktop.login1.Session", "TTY",                bus_property_append_string,   "s",    s->tty                  },
-                { "org.freedesktop.login1.Session", "Display",            bus_property_append_string,   "s",    s->display              },
-                { "org.freedesktop.login1.Session", "Remote",             bus_property_append_bool,     "b",    &s->remote              },
-                { "org.freedesktop.login1.Session", "RemoteUser",         bus_property_append_string,   "s",    s->remote_user          },
-                { "org.freedesktop.login1.Session", "RemoteHost",         bus_property_append_string,   "s",    s->remote_host          },
-                { "org.freedesktop.login1.Session", "Service",            bus_property_append_string,   "s",    s->service              },
-                { "org.freedesktop.login1.Session", "Leader",             bus_property_append_pid,      "u",    &s->leader              },
-                { "org.freedesktop.login1.Session", "Audit",              bus_property_append_uint32,   "u",    &s->audit_id            },
-                { "org.freedesktop.login1.Session", "Type",               bus_session_append_type,      "s",    &s->type                },
-                { "org.freedesktop.login1.Session", "Active",             bus_session_append_active,    "b",    s                       },
-                { "org.freedesktop.login1.Session", "Controllers",        bus_property_append_strv,     "as",   s->controllers          },
-                { "org.freedesktop.login1.Session", "ResetControllers",   bus_property_append_strv,     "as",   s->reset_controllers    },
-                { "org.freedesktop.login1.Session", "KillProcesses",      bus_property_append_bool,     "b",    &s->kill_processes      },
-                { "org.freedesktop.login1.Session", "IdleHint",           bus_session_append_idle_hint, "b",    s                       },
-                { "org.freedesktop.login1.Session", "IdleSinceHint",          bus_session_append_idle_hint_since, "t", s                },
-                { "org.freedesktop.login1.Session", "IdleSinceHintMonotonic", bus_session_append_idle_hint_since, "t", s                },
-                { NULL, NULL, NULL, NULL, NULL }
-        };
-
         DBusError error;
         DBusMessage *reply = NULL;
         int r;
@@ -351,8 +354,14 @@ static DBusHandlerResult session_message_dispatch(
                 if (!reply)
                         goto oom;
 
-        } else
-                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, properties);
+        } else {
+                const BusBoundProperties bps[] = {
+                        { "org.freedesktop.login1.Session", bus_login_session_properties,      s       },
+                        { "org.freedesktop.login1.Session", bus_login_session_user_properties, s->user },
+                        { NULL, }
+                };
+                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
+        }
 
         if (reply) {
                 if (!dbus_connection_send(connection, reply, NULL))
index 3673a28..a9d680f 100644 (file)
@@ -213,29 +213,29 @@ static int get_user_for_path(Manager *m, const char *path, User **_u) {
         return 0;
 }
 
+static const BusProperty bus_login_user_properties[] = {
+        { "UID",                    bus_property_append_uid,         "u", offsetof(User, uid)                 },
+        { "GID",                    bus_property_append_gid,         "u", offsetof(User, gid)                 },
+        { "Name",                   bus_property_append_string,      "s", offsetof(User, name),               true },
+        { "Timestamp",              bus_property_append_usec,        "t", offsetof(User, timestamp.realtime)  },
+        { "TimestampMonotonic",     bus_property_append_usec,        "t", offsetof(User, timestamp.monotonic) },
+        { "RuntimePath",            bus_property_append_string,      "s", offsetof(User, runtime_path),       true },
+        { "ControlGroupPath",       bus_property_append_string,      "s", offsetof(User, cgroup_path),        true },
+        { "Service",                bus_property_append_string,      "s", offsetof(User, service),            true },
+        { "Display",                bus_user_append_display,      "(so)", 0 },
+        { "State",                  bus_user_append_state,           "s", 0 },
+        { "Sessions",               bus_user_append_sessions,    "a(so)", 0 },
+        { "IdleHint",               bus_user_append_idle_hint,       "b", 0 },
+        { "IdleSinceHint",          bus_user_append_idle_hint_since, "t", 0 },
+        { "IdleSinceHintMonotonic", bus_user_append_idle_hint_since, "t", 0 },
+        { NULL, }
+};
+
 static DBusHandlerResult user_message_dispatch(
                 User *u,
                 DBusConnection *connection,
                 DBusMessage *message) {
 
-        const BusProperty properties[] = {
-                { "org.freedesktop.login1.User", "UID",                bus_property_append_uid,    "u",     &u->uid                 },
-                { "org.freedesktop.login1.User", "GID",                bus_property_append_gid,    "u",     &u->gid                 },
-                { "org.freedesktop.login1.User", "Name",               bus_property_append_string, "s",     u->name                 },
-                { "org.freedesktop.login1.User", "Timestamp",          bus_property_append_usec,   "t",     &u->timestamp.realtime  },
-                { "org.freedesktop.login1.User", "TimestampMonotonic", bus_property_append_usec,   "t",     &u->timestamp.monotonic },
-                { "org.freedesktop.login1.User", "RuntimePath",        bus_property_append_string, "s",     u->runtime_path         },
-                { "org.freedesktop.login1.User", "ControlGroupPath",   bus_property_append_string, "s",     u->cgroup_path          },
-                { "org.freedesktop.login1.User", "Service",            bus_property_append_string, "s",     u->service              },
-                { "org.freedesktop.login1.User", "Display",            bus_user_append_display,    "(so)",  u                       },
-                { "org.freedesktop.login1.User", "State",              bus_user_append_state,      "s",     u                       },
-                { "org.freedesktop.login1.User", "Sessions",           bus_user_append_sessions,   "a(so)", u                       },
-                { "org.freedesktop.login1.User", "IdleHint",           bus_user_append_idle_hint,  "b",     u                       },
-                { "org.freedesktop.login1.User", "IdleSinceHint",          bus_user_append_idle_hint_since, "t", u                  },
-                { "org.freedesktop.login1.User", "IdleSinceHintMonotonic", bus_user_append_idle_hint_since, "t", u                  },
-                { NULL, NULL, NULL, NULL, NULL }
-        };
-
         DBusError error;
         DBusMessage *reply = NULL;
         int r;
@@ -274,8 +274,14 @@ static DBusHandlerResult user_message_dispatch(
                 if (!reply)
                         goto oom;
 
-        } else
-                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, properties);
+        } else {
+                const BusBoundProperties bps[] = {
+                        { "org.freedesktop.login1.User", bus_login_user_properties, u },
+                        { NULL, }
+                };
+
+                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
+        }
 
         if (reply) {
                 if (!dbus_connection_send(connection, reply, NULL))
index 16f54b5..97306e9 100644 (file)
 
 const char timedate_interface[] _introspect_("timedate1") = INTERFACE;
 
-static char *zone = NULL;
-static bool local_rtc = false;
-static int use_ntp = -1;
+typedef struct TZ {
+        char *zone;
+        bool local_rtc;
+        int use_ntp;
+} TZ;
 
-static usec_t remain_until = 0;
+static TZ tz = {
+        .use_ntp = -1,
+};
+
+static usec_t remain_until;
 
 static void free_data(void) {
-        free(zone);
-        zone = NULL;
+        free(tz.zone);
+        tz.zone = NULL;
 
-        local_rtc = false;
+        tz.local_rtc = false;
 }
 
 static bool valid_timezone(const char *name) {
@@ -140,10 +146,10 @@ static void verify_timezone(void) {
         size_t l, q;
         int j, k;
 
-        if (!zone)
+        if (!tz.zone)
                 return;
 
-        p = strappend("/usr/share/zoneinfo/", zone);
+        p = strappend("/usr/share/zoneinfo/", tz.zone);
         if (!p) {
                 log_error("Out of memory");
                 return;
@@ -156,8 +162,8 @@ static void verify_timezone(void) {
 
         if (j < 0 || k < 0 || l != q || memcmp(a, b, l)) {
                 log_warning("/etc/localtime and /etc/timezone out of sync.");
-                free(zone);
-                zone = NULL;
+                free(tz.zone);
+                tz.zone = NULL;
         }
 
         free(a);
@@ -169,14 +175,14 @@ static int read_data(void) {
 
         free_data();
 
-        r = read_one_line_file("/etc/timezone", &zone);
+        r = read_one_line_file("/etc/timezone", &tz.zone);
         if (r < 0) {
                 if (r != -ENOENT)
                         log_warning("Failed to read /etc/timezone: %s", strerror(-r));
 
 #ifdef TARGET_FEDORA
                 r = parse_env_file("/etc/sysconfig/clock", NEWLINE,
-                                   "ZONE", &zone,
+                                   "ZONE", &tz.zone,
                                    NULL);
 
                 if (r < 0 && r != -ENOENT)
@@ -184,14 +190,14 @@ static int read_data(void) {
 #endif
         }
 
-        if (isempty(zone)) {
-                free(zone);
-                zone = NULL;
+        if (isempty(tz.zone)) {
+                free(tz.zone);
+                tz.zone = NULL;
         }
 
         verify_timezone();
 
-        local_rtc = hwclock_is_localtime() > 0;
+        tz.local_rtc = hwclock_is_localtime() > 0;
 
         return 0;
 }
@@ -200,7 +206,7 @@ static int write_data_timezone(void) {
         int r = 0;
         char *p;
 
-        if (!zone) {
+        if (!tz.zone) {
                 if (unlink("/etc/timezone") < 0 && errno != ENOENT)
                         r = -errno;
 
@@ -210,7 +216,7 @@ static int write_data_timezone(void) {
                 return r;
         }
 
-        p = strappend("/usr/share/zoneinfo/", zone);
+        p = strappend("/usr/share/zoneinfo/", tz.zone);
         if (!p) {
                 log_error("Out of memory");
                 return -ENOMEM;
@@ -222,7 +228,7 @@ static int write_data_timezone(void) {
         if (r < 0)
                 return r;
 
-        r = write_one_line_file_atomic("/etc/timezone", zone);
+        r = write_one_line_file_atomic("/etc/timezone", tz.zone);
         if (r < 0)
                 return r;
 
@@ -238,7 +244,7 @@ static int write_data_local_rtc(void) {
                 if (r != -ENOENT)
                         return r;
 
-                if (!local_rtc)
+                if (!tz.local_rtc)
                         return 0;
 
                 w = strdup(NULL_ADJTIME_LOCAL);
@@ -270,13 +276,13 @@ static int write_data_local_rtc(void) {
                 a = p - s;
                 b = strlen(e);
 
-                w = new(char, a + (local_rtc ? 5 : 3) + b + 1);
+                w = new(char, a + (tz.local_rtc ? 5 : 3) + b + 1);
                 if (!w) {
                         free(s);
                         return -ENOMEM;
                 }
 
-                *(char*) mempcpy(stpcpy(mempcpy(w, s, a), local_rtc ? "LOCAL" : "UTC"), e, b) = 0;
+                *(char*) mempcpy(stpcpy(mempcpy(w, s, a), tz.local_rtc ? "LOCAL" : "UTC"), e, b) = 0;
 
                 if (streq(w, NULL_ADJTIME_UTC)) {
                         free(w);
@@ -341,7 +347,7 @@ static int read_ntp(DBusConnection *bus) {
                 goto finish;
         }
 
-        use_ntp =
+        tz.use_ntp =
                 streq(s, "enabled") ||
                 streq(s, "enabled-runtime");
         r = 0;
@@ -370,7 +376,7 @@ static int start_ntp(DBusConnection *bus, DBusError *error) {
                         "org.freedesktop.systemd1",
                         "/org/freedesktop/systemd1",
                         "org.freedesktop.systemd1.Manager",
-                        use_ntp ? "StartUnit" : "StopUnit");
+                        tz.use_ntp ? "StartUnit" : "StopUnit");
         if (!m) {
                 log_error("Could not allocate message.");
                 r = -ENOMEM;
@@ -419,7 +425,7 @@ static int enable_ntp(DBusConnection *bus, DBusError *error) {
                         "org.freedesktop.systemd1",
                         "/org/freedesktop/systemd1",
                         "org.freedesktop.systemd1.Manager",
-                        use_ntp ? "EnableUnitFiles" : "DisableUnitFiles");
+                        tz.use_ntp ? "EnableUnitFiles" : "DisableUnitFiles");
 
         if (!m) {
                 log_error("Could not allocate message.");
@@ -441,7 +447,7 @@ static int enable_ntp(DBusConnection *bus, DBusError *error) {
                 goto finish;
         }
 
-        if (use_ntp) {
+        if (tz.use_ntp) {
                 /* send force bool */
                 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &t)) {
                         log_error("Failed to append force boolean.");
@@ -495,7 +501,7 @@ static int property_append_ntp(DBusMessageIter *i, const char *property, void *d
         assert(i);
         assert(property);
 
-        db = use_ntp > 0;
+        db = tz.use_ntp > 0;
 
         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &db))
                 return -ENOMEM;
@@ -503,18 +509,23 @@ static int property_append_ntp(DBusMessageIter *i, const char *property, void *d
         return 0;
 }
 
+static const BusProperty bus_timedate_properties[] = {
+        { "Timezone", bus_property_append_string, "s", offsetof(TZ, zone),     true },
+        { "LocalRTC", bus_property_append_bool,   "b", offsetof(TZ, local_rtc) },
+        { "NTP",      property_append_ntp,        "b", offsetof(TZ, use_ntp)   },
+        { NULL, }
+};
+
+static const BusBoundProperties bps[] = {
+        { "org.freedesktop.timedate1", bus_timedate_properties, &tz },
+        { NULL, }
+};
+
 static DBusHandlerResult timedate_message_handler(
                 DBusConnection *connection,
                 DBusMessage *message,
                 void *userdata) {
 
-        const BusProperty properties[] = {
-                { "org.freedesktop.timedate1", "Timezone", bus_property_append_string, "s", zone       },
-                { "org.freedesktop.timedate1", "LocalRTC", bus_property_append_bool,   "b", &local_rtc },
-                { "org.freedesktop.timedate1", "NTP",      property_append_ntp,        "b", NULL       },
-                { NULL, NULL, NULL, NULL, NULL }
-        };
-
         DBusMessage *reply = NULL, *changed = NULL;
         DBusError error;
         int r;
@@ -539,7 +550,7 @@ static DBusHandlerResult timedate_message_handler(
                 if (!valid_timezone(z))
                         return bus_send_error_reply(connection, message, NULL, -EINVAL);
 
-                if (!streq_ptr(z, zone)) {
+                if (!streq_ptr(z, tz.zone)) {
                         char *t;
 
                         r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-timezone", interactive, &error);
@@ -550,8 +561,8 @@ static DBusHandlerResult timedate_message_handler(
                         if (!t)
                                 goto oom;
 
-                        free(zone);
-                        zone = t;
+                        free(tz.zone);
+                        tz.zone = t;
 
                         /* 1. Write new configuration file */
                         r = write_data_timezone();
@@ -560,7 +571,7 @@ static DBusHandlerResult timedate_message_handler(
                                 return bus_send_error_reply(connection, message, NULL, r);
                         }
 
-                        if (local_rtc) {
+                        if (tz.local_rtc) {
                                 struct timespec ts;
                                 struct tm *tm;
 
@@ -573,7 +584,7 @@ static DBusHandlerResult timedate_message_handler(
                                 hwclock_set_time(tm);
                         }
 
-                        log_info("Changed timezone to '%s'.", zone);
+                        log_info("Changed timezone to '%s'.", tz.zone);
 
                         changed = bus_properties_changed_new(
                                         "/org/freedesktop/timedate1",
@@ -597,14 +608,14 @@ static DBusHandlerResult timedate_message_handler(
                                     DBUS_TYPE_INVALID))
                         return bus_send_error_reply(connection, message, &error, -EINVAL);
 
-                if (lrtc != local_rtc) {
+                if (lrtc != tz.local_rtc) {
                         struct timespec ts;
 
                         r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-local-rtc", interactive, &error);
                         if (r < 0)
                                 return bus_send_error_reply(connection, message, &error, r);
 
-                        local_rtc = lrtc;
+                        tz.local_rtc = lrtc;
 
                         /* 1. Write new configuration file */
                         r = write_data_local_rtc();
@@ -614,7 +625,7 @@ static DBusHandlerResult timedate_message_handler(
                         }
 
                         /* 2. Teach kernel new timezone */
-                        if (local_rtc)
+                        if (tz.local_rtc)
                                 hwclock_apply_localtime_delta(NULL);
                         else
                                 hwclock_reset_localtime_delta();
@@ -628,7 +639,7 @@ static DBusHandlerResult timedate_message_handler(
                                 /* Sync system clock from RTC; first,
                                  * initialize the timezone fields of
                                  * struct tm. */
-                                if (local_rtc)
+                                if (tz.local_rtc)
                                         tm = *localtime(&ts.tv_sec);
                                 else
                                         tm = *gmtime(&ts.tv_sec);
@@ -640,7 +651,7 @@ static DBusHandlerResult timedate_message_handler(
 
                                         /* And set the system clock
                                          * with this */
-                                        if (local_rtc)
+                                        if (tz.local_rtc)
                                                 ts.tv_sec = mktime(&tm);
                                         else
                                                 ts.tv_sec = timegm(&tm);
@@ -652,7 +663,7 @@ static DBusHandlerResult timedate_message_handler(
                                 struct tm *tm;
 
                                 /* Sync RTC from system clock */
-                                if (local_rtc)
+                                if (tz.local_rtc)
                                         tm = localtime(&ts.tv_sec);
                                 else
                                         tm = gmtime(&ts.tv_sec);
@@ -660,7 +671,7 @@ static DBusHandlerResult timedate_message_handler(
                                 hwclock_set_time(tm);
                         }
 
-                        log_info("RTC configured to %s time.", local_rtc ? "local" : "UTC");
+                        log_info("RTC configured to %s time.", tz.local_rtc ? "local" : "UTC");
 
                         changed = bus_properties_changed_new(
                                         "/org/freedesktop/timedate1",
@@ -707,7 +718,7 @@ static DBusHandlerResult timedate_message_handler(
                         }
 
                         /* Sync down to RTC */
-                        if (local_rtc)
+                        if (tz.local_rtc)
                                 tm = localtime(&ts.tv_sec);
                         else
                                 tm = gmtime(&ts.tv_sec);
@@ -728,13 +739,13 @@ static DBusHandlerResult timedate_message_handler(
                                     DBUS_TYPE_INVALID))
                         return bus_send_error_reply(connection, message, &error, -EINVAL);
 
-                if (ntp != !!use_ntp) {
+                if (ntp != !!tz.use_ntp) {
 
                         r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-ntp", interactive, &error);
                         if (r < 0)
                                 return bus_send_error_reply(connection, message, &error, r);
 
-                        use_ntp = !!ntp;
+                        tz.use_ntp = !!ntp;
 
                         r = enable_ntp(connection, &error);
                         if (r < 0)
@@ -744,7 +755,7 @@ static DBusHandlerResult timedate_message_handler(
                         if (r < 0)
                                 return bus_send_error_reply(connection, message, &error, r);
 
-                        log_info("Set NTP to %s", use_ntp ? "enabled" : "disabled");
+                        log_info("Set NTP to %s", tz.use_ntp ? "enabled" : "disabled");
 
                         changed = bus_properties_changed_new(
                                         "/org/freedesktop/timedate1",
@@ -755,7 +766,7 @@ static DBusHandlerResult timedate_message_handler(
                 }
 
         } else
-                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, properties);
+                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
 
         if (!(reply = dbus_message_new_method_return(message)))
                 goto oom;