]> code.delx.au - pulseaudio/blobdiff - src/modules/module-console-kit.c
Use pa_hashmap_remove_and_free() where appropriate
[pulseaudio] / src / modules / module-console-kit.c
index c8dbc256ba138ad8a8157f66a40b6f1617816116..0fed15f067fa997bf1f3be22c188edecd4732529 100644 (file)
@@ -1,5 +1,3 @@
-/* $Id$ */
-
 /***
     This file is part of PulseAudio.
 
 /***
     This file is part of PulseAudio.
 
@@ -7,7 +5,7 @@
 
     PulseAudio is free software; you can redistribute it and/or modify
     it under the terms of the GNU Lesser General Public License as published
 
     PulseAudio is free software; you can redistribute it and/or modify
     it under the terms of the GNU Lesser General Public License as published
-    by the Free Software Foundation; either version 2 of the License,
+    by the Free Software Foundation; either version 2.1 of the License,
     or (at your option) any later version.
 
     PulseAudio is distributed in the hope that it will be useful, but
     or (at your option) any later version.
 
     PulseAudio is distributed in the hope that it will be useful, but
 
 #include <stdio.h>
 #include <unistd.h>
 
 #include <stdio.h>
 #include <unistd.h>
-#include <string.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <sys/types.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <sys/types.h>
-#include <sys/stat.h>
 
 #include <pulse/xmalloc.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/timeval.h>
 
 
-#include <pulsecore/core-error.h>
 #include <pulsecore/module.h>
 #include <pulsecore/log.h>
 #include <pulsecore/hashmap.h>
 #include <pulsecore/idxset.h>
 #include <pulsecore/module.h>
 #include <pulsecore/log.h>
 #include <pulsecore/hashmap.h>
 #include <pulsecore/idxset.h>
-#include <pulsecore/core-util.h>
-#include <pulsecore/namereg.h>
-#include <pulsecore/core-scache.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/modargs.h>
+#include <pulsecore/dbus-shared.h>
 
 
-#include <hal/libhal.h>
-
-#include "dbus-util.h"
 #include "module-console-kit-symdef.h"
 
 PA_MODULE_AUTHOR("Lennart Poettering");
 PA_MODULE_DESCRIPTION("Create a client for each ConsoleKit session of this user");
 PA_MODULE_VERSION(PACKAGE_VERSION);
 #include "module-console-kit-symdef.h"
 
 PA_MODULE_AUTHOR("Lennart Poettering");
 PA_MODULE_DESCRIPTION("Create a client for each ConsoleKit session of this user");
 PA_MODULE_VERSION(PACKAGE_VERSION);
-PA_MODULE_LOAD_ONCE(TRUE);
+PA_MODULE_LOAD_ONCE(true);
 
 static const char* const valid_modargs[] = {
     NULL
 
 static const char* const valid_modargs[] = {
     NULL
@@ -67,19 +56,21 @@ struct session {
 };
 
 struct userdata {
 };
 
 struct userdata {
+    pa_module *module;
     pa_core *core;
     pa_dbus_connection *connection;
     pa_hashmap *sessions;
     pa_core *core;
     pa_dbus_connection *connection;
     pa_hashmap *sessions;
+    bool filter_added;
 };
 
 static void add_session(struct userdata *u, const char *id) {
     DBusError error;
     DBusMessage *m = NULL, *reply = NULL;
 };
 
 static void add_session(struct userdata *u, const char *id) {
     DBusError error;
     DBusMessage *m = NULL, *reply = NULL;
-    int32_t uid;
+    uint32_t uid;
     struct session *session;
     struct session *session;
-    char *t;
+    pa_client_new_data data;
 
 
-    dbus_error_init (&error);
+    dbus_error_init(&error);
 
     if (pa_hashmap_get(u->sessions, id)) {
         pa_log_warn("Duplicate session %s, ignoring.", id);
 
     if (pa_hashmap_get(u->sessions, id)) {
         pa_log_warn("Duplicate session %s, ignoring.", id);
@@ -96,10 +87,14 @@ static void add_session(struct userdata *u, const char *id) {
         goto fail;
     }
 
         goto fail;
     }
 
-    /* FIXME: Why is this in int32? and not an uint32? */
-    if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INVALID)) {
-        pa_log("Failed to parse GetUnixUser() result: %s: %s", error.name, error.message);
-        goto fail;
+    /* CK 0.3 this changed from int32 to uint32 */
+    if (!dbus_message_get_args(reply, &error, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INVALID)) {
+        dbus_error_free(&error);
+
+        if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INVALID)) {
+            pa_log("Failed to parse GetUnixUser() result: %s: %s", error.name, error.message);
+            goto fail;
+        }
     }
 
     /* We only care about our own sessions */
     }
 
     /* We only care about our own sessions */
@@ -109,11 +104,19 @@ static void add_session(struct userdata *u, const char *id) {
     session = pa_xnew(struct session, 1);
     session->id = pa_xstrdup(id);
 
     session = pa_xnew(struct session, 1);
     session->id = pa_xstrdup(id);
 
-    t = pa_sprintf_malloc("ConsoleKit Session %s", id);
-    session->client = pa_client_new(u->core, __FILE__, t);
-    pa_xfree(t);
-
-    pa_proplist_sets(session->client->proplist, "console-kit.session", id);
+    pa_client_new_data_init(&data);
+    data.module = u->module;
+    data.driver = __FILE__;
+    pa_proplist_setf(data.proplist, PA_PROP_APPLICATION_NAME, "ConsoleKit Session %s", id);
+    pa_proplist_sets(data.proplist, "console-kit.session", id);
+    session->client = pa_client_new(u->core, &data);
+    pa_client_new_data_done(&data);
+
+    if (!session->client) {
+        pa_xfree(session->id);
+        pa_xfree(session);
+        goto fail;
+    }
 
     pa_hashmap_put(u->sessions, session->id, session);
 
 
     pa_hashmap_put(u->sessions, session->id, session);
 
@@ -141,12 +144,10 @@ static void free_session(struct session *session) {
 }
 
 static void remove_session(struct userdata *u, const char *id) {
 }
 
 static void remove_session(struct userdata *u, const char *id) {
-    struct session *session;
-
-    if (!(session = pa_hashmap_remove(u->sessions, id)))
-        return;
+    pa_assert(u);
+    pa_assert(id);
 
 
-    free_session(session);
+    pa_hashmap_remove_and_free(u->sessions, id);
 }
 
 static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata) {
 }
 
 static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata) {
@@ -160,25 +161,30 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo
 
     dbus_error_init(&error);
 
 
     dbus_error_init(&error);
 
-    pa_log_debug("dbus: interface=%s, path=%s, member=%s\n",
-                 dbus_message_get_interface(message),
-                 dbus_message_get_path(message),
-                 dbus_message_get_member(message));
-
     if (dbus_message_is_signal(message, "org.freedesktop.ConsoleKit.Seat", "SessionAdded")) {
 
     if (dbus_message_is_signal(message, "org.freedesktop.ConsoleKit.Seat", "SessionAdded")) {
 
-        if (!dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID) || dbus_error_is_set(&error)) {
-            pa_log_error("Failed to parse SessionAdded message: %s: %s", error.name, error.message);
-            goto finish;
+        /* CK API changed to match spec in 0.3 */
+        if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
+            dbus_error_free(&error);
+
+            if (!dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) {
+                pa_log_error("Failed to parse SessionAdded message: %s: %s", error.name, error.message);
+                goto finish;
+            }
         }
 
         add_session(u, path);
 
     } else if (dbus_message_is_signal(message, "org.freedesktop.ConsoleKit.Seat", "SessionRemoved")) {
 
         }
 
         add_session(u, path);
 
     } else if (dbus_message_is_signal(message, "org.freedesktop.ConsoleKit.Seat", "SessionRemoved")) {
 
-        if (!dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID) || dbus_error_is_set(&error)) {
-            pa_log_error("Failed to parse SessionRemoved message: %s: %s", error.name, error.message);
-            goto finish;
+        /* CK API changed to match spec in 0.3 */
+        if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
+            dbus_error_free(&error);
+
+            if (!dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) {
+                pa_log_error("Failed to parse SessionRemoved message: %s: %s", error.name, error.message);
+                goto finish;
+            }
         }
 
         remove_session(u, path);
         }
 
         remove_session(u, path);
@@ -187,7 +193,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo
 finish:
     dbus_error_free(&error);
 
 finish:
     dbus_error_free(&error);
 
-    return DBUS_HANDLER_RESULT_HANDLED;
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
 static int get_session_list(struct userdata *u) {
 }
 
 static int get_session_list(struct userdata *u) {
@@ -267,6 +273,11 @@ int pa__init(pa_module*m) {
 
     dbus_error_init(&error);
 
 
     dbus_error_init(&error);
 
+    /* If systemd's logind service is running, we shouldn't watch ConsoleKit
+     * but login */
+    if (access("/run/systemd/seats/", F_OK) >= 0)
+        return 0;
+
     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
         pa_log("Failed to parse module arguments");
         goto fail;
     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
         pa_log("Failed to parse module arguments");
         goto fail;
@@ -281,18 +292,23 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
         goto fail;
     }
 
-    m->userdata = u = pa_xnew(struct userdata, 1);
+    m->userdata = u = pa_xnew0(struct userdata, 1);
     u->core = m->core;
     u->core = m->core;
+    u->module = m;
     u->connection = connection;
     u->connection = connection;
-    u->sessions = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    u->sessions = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) free_session);
 
     if (!dbus_connection_add_filter(pa_dbus_connection_get(connection), filter_cb, u, NULL)) {
         pa_log_error("Failed to add filter function");
         goto fail;
     }
 
 
     if (!dbus_connection_add_filter(pa_dbus_connection_get(connection), filter_cb, u, NULL)) {
         pa_log_error("Failed to add filter function");
         goto fail;
     }
 
-    dbus_bus_add_match(pa_dbus_connection_get(connection), "type='signal',sender='org.freedesktop.ConsoleKit', interface='org.freedesktop.ConsoleKit.Seat'", &error);
-    if (dbus_error_is_set(&error)) {
+    u->filter_added = true;
+
+    if (pa_dbus_add_matches(
+                pa_dbus_connection_get(connection), &error,
+                "type='signal',sender='org.freedesktop.ConsoleKit',interface='org.freedesktop.ConsoleKit.Seat',member='SessionAdded'",
+                "type='signal',sender='org.freedesktop.ConsoleKit',interface='org.freedesktop.ConsoleKit.Seat',member='SessionRemoved'", NULL) < 0) {
         pa_log_error("Unable to subscribe to ConsoleKit signals: %s: %s", error.name, error.message);
         goto fail;
     }
         pa_log_error("Unable to subscribe to ConsoleKit signals: %s: %s", error.name, error.message);
         goto fail;
     }
@@ -314,21 +330,28 @@ fail:
     return -1;
 }
 
     return -1;
 }
 
-
 void pa__done(pa_module *m) {
     struct userdata *u;
 void pa__done(pa_module *m) {
     struct userdata *u;
-    struct session *session;
 
     pa_assert(m);
 
     if (!(u = m->userdata))
         return;
 
 
     pa_assert(m);
 
     if (!(u = m->userdata))
         return;
 
-    while ((session = pa_hashmap_steal_first(u->sessions)))
-        free_session(session);
+    if (u->sessions)
+        pa_hashmap_free(u->sessions);
+
+    if (u->connection) {
+        pa_dbus_remove_matches(
+                pa_dbus_connection_get(u->connection),
+                "type='signal',sender='org.freedesktop.ConsoleKit',interface='org.freedesktop.ConsoleKit.Seat',member='SessionAdded'",
+                "type='signal',sender='org.freedesktop.ConsoleKit',interface='org.freedesktop.ConsoleKit.Seat',member='SessionRemoved'", NULL);
+
+        if (u->filter_added)
+            dbus_connection_remove_filter(pa_dbus_connection_get(u->connection), filter_cb, u);
 
 
-    if (u->connection)
         pa_dbus_connection_unref(u->connection);
         pa_dbus_connection_unref(u->connection);
+    }
 
     pa_xfree(u);
 }
 
     pa_xfree(u);
 }