*
* D-Bus helper library
*
- * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
void *iface_user_data;
};
-static void print_arguments(GString *gstr, const char *sig,
+static void print_arguments(GString *gstr, const GDBusArgInfo *args,
const char *direction)
{
- int i;
-
- for (i = 0; sig[i]; i++) {
- char type[32];
- int struct_level, dict_level;
- unsigned int len;
- gboolean complete;
-
- complete = FALSE;
- struct_level = dict_level = 0;
- memset(type, 0, sizeof(type));
-
- /* Gather enough data to have a single complete type */
- for (len = 0; len < (sizeof(type) - 1) && sig[i]; len++, i++) {
- switch (sig[i]){
- case '(':
- struct_level++;
- break;
- case ')':
- struct_level--;
- if (struct_level <= 0 && dict_level <= 0)
- complete = TRUE;
- break;
- case '{':
- dict_level++;
- break;
- case '}':
- dict_level--;
- if (struct_level <= 0 && dict_level <= 0)
- complete = TRUE;
- break;
- case 'a':
- break;
- default:
- if (struct_level <= 0 && dict_level <= 0)
- complete = TRUE;
- break;
- }
-
- type[len] = sig[i];
-
- if (complete)
- break;
- }
-
+ for (; args && args->name; args++) {
+ g_string_append_printf(gstr,
+ "\t\t\t<arg name=\"%s\" type=\"%s\"",
+ args->name, args->signature);
if (direction)
g_string_append_printf(gstr,
- "\t\t\t<arg type=\"%s\" direction=\"%s\"/>\n",
- type, direction);
+ " direction=\"%s\"/>\n", direction);
else
- g_string_append_printf(gstr,
- "\t\t\t<arg type=\"%s\"/>\n",
- type);
+ g_string_append_printf(gstr, "/>\n");
+
}
}
const GDBusSignalTable *signal;
for (method = iface->methods; method && method->name; method++) {
- if (!strlen(method->signature) && !strlen(method->reply))
+ if (!(method->in_args && method->in_args->name) &&
+ !(method->out_args && method->out_args->name))
g_string_append_printf(gstr, "\t\t<method name=\"%s\"/>\n",
method->name);
else {
g_string_append_printf(gstr, "\t\t<method name=\"%s\">\n",
method->name);
- print_arguments(gstr, method->signature, "in");
- print_arguments(gstr, method->reply, "out");
+ print_arguments(gstr, method->in_args, "in");
+ print_arguments(gstr, method->out_args, "out");
g_string_append_printf(gstr, "\t\t</method>\n");
}
}
for (signal = iface->signals; signal && signal->name; signal++) {
- if (!strlen(signal->signature))
+ if (!(signal->args && signal->args->name))
g_string_append_printf(gstr, "\t\t<signal name=\"%s\"/>\n",
signal->name);
else {
g_string_append_printf(gstr, "\t\t<signal name=\"%s\">\n",
signal->name);
- print_arguments(gstr, signal->signature, NULL);
+ print_arguments(gstr, signal->args, NULL);
g_string_append_printf(gstr, "\t\t</signal>\n");
}
}
gstr = g_string_new(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE);
- g_string_append_printf(gstr, "<node name=\"%s\">\n", path);
+ g_string_append_printf(gstr, "<node>\n");
for (list = data->interfaces; list; list = list->next) {
struct interface_data *iface = list->data;
return NULL;
}
- if (!data->introspect)
+ if (data->introspect == NULL)
generate_introspection_xml(connection, data,
dbus_message_get_path(message));
reply = dbus_message_new_method_return(message);
- if (!reply)
+ if (reply == NULL)
return NULL;
dbus_message_append_args(reply, DBUS_TYPE_STRING, &data->introspect,
for (list = pending_security; list; list = list->next) {
struct security_data *secdata = list->data;
- DBusHandlerResult result;
if (secdata->pending != pending)
continue;
pending_security = g_slist_remove(pending_security, secdata);
- result = process_message(connection, secdata->message,
+ process_message(connection, secdata->message,
secdata->method, secdata->iface_user_data);
dbus_message_unref(secdata->message);
va_end(args);
}
+int polkit_check_authorization(DBusConnection *conn,
+ const char *action, gboolean interaction,
+ void (*function) (dbus_bool_t authorized,
+ void *user_data),
+ void *user_data, int timeout);
+
+struct builtin_security_data {
+ DBusConnection *conn;
+ GDBusPendingReply pending;
+};
+
+static void builtin_security_result(dbus_bool_t authorized, void *user_data)
+{
+ struct builtin_security_data *data = user_data;
+
+ if (authorized == TRUE)
+ g_dbus_pending_success(data->conn, data->pending);
+ else
+ g_dbus_pending_error(data->conn, data->pending,
+ DBUS_ERROR_AUTH_FAILED, NULL);
+
+ g_free(data);
+}
+
+static void builtin_security_function(DBusConnection *conn,
+ const char *action,
+ gboolean interaction,
+ GDBusPendingReply pending)
+{
+ struct builtin_security_data *data;
+
+ data = g_new0(struct builtin_security_data, 1);
+ data->conn = conn;
+ data->pending = pending;
+
+ if (polkit_check_authorization(conn, action, interaction,
+ builtin_security_result, data, 30000) < 0)
+ g_dbus_pending_error(conn, pending, NULL, NULL);
+}
+
static gboolean check_privilege(DBusConnection *conn, DBusMessage *msg,
const GDBusMethodTable *method, void *iface_user_data)
{
else
interaction = FALSE;
- if (security->function)
+ if (!(security->flags & G_DBUS_SECURITY_FLAG_BUILTIN) &&
+ security->function)
security->function(conn, security->action,
interaction, secdata->pending);
+ else
+ builtin_security_function(conn, security->action,
+ interaction, secdata->pending);
return TRUE;
}
{
GSList *list;
- if (!name)
+ if (name == NULL)
return NULL;
for (list = interfaces; list; list = list->next) {
interface = dbus_message_get_interface(message);
iface = find_interface(data->interfaces, interface);
- if (!iface)
+ if (iface == NULL)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
for (method = iface->methods; method &&
parent_path = g_strdup(child_path);
slash = strrchr(parent_path, '/');
- if (!slash)
+ if (slash == NULL)
goto done;
if (slash == parent_path && parent_path[1] != '\0')
if (!strlen(parent_path))
goto done;
- if (!dbus_connection_get_object_path_data(conn, parent_path,
- (void *) &data)) {
- invalidate_parent_data(conn, parent_path);
+ if (dbus_connection_get_object_path_data(conn, parent_path,
+ (void *) &data) == FALSE) {
goto done;
}
- if (!data)
+ invalidate_parent_data(conn, parent_path);
+
+ if (data == NULL)
goto done;
g_free(data->introspect);
g_free(parent_path);
}
-static GDBusMethodTable introspect_methods[] = {
- { "Introspect", "", "s", introspect },
+static const GDBusMethodTable introspect_methods[] = {
+ { _GDBUS_METHOD("Introspect", "", "s", NULL,
+ GDBUS_ARGS({ "xml", "s" }), introspect) },
{ }
};
struct interface_data *iface;
iface = find_interface(data->interfaces, name);
- if (!iface)
+ if (iface == NULL)
return FALSE;
data->interfaces = g_slist_remove(data->interfaces, iface);
*args = NULL;
if (!dbus_connection_get_object_path_data(conn, path,
- (void *) &data) || !data) {
+ (void *) &data) || data == NULL) {
error("dbus_connection_emit_signal: path %s isn't registered",
path);
return FALSE;
}
iface = find_interface(data->interfaces, interface);
- if (!iface) {
+ if (iface == NULL) {
error("dbus_connection_emit_signal: %s does not implement %s",
path, interface);
return FALSE;
}
}
- if (!*args) {
+ if (*args == NULL) {
error("No signal named %s on interface %s", name, interface);
return FALSE;
}
return FALSE;
signal = dbus_message_new_signal(path, interface, name);
- if (!signal) {
+ if (signal == NULL) {
error("Unable to allocate new %s.%s signal", interface, name);
return FALSE;
}
{
struct generic_data *data = NULL;
- if (!path)
+ if (path == NULL)
return FALSE;
if (dbus_connection_get_object_path_data(connection, path,