jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

835 lines
20KB

  1. /* -*- Mode: C ; c-basic-offset: 4 -*- */
  2. /*
  3. Copyright (C) 2007,2008 Nedko Arnaudov
  4. Copyright (C) 2007-2008 Juuso Alasuutari
  5. Copyright (C) 2008 Marc-Olivier Barre
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #if defined(HAVE_CONFIG_H)
  18. #include "config.h"
  19. #endif
  20. #include <stdbool.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <errno.h>
  25. #include <sys/stat.h>
  26. #include <signal.h>
  27. #include <dbus/dbus.h>
  28. #include <pthread.h>
  29. #include <unistd.h>
  30. #include "config.h"
  31. #include "jackdbus.h"
  32. #include "controller.h"
  33. #include "jack/jack.h"
  34. #include "jack/jslist.h"
  35. #include "jack/control.h"
  36. #include "sigsegv.h"
  37. #include "svnversion.h"
  38. FILE *g_logfile;
  39. char *g_jackdbus_config_dir;
  40. size_t g_jackdbus_config_dir_len; /* without terminating '\0' char */
  41. char *g_jackdbus_log_dir;
  42. size_t g_jackdbus_log_dir_len; /* without terminating '\0' char */
  43. int g_exit_command;
  44. DBusConnection *g_connection;
  45. void
  46. jack_dbus_send_signal(
  47. const char *sender_object_path,
  48. const char *iface,
  49. const char *signal_name,
  50. int first_arg_type,
  51. ...)
  52. {
  53. DBusMessage *message_ptr;
  54. va_list ap;
  55. va_start(ap, first_arg_type);
  56. message_ptr = dbus_message_new_signal(sender_object_path, iface, signal_name);
  57. if (message_ptr == NULL)
  58. {
  59. jack_error("dbus_message_new_signal() failed.");
  60. goto exit;
  61. }
  62. if (!dbus_message_append_args_valist(message_ptr, first_arg_type, ap))
  63. {
  64. jack_error("dbus_message_append_args_valist() failed.");
  65. goto unref;
  66. }
  67. /* Add message to outgoing message queue */
  68. if (!dbus_connection_send(g_connection, message_ptr, NULL))
  69. {
  70. jack_error("dbus_connection_send() failed.");
  71. goto unref;
  72. }
  73. unref:
  74. dbus_message_unref(message_ptr);
  75. exit:
  76. va_end(ap);
  77. }
  78. /*
  79. * Send a method return.
  80. *
  81. * If call->reply is NULL (i.e. a message construct method failed
  82. * due to lack of memory) attempt to send a void method return.
  83. */
  84. static
  85. void
  86. jack_dbus_send_method_return(
  87. struct jack_dbus_method_call * call)
  88. {
  89. if (call->reply)
  90. {
  91. retry_send:
  92. if (!dbus_connection_send (call->connection, call->reply, NULL))
  93. {
  94. jack_error ("Ran out of memory trying to queue method return");
  95. }
  96. dbus_connection_flush (call->connection);
  97. dbus_message_unref (call->reply);
  98. call->reply = NULL;
  99. }
  100. else
  101. {
  102. jack_error ("send_method_return() called with a NULL message,"
  103. " trying to construct a void return...");
  104. if ((call->reply = dbus_message_new_method_return (call->message)))
  105. {
  106. goto retry_send;
  107. }
  108. else
  109. {
  110. jack_error ("Failed to construct method return!");
  111. }
  112. }
  113. }
  114. #define object_ptr ((struct jack_dbus_object_descriptor *)data)
  115. /*
  116. * The D-Bus message handler for object path /org/jackaudio/Controller.
  117. */
  118. DBusHandlerResult
  119. jack_dbus_message_handler(
  120. DBusConnection *connection,
  121. DBusMessage *message,
  122. void *data)
  123. {
  124. struct jack_dbus_method_call call;
  125. const char *interface_name;
  126. struct jack_dbus_interface_descriptor ** interface_ptr_ptr;
  127. /* Check if the message is a method call. If not, ignore it. */
  128. if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
  129. {
  130. goto handled;
  131. }
  132. /* Get the invoked method's name and make sure it's non-NULL. */
  133. if (!(call.method_name = dbus_message_get_member (message)))
  134. {
  135. jack_dbus_error(
  136. &call,
  137. JACK_DBUS_ERROR_UNKNOWN_METHOD,
  138. "Received method call with empty method name");
  139. goto send_return;
  140. }
  141. /* Initialize our data. */
  142. call.context = object_ptr->context;
  143. call.connection = connection;
  144. call.message = message;
  145. call.reply = NULL;
  146. /* Check if there's an interface specified for this method call. */
  147. interface_name = dbus_message_get_interface (message);
  148. if (interface_name != NULL)
  149. {
  150. /* Check if we can match the interface and method.
  151. * The inteface handler functions only return false if the
  152. * method name was unknown, otherwise they run the specified
  153. * method and return TRUE.
  154. */
  155. interface_ptr_ptr = object_ptr->interfaces;
  156. while (*interface_ptr_ptr != NULL)
  157. {
  158. if (strcmp(interface_name, (*interface_ptr_ptr)->name) == 0)
  159. {
  160. if (!(*interface_ptr_ptr)->handler(&call, (*interface_ptr_ptr)->methods))
  161. {
  162. break;
  163. }
  164. goto send_return;
  165. }
  166. interface_ptr_ptr++;
  167. }
  168. }
  169. else
  170. {
  171. /* No interface was specified so we have to try them all. This is
  172. * dictated by the D-Bus specification which states that method calls
  173. * omitting the interface must never be rejected.
  174. */
  175. interface_ptr_ptr = object_ptr->interfaces;
  176. while (*interface_ptr_ptr != NULL)
  177. {
  178. if ((*interface_ptr_ptr)->handler(&call, (*interface_ptr_ptr)->methods))
  179. {
  180. goto send_return;
  181. }
  182. interface_ptr_ptr++;
  183. }
  184. }
  185. jack_dbus_error(
  186. &call,
  187. JACK_DBUS_ERROR_UNKNOWN_METHOD,
  188. "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist",
  189. call.method_name,
  190. dbus_message_get_signature(message),
  191. interface_name);
  192. send_return:
  193. jack_dbus_send_method_return(&call);
  194. handled:
  195. return DBUS_HANDLER_RESULT_HANDLED;
  196. }
  197. void
  198. jack_dbus_message_handler_unregister(
  199. DBusConnection *connection,
  200. void *data)
  201. {
  202. jack_info ("Message handler was unregistered");
  203. }
  204. #undef object_ptr
  205. /*
  206. * Check if the supplied method name exists in org.jackaudio.JackConfigure,
  207. * if it does execute it and return TRUE. Otherwise return FALSE.
  208. */
  209. bool
  210. jack_dbus_run_method(
  211. struct jack_dbus_method_call *call,
  212. const struct jack_dbus_interface_method_descriptor * methods)
  213. {
  214. const struct jack_dbus_interface_method_descriptor * method_ptr;
  215. method_ptr = methods;
  216. while (method_ptr->name != NULL)
  217. {
  218. if (strcmp(call->method_name, method_ptr->name) == 0)
  219. {
  220. method_ptr->handler(call);
  221. return TRUE;
  222. }
  223. method_ptr++;
  224. }
  225. return FALSE;
  226. }
  227. /*
  228. * Read arguments from a method call.
  229. * If the operation fails construct an error and return false,
  230. * otherwise return true.
  231. */
  232. bool
  233. jack_dbus_get_method_args(
  234. struct jack_dbus_method_call *call,
  235. int type,
  236. ...)
  237. {
  238. va_list args;
  239. DBusError error;
  240. bool retval = true;
  241. va_start (args, type);
  242. dbus_error_init (&error);
  243. if (!dbus_message_get_args_valist (call->message, &error, type, args))
  244. {
  245. jack_dbus_error (call, JACK_DBUS_ERROR_INVALID_ARGS,
  246. "Invalid arguments to method \"%s\"",
  247. call->method_name);
  248. retval = false;
  249. }
  250. dbus_error_free (&error);
  251. va_end (args);
  252. return retval;
  253. }
  254. /*
  255. * Read a string and a variant argument from a method call.
  256. * If the operation fails construct an error and return false,
  257. * otherwise return true.
  258. */
  259. bool
  260. jack_dbus_get_method_args_string_and_variant(
  261. struct jack_dbus_method_call *call,
  262. const char **arg1,
  263. message_arg_t *arg2,
  264. int *type_ptr)
  265. {
  266. DBusMessageIter iter, sub_iter;
  267. /* First we want a string... */
  268. if (dbus_message_iter_init (call->message, &iter)
  269. && dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING)
  270. {
  271. dbus_message_iter_get_basic (&iter, arg1);
  272. dbus_message_iter_next (&iter);
  273. /* ...and then a variant. */
  274. if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_VARIANT)
  275. {
  276. dbus_message_iter_recurse (&iter, &sub_iter);
  277. dbus_message_iter_get_basic (&sub_iter, arg2);
  278. *type_ptr = dbus_message_iter_get_arg_type (&sub_iter);
  279. /* Got what we wanted. */
  280. return true;
  281. }
  282. }
  283. jack_dbus_error (call, JACK_DBUS_ERROR_INVALID_ARGS,
  284. "Invalid arguments to method \"%s\"",
  285. call->method_name);
  286. return false;
  287. }
  288. /*
  289. * Append a variant type to a D-Bus message.
  290. * Return false if something fails, true otherwise.
  291. */
  292. bool
  293. jack_dbus_message_append_variant(
  294. DBusMessageIter *iter,
  295. int type,
  296. const char *signature,
  297. message_arg_t *arg)
  298. {
  299. DBusMessageIter sub_iter;
  300. /* Open a variant container. */
  301. if (!dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, signature, &sub_iter))
  302. {
  303. goto fail;
  304. }
  305. /* Append the supplied value. */
  306. if (!dbus_message_iter_append_basic (&sub_iter, type, (const void *) arg))
  307. {
  308. dbus_message_iter_close_container (iter, &sub_iter);
  309. goto fail;
  310. }
  311. /* Close the container. */
  312. if (!dbus_message_iter_close_container (iter, &sub_iter))
  313. {
  314. goto fail;
  315. }
  316. return true;
  317. fail:
  318. return false;
  319. }
  320. /*
  321. * Construct an empty method return message.
  322. *
  323. * The operation can only fail due to lack of memory, in which case
  324. * there's no sense in trying to construct an error return. Instead,
  325. * call->reply will be set to NULL and handled in send_method_return().
  326. */
  327. void
  328. jack_dbus_construct_method_return_empty(
  329. struct jack_dbus_method_call * call)
  330. {
  331. call->reply = dbus_message_new_method_return (call->message);
  332. if (call->reply == NULL)
  333. {
  334. jack_error ("Ran out of memory trying to construct method return");
  335. }
  336. }
  337. /*
  338. * Construct a method return which holds a single argument or, if
  339. * the type parameter is DBUS_TYPE_INVALID, no arguments at all
  340. * (a void message).
  341. *
  342. * The operation can only fail due to lack of memory, in which case
  343. * there's no sense in trying to construct an error return. Instead,
  344. * call->reply will be set to NULL and handled in send_method_return().
  345. */
  346. void
  347. jack_dbus_construct_method_return_single(
  348. struct jack_dbus_method_call *call,
  349. int type,
  350. message_arg_t arg)
  351. {
  352. DBusMessageIter iter;
  353. call->reply = dbus_message_new_method_return (call->message);
  354. if (call->reply == NULL)
  355. {
  356. goto fail_no_mem;
  357. }
  358. /* Void method return requested by caller. */
  359. if (type == DBUS_TYPE_INVALID)
  360. {
  361. return;
  362. }
  363. /* Prevent crash on NULL input string. */
  364. else if (type == DBUS_TYPE_STRING && arg.string == NULL)
  365. {
  366. arg.string = "";
  367. }
  368. dbus_message_iter_init_append (call->reply, &iter);
  369. if (!dbus_message_iter_append_basic (&iter, type, (const void *) &arg))
  370. {
  371. dbus_message_unref (call->reply);
  372. call->reply = NULL;
  373. goto fail_no_mem;
  374. }
  375. return;
  376. fail_no_mem:
  377. jack_error ("Ran out of memory trying to construct method return");
  378. }
  379. /*
  380. * Construct a method return which holds an array of strings.
  381. *
  382. * The operation can only fail due to lack of memory, in which case
  383. * there's no sense in trying to construct an error return. Instead,
  384. * call->reply will be set to NULL and handled in send_method_return().
  385. */
  386. void
  387. jack_dbus_construct_method_return_array_of_strings(
  388. struct jack_dbus_method_call *call,
  389. unsigned int num_members,
  390. const char **array)
  391. {
  392. DBusMessageIter iter, sub_iter;
  393. unsigned int i;
  394. call->reply = dbus_message_new_method_return (call->message);
  395. if (!call->reply)
  396. {
  397. goto fail;
  398. }
  399. dbus_message_iter_init_append (call->reply, &iter);
  400. if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s", &sub_iter))
  401. {
  402. goto fail_unref;
  403. }
  404. for (i = 0; i < num_members; ++i)
  405. {
  406. if (!dbus_message_iter_append_basic (&sub_iter, DBUS_TYPE_STRING, (const void *) &array[i]))
  407. {
  408. dbus_message_iter_close_container (&iter, &sub_iter);
  409. goto fail_unref;
  410. }
  411. }
  412. if (!dbus_message_iter_close_container (&iter, &sub_iter))
  413. {
  414. goto fail_unref;
  415. }
  416. return;
  417. fail_unref:
  418. dbus_message_unref (call->reply);
  419. call->reply = NULL;
  420. fail:
  421. jack_error ("Ran out of memory trying to construct method return");
  422. }
  423. void
  424. jack_dbus_info_callback(const char *msg)
  425. {
  426. time_t timestamp;
  427. char timestamp_str[26];
  428. time(&timestamp);
  429. ctime_r(&timestamp, timestamp_str);
  430. timestamp_str[24] = 0;
  431. fprintf(g_logfile, "%s: %s\n", timestamp_str, msg);
  432. fflush(g_logfile);
  433. }
  434. #define ANSI_BOLD_ON "\033[1m"
  435. #define ANSI_BOLD_OFF "\033[22m"
  436. #define ANSI_COLOR_RED "\033[31m"
  437. #define ANSI_RESET "\033[0m"
  438. void
  439. jack_dbus_error_callback(const char *msg)
  440. {
  441. time_t timestamp;
  442. char timestamp_str[26];
  443. time(&timestamp);
  444. ctime_r(&timestamp, timestamp_str);
  445. timestamp_str[24] = 0;
  446. fprintf(g_logfile, "%s: " ANSI_BOLD_ON ANSI_COLOR_RED "ERROR: %s" ANSI_RESET "\n", timestamp_str, msg);
  447. fflush(g_logfile);
  448. }
  449. bool
  450. ensure_dir_exist(const char *dirname, int mode)
  451. {
  452. struct stat st;
  453. if (stat(dirname, &st) != 0)
  454. {
  455. if (errno == ENOENT)
  456. {
  457. printf("Directory \"%s\" does not exist. Creating...\n", dirname);
  458. if (mkdir(dirname, mode) != 0)
  459. {
  460. fprintf(stderr, "Failed to create \"%s\" directory: %d (%s)\n", dirname, errno, strerror(errno));
  461. return false;
  462. }
  463. }
  464. else
  465. {
  466. fprintf(stderr, "Failed to stat \"%s\": %d (%s)\n", dirname, errno, strerror(errno));
  467. return false;
  468. }
  469. }
  470. else
  471. {
  472. if (!S_ISDIR(st.st_mode))
  473. {
  474. fprintf(stderr, "\"%s\" exists but is not directory.\n", dirname);
  475. return false;
  476. }
  477. }
  478. return true;
  479. }
  480. char *
  481. pathname_cat(const char *pathname_a, const char *pathname_b)
  482. {
  483. char *pathname;
  484. int pathname_a_len, pathname_b_len, pathname_len;
  485. pathname_a_len = strlen(pathname_a);
  486. pathname_b_len = strlen(pathname_b);
  487. pathname = malloc(pathname_a_len + pathname_b_len + 1);
  488. if (pathname == NULL)
  489. {
  490. fprintf(stderr, "Out of memory\n");
  491. return NULL;
  492. }
  493. memcpy(pathname, pathname_a, pathname_a_len);
  494. memcpy(pathname + pathname_a_len, pathname_b, pathname_b_len);
  495. pathname_len = pathname_a_len + pathname_b_len;
  496. pathname[pathname_len] = 0;
  497. return pathname;
  498. }
  499. bool
  500. paths_init()
  501. {
  502. const char *home_dir, *xdg_config_home, *xdg_log_home;
  503. home_dir = getenv("HOME");
  504. if (home_dir == NULL)
  505. {
  506. fprintf(stderr, "Environment variable HOME not set\n");
  507. goto fail;
  508. }
  509. xdg_config_home = getenv("XDG_CONFIG_HOME");
  510. if (xdg_config_home == NULL)
  511. {
  512. if (!(xdg_config_home = pathname_cat(home_dir, DEFAULT_XDG_CONFIG))) goto fail;
  513. }
  514. if (!(xdg_log_home = pathname_cat(home_dir, DEFAULT_XDG_LOG))) goto fail;
  515. if (!(g_jackdbus_config_dir = pathname_cat(xdg_config_home, JACKDBUS_DIR))) goto fail;
  516. if (!(g_jackdbus_log_dir = pathname_cat(xdg_log_home, JACKDBUS_DIR))) goto fail;
  517. if (!ensure_dir_exist(xdg_config_home, 0700))
  518. {
  519. goto fail;
  520. }
  521. if (!ensure_dir_exist(xdg_log_home, 0700))
  522. {
  523. goto fail;
  524. }
  525. if (!ensure_dir_exist(g_jackdbus_config_dir, 0700))
  526. {
  527. free(g_jackdbus_config_dir);
  528. goto fail;
  529. }
  530. g_jackdbus_config_dir_len = strlen(g_jackdbus_config_dir);
  531. if (!ensure_dir_exist(g_jackdbus_log_dir, 0700))
  532. {
  533. free(g_jackdbus_log_dir);
  534. goto fail;
  535. }
  536. g_jackdbus_log_dir_len = strlen(g_jackdbus_log_dir);
  537. return true;
  538. fail:
  539. return false;
  540. }
  541. void
  542. paths_uninit()
  543. {
  544. free(g_jackdbus_config_dir);
  545. free(g_jackdbus_log_dir);
  546. }
  547. int
  548. log_init()
  549. {
  550. char *log_filename;
  551. size_t log_len;
  552. log_len = strlen(JACKDBUS_LOG);
  553. log_filename = malloc(g_jackdbus_log_dir_len + log_len + 1);
  554. if (log_filename == NULL)
  555. {
  556. fprintf(stderr, "Out of memory\n");
  557. return FALSE;
  558. }
  559. memcpy(log_filename, g_jackdbus_log_dir, g_jackdbus_log_dir_len);
  560. memcpy(log_filename + g_jackdbus_log_dir_len, JACKDBUS_LOG, log_len);
  561. log_filename[g_jackdbus_log_dir_len + log_len] = 0;
  562. g_logfile = fopen(log_filename, "a");
  563. if (g_logfile == NULL)
  564. {
  565. fprintf(stderr, "Cannot open jackdbus log file \"%s\": %d (%s)\n", log_filename, errno, strerror(errno));
  566. free(log_filename);
  567. return FALSE;
  568. }
  569. free(log_filename);
  570. return TRUE;
  571. }
  572. void
  573. log_uninit()
  574. {
  575. fclose(g_logfile);
  576. }
  577. void
  578. jack_dbus_error(
  579. void *dbus_call_context_ptr,
  580. const char *error_name,
  581. const char *format,
  582. ...)
  583. {
  584. va_list ap;
  585. char buffer[300];
  586. va_start(ap, format);
  587. vsnprintf(buffer, sizeof(buffer), format, ap);
  588. jack_error_callback(buffer);
  589. if (dbus_call_context_ptr != NULL)
  590. {
  591. ((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = dbus_message_new_error(
  592. ((struct jack_dbus_method_call *)dbus_call_context_ptr)->message,
  593. error_name,
  594. buffer);
  595. }
  596. va_end(ap);
  597. }
  598. int
  599. main (int argc, char **argv)
  600. {
  601. DBusError error;
  602. int ret;
  603. void *controller_ptr;
  604. struct stat st;
  605. char timestamp_str[26];
  606. st.st_mtime = 0;
  607. stat(argv[0], &st);
  608. ctime_r(&st.st_mtime, timestamp_str);
  609. timestamp_str[24] = 0;
  610. if (!jack_controller_settings_init())
  611. {
  612. ret = 1;
  613. goto fail;
  614. }
  615. if (argc != 2 || strcmp(argv[1], "auto") != 0)
  616. {
  617. ret = 0;
  618. fprintf(
  619. stderr,
  620. "jackdbus should be auto-executed by D-Bus message bus daemon.\n"
  621. "If you want to run it manually anyway, specify \"auto\" as only parameter\n");
  622. goto fail_uninit_xml;
  623. }
  624. if (!paths_init())
  625. {
  626. ret = 1;
  627. goto fail_uninit_xml;
  628. }
  629. if (!log_init())
  630. {
  631. ret = 1;
  632. goto fail_uninit_paths;
  633. }
  634. #if !defined(DISABLE_SIGNAL_MAGIC)
  635. jackctl_setup_signals(0);
  636. #endif
  637. jack_set_error_function(jack_dbus_error_callback);
  638. jack_set_info_function(jack_dbus_info_callback);
  639. /* setup our SIGSEGV magic that prints nice stack in our logfile */
  640. setup_sigsegv();
  641. jack_info("------------------");
  642. jack_info("Controller activated. Version %s (%s) built on %s", jack_get_version_string(), SVN_VERSION, timestamp_str);
  643. if (!dbus_threads_init_default())
  644. {
  645. jack_error("dbus_threads_init_default() failed");
  646. ret = 1;
  647. goto fail_uninit_log;
  648. }
  649. dbus_error_init (&error);
  650. g_connection = dbus_bus_get (DBUS_BUS_SESSION, &error);
  651. if (dbus_error_is_set (&error))
  652. {
  653. jack_error("Cannot connect to D-Bus session bus: %s", error.message);
  654. ret = 1;
  655. goto fail_uninit_log;
  656. }
  657. ret = dbus_bus_request_name(
  658. g_connection,
  659. "org.jackaudio.service",
  660. DBUS_NAME_FLAG_DO_NOT_QUEUE,
  661. &error);
  662. if (ret == -1)
  663. {
  664. jack_error("Cannot request service name: %s", error.message);
  665. dbus_error_free(&error);
  666. ret = 1;
  667. goto fail_unref_connection;
  668. }
  669. else if (ret == DBUS_REQUEST_NAME_REPLY_EXISTS)
  670. {
  671. jack_error("Requested D-Bus service name already exists");
  672. ret = 1;
  673. goto fail_unref_connection;
  674. }
  675. controller_ptr = jack_controller_create(g_connection);
  676. if (controller_ptr == NULL)
  677. {
  678. ret = 1;
  679. goto fail_unref_connection;
  680. }
  681. jack_info("Listening for D-Bus messages");
  682. g_exit_command = FALSE;
  683. while (!g_exit_command && dbus_connection_read_write_dispatch (g_connection, 200));
  684. jack_controller_destroy(controller_ptr);
  685. jack_info("Controller deactivated.");
  686. ret = 0;
  687. fail_unref_connection:
  688. dbus_connection_unref(g_connection);
  689. fail_uninit_log:
  690. log_uninit();
  691. fail_uninit_paths:
  692. paths_uninit();
  693. fail_uninit_xml:
  694. jack_controller_settings_uninit();
  695. fail:
  696. return ret;
  697. }