As same uptime() is shared between linux and freebsd, adjust the wscript
[jackdbus.git] / dbus / jackdbus.c
blobb6e2698ddf92a6f2a401aa4b2aa9ee9d34d143e4
1 /* -*- Mode: C ; c-basic-offset: 4 -*- */
2 /*
3 Copyright (C) 2007,2008,2010 Nedko Arnaudov
4 Copyright (C) 2007-2008 Juuso Alasuutari
5 Copyright (C) 2008 Marc-Olivier Barre
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #if defined(HAVE_CONFIG_H)
23 #include "config.h"
24 #endif
26 #include <stdbool.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <sys/stat.h>
32 #include <signal.h>
33 #include <dbus/dbus.h>
34 #include <pthread.h>
35 #include <unistd.h>
37 #include "config.h"
38 #include "version.h"
40 #include "jackdbus.h"
41 #include "controller.h"
42 #include "jack/jack.h"
43 #include "jack/jslist.h"
44 #include "jack/control.h"
45 #if SIGINFO_ENABLED
46 #include "../siginfo/siginfo.h"
47 #endif
49 static char * g_log_filename;
50 static ino_t g_log_file_ino;
51 FILE *g_logfile;
52 char *g_jackdbus_config_dir;
53 size_t g_jackdbus_config_dir_len; /* without terminating '\0' char */
54 char *g_jackdbus_log_dir;
55 size_t g_jackdbus_log_dir_len; /* without terminating '\0' char */
56 int g_exit_command;
57 DBusConnection *g_connection;
59 void
60 jack_dbus_send_signal(
61 const char *sender_object_path,
62 const char *iface,
63 const char *signal_name,
64 int first_arg_type,
65 ...)
67 DBusMessage *message_ptr;
68 va_list ap;
70 va_start(ap, first_arg_type);
72 message_ptr = dbus_message_new_signal(sender_object_path, iface, signal_name);
73 if (message_ptr == NULL)
75 jack_error("dbus_message_new_signal() failed.");
76 goto exit;
79 if (!dbus_message_append_args_valist(message_ptr, first_arg_type, ap))
81 jack_error("dbus_message_append_args_valist() failed.");
82 goto unref;
85 /* Add message to outgoing message queue */
86 if (!dbus_connection_send(g_connection, message_ptr, NULL))
88 jack_error("dbus_connection_send() failed.");
89 goto unref;
92 unref:
93 dbus_message_unref(message_ptr);
95 exit:
96 va_end(ap);
100 * Send a method return.
102 * If call->reply is NULL (i.e. a message construct method failed
103 * due to lack of memory) attempt to send a void method return.
105 static
106 void
107 jack_dbus_send_method_return(
108 struct jack_dbus_method_call * call)
110 if (call->message == NULL)
112 /* async call */
113 return;
116 if (call->reply)
118 retry_send:
119 if (!dbus_connection_send (call->connection, call->reply, NULL))
121 jack_error ("Ran out of memory trying to queue method return");
124 dbus_connection_flush (call->connection);
125 dbus_message_unref (call->reply);
126 call->reply = NULL;
128 else
130 jack_error ("send_method_return() called with a NULL message,"
131 " trying to construct a void return...");
133 if ((call->reply = dbus_message_new_method_return (call->message)))
135 goto retry_send;
137 else
139 jack_error ("Failed to construct method return!");
144 #define object_ptr ((struct jack_dbus_object_descriptor *)data)
147 * The D-Bus message handler for object path /org/jackaudio/Controller.
149 DBusHandlerResult
150 jack_dbus_message_handler(
151 DBusConnection *connection,
152 DBusMessage *message,
153 void *data)
155 struct jack_dbus_method_call call;
156 const char *interface_name;
157 struct jack_dbus_interface_descriptor ** interface_ptr_ptr;
159 /* Check if the message is a method call. If not, ignore it. */
160 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
162 goto handled;
165 /* Get the invoked method's name and make sure it's non-NULL. */
166 if (!(call.method_name = dbus_message_get_member (message)))
168 jack_dbus_error(
169 &call,
170 JACK_DBUS_ERROR_UNKNOWN_METHOD,
171 "Received method call with empty method name");
172 goto send_return;
175 /* Initialize our data. */
176 call.context = object_ptr->context;
177 call.connection = connection;
178 call.message = message;
179 call.reply = NULL;
181 /* Check if there's an interface specified for this method call. */
182 interface_name = dbus_message_get_interface (message);
183 if (interface_name != NULL)
185 /* Check if we can match the interface and method.
186 * The interface handler functions only return false if the
187 * method name was unknown, otherwise they run the specified
188 * method and return TRUE.
191 interface_ptr_ptr = object_ptr->interfaces;
193 while (*interface_ptr_ptr != NULL)
195 if (strcmp(interface_name, (*interface_ptr_ptr)->name) == 0)
197 if (!(*interface_ptr_ptr)->handler(&call, (*interface_ptr_ptr)->methods))
199 break;
202 goto send_return;
205 interface_ptr_ptr++;
208 else
210 /* No interface was specified so we have to try them all. This is
211 * dictated by the D-Bus specification which states that method calls
212 * omitting the interface must never be rejected.
215 interface_ptr_ptr = object_ptr->interfaces;
217 while (*interface_ptr_ptr != NULL)
219 if ((*interface_ptr_ptr)->handler(&call, (*interface_ptr_ptr)->methods))
221 goto send_return;
224 interface_ptr_ptr++;
228 jack_dbus_error(
229 &call,
230 JACK_DBUS_ERROR_UNKNOWN_METHOD,
231 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist",
232 call.method_name,
233 dbus_message_get_signature(message),
234 interface_name);
236 send_return:
237 jack_dbus_send_method_return(&call);
239 handled:
240 return DBUS_HANDLER_RESULT_HANDLED;
243 void
244 jack_dbus_message_handler_unregister(
245 DBusConnection *connection,
246 void *data)
248 jack_info ("Message handler was unregistered");
251 #undef object_ptr
254 * Check if the supplied method name exists in org.jackaudio.JackConfigure,
255 * if it does execute it and return TRUE. Otherwise return FALSE.
257 bool
258 jack_dbus_run_method(
259 struct jack_dbus_method_call *call,
260 const struct jack_dbus_interface_method_descriptor * methods)
262 const struct jack_dbus_interface_method_descriptor * method_ptr;
264 method_ptr = methods;
266 while (method_ptr->name != NULL)
268 if (strcmp(call->method_name, method_ptr->name) == 0)
270 method_ptr->handler(call);
271 return TRUE;
274 method_ptr++;
277 return FALSE;
281 * Read arguments from a method call.
282 * If the operation fails construct an error and return false,
283 * otherwise return true.
285 bool
286 jack_dbus_get_method_args(
287 struct jack_dbus_method_call *call,
288 int type,
289 ...)
291 va_list args;
292 DBusError error;
293 bool retval = true;
295 va_start (args, type);
296 dbus_error_init (&error);
298 if (!dbus_message_get_args_valist (call->message, &error, type, args))
300 jack_dbus_error (call, JACK_DBUS_ERROR_INVALID_ARGS,
301 "Invalid arguments to method \"%s\"",
302 call->method_name);
303 retval = false;
306 dbus_error_free (&error);
307 va_end (args);
309 return retval;
313 * Read a string and a variant argument from a method call.
314 * If the operation fails construct an error and return false,
315 * otherwise return true.
317 bool
318 jack_dbus_get_method_args_string_and_variant(
319 struct jack_dbus_method_call *call,
320 const char **arg1,
321 message_arg_t *arg2,
322 int *type_ptr)
324 DBusMessageIter iter, sub_iter;
326 /* First we want a string... */
327 if (dbus_message_iter_init (call->message, &iter)
328 && dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING)
330 dbus_message_iter_get_basic (&iter, arg1);
331 dbus_message_iter_next (&iter);
333 /* ...and then a variant. */
334 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_VARIANT)
336 dbus_message_iter_recurse (&iter, &sub_iter);
337 dbus_message_iter_get_basic (&sub_iter, arg2);
338 *type_ptr = dbus_message_iter_get_arg_type (&sub_iter);
340 /* Got what we wanted. */
341 return true;
345 jack_dbus_error (call, JACK_DBUS_ERROR_INVALID_ARGS,
346 "Invalid arguments to method \"%s\"",
347 call->method_name);
349 return false;
353 * Read two strings and a variant argument from a method call.
354 * If the operation fails construct an error and return false,
355 * otherwise return true.
357 bool
358 jack_dbus_get_method_args_two_strings_and_variant(
359 struct jack_dbus_method_call *call,
360 const char **arg1,
361 const char **arg2,
362 message_arg_t *arg3,
363 int *type_ptr)
365 DBusMessageIter iter, sub_iter;
367 /* First we want a string... */
368 if (dbus_message_iter_init (call->message, &iter)
369 && dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING)
371 dbus_message_iter_get_basic (&iter, arg1);
372 dbus_message_iter_next (&iter);
374 /* ...and then a second string. */
375 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
377 return false;
380 /* Got what we wanted. */
381 dbus_message_iter_get_basic (&iter, arg2);
382 dbus_message_iter_next (&iter);
384 /* ...and then a variant. */
385 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_VARIANT)
387 dbus_message_iter_recurse (&iter, &sub_iter);
388 dbus_message_iter_get_basic (&sub_iter, arg3);
389 *type_ptr = dbus_message_iter_get_arg_type (&sub_iter);
391 /* Got what we wanted. */
392 return true;
396 jack_dbus_error (call, JACK_DBUS_ERROR_INVALID_ARGS,
397 "Invalid arguments to method \"%s\"",
398 call->method_name);
400 return false;
404 * Append a variant type to a D-Bus message.
405 * Return false if something fails, true otherwise.
407 bool
408 jack_dbus_message_append_variant(
409 DBusMessageIter *iter,
410 int type,
411 const char *signature,
412 message_arg_t *arg)
414 DBusMessageIter sub_iter;
416 /* Open a variant container. */
417 if (!dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, signature, &sub_iter))
419 goto fail;
422 /* Append the supplied value. */
423 if (!dbus_message_iter_append_basic (&sub_iter, type, (const void *) arg))
425 dbus_message_iter_close_container (iter, &sub_iter);
426 goto fail;
429 /* Close the container. */
430 if (!dbus_message_iter_close_container (iter, &sub_iter))
432 goto fail;
435 return true;
437 fail:
438 return false;
442 * Construct an empty method return message.
444 * The operation can only fail due to lack of memory, in which case
445 * there's no sense in trying to construct an error return. Instead,
446 * call->reply will be set to NULL and handled in send_method_return().
448 void
449 jack_dbus_construct_method_return_empty(
450 struct jack_dbus_method_call * call)
452 call->reply = dbus_message_new_method_return (call->message);
454 if (call->reply == NULL)
456 jack_error ("Ran out of memory trying to construct method return");
461 * Construct a method return which holds a single argument or, if
462 * the type parameter is DBUS_TYPE_INVALID, no arguments at all
463 * (a void message).
465 * The operation can only fail due to lack of memory, in which case
466 * there's no sense in trying to construct an error return. Instead,
467 * call->reply will be set to NULL and handled in send_method_return().
469 void
470 jack_dbus_construct_method_return_single(
471 struct jack_dbus_method_call *call,
472 int type,
473 message_arg_t arg)
475 DBusMessageIter iter;
476 call->reply = dbus_message_new_method_return (call->message);
478 if (call->reply == NULL)
480 goto fail_no_mem;
483 /* Void method return requested by caller. */
484 if (type == DBUS_TYPE_INVALID)
486 return;
489 /* Prevent crash on NULL input string. */
490 else if (type == DBUS_TYPE_STRING && arg.string == NULL)
492 arg.string = "";
495 dbus_message_iter_init_append (call->reply, &iter);
497 if (!dbus_message_iter_append_basic (&iter, type, (const void *) &arg))
499 dbus_message_unref (call->reply);
500 call->reply = NULL;
501 goto fail_no_mem;
504 return;
506 fail_no_mem:
507 jack_error ("Ran out of memory trying to construct method return");
511 * Construct a method return which holds an array of strings.
513 * The operation can only fail due to lack of memory, in which case
514 * there's no sense in trying to construct an error return. Instead,
515 * call->reply will be set to NULL and handled in send_method_return().
517 void
518 jack_dbus_construct_method_return_array_of_strings(
519 struct jack_dbus_method_call *call,
520 unsigned int num_members,
521 const char **array)
523 DBusMessageIter iter, sub_iter;
524 unsigned int i;
526 call->reply = dbus_message_new_method_return (call->message);
527 if (!call->reply)
529 goto fail;
532 dbus_message_iter_init_append (call->reply, &iter);
534 if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s", &sub_iter))
536 goto fail_unref;
539 for (i = 0; i < num_members; ++i)
541 if (!dbus_message_iter_append_basic (&sub_iter, DBUS_TYPE_STRING, (const void *) &array[i]))
543 dbus_message_iter_close_container (&iter, &sub_iter);
544 goto fail_unref;
548 if (!dbus_message_iter_close_container (&iter, &sub_iter))
550 goto fail_unref;
553 return;
555 fail_unref:
556 dbus_message_unref (call->reply);
557 call->reply = NULL;
559 fail:
560 jack_error ("Ran out of memory trying to construct method return");
563 static bool jack_dbus_log_open(void)
565 struct stat st;
566 int ret;
567 int retry;
569 if (g_logfile != NULL)
571 ret = stat(g_log_filename, &st);
572 if (ret != 0 || g_log_file_ino != st.st_ino)
574 fclose(g_logfile);
576 else
578 return true;
582 for (retry = 0; retry < 10; retry++)
584 g_logfile = fopen(g_log_filename, "a");
585 if (g_logfile == NULL)
587 fprintf(stderr, "Cannot open jackdbus log file \"%s\": %d (%s)\n", g_log_filename, errno, strerror(errno));
588 return false;
591 ret = stat(g_log_filename, &st);
592 if (ret == 0)
594 g_log_file_ino = st.st_ino;
595 return true;
598 fclose(g_logfile);
599 g_logfile = NULL;
602 fprintf(stderr, "Cannot stat just opened jackdbus log file \"%s\": %d (%s). %d retries\n", g_log_filename, errno, strerror(errno), retry);
603 return false;
606 void
607 jack_dbus_info_callback(const char *msg)
609 time_t timestamp;
610 char timestamp_str[26];
612 time(&timestamp);
613 ctime_r(&timestamp, timestamp_str);
614 timestamp_str[24] = 0;
616 if (jack_dbus_log_open())
618 fprintf(g_logfile, "%s: %s\n", timestamp_str, msg);
619 fflush(g_logfile);
623 #define ANSI_BOLD_ON "\033[1m"
624 #define ANSI_BOLD_OFF "\033[22m"
625 #define ANSI_COLOR_RED "\033[31m"
626 #define ANSI_RESET "\033[0m"
628 void
629 jack_dbus_error_callback(const char *msg)
631 time_t timestamp;
632 char timestamp_str[26];
634 time(&timestamp);
635 ctime_r(&timestamp, timestamp_str);
636 timestamp_str[24] = 0;
638 if (jack_dbus_log_open())
640 fprintf(g_logfile, "%s: " ANSI_BOLD_ON ANSI_COLOR_RED "ERROR: %s" ANSI_RESET "\n", timestamp_str, msg);
641 fflush(g_logfile);
645 bool
646 ensure_dir_exist(const char *dirname, int mode)
648 struct stat st;
649 if (stat(dirname, &st) != 0)
651 if (errno == ENOENT)
653 printf("Directory \"%s\" does not exist. Creating...\n", dirname);
654 if (mkdir(dirname, mode) != 0)
656 fprintf(stderr, "Failed to create \"%s\" directory: %d (%s)\n", dirname, errno, strerror(errno));
657 return false;
660 else
662 fprintf(stderr, "Failed to stat \"%s\": %d (%s)\n", dirname, errno, strerror(errno));
663 return false;
666 else
668 if (!S_ISDIR(st.st_mode))
670 fprintf(stderr, "\"%s\" exists but is not directory.\n", dirname);
671 return false;
674 return true;
677 char *
678 pathname_cat(const char *pathname_a, const char *pathname_b)
680 char *pathname;
681 int pathname_a_len, pathname_b_len, pathname_len;
682 pathname_a_len = strlen(pathname_a);
683 pathname_b_len = strlen(pathname_b);
684 pathname = malloc(pathname_a_len + pathname_b_len + 1);
685 if (pathname == NULL)
687 fprintf(stderr, "Out of memory\n");
688 return NULL;
690 memcpy(pathname, pathname_a, pathname_a_len);
691 memcpy(pathname + pathname_a_len, pathname_b, pathname_b_len);
692 pathname_len = pathname_a_len + pathname_b_len;
693 pathname[pathname_len] = 0;
694 return pathname;
697 bool
698 paths_init(void)
700 const char *home_dir, *xdg_config_home, *xdg_log_home;
702 home_dir = getenv("HOME");
703 if (home_dir == NULL)
705 fprintf(stderr, "Environment variable HOME not set\n");
706 goto fail;
709 xdg_config_home = getenv("XDG_CONFIG_HOME");
710 if (xdg_config_home == NULL)
712 if (!(xdg_config_home = pathname_cat(home_dir, DEFAULT_XDG_CONFIG))) goto fail;
715 if (!(xdg_log_home = pathname_cat(home_dir, DEFAULT_XDG_LOG))) goto fail;
717 if (!(g_jackdbus_config_dir = pathname_cat(xdg_config_home, JACKDBUS_DIR))) goto fail;
718 if (!(g_jackdbus_log_dir = pathname_cat(xdg_log_home, JACKDBUS_DIR))) goto fail;
720 if (!ensure_dir_exist(xdg_config_home, 0700))
722 goto fail;
725 if (!ensure_dir_exist(xdg_log_home, 0700))
727 goto fail;
730 if (!ensure_dir_exist(g_jackdbus_config_dir, 0700))
732 free(g_jackdbus_config_dir);
733 goto fail;
735 g_jackdbus_config_dir_len = strlen(g_jackdbus_config_dir);
737 if (!ensure_dir_exist(g_jackdbus_log_dir, 0700))
739 free(g_jackdbus_log_dir);
740 goto fail;
742 g_jackdbus_log_dir_len = strlen(g_jackdbus_log_dir);
744 return true;
746 fail:
747 return false;
750 void
751 paths_uninit(void)
753 free(g_jackdbus_config_dir);
754 free(g_jackdbus_log_dir);
757 static bool log_init(void)
759 size_t log_len;
761 log_len = strlen(JACKDBUS_LOG);
763 g_log_filename = malloc(g_jackdbus_log_dir_len + log_len + 1);
764 if (g_log_filename == NULL)
766 fprintf(stderr, "Out of memory\n");
767 return false;
770 memcpy(g_log_filename, g_jackdbus_log_dir, g_jackdbus_log_dir_len);
771 memcpy(g_log_filename + g_jackdbus_log_dir_len, JACKDBUS_LOG, log_len);
772 g_log_filename[g_jackdbus_log_dir_len + log_len] = 0;
774 if (!jack_dbus_log_open())
776 return false;
779 return true;
782 static void log_uninit(void)
784 if (g_logfile != NULL)
786 fclose(g_logfile);
789 free(g_log_filename);
792 void
793 jack_dbus_error(
794 void *dbus_call_context_ptr,
795 const char *error_name,
796 const char *format,
797 ...)
799 va_list ap;
800 char buffer[300];
802 va_start(ap, format);
804 vsnprintf(buffer, sizeof(buffer), format, ap);
806 jack_error_callback(buffer);
807 if (dbus_call_context_ptr != NULL)
809 if (((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply != NULL)
811 dbus_message_unref(((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply);
812 ((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = NULL;
815 ((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = dbus_message_new_error(
816 ((struct jack_dbus_method_call *)dbus_call_context_ptr)->message,
817 error_name,
818 buffer);
821 va_end(ap);
824 void
825 jack_dbus_only_error(
826 void *dbus_call_context_ptr,
827 const char *error_name,
828 const char *format,
829 ...)
831 va_list ap;
832 char buffer[300];
834 va_start(ap, format);
836 vsnprintf(buffer, sizeof(buffer), format, ap);
838 if (((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply != NULL)
840 dbus_message_unref(((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply);
841 ((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = NULL;
844 ((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = dbus_message_new_error(
845 ((struct jack_dbus_method_call *)dbus_call_context_ptr)->message,
846 error_name,
847 buffer);
849 va_end(ap);
853 main (int argc, char **argv)
855 DBusError error;
856 int ret;
857 void *controller_ptr;
858 struct stat st;
859 char timestamp_str[26];
861 st.st_mtime = 0;
862 stat(argv[0], &st);
863 ctime_r(&st.st_mtime, timestamp_str);
864 timestamp_str[24] = 0;
866 if (!jack_controller_settings_init())
868 ret = 1;
869 goto fail;
872 if (argc != 2 || strcmp(argv[1], "auto") != 0)
874 ret = 0;
875 fprintf(
876 stderr,
877 "jackdbus should be auto-executed by D-Bus message bus daemon.\n"
878 "If you want to run it manually anyway, specify \"auto\" as only parameter\n");
879 goto fail_uninit_xml;
882 if (!paths_init())
884 ret = 1;
885 goto fail_uninit_xml;
888 if (!log_init())
890 ret = 1;
891 goto fail_uninit_paths;
894 #if !defined(DISABLE_SIGNAL_MAGIC)
895 jackctl_setup_signals(0);
896 #endif
898 jack_set_error_function(jack_dbus_error_callback);
899 jack_set_info_function(jack_dbus_info_callback);
901 #if SIGINFO_ENABLED
902 /* setup our SIGSEGV magic that prints nice stack in our logfile */
903 setup_siginfo();
904 #endif
906 jack_info("------------------");
907 jack_info("jackdbus version %s built from %s on %s", JACK_VERSION, GIT_VERSION, timestamp_str);
908 jack_info("JACK server version %s", jack_get_version_string());
909 jack_info("jackdbus controller activated.");
911 if (!dbus_threads_init_default())
913 jack_error("dbus_threads_init_default() failed");
914 ret = 1;
915 goto fail_uninit_log;
918 dbus_error_init (&error);
919 g_connection = dbus_bus_get (DBUS_BUS_SESSION, &error);
920 if (dbus_error_is_set (&error))
922 jack_error("Cannot connect to D-Bus session bus: %s", error.message);
923 ret = 1;
924 goto fail_uninit_log;
927 ret = dbus_bus_request_name(
928 g_connection,
929 "org.jackaudio.service",
930 DBUS_NAME_FLAG_DO_NOT_QUEUE,
931 &error);
932 if (ret == -1)
934 jack_error("Cannot request service name: %s", error.message);
935 dbus_error_free(&error);
936 ret = 1;
937 goto fail_unref_connection;
939 else if (ret == DBUS_REQUEST_NAME_REPLY_EXISTS)
941 jack_error("Requested D-Bus service name already exists");
942 ret = 1;
943 goto fail_unref_connection;
946 controller_ptr = jack_controller_create(g_connection);
948 if (controller_ptr == NULL)
950 ret = 1;
951 goto fail_unref_connection;
954 jack_info("Listening for D-Bus messages");
956 g_exit_command = FALSE;
957 while (!g_exit_command && dbus_connection_read_write_dispatch (g_connection, 200))
959 jack_controller_run(controller_ptr);
962 jack_controller_destroy(controller_ptr);
964 jack_info("Controller deactivated.");
966 ret = 0;
968 fail_unref_connection:
969 dbus_connection_unref(g_connection);
971 fail_uninit_log:
972 log_uninit();
974 fail_uninit_paths:
975 paths_uninit();
977 fail_uninit_xml:
978 jack_controller_settings_uninit();
980 fail:
981 return ret;