static int status_property(const char *name, DBusMessageIter *iter, StatusInfo *i) { int r; assert(name); assert(iter); switch (dbus_message_iter_get_arg_type(iter)) { case DBUS_TYPE_STRING: { const char *s; dbus_message_iter_get_basic(iter, &s); if (!isempty(s)) { if (streq(name, "VConsoleKeymap")) i->vconsole_keymap = s; else if (streq(name, "VConsoleKeymapToggle")) i->vconsole_keymap_toggle = s; else if (streq(name, "X11Layout")) i->x11_layout = s; else if (streq(name, "X11Model")) i->x11_model = s; else if (streq(name, "X11Variant")) i->x11_variant = s; else if (streq(name, "X11Options")) i->x11_options = s; } break; } case DBUS_TYPE_ARRAY: if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING) { char **l; r = bus_parse_strv_iter(iter, &l); if (r < 0) return r; if (streq(name, "Locale")) { strv_free(i->locale); i->locale = l; l = NULL; } strv_free(l); } } return 0; }
static DBusHandlerResult locale_message_handler( DBusConnection *connection, DBusMessage *message, void *userdata) { DBusMessage *reply = NULL, *changed = NULL; DBusError error; int r; assert(connection); assert(message); dbus_error_init(&error); if (dbus_message_is_method_call(message, "org.freedesktop.locale1", "SetLocale")) { char **l = NULL, **i; dbus_bool_t interactive; DBusMessageIter iter; bool modified = false; bool passed[_PROP_MAX]; int p; if (!dbus_message_iter_init(message, &iter)) return bus_send_error_reply(connection, message, NULL, -EINVAL); r = bus_parse_strv_iter(&iter, &l); if (r < 0) { if (r == -ENOMEM) goto oom; return bus_send_error_reply(connection, message, NULL, r); } if (!dbus_message_iter_next(&iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN) { strv_free(l); return bus_send_error_reply(connection, message, NULL, -EINVAL); } dbus_message_iter_get_basic(&iter, &interactive); zero(passed); /* Check whether a variable changed and if so valid */ STRV_FOREACH(i, l) { bool valid = false; for (p = 0; p < _PROP_MAX; p++) { size_t k; k = strlen(names[p]); if (startswith(*i, names[p]) && (*i)[k] == '=') { valid = true; passed[p] = true; if (!streq_ptr(*i + k + 1, data[p])) modified = true; break; } } if (!valid) { strv_free(l); return bus_send_error_reply(connection, message, NULL, -EINVAL); } }