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.

886 lines
22KB

  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. * Read two strings and a variant argument from a method call.
  290. * If the operation fails construct an error and return false,
  291. * otherwise return true.
  292. */
  293. bool
  294. jack_dbus_get_method_args_two_strings_and_variant(
  295. struct jack_dbus_method_call *call,
  296. const char **arg1,
  297. const char **arg2,
  298. message_arg_t *arg3,
  299. int *type_ptr)
  300. {
  301. DBusMessageIter iter, sub_iter;
  302. /* First we want a string... */
  303. if (dbus_message_iter_init (call->message, &iter)
  304. && dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING)
  305. {
  306. dbus_message_iter_get_basic (&iter, arg1);
  307. dbus_message_iter_next (&iter);
  308. /* ...and then a second string. */
  309. if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
  310. {
  311. return false;
  312. }
  313. /* Got what we wanted. */
  314. dbus_message_iter_get_basic (&iter, arg2);
  315. dbus_message_iter_next (&iter);
  316. /* ...and then a variant. */
  317. if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_VARIANT)
  318. {
  319. dbus_message_iter_recurse (&iter, &sub_iter);
  320. dbus_message_iter_get_basic (&sub_iter, arg3);
  321. *type_ptr = dbus_message_iter_get_arg_type (&sub_iter);
  322. /* Got what we wanted. */
  323. return true;
  324. }
  325. }
  326. jack_dbus_error (call, JACK_DBUS_ERROR_INVALID_ARGS,
  327. "Invalid arguments to method \"%s\"",
  328. call->method_name);
  329. return false;
  330. }
  331. /*
  332. * Append a variant type to a D-Bus message.
  333. * Return false if something fails, true otherwise.
  334. */
  335. bool
  336. jack_dbus_message_append_variant(
  337. DBusMessageIter *iter,
  338. int type,
  339. const char *signature,
  340. message_arg_t *arg)
  341. {
  342. DBusMessageIter sub_iter;
  343. /* Open a variant container. */
  344. if (!dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, signature, &sub_iter))
  345. {
  346. goto fail;
  347. }
  348. /* Append the supplied value. */
  349. if (!dbus_message_iter_append_basic (&sub_iter, type, (const void *) arg))
  350. {
  351. dbus_message_iter_close_container (iter, &sub_iter);
  352. goto fail;
  353. }
  354. /* Close the container. */
  355. if (!dbus_message_iter_close_container (iter, &sub_iter))
  356. {
  357. goto fail;
  358. }
  359. return true;
  360. fail:
  361. return false;
  362. }
  363. /*
  364. * Construct an empty method return message.
  365. *
  366. * The operation can only fail due to lack of memory, in which case
  367. * there's no sense in trying to construct an error return. Instead,
  368. * call->reply will be set to NULL and handled in send_method_return().
  369. */
  370. void
  371. jack_dbus_construct_method_return_empty(
  372. struct jack_dbus_method_call * call)
  373. {
  374. call->reply = dbus_message_new_method_return (call->message);
  375. if (call->reply == NULL)
  376. {
  377. jack_error ("Ran out of memory trying to construct method return");
  378. }
  379. }
  380. /*
  381. * Construct a method return which holds a single argument or, if
  382. * the type parameter is DBUS_TYPE_INVALID, no arguments at all
  383. * (a void message).
  384. *
  385. * The operation can only fail due to lack of memory, in which case
  386. * there's no sense in trying to construct an error return. Instead,
  387. * call->reply will be set to NULL and handled in send_method_return().
  388. */
  389. void
  390. jack_dbus_construct_method_return_single(
  391. struct jack_dbus_method_call *call,
  392. int type,
  393. message_arg_t arg)
  394. {
  395. DBusMessageIter iter;
  396. call->reply = dbus_message_new_method_return (call->message);
  397. if (call->reply == NULL)
  398. {
  399. goto fail_no_mem;
  400. }
  401. /* Void method return requested by caller. */
  402. if (type == DBUS_TYPE_INVALID)
  403. {
  404. return;
  405. }
  406. /* Prevent crash on NULL input string. */
  407. else if (type == DBUS_TYPE_STRING && arg.string == NULL)
  408. {
  409. arg.string = "";
  410. }
  411. dbus_message_iter_init_append (call->reply, &iter);
  412. if (!dbus_message_iter_append_basic (&iter, type, (const void *) &arg))
  413. {
  414. dbus_message_unref (call->reply);
  415. call->reply = NULL;
  416. goto fail_no_mem;
  417. }
  418. return;
  419. fail_no_mem:
  420. jack_error ("Ran out of memory trying to construct method return");
  421. }
  422. /*
  423. * Construct a method return which holds an array of strings.
  424. *
  425. * The operation can only fail due to lack of memory, in which case
  426. * there's no sense in trying to construct an error return. Instead,
  427. * call->reply will be set to NULL and handled in send_method_return().
  428. */
  429. void
  430. jack_dbus_construct_method_return_array_of_strings(
  431. struct jack_dbus_method_call *call,
  432. unsigned int num_members,
  433. const char **array)
  434. {
  435. DBusMessageIter iter, sub_iter;
  436. unsigned int i;
  437. call->reply = dbus_message_new_method_return (call->message);
  438. if (!call->reply)
  439. {
  440. goto fail;
  441. }
  442. dbus_message_iter_init_append (call->reply, &iter);
  443. if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s", &sub_iter))
  444. {
  445. goto fail_unref;
  446. }
  447. for (i = 0; i < num_members; ++i)
  448. {
  449. if (!dbus_message_iter_append_basic (&sub_iter, DBUS_TYPE_STRING, (const void *) &array[i]))
  450. {
  451. dbus_message_iter_close_container (&iter, &sub_iter);
  452. goto fail_unref;
  453. }
  454. }
  455. if (!dbus_message_iter_close_container (&iter, &sub_iter))
  456. {
  457. goto fail_unref;
  458. }
  459. return;
  460. fail_unref:
  461. dbus_message_unref (call->reply);
  462. call->reply = NULL;
  463. fail:
  464. jack_error ("Ran out of memory trying to construct method return");
  465. }
  466. void
  467. jack_dbus_info_callback(const char *msg)
  468. {
  469. time_t timestamp;
  470. char timestamp_str[26];
  471. time(&timestamp);
  472. ctime_r(&timestamp, timestamp_str);
  473. timestamp_str[24] = 0;
  474. fprintf(g_logfile, "%s: %s\n", timestamp_str, msg);
  475. fflush(g_logfile);
  476. }
  477. #define ANSI_BOLD_ON "\033[1m"
  478. #define ANSI_BOLD_OFF "\033[22m"
  479. #define ANSI_COLOR_RED "\033[31m"
  480. #define ANSI_RESET "\033[0m"
  481. void
  482. jack_dbus_error_callback(const char *msg)
  483. {
  484. time_t timestamp;
  485. char timestamp_str[26];
  486. time(&timestamp);
  487. ctime_r(&timestamp, timestamp_str);
  488. timestamp_str[24] = 0;
  489. fprintf(g_logfile, "%s: " ANSI_BOLD_ON ANSI_COLOR_RED "ERROR: %s" ANSI_RESET "\n", timestamp_str, msg);
  490. fflush(g_logfile);
  491. }
  492. bool
  493. ensure_dir_exist(const char *dirname, int mode)
  494. {
  495. struct stat st;
  496. if (stat(dirname, &st) != 0)
  497. {
  498. if (errno == ENOENT)
  499. {
  500. printf("Directory \"%s\" does not exist. Creating...\n", dirname);
  501. if (mkdir(dirname, mode) != 0)
  502. {
  503. fprintf(stderr, "Failed to create \"%s\" directory: %d (%s)\n", dirname, errno, strerror(errno));
  504. return false;
  505. }
  506. }
  507. else
  508. {
  509. fprintf(stderr, "Failed to stat \"%s\": %d (%s)\n", dirname, errno, strerror(errno));
  510. return false;
  511. }
  512. }
  513. else
  514. {
  515. if (!S_ISDIR(st.st_mode))
  516. {
  517. fprintf(stderr, "\"%s\" exists but is not directory.\n", dirname);
  518. return false;
  519. }
  520. }
  521. return true;
  522. }
  523. char *
  524. pathname_cat(const char *pathname_a, const char *pathname_b)
  525. {
  526. char *pathname;
  527. int pathname_a_len, pathname_b_len, pathname_len;
  528. pathname_a_len = strlen(pathname_a);
  529. pathname_b_len = strlen(pathname_b);
  530. pathname = malloc(pathname_a_len + pathname_b_len + 1);
  531. if (pathname == NULL)
  532. {
  533. fprintf(stderr, "Out of memory\n");
  534. return NULL;
  535. }
  536. memcpy(pathname, pathname_a, pathname_a_len);
  537. memcpy(pathname + pathname_a_len, pathname_b, pathname_b_len);
  538. pathname_len = pathname_a_len + pathname_b_len;
  539. pathname[pathname_len] = 0;
  540. return pathname;
  541. }
  542. bool
  543. paths_init()
  544. {
  545. const char *home_dir, *xdg_config_home, *xdg_log_home;
  546. home_dir = getenv("HOME");
  547. if (home_dir == NULL)
  548. {
  549. fprintf(stderr, "Environment variable HOME not set\n");
  550. goto fail;
  551. }
  552. xdg_config_home = getenv("XDG_CONFIG_HOME");
  553. if (xdg_config_home == NULL)
  554. {
  555. if (!(xdg_config_home = pathname_cat(home_dir, DEFAULT_XDG_CONFIG))) goto fail;
  556. }
  557. if (!(xdg_log_home = pathname_cat(home_dir, DEFAULT_XDG_LOG))) goto fail;
  558. if (!(g_jackdbus_config_dir = pathname_cat(xdg_config_home, JACKDBUS_DIR))) goto fail;
  559. if (!(g_jackdbus_log_dir = pathname_cat(xdg_log_home, JACKDBUS_DIR))) goto fail;
  560. if (!ensure_dir_exist(xdg_config_home, 0700))
  561. {
  562. goto fail;
  563. }
  564. if (!ensure_dir_exist(xdg_log_home, 0700))
  565. {
  566. goto fail;
  567. }
  568. if (!ensure_dir_exist(g_jackdbus_config_dir, 0700))
  569. {
  570. free(g_jackdbus_config_dir);
  571. goto fail;
  572. }
  573. g_jackdbus_config_dir_len = strlen(g_jackdbus_config_dir);
  574. if (!ensure_dir_exist(g_jackdbus_log_dir, 0700))
  575. {
  576. free(g_jackdbus_log_dir);
  577. goto fail;
  578. }
  579. g_jackdbus_log_dir_len = strlen(g_jackdbus_log_dir);
  580. return true;
  581. fail:
  582. return false;
  583. }
  584. void
  585. paths_uninit()
  586. {
  587. free(g_jackdbus_config_dir);
  588. free(g_jackdbus_log_dir);
  589. }
  590. int
  591. log_init()
  592. {
  593. char *log_filename;
  594. size_t log_len;
  595. log_len = strlen(JACKDBUS_LOG);
  596. log_filename = malloc(g_jackdbus_log_dir_len + log_len + 1);
  597. if (log_filename == NULL)
  598. {
  599. fprintf(stderr, "Out of memory\n");
  600. return FALSE;
  601. }
  602. memcpy(log_filename, g_jackdbus_log_dir, g_jackdbus_log_dir_len);
  603. memcpy(log_filename + g_jackdbus_log_dir_len, JACKDBUS_LOG, log_len);
  604. log_filename[g_jackdbus_log_dir_len + log_len] = 0;
  605. g_logfile = fopen(log_filename, "a");
  606. if (g_logfile == NULL)
  607. {
  608. fprintf(stderr, "Cannot open jackdbus log file \"%s\": %d (%s)\n", log_filename, errno, strerror(errno));
  609. free(log_filename);
  610. return FALSE;
  611. }
  612. free(log_filename);
  613. return TRUE;
  614. }
  615. void
  616. log_uninit()
  617. {
  618. fclose(g_logfile);
  619. }
  620. void
  621. jack_dbus_error(
  622. void *dbus_call_context_ptr,
  623. const char *error_name,
  624. const char *format,
  625. ...)
  626. {
  627. va_list ap;
  628. char buffer[300];
  629. va_start(ap, format);
  630. vsnprintf(buffer, sizeof(buffer), format, ap);
  631. jack_error_callback(buffer);
  632. if (dbus_call_context_ptr != NULL)
  633. {
  634. ((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = dbus_message_new_error(
  635. ((struct jack_dbus_method_call *)dbus_call_context_ptr)->message,
  636. error_name,
  637. buffer);
  638. }
  639. va_end(ap);
  640. }
  641. int
  642. main (int argc, char **argv)
  643. {
  644. DBusError error;
  645. int ret;
  646. void *controller_ptr;
  647. struct stat st;
  648. char timestamp_str[26];
  649. st.st_mtime = 0;
  650. stat(argv[0], &st);
  651. ctime_r(&st.st_mtime, timestamp_str);
  652. timestamp_str[24] = 0;
  653. if (!jack_controller_settings_init())
  654. {
  655. ret = 1;
  656. goto fail;
  657. }
  658. if (argc != 2 || strcmp(argv[1], "auto") != 0)
  659. {
  660. ret = 0;
  661. fprintf(
  662. stderr,
  663. "jackdbus should be auto-executed by D-Bus message bus daemon.\n"
  664. "If you want to run it manually anyway, specify \"auto\" as only parameter\n");
  665. goto fail_uninit_xml;
  666. }
  667. if (!paths_init())
  668. {
  669. ret = 1;
  670. goto fail_uninit_xml;
  671. }
  672. if (!log_init())
  673. {
  674. ret = 1;
  675. goto fail_uninit_paths;
  676. }
  677. #if !defined(DISABLE_SIGNAL_MAGIC)
  678. jackctl_setup_signals(0);
  679. #endif
  680. jack_set_error_function(jack_dbus_error_callback);
  681. jack_set_info_function(jack_dbus_info_callback);
  682. /* setup our SIGSEGV magic that prints nice stack in our logfile */
  683. setup_sigsegv();
  684. jack_info("------------------");
  685. jack_info("Controller activated. Version %s (%s) built on %s", jack_get_version_string(), SVN_VERSION, timestamp_str);
  686. if (!dbus_threads_init_default())
  687. {
  688. jack_error("dbus_threads_init_default() failed");
  689. ret = 1;
  690. goto fail_uninit_log;
  691. }
  692. dbus_error_init (&error);
  693. g_connection = dbus_bus_get (DBUS_BUS_SESSION, &error);
  694. if (dbus_error_is_set (&error))
  695. {
  696. jack_error("Cannot connect to D-Bus session bus: %s", error.message);
  697. ret = 1;
  698. goto fail_uninit_log;
  699. }
  700. ret = dbus_bus_request_name(
  701. g_connection,
  702. "org.jackaudio.service",
  703. DBUS_NAME_FLAG_DO_NOT_QUEUE,
  704. &error);
  705. if (ret == -1)
  706. {
  707. jack_error("Cannot request service name: %s", error.message);
  708. dbus_error_free(&error);
  709. ret = 1;
  710. goto fail_unref_connection;
  711. }
  712. else if (ret == DBUS_REQUEST_NAME_REPLY_EXISTS)
  713. {
  714. jack_error("Requested D-Bus service name already exists");
  715. ret = 1;
  716. goto fail_unref_connection;
  717. }
  718. controller_ptr = jack_controller_create(g_connection);
  719. if (controller_ptr == NULL)
  720. {
  721. ret = 1;
  722. goto fail_unref_connection;
  723. }
  724. jack_info("Listening for D-Bus messages");
  725. g_exit_command = FALSE;
  726. while (!g_exit_command && dbus_connection_read_write_dispatch (g_connection, 200));
  727. jack_controller_destroy(controller_ptr);
  728. jack_info("Controller deactivated.");
  729. ret = 0;
  730. fail_unref_connection:
  731. dbus_connection_unref(g_connection);
  732. fail_uninit_log:
  733. log_uninit();
  734. fail_uninit_paths:
  735. paths_uninit();
  736. fail_uninit_xml:
  737. jack_controller_settings_uninit();
  738. fail:
  739. return ret;
  740. }