From de42489ef3cea5bd11d385ac9553e5f3b0518db9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Wed, 3 Apr 2019 23:14:30 +0200 Subject: [PATCH] pulse: replace dbus control with QubesDB + local socket Since pacat-simple-vchan not necessary run in dom0 anymore, it needs some better control mechanism than dbus, to be cross-domain compatible. Use QubesDB for notification of the audio-input state. But use local socket + qrexec service (coming in the next commit) for changing the state, as it gives immediate feedback if it was received by pacat-simple-vchan. QubesOS/qubes-issues#4547 --- Makefile | 2 - debian/control | 2 +- debian/qubes-gui-daemon-pulseaudio.install | 2 - pulse/Makefile | 14 +- pulse/org.qubesos.Audio.conf | 19 -- pulse/pacat-control-api.xml | 16 -- pulse/pacat-control-object.c | 220 --------------------- pulse/pacat-control-object.h | 49 ----- pulse/pacat-control-stub.h | 73 ------- pulse/pacat-simple-vchan.c | 164 ++++++++++++++- pulse/pacat-simple-vchan.h | 8 +- rpm_spec/gui-daemon.spec.in | 2 +- 12 files changed, 165 insertions(+), 406 deletions(-) delete mode 100644 pulse/org.qubesos.Audio.conf delete mode 100644 pulse/pacat-control-api.xml delete mode 100644 pulse/pacat-control-object.c delete mode 100644 pulse/pacat-control-object.h delete mode 100644 pulse/pacat-control-stub.h diff --git a/Makefile b/Makefile index cfc020d5..f453f4df 100644 --- a/Makefile +++ b/Makefile @@ -52,8 +52,6 @@ install: install -D gui-daemon/qubes-guid $(DESTDIR)/usr/bin/qubes-guid install -m 0644 -D gui-daemon/qubes-guid.1 $(DESTDIR)$(MANDIR)/man1/qubes-guid.1 install -D pulse/pacat-simple-vchan $(DESTDIR)/usr/bin/pacat-simple-vchan - install -D -m 0644 pulse/pacat-control-api.xml $(DESTDIR)/usr/share/dbus-1/interfaces/org.qubesos.Audio.xml - install -D -m 0644 pulse/org.qubesos.Audio.conf $(DESTDIR)/etc/dbus-1/system.d/org.qubesos.Audio.conf install -D shmoverride/X-wrapper-qubes $(DESTDIR)/usr/bin/X-wrapper-qubes install -D shmoverride/shmoverride.so $(DESTDIR)$(LIBDIR)/qubes-gui-daemon/shmoverride.so install -D -m 0644 gui-daemon/guid.conf $(DESTDIR)/etc/qubes/guid.conf diff --git a/debian/control b/debian/control index 69c02004..7fb4b4cd 100644 --- a/debian/control +++ b/debian/control @@ -16,7 +16,7 @@ Build-Depends: libconfig-dev, libpng-dev, libnotify-dev, - libdbus-glib-1-dev, + qubesdb-dev, help2man Standards-Version: 4.1.3 Homepage: https://qubes-os.org/ diff --git a/debian/qubes-gui-daemon-pulseaudio.install b/debian/qubes-gui-daemon-pulseaudio.install index 5b996298..5064a855 100644 --- a/debian/qubes-gui-daemon-pulseaudio.install +++ b/debian/qubes-gui-daemon-pulseaudio.install @@ -1,3 +1 @@ usr/bin/pacat-simple-vchan -usr/share/dbus-1/interfaces/org.qubesos.Audio.xml -etc/dbus-1/system.d/org.qubesos.Audio.conf diff --git a/pulse/Makefile b/pulse/Makefile index 340e8b30..29ca5a4e 100644 --- a/pulse/Makefile +++ b/pulse/Makefile @@ -2,19 +2,13 @@ CC=gcc CFLAGS=-Wall -Wextra -Werror -g -O2 VCHANLIBS=`pkg-config --libs vchan-$(BACKEND_VMM)` VCHANCFLAGS=`pkg-config --cflags vchan-$(BACKEND_VMM)` -GLIBCFLAGS=`pkg-config --cflags glib-2.0` `pkg-config --cflags dbus-glib-1` -GLIBLIBS=`pkg-config --libs glib-2.0` `pkg-config --libs dbus-glib-1` `pkg-config --libs gthread-2.0` +GLIBCFLAGS=`pkg-config --cflags glib-2.0` +GLIBLIBS=`pkg-config --libs glib-2.0` all: module-vchan-sink.so pacat-simple-vchan pacat-simple-vchan.o: pacat-simple-vchan.c $(CC) $(CFLAGS) -c $(VCHANCFLAGS) -I. $(GLIBCFLAGS) pacat-simple-vchan.c -pacat-control-object.o: pacat-control-object.c pacat-control-object.h pacat-control-stub.h - $(CC) $(CFLAGS) -c $(VCHANCFLAGS) -I. $(GLIBCFLAGS) $< -pacat-simple-vchan: pacat-simple-vchan.o pacat-control-object.o +pacat-simple-vchan: pacat-simple-vchan.o $(CC) -o pacat-simple-vchan $^ \ - $(VCHANLIBS) -lpulse -lpulse-mainloop-glib $(GLIBLIBS) -# Do not autogenerate because dbus-binding-tool from dbus-glib-0.86 (in chroot) -# produces output incompatible with dbus-glib-0.84 (in Qubes dom0). -#pacat-control-stub.h: pacat-control-api.xml -# dbus-binding-tool --mode=glib-server --prefix=pacat-control $< > $@ + $(VCHANLIBS) -lpulse -lpulse-mainloop-glib -lqubesdb $(GLIBLIBS) clean: rm -f *.so *.o pacat-simple-vchan *~ diff --git a/pulse/org.qubesos.Audio.conf b/pulse/org.qubesos.Audio.conf deleted file mode 100644 index 68db6f62..00000000 --- a/pulse/org.qubesos.Audio.conf +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/pulse/pacat-control-api.xml b/pulse/pacat-control-api.xml deleted file mode 100644 index 1c8046d3..00000000 --- a/pulse/pacat-control-api.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - diff --git a/pulse/pacat-control-object.c b/pulse/pacat-control-object.c deleted file mode 100644 index 4a838d9b..00000000 --- a/pulse/pacat-control-object.c +++ /dev/null @@ -1,220 +0,0 @@ -#include -#include -#include -#include -#include "pacat-control-object.h" - -#include "pacat-control-stub.h" - -/* Properties */ -enum -{ - PROP_0, - PROP_REC_ALLOWED -}; - -enum -{ - SIGNAL_REC_ALLOWED_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0, }; - -G_DEFINE_TYPE(PacatControl, pacat_control, G_TYPE_OBJECT) - -#define PACAT_CONTROL_TYPE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PACAT_CONTROL_TYPE, userdata)) - -static void pacat_control_finalize (GObject *object) -{ - //PacatControl *p = PACAT_CONTROL (object); - - (G_OBJECT_CLASS (pacat_control_parent_class)->finalize) (object); -} - -static void pacat_control_init (PacatControl *obj __attribute__((__unused__))) -{ -} - -static void pacat_control_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - PacatControl *p; - int rec_allowed; - - p = PACAT_CONTROL (object); - - switch (prop_id) - { - case PROP_REC_ALLOWED: - assert(p->u); - rec_allowed = g_value_get_boolean(value); - g_mutex_lock(&p->u->prop_mutex); - p->u->rec_allowed = rec_allowed; - pacat_log("Setting audio-input to %s", p->u->rec_allowed ? "enabled" : "disabled"); - if (p->u->rec_allowed && p->u->rec_requested) { - pacat_log("Recording start"); - pa_stream_cork(p->u->rec_stream, 0, NULL, NULL); - } else if (!p->u->rec_allowed && - (p->u->rec_requested || !pa_stream_is_corked(p->u->rec_stream))) { - pacat_log("Recording stop"); - pa_stream_cork(p->u->rec_stream, 1, NULL, NULL); - } - g_mutex_unlock(&p->u->prop_mutex); - /* notify about the change */ - g_signal_emit(object, signals[SIGNAL_REC_ALLOWED_CHANGED], 0, rec_allowed, p->u->name); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void pacat_control_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - PacatControl *p; - - p = PACAT_CONTROL (object); - - switch (prop_id) - { - case PROP_REC_ALLOWED: - assert(p->u); - g_value_set_boolean (value, p->u->rec_allowed); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void pacat_control_class_init (PacatControlClass *p_class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (p_class); - - dbus_g_object_type_install_info (PACAT_CONTROL_TYPE, - &dbus_glib_pacat_control_object_info); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* pointer to userdata struct */ - g_type_class_add_private(p_class, sizeof(void*)); -G_GNUC_END_IGNORE_DEPRECATIONS - - gobject_class->finalize = pacat_control_finalize; - gobject_class->set_property = pacat_control_set_property; - gobject_class->get_property = pacat_control_get_property; - - g_object_class_install_property(gobject_class, PROP_REC_ALLOWED, - g_param_spec_boolean("rec_allowed", "Allow use audio source", "Allow use audio source", FALSE, G_PARAM_READWRITE)); - - signals[SIGNAL_REC_ALLOWED_CHANGED] = - g_signal_new ("rec_allowed_changed", - G_OBJECT_CLASS_TYPE (p_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_STRING); - -} - -int dbus_init(struct userdata *u) { - DBusGProxy *busProxy = NULL; - GError *error = NULL; - char obj_path[1024]; - PacatControl *pc; - int result, ret; - -#if !GLIB_CHECK_VERSION(2,35,0) - g_type_init (); -#endif -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - g_thread_init (NULL); -#pragma GCC diagnostic pop - dbus_g_thread_init (); - error = NULL; - - if (!(u->dbus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error))) { - goto fail; - } - - busProxy = dbus_g_proxy_new_for_name(u->dbus, - DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); - if (busProxy == NULL) { - pacat_log("Failed to get a proxy for D-Bus"); - goto fail; - } - - /* Attempt to register the well-known name. - The RPC call requires two parameters: - - arg0: (D-Bus STRING): name to request - - arg1: (D-Bus UINT32): flags for registration. - (please see "org.freedesktop.DBus.RequestName" in - http://dbus.freedesktop.org/doc/dbus-specification.html) - Will return one uint32 giving the result of the RPC call. - We're interested in 1 (we're now the primary owner of the name) - or 4 (we were already the owner of the name) - - The function will return FALSE if it sets the GError. */ - if (snprintf(obj_path, sizeof(obj_path), "org.qubesos.Audio.%s", u->name) >= (int)sizeof(obj_path)) { - pacat_log("VM name too long"); - goto fail; - } - if (!dbus_g_proxy_call(busProxy, - "RequestName", - &error, - G_TYPE_STRING, obj_path, /* name */ - G_TYPE_UINT, 0, /* flags */ - G_TYPE_INVALID, /* end of input args */ - G_TYPE_UINT, &result, /* result */ - G_TYPE_INVALID)) { - pacat_log("D-Bus.RequestName RPC failed: %s", error->message); - g_error_free (error); - goto fail; - } - /* Check the result code of the registration RPC. */ - if (result != 1 && result != 4) { - pacat_log("Failed to get the primary well-known name."); - goto fail; - } - if (!(u->pacat_control = g_object_new (PACAT_CONTROL_TYPE, NULL))) { - pacat_log("failed to create pacat_control object"); - goto fail; - } - - pc = PACAT_CONTROL(u->pacat_control); - pc->u = u; - - dbus_g_connection_register_g_object (u->dbus, - "/org/qubesos/audio", u->pacat_control); - - ret = 0; - goto finish; - -fail: - - if (u->pacat_control) { - dbus_g_connection_unregister_g_object(u->dbus, u->pacat_control); - g_object_unref(u->pacat_control); - u->pacat_control = NULL; - } - - if (u->dbus) { - dbus_g_connection_unref(u->dbus); - } - - ret = -1; -finish: - if (busProxy) - g_object_unref (busProxy); - - return ret; -} - diff --git a/pulse/pacat-control-object.h b/pulse/pacat-control-object.h deleted file mode 100644 index eeff05d2..00000000 --- a/pulse/pacat-control-object.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef __PACAT_CONTROL_H__ -#define __PACAT_CONTROL_H__ - -#include -#include -#include "pacat-simple-vchan.h" - -typedef struct PacatControl PacatControl; -typedef struct PacatControlClass PacatControlClass; - -GType pacat_control_get_type (void); - -struct PacatControl -{ - GObject parent; - struct userdata *u; -}; - -struct PacatControlClass -{ - GObjectClass parent; -}; - -#define PACAT_CONTROL_TYPE (pacat_control_get_type ()) -#define PACAT_CONTROL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PACAT_CONTROL_TYPE, PacatControl)) -#define PACAT_CONTROL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PACAT_CONTROL_TYPE, PacatControlClass)) -#define IS_PACAT_CONTROL(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PACAT_CONTROL_TYPE)) -#define IS_PACAT_CONTROL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PACAT_CONTROL_TYPE)) -#define PACAT_CONTROL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PACAT_CONTROL_TYPE, PacatControlClass)) - -/* -typedef enum -{ - PACAT_CONTROL_ERROR_FOO, - PACAT_CONTROL_ERROR_BAR, - PACAT_CONTROL_ERROR_MULTI_WORD -} PacatControlError; - -#define PACAT_CONTROL_ERROR (pacat_control_error_quark ()) -#define PACAT_CONTROL_TYPE_ERROR (pacat_control_error_get_type ()) - -GQuark pacat_control_error_quark (void); -GType pacat_control_error_get_type (void); - -*/ - -int dbus_init(struct userdata *u); - -#endif diff --git a/pulse/pacat-control-stub.h b/pulse/pacat-control-stub.h deleted file mode 100644 index dbb592fd..00000000 --- a/pulse/pacat-control-stub.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Generated by dbus-binding-tool; do not edit! */ - - -#ifndef __dbus_glib_marshal_pacat_control_MARSHAL_H__ -#define __dbus_glib_marshal_pacat_control_MARSHAL_H__ - -#include - -G_BEGIN_DECLS - -#ifdef G_ENABLE_DEBUG -#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) -#define g_marshal_value_peek_char(v) g_value_get_schar (v) -#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) -#define g_marshal_value_peek_int(v) g_value_get_int (v) -#define g_marshal_value_peek_uint(v) g_value_get_uint (v) -#define g_marshal_value_peek_long(v) g_value_get_long (v) -#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) -#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) -#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) -#define g_marshal_value_peek_enum(v) g_value_get_enum (v) -#define g_marshal_value_peek_flags(v) g_value_get_flags (v) -#define g_marshal_value_peek_float(v) g_value_get_float (v) -#define g_marshal_value_peek_double(v) g_value_get_double (v) -#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) -#define g_marshal_value_peek_param(v) g_value_get_param (v) -#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) -#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) -#define g_marshal_value_peek_object(v) g_value_get_object (v) -#define g_marshal_value_peek_variant(v) g_value_get_variant (v) -#else /* !G_ENABLE_DEBUG */ -/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. - * Do not access GValues directly in your code. Instead, use the - * g_value_get_*() functions - */ -#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int -#define g_marshal_value_peek_char(v) (v)->data[0].v_int -#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint -#define g_marshal_value_peek_int(v) (v)->data[0].v_int -#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint -#define g_marshal_value_peek_long(v) (v)->data[0].v_long -#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 -#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 -#define g_marshal_value_peek_enum(v) (v)->data[0].v_long -#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_float(v) (v)->data[0].v_float -#define g_marshal_value_peek_double(v) (v)->data[0].v_double -#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer -#endif /* !G_ENABLE_DEBUG */ - - -G_END_DECLS - -#endif /* __dbus_glib_marshal_pacat_control_MARSHAL_H__ */ - -#include -static const DBusGMethodInfo dbus_glib_pacat_control_methods[] = { -}; - -const DBusGObjectInfo dbus_glib_pacat_control_object_info = { 0, - dbus_glib_pacat_control_methods, - 0, -"\0", -"org.QubesOS.Audio\0RecAllowedChanged\0\0", -"org.QubesOS.Audio\0RecAllowed\0\0" -}; - diff --git a/pulse/pacat-simple-vchan.c b/pulse/pacat-simple-vchan.c index 3c37af3d..e7edd05f 100644 --- a/pulse/pacat-simple-vchan.c +++ b/pulse/pacat-simple-vchan.c @@ -38,6 +38,7 @@ * */ +#define _GNU_SOURCE #ifdef HAVE_CONFIG_H #include #endif @@ -54,6 +55,8 @@ #include #include #include +#include +#include #include #include @@ -63,7 +66,6 @@ #include "pacat-simple-vchan.h" #include "qubes-vchan-sink.h" -#include "pacat-control-object.h" #define CLEAR_LINE "\x1B[K" #ifdef __GNUC__ @@ -652,6 +654,153 @@ static void check_vchan_eof_timer(pa_mainloop_api*a, pa_time_event* e, a->time_restart(e, &restart_tv); } +static void control_socket_callback(pa_mainloop_api *UNUSED(a), + pa_io_event *UNUSED(e), int fd, pa_io_event_flags_t f, + void *userdata) { + struct userdata *u = userdata; + int client_fd; + char command_buffer[32]; + size_t command_len = 0; + int ret; + int new_rec_allowed = -1; + + if (!(f & PA_IO_EVENT_INPUT)) + return; + + client_fd = accept(fd, NULL, NULL); + if (client_fd < 0) { + pacat_log("Accept control connection failed: %s", strerror(errno)); + return; + } + + /* read until either: + * - end of command (\n) is found + * - EOF + */ + do { + ret = read(client_fd, command_buffer+command_len, sizeof(command_buffer)-command_len); + if (ret < 0) { + pacat_log("Control client read failed: %s", strerror(errno)); + } + command_len += ret; + if (ret == 0) + break; + } while (!memchr(command_buffer, '\n', command_len)); + + if (strncmp(command_buffer, "audio-input 0\n", command_len) == 0) { + new_rec_allowed = 0; + } else if (strncmp(command_buffer, "audio-input 1\n", command_len) == 0) { + new_rec_allowed = 1; + } + if (new_rec_allowed != -1) { + g_mutex_lock(&u->prop_mutex); + u->rec_allowed = new_rec_allowed; + pacat_log("Setting audio-input to %s", u->rec_allowed ? "enabled" : "disabled"); + if (u->rec_allowed && u->rec_requested) { + pacat_log("Recording start"); + pa_stream_cork(u->rec_stream, 0, NULL, NULL); + } else if (!u->rec_allowed && + (u->rec_requested || !pa_stream_is_corked(u->rec_stream))) { + pacat_log("Recording stop"); + pa_stream_cork(u->rec_stream, 1, NULL, NULL); + } + g_mutex_unlock(&u->prop_mutex); + if (!qdb_write(u->qdb, u->qdb_path, new_rec_allowed ? "1" : "0", 1)) { + pacat_log("Failed to write QubesDB %s: %s", u->qdb_path, strerror(errno)); + } + } + /* accept only one command per connection */ + close(client_fd); +} + +static int setup_control(struct userdata *u) { + int socket_fd = -1; + struct sockaddr_un addr; + + socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (socket_fd == -1) { + pacat_log("socket failed: %s", strerror(errno)); + goto fail; + } + + if (snprintf(addr.sun_path, sizeof(addr.sun_path), + "/var/run/qubes/audio-control.%s", u->name) + >= (int)sizeof(addr.sun_path)) { + pacat_log("VM name too long"); + goto fail; + } + + /* ignore result */ + unlink(addr.sun_path); + + if (bind(socket_fd, &addr, sizeof(addr)) == -1) { + pacat_log("bind to %s failed: %s", addr.sun_path, strerror(errno)); + goto fail; + } + + if (listen(socket_fd, 5) == -1) { + pacat_log("listen on %s failed: %s", addr.sun_path, strerror(errno)); + goto fail; + } + + u->control_socket_event = u->mainloop_api->io_new(u->mainloop_api, + socket_fd, PA_IO_EVENT_INPUT, control_socket_callback, u); + if (!u->control_socket_event) { + pacat_log("io_new control failed"); + goto fail; + } + + u->qdb = qdb_open(NULL); + if (!u->qdb) { + pacat_log("qdb_open failed: %s", strerror(errno)); + goto fail; + } + + if (asprintf(&u->qdb_path, "/audio-input/%s", u->name) < 0) { + pacat_log("QubesDB path setup failed: %s", strerror(errno)); + u->qdb_path = NULL; + goto fail; + } + + if (!qdb_write(u->qdb, u->qdb_path, "0", 1)) { + pacat_log("qdb_write failed: %s", strerror(errno)); + goto fail; + } + + u->control_socket_fd = socket_fd; + + return 0; + +fail: + if (u->qdb_path) + free(u->qdb_path); + u->qdb_path = NULL; + if (u->qdb) + qdb_close(u->qdb); + u->qdb = NULL; + if (u->control_socket_event) + u->mainloop_api->io_free(u->control_socket_event); + u->control_socket_event = NULL; + if (socket_fd >= 0) + close(socket_fd); + + return 1; +} + +static void control_cleanup(struct userdata *u) { + + if (u->control_socket_event) + u->mainloop_api->io_free(u->control_socket_event); + if (u->control_socket_fd > 0) + close(u->control_socket_fd); + if (u->qdb && u->qdb_path) + qdb_rm(u->qdb, u->qdb_path); + if (u->qdb_path) + free(u->qdb_path); + if (u->qdb) + qdb_close(u->qdb); +} + int main(int argc, char *argv[]) { struct timeval tv; @@ -776,8 +925,8 @@ int main(int argc, char *argv[]) goto quit; } - if (dbus_init(&u) < 0) { - pacat_log("dbus initialization failed"); + if (setup_control(&u) < 0) { + pacat_log("control socket initialization failed"); goto quit; } @@ -787,15 +936,10 @@ int main(int argc, char *argv[]) g_main_loop_run (u.loop); quit: - if (u.pacat_control) { - assert(u.dbus); - dbus_g_connection_unregister_g_object(u.dbus, u.pacat_control); - g_object_unref(u.pacat_control); + if (u.control_socket_event) { + control_cleanup(&u); } - if (u.dbus) - dbus_g_connection_unref(u.dbus); - if (u.play_stream) pa_stream_unref(u.play_stream); diff --git a/pulse/pacat-simple-vchan.h b/pulse/pacat-simple-vchan.h index 99d1e9a1..66555a49 100644 --- a/pulse/pacat-simple-vchan.h +++ b/pulse/pacat-simple-vchan.h @@ -3,8 +3,8 @@ #include #include -#include #include +#include #define PACAT_PIDFILE_PATH_TPL "/var/run/qubes/pacat.%d" @@ -29,9 +29,11 @@ struct userdata { int rec_allowed; int rec_requested; - DBusGConnection *dbus; - GObject *pacat_control; GMutex prop_mutex; + qdb_handle_t qdb; + char *qdb_path; + int control_socket_fd; + pa_io_event* control_socket_event; }; void pacat_log(const char *fmt, ...); diff --git a/rpm_spec/gui-daemon.spec.in b/rpm_spec/gui-daemon.spec.in index 749462d3..5ea11f21 100644 --- a/rpm_spec/gui-daemon.spec.in +++ b/rpm_spec/gui-daemon.spec.in @@ -51,7 +51,7 @@ BuildRequires: libconfig-devel BuildRequires: libpng-devel BuildRequires: libnotify-devel BuildRequires: xen-devel -BuildRequires: dbus-glib-devel +BuildRequires: qubes-db-devel BuildRequires: help2man BuildRequires: gcc BuildRequires: qubes-core-libs-devel >= 1.6.1