| 
							- /* -*- Mode: C ; c-basic-offset: 4 -*- */
 - /*
 -     Copyright (C) 2007,2008,2010 Nedko Arnaudov
 -     Copyright (C) 2007-2008 Juuso Alasuutari
 -     Copyright (C) 2008 Marc-Olivier Barre
 - 
 -     This program is free software; you can redistribute it and/or modify
 -     it under the terms of the GNU General Public License as published by
 -     the Free Software Foundation; either version 2 of the License.
 - 
 -     This program is distributed in the hope that it will be useful,
 -     but WITHOUT ANY WARRANTY; without even the implied warranty of
 -     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 -     GNU General Public License for more details.
 - 
 -     You should have received a copy of the GNU General Public License
 -     along with this program; if not, write to the Free Software
 -     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 - 
 - */
 - 
 - #if defined(HAVE_CONFIG_H)
 - #include "config.h"
 - #endif
 - 
 - #include <stdbool.h>
 - #include <stdlib.h>
 - #include <stdio.h>
 - #include <string.h>
 - #include <errno.h>
 - #include <sys/stat.h>
 - #include <signal.h>
 - #include <dbus/dbus.h>
 - #include <pthread.h>
 - #include <unistd.h>
 - 
 - #include "config.h"
 - 
 - #include "jackdbus.h"
 - #include "controller.h"
 - #include "jack/jack.h"
 - #include "jack/jslist.h"
 - #include "jack/control.h"
 - #include "sigsegv.h"
 - 
 - static char * g_log_filename;
 - static ino_t g_log_file_ino;
 - FILE *g_logfile;
 - char *g_jackdbus_config_dir;
 - size_t g_jackdbus_config_dir_len; /* without terminating '\0' char */
 - char *g_jackdbus_log_dir;
 - size_t g_jackdbus_log_dir_len; /* without terminating '\0' char */
 - int g_exit_command;
 - DBusConnection *g_connection;
 - 
 - void
 - jack_dbus_send_signal(
 -     const char *sender_object_path,
 -     const char *iface,
 -     const char *signal_name,
 -     int first_arg_type,
 -     ...)
 - {
 -     DBusMessage *message_ptr;
 -     va_list ap;
 - 
 -     va_start(ap, first_arg_type);
 - 
 -     message_ptr = dbus_message_new_signal(sender_object_path, iface, signal_name);
 -     if (message_ptr == NULL)
 -     {
 -         jack_error("dbus_message_new_signal() failed.");
 -         goto exit;
 -     }
 - 
 -     if (!dbus_message_append_args_valist(message_ptr, first_arg_type, ap))
 -     {
 -         jack_error("dbus_message_append_args_valist() failed.");
 -         goto unref;
 -     }
 - 
 -     /* Add message to outgoing message queue */
 -     if (!dbus_connection_send(g_connection, message_ptr, NULL))
 -     {
 -         jack_error("dbus_connection_send() failed.");
 -         goto unref;
 -     }
 - 
 - unref:
 -     dbus_message_unref(message_ptr);
 - 
 - exit:
 -     va_end(ap);
 - }
 - 
 - /*
 -  * Send a method return.
 -  *
 -  * If call->reply is NULL (i.e. a message construct method failed
 -  * due to lack of memory) attempt to send a void method return.
 -  */
 - static
 - void
 - jack_dbus_send_method_return(
 -     struct jack_dbus_method_call * call)
 - {
 -     if (call->message == NULL)
 -     {
 -         /* async call */
 -         return;
 -     }
 - 
 -     if (call->reply)
 -     {
 -     retry_send:
 -         if (!dbus_connection_send (call->connection, call->reply, NULL))
 -         {
 -             jack_error ("Ran out of memory trying to queue method return");
 -         }
 - 
 -         dbus_connection_flush (call->connection);
 -         dbus_message_unref (call->reply);
 -         call->reply = NULL;
 -     }
 -     else
 -     {
 -         jack_error ("send_method_return() called with a NULL message,"
 -                     " trying to construct a void return...");
 - 
 -         if ((call->reply = dbus_message_new_method_return (call->message)))
 -         {
 -             goto retry_send;
 -         }
 -         else
 -         {
 -             jack_error ("Failed to construct method return!");
 -         }
 -     }
 - }
 - 
 - #define object_ptr ((struct jack_dbus_object_descriptor *)data)
 - 
 - /*
 -  * The D-Bus message handler for object path /org/jackaudio/Controller.
 -  */
 - DBusHandlerResult
 - jack_dbus_message_handler(
 -     DBusConnection *connection,
 -     DBusMessage *message,
 -     void *data)
 - {
 -     struct jack_dbus_method_call call;
 -     const char *interface_name;
 -     struct jack_dbus_interface_descriptor ** interface_ptr_ptr;
 - 
 -     /* Check if the message is a method call. If not, ignore it. */
 -     if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
 -     {
 -         goto handled;
 -     }
 - 
 -     /* Get the invoked method's name and make sure it's non-NULL. */
 -     if (!(call.method_name = dbus_message_get_member (message)))
 -     {
 -         jack_dbus_error(
 -             &call,
 -             JACK_DBUS_ERROR_UNKNOWN_METHOD,
 -             "Received method call with empty method name");
 -         goto send_return;
 -     }
 - 
 -     /* Initialize our data. */
 -     call.context = object_ptr->context;
 -     call.connection = connection;
 -     call.message = message;
 -     call.reply = NULL;
 - 
 -     /* Check if there's an interface specified for this method call. */
 -     interface_name = dbus_message_get_interface (message);
 -     if (interface_name != NULL)
 -     {
 -         /* Check if we can match the interface and method.
 -          * The interface handler functions only return false if the
 -          * method name was unknown, otherwise they run the specified
 -          * method and return TRUE.
 -          */
 - 
 -         interface_ptr_ptr = object_ptr->interfaces;
 - 
 -         while (*interface_ptr_ptr != NULL)
 -         {
 -             if (strcmp(interface_name, (*interface_ptr_ptr)->name) == 0)
 -             {
 -                 if (!(*interface_ptr_ptr)->handler(&call, (*interface_ptr_ptr)->methods))
 -                 {
 -                     break;
 -                 }
 - 
 -                 goto send_return;
 -             }
 - 
 -             interface_ptr_ptr++;
 -         }
 -     }
 -     else
 -     {
 -         /* No interface was specified so we have to try them all. This is
 -          * dictated by the D-Bus specification which states that method calls
 -          * omitting the interface must never be rejected.
 -          */
 - 
 -         interface_ptr_ptr = object_ptr->interfaces;
 - 
 -         while (*interface_ptr_ptr != NULL)
 -         {
 -             if ((*interface_ptr_ptr)->handler(&call, (*interface_ptr_ptr)->methods))
 -             {
 -                 goto send_return;
 -             }
 - 
 -             interface_ptr_ptr++;
 -         }
 -     }
 - 
 -     jack_dbus_error(
 -         &call,
 -         JACK_DBUS_ERROR_UNKNOWN_METHOD,
 -         "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist",
 -         call.method_name,
 -         dbus_message_get_signature(message),
 -         interface_name);
 - 
 - send_return:
 -     jack_dbus_send_method_return(&call);
 - 
 - handled:
 -     return DBUS_HANDLER_RESULT_HANDLED;
 - }
 - 
 - void
 - jack_dbus_message_handler_unregister(
 -     DBusConnection *connection,
 -     void *data)
 - {
 -     jack_info ("Message handler was unregistered");
 - }
 - 
 - #undef object_ptr
 - 
 - /*
 -  * Check if the supplied method name exists in org.jackaudio.JackConfigure,
 -  * if it does execute it and return TRUE. Otherwise return FALSE.
 -  */
 - bool
 - jack_dbus_run_method(
 -     struct jack_dbus_method_call *call,
 -     const struct jack_dbus_interface_method_descriptor * methods)
 - {
 -     const struct jack_dbus_interface_method_descriptor * method_ptr;
 - 
 -     method_ptr = methods;
 - 
 -     while (method_ptr->name != NULL)
 -     {
 -         if (strcmp(call->method_name, method_ptr->name) == 0)
 -         {
 -             method_ptr->handler(call);
 -             return TRUE;
 -         }
 - 
 -         method_ptr++;
 -     }
 - 
 -     return FALSE;
 - }
 - 
 - /*
 -  * Read arguments from a method call.
 -  * If the operation fails construct an error and return false,
 -  * otherwise return true.
 -  */
 - bool
 - jack_dbus_get_method_args(
 -     struct jack_dbus_method_call *call,
 -     int type,
 -     ...)
 - {
 -     va_list args;
 -     DBusError error;
 -     bool retval = true;
 - 
 -     va_start (args, type);
 -     dbus_error_init (&error);
 - 
 -     if (!dbus_message_get_args_valist (call->message, &error, type, args))
 -     {
 -         jack_dbus_error (call, JACK_DBUS_ERROR_INVALID_ARGS,
 -                          "Invalid arguments to method \"%s\"",
 -                          call->method_name);
 -         retval = false;
 -     }
 - 
 -     dbus_error_free (&error);
 -     va_end (args);
 - 
 -     return retval;
 - }
 - 
 - /*
 -  * Read a string and a variant argument from a method call.
 -  * If the operation fails construct an error and return false,
 -  * otherwise return true.
 -  */
 - bool
 - jack_dbus_get_method_args_string_and_variant(
 -     struct jack_dbus_method_call *call,
 -     const char **arg1,
 -     message_arg_t *arg2,
 -     int *type_ptr)
 - {
 -     DBusMessageIter iter, sub_iter;
 - 
 -     /* First we want a string... */
 -     if (dbus_message_iter_init (call->message, &iter)
 -         && dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING)
 -     {
 -         dbus_message_iter_get_basic (&iter, arg1);
 -         dbus_message_iter_next (&iter);
 - 
 -         /* ...and then a variant. */
 -         if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_VARIANT)
 -         {
 -             dbus_message_iter_recurse (&iter, &sub_iter);
 -             dbus_message_iter_get_basic (&sub_iter, arg2);
 -             *type_ptr = dbus_message_iter_get_arg_type (&sub_iter);
 - 
 -             /* Got what we wanted. */
 -             return true;
 -         }
 -     }
 - 
 -     jack_dbus_error (call, JACK_DBUS_ERROR_INVALID_ARGS,
 -                      "Invalid arguments to method \"%s\"",
 -                      call->method_name);
 - 
 -     return false;
 - }
 - 
 - /*
 -  * Read two strings and a variant argument from a method call.
 -  * If the operation fails construct an error and return false,
 -  * otherwise return true.
 -  */
 - bool
 - jack_dbus_get_method_args_two_strings_and_variant(
 -     struct jack_dbus_method_call *call,
 -     const char **arg1,
 -     const char **arg2,
 -     message_arg_t *arg3,
 -     int *type_ptr)
 - {
 -     DBusMessageIter iter, sub_iter;
 - 
 -     /* First we want a string... */
 -     if (dbus_message_iter_init (call->message, &iter)
 -         && dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING)
 -     {
 -         dbus_message_iter_get_basic (&iter, arg1);
 -         dbus_message_iter_next (&iter);
 -         
 -         /* ...and then a second string. */
 -         if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
 -         {
 -             return false;
 -         }
 -         
 -         /* Got what we wanted. */
 -         dbus_message_iter_get_basic (&iter, arg2);
 -         dbus_message_iter_next (&iter);
 - 
 -         /* ...and then a variant. */
 -         if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_VARIANT)
 -         {
 -             dbus_message_iter_recurse (&iter, &sub_iter);
 -             dbus_message_iter_get_basic (&sub_iter, arg3);
 -             *type_ptr = dbus_message_iter_get_arg_type (&sub_iter);
 - 
 -             /* Got what we wanted. */
 -             return true;
 -         }
 -     }
 - 
 -     jack_dbus_error (call, JACK_DBUS_ERROR_INVALID_ARGS,
 -                      "Invalid arguments to method \"%s\"",
 -                      call->method_name);
 - 
 -     return false;
 - }
 - 
 - /*
 -  * Append a variant type to a D-Bus message.
 -  * Return false if something fails, true otherwise.
 -  */
 - bool
 - jack_dbus_message_append_variant(
 -     DBusMessageIter *iter,
 -     int type,
 -     const char *signature,
 -     message_arg_t *arg)
 - {
 -     DBusMessageIter sub_iter;
 - 
 -     /* Open a variant container. */
 -     if (!dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, signature, &sub_iter))
 -     {
 -         goto fail;
 -     }
 - 
 -     /* Append the supplied value. */
 -     if (!dbus_message_iter_append_basic (&sub_iter, type, (const void *) arg))
 -     {
 -         dbus_message_iter_close_container (iter, &sub_iter);
 -         goto fail;
 -     }
 - 
 -     /* Close the container. */
 -     if (!dbus_message_iter_close_container (iter, &sub_iter))
 -     {
 -         goto fail;
 -     }
 - 
 -     return true;
 - 
 - fail:
 -     return false;
 - }
 - 
 - /*
 -  * Construct an empty method return message.
 -  *
 -  * The operation can only fail due to lack of memory, in which case
 -  * there's no sense in trying to construct an error return. Instead,
 -  * call->reply will be set to NULL and handled in send_method_return().
 -  */
 - void
 - jack_dbus_construct_method_return_empty(
 -     struct jack_dbus_method_call * call)
 - {
 -     call->reply = dbus_message_new_method_return (call->message);
 - 
 -     if (call->reply == NULL)
 -     {
 -         jack_error ("Ran out of memory trying to construct method return");
 -     }
 - }
 - 
 - /*
 -  * Construct a method return which holds a single argument or, if
 -  * the type parameter is DBUS_TYPE_INVALID, no arguments at all
 -  * (a void message).
 -  *
 -  * The operation can only fail due to lack of memory, in which case
 -  * there's no sense in trying to construct an error return. Instead,
 -  * call->reply will be set to NULL and handled in send_method_return().
 -  */
 - void
 - jack_dbus_construct_method_return_single(
 -     struct jack_dbus_method_call *call,
 -     int type,
 -     message_arg_t arg)
 - {
 -     DBusMessageIter iter;
 -     call->reply = dbus_message_new_method_return (call->message);
 - 
 -     if (call->reply == NULL)
 -     {
 -         goto fail_no_mem;
 -     }
 - 
 -     /* Void method return requested by caller. */
 -     if (type == DBUS_TYPE_INVALID)
 -     {
 -         return;
 -     }
 - 
 -     /* Prevent crash on NULL input string. */
 -     else if (type == DBUS_TYPE_STRING && arg.string == NULL)
 -     {
 -         arg.string = "";
 -     }
 - 
 -     dbus_message_iter_init_append (call->reply, &iter);
 - 
 -     if (!dbus_message_iter_append_basic (&iter, type, (const void *) &arg))
 -     {
 -         dbus_message_unref (call->reply);
 -         call->reply = NULL;
 -         goto fail_no_mem;
 -     }
 - 
 -     return;
 - 
 - fail_no_mem:
 -     jack_error ("Ran out of memory trying to construct method return");
 - }
 - 
 - /*
 -  * Construct a method return which holds an array of strings.
 -  *
 -  * The operation can only fail due to lack of memory, in which case
 -  * there's no sense in trying to construct an error return. Instead,
 -  * call->reply will be set to NULL and handled in send_method_return().
 -  */
 - void
 - jack_dbus_construct_method_return_array_of_strings(
 -     struct jack_dbus_method_call *call,
 -     unsigned int num_members,
 -     const char **array)
 - {
 -     DBusMessageIter iter, sub_iter;
 -     unsigned int i;
 - 
 -     call->reply = dbus_message_new_method_return (call->message);
 -     if (!call->reply)
 -     {
 -         goto fail;
 -     }
 - 
 -     dbus_message_iter_init_append (call->reply, &iter);
 - 
 -     if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s", &sub_iter))
 -     {
 -         goto fail_unref;
 -     }
 - 
 -     for (i = 0; i < num_members; ++i)
 -     {
 -         if (!dbus_message_iter_append_basic (&sub_iter, DBUS_TYPE_STRING, (const void *) &array[i]))
 -         {
 -             dbus_message_iter_close_container (&iter, &sub_iter);
 -             goto fail_unref;
 -         }
 -     }
 - 
 -     if (!dbus_message_iter_close_container (&iter, &sub_iter))
 -     {
 -         goto fail_unref;
 -     }
 - 
 -     return;
 - 
 - fail_unref:
 -     dbus_message_unref (call->reply);
 -     call->reply = NULL;
 - 
 - fail:
 -     jack_error ("Ran out of memory trying to construct method return");
 - }
 - 
 - static bool jack_dbus_log_open(void)
 - {
 -     struct stat st;
 -     int ret;
 -     int retry;
 - 
 -     if (g_logfile != NULL)
 -     {
 -         ret = stat(g_log_filename, &st);
 -         if (ret != 0 || g_log_file_ino != st.st_ino)
 -         {
 -             fclose(g_logfile);
 -         }
 -         else
 -         {
 -             return true;
 -         }
 -     }
 - 
 -     for (retry = 0; retry < 10; retry++)
 -     {
 -         g_logfile = fopen(g_log_filename, "a");
 -         if (g_logfile == NULL)
 -         {
 -             fprintf(stderr, "Cannot open jackdbus log file \"%s\": %d (%s)\n", g_log_filename, errno, strerror(errno));
 -             return false;
 -         }
 - 
 -         ret = stat(g_log_filename, &st);
 -         if (ret == 0)
 -         {
 -             g_log_file_ino = st.st_ino;
 -             return true;
 -         }
 - 
 -         fclose(g_logfile);
 -         g_logfile = NULL;
 -     }
 - 
 -     fprintf(stderr, "Cannot stat just opened jackdbus log file \"%s\": %d (%s). %d retries\n", g_log_filename, errno, strerror(errno), retry);
 -     return false;
 - }
 - 
 - void 
 - jack_dbus_info_callback(const char *msg)
 - {
 -     time_t timestamp;
 -     char timestamp_str[26];
 - 
 -     time(×tamp);
 -     ctime_r(×tamp, timestamp_str);
 -     timestamp_str[24] = 0;
 - 
 -     if (jack_dbus_log_open())
 -     {
 -         fprintf(g_logfile, "%s: %s\n", timestamp_str, msg);
 -         fflush(g_logfile);
 -     }
 - }
 - 
 - #define ANSI_BOLD_ON    "\033[1m"
 - #define ANSI_BOLD_OFF   "\033[22m"
 - #define ANSI_COLOR_RED  "\033[31m"
 - #define ANSI_RESET      "\033[0m"
 - 
 - void 
 - jack_dbus_error_callback(const char *msg)
 - {
 -     time_t timestamp;
 -     char timestamp_str[26];
 - 
 -     time(×tamp);
 -     ctime_r(×tamp, timestamp_str);
 -     timestamp_str[24] = 0;
 - 
 -     if (jack_dbus_log_open())
 -     {
 -         fprintf(g_logfile, "%s: " ANSI_BOLD_ON ANSI_COLOR_RED "ERROR: %s" ANSI_RESET "\n", timestamp_str, msg);
 -         fflush(g_logfile);
 -     }
 - }
 - 
 - bool
 - ensure_dir_exist(const char *dirname, int mode)
 - {
 -     struct stat st;
 -     if (stat(dirname, &st) != 0)
 -     {
 -         if (errno == ENOENT)
 -         {
 -             printf("Directory \"%s\" does not exist. Creating...\n", dirname);
 -             if (mkdir(dirname, mode) != 0)
 -             {
 -                 fprintf(stderr, "Failed to create \"%s\" directory: %d (%s)\n", dirname, errno, strerror(errno));
 -                 return false;
 -             }
 -         }
 -         else
 -         {
 -             fprintf(stderr, "Failed to stat \"%s\": %d (%s)\n", dirname, errno, strerror(errno));
 -             return false;
 -         }
 -     }
 -     else
 -     {
 -         if (!S_ISDIR(st.st_mode))
 -         {
 -             fprintf(stderr, "\"%s\" exists but is not directory.\n", dirname);
 -             return false;
 -         }
 -     }
 -     return true;
 - }
 - 
 - char *
 - pathname_cat(const char *pathname_a, const char *pathname_b)
 - {
 -     char *pathname;
 -     int pathname_a_len, pathname_b_len, pathname_len;
 -     pathname_a_len = strlen(pathname_a);
 -     pathname_b_len = strlen(pathname_b);
 -     pathname = malloc(pathname_a_len + pathname_b_len + 1);
 -     if (pathname == NULL)
 -     {
 -         fprintf(stderr, "Out of memory\n");
 -         return NULL;
 -     }
 -     memcpy(pathname, pathname_a, pathname_a_len);
 -     memcpy(pathname + pathname_a_len, pathname_b, pathname_b_len);
 -     pathname_len = pathname_a_len + pathname_b_len;
 -     pathname[pathname_len] = 0;
 -     return pathname;
 - }
 - 
 - bool
 - paths_init()
 - {
 - 	const char *home_dir, *xdg_config_home, *xdg_log_home;
 -     
 -     home_dir = getenv("HOME");
 -     if (home_dir == NULL)
 -     {
 -         fprintf(stderr, "Environment variable HOME not set\n");
 -         goto fail;
 -     }
 - 
 - 	xdg_config_home = getenv("XDG_CONFIG_HOME");
 - 	if (xdg_config_home == NULL)
 - 	{
 - 	    if (!(xdg_config_home = pathname_cat(home_dir, DEFAULT_XDG_CONFIG))) goto fail;
 - 	}
 - 
 -     if (!(xdg_log_home = pathname_cat(home_dir, DEFAULT_XDG_LOG))) goto fail;
 - 
 - 	if (!(g_jackdbus_config_dir = pathname_cat(xdg_config_home, JACKDBUS_DIR))) goto fail;
 - 	if (!(g_jackdbus_log_dir = pathname_cat(xdg_log_home, JACKDBUS_DIR))) goto fail;
 - 
 -     if (!ensure_dir_exist(xdg_config_home, 0700))
 -     {
 -         goto fail;
 -     }
 -     
 -     if (!ensure_dir_exist(xdg_log_home, 0700))
 -     {
 -         goto fail;
 -     }
 - 
 -     if (!ensure_dir_exist(g_jackdbus_config_dir, 0700))
 -     {
 -         free(g_jackdbus_config_dir);
 -         goto fail;
 -     }
 -     g_jackdbus_config_dir_len = strlen(g_jackdbus_config_dir);
 -     
 -     if (!ensure_dir_exist(g_jackdbus_log_dir, 0700))
 -     {
 -         free(g_jackdbus_log_dir);
 -         goto fail;
 -     }
 -     g_jackdbus_log_dir_len = strlen(g_jackdbus_log_dir);
 - 
 -     return true;
 - 
 - fail:
 -     return false;
 - }
 - 
 - void
 - paths_uninit()
 - {
 -     free(g_jackdbus_config_dir);
 -     free(g_jackdbus_log_dir);
 - }
 - 
 - static bool log_init(void)
 - {
 -     size_t log_len;
 - 
 -     log_len = strlen(JACKDBUS_LOG);
 - 
 -     g_log_filename = malloc(g_jackdbus_log_dir_len + log_len + 1);
 -     if (g_log_filename == NULL)
 -     {
 -         fprintf(stderr, "Out of memory\n");
 -         return false;
 -     }
 - 
 -     memcpy(g_log_filename, g_jackdbus_log_dir, g_jackdbus_log_dir_len);
 -     memcpy(g_log_filename + g_jackdbus_log_dir_len, JACKDBUS_LOG, log_len);
 -     g_log_filename[g_jackdbus_log_dir_len + log_len] = 0;
 - 
 -     if (!jack_dbus_log_open())
 -     {
 -         return false;
 -     }
 - 
 -     return true;
 - }
 - 
 - static void log_uninit(void)
 - {
 -     if (g_logfile != NULL)
 -     {
 -         fclose(g_logfile);
 -     }
 - 
 -     free(g_log_filename);
 - }
 - 
 - void
 - jack_dbus_error(
 -     void *dbus_call_context_ptr,
 -     const char *error_name,
 -     const char *format,
 -     ...)
 - {
 -     va_list ap;
 -     char buffer[300];
 - 
 -     va_start(ap, format);
 - 
 -     vsnprintf(buffer, sizeof(buffer), format, ap);
 - 
 -     jack_error_callback(buffer);
 -     if (dbus_call_context_ptr != NULL)
 -     {
 -         if (((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply != NULL)
 -         {
 -             dbus_message_unref(((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply);
 -             ((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = NULL;
 -         }
 - 
 -         ((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = dbus_message_new_error(
 -             ((struct jack_dbus_method_call *)dbus_call_context_ptr)->message,
 -             error_name,
 -             buffer);
 -     }
 - 
 -     va_end(ap);
 - }
 - 
 - void
 - jack_dbus_only_error(
 -     void *dbus_call_context_ptr,
 -     const char *error_name,
 -     const char *format,
 -     ...)
 - {
 -     va_list ap;
 -     char buffer[300];
 - 
 -     va_start(ap, format);
 - 
 -     vsnprintf(buffer, sizeof(buffer), format, ap);
 - 
 -     if (((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply != NULL)
 -     {
 -         dbus_message_unref(((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply);
 -         ((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = NULL;
 -     }
 - 
 -     ((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = dbus_message_new_error(
 -         ((struct jack_dbus_method_call *)dbus_call_context_ptr)->message,
 -         error_name,
 -         buffer);
 - 
 -     va_end(ap);
 - }
 - 
 - int
 - main (int argc, char **argv)
 - {
 -     DBusError error;
 -     int ret;
 -     void *controller_ptr;
 -     struct stat st;
 -     char timestamp_str[26];
 - 
 -     st.st_mtime = 0;
 -     stat(argv[0], &st);
 -     ctime_r(&st.st_mtime, timestamp_str);
 -     timestamp_str[24] = 0;
 - 
 -     if (!jack_controller_settings_init())
 -     {
 -         ret = 1;
 -         goto fail;
 -     }
 - 
 -     if (argc != 2 || strcmp(argv[1], "auto") != 0)
 -     {
 -         ret = 0;
 -         fprintf(
 -             stderr,
 -             "jackdbus should be auto-executed by D-Bus message bus daemon.\n"
 -             "If you want to run it manually anyway, specify \"auto\" as only parameter\n");
 -         goto fail_uninit_xml;
 -     }
 - 
 -     if (!paths_init())
 -     {
 -         ret = 1;
 -         goto fail_uninit_xml;
 -     }
 - 
 -     if (!log_init())
 -     {
 -         ret = 1;
 -         goto fail_uninit_paths;
 -     }
 - 
 - #if !defined(DISABLE_SIGNAL_MAGIC)
 -     jackctl_setup_signals(0);
 - #endif
 - 
 -     jack_set_error_function(jack_dbus_error_callback);
 -     jack_set_info_function(jack_dbus_info_callback);
 - 
 -     /* setup our SIGSEGV magic that prints nice stack in our logfile */
 -     setup_sigsegv();
 - 
 -     jack_info("------------------");
 -     jack_info("Controller activated. Version %s (%s) built on %s", jack_get_version_string(), JACK_VERSION, timestamp_str);
 - 
 -     if (!dbus_threads_init_default())
 -     {
 -         jack_error("dbus_threads_init_default() failed");
 -         ret = 1;
 -         goto fail_uninit_log;
 -     }
 - 
 -     dbus_error_init (&error);
 -     g_connection = dbus_bus_get (DBUS_BUS_SESSION, &error);
 -     if (dbus_error_is_set (&error))
 -     {
 -         jack_error("Cannot connect to D-Bus session bus: %s", error.message);
 -         ret = 1;
 -         goto fail_uninit_log;
 -     }
 - 
 -     ret = dbus_bus_request_name(
 -                 g_connection,
 -                 "org.jackaudio.service",
 -                 DBUS_NAME_FLAG_DO_NOT_QUEUE,
 -                 &error);
 -     if (ret == -1)
 -     {
 -         jack_error("Cannot request service name: %s", error.message);
 -                 dbus_error_free(&error);
 -         ret = 1;
 -         goto fail_unref_connection;
 -     }
 -     else if (ret == DBUS_REQUEST_NAME_REPLY_EXISTS)
 -     {
 -         jack_error("Requested D-Bus service name already exists");
 -         ret = 1;
 -         goto fail_unref_connection;
 -     }
 - 
 -     controller_ptr = jack_controller_create(g_connection);
 - 
 -     if (controller_ptr == NULL)
 -     {
 -         ret = 1;
 -         goto fail_unref_connection;
 -     }
 - 
 -     jack_info("Listening for D-Bus messages");
 - 
 -     g_exit_command = FALSE;
 -     while (!g_exit_command && dbus_connection_read_write_dispatch (g_connection, 200))
 -     {
 -         jack_controller_run(controller_ptr);
 -     }
 - 
 -     jack_controller_destroy(controller_ptr);
 - 
 -     jack_info("Controller deactivated.");
 - 
 -     ret = 0;
 - 
 - fail_unref_connection:
 -     dbus_connection_unref(g_connection);
 - 
 - fail_uninit_log:
 -     log_uninit();
 - 
 - fail_uninit_paths:
 -     paths_uninit();
 - 
 - fail_uninit_xml:
 -     jack_controller_settings_uninit();
 - 
 - fail:
 -     return ret;
 - }
 
 
  |