# HG changeset patch # User Gabriel Schulhof # Date 1179261696 0 # Node ID 176d0fc8bc1690b786c0a394ffe037249caa1ba9 # Parent 9f5c9df302877e28aa3c2320e4ec4fae63ee6383 Alternative dbus_uniq implementation diff -r 9f5c9df30287 -r 176d0fc8bc16 libpurple/core.c --- a/libpurple/core.c Sun May 13 19:52:05 2007 +0000 +++ b/libpurple/core.c Tue May 15 20:41:36 2007 +0000 @@ -48,7 +48,11 @@ #include "util.h" #ifdef HAVE_DBUS +# define DBUS_API_SUBJECT_TO_CHANGE +# include +# include "dbus-purple.h" # include "dbus-server.h" +# include "dbus-bindings.h" #endif struct PurpleCore @@ -276,6 +280,85 @@ return _ops; } +#ifdef HAVE_DBUS +static char *purple_dbus_owner_user_dir(void) +{ + DBusMessage *msg = NULL, *reply = NULL; + DBusConnection *dbus_connection = NULL; + DBusError dbus_error; + char *remote_user_dir = NULL; + + if (NULL == (dbus_connection = purple_dbus_get_connection())) + return NULL; + + if (NULL == (msg = dbus_message_new_method_call(DBUS_SERVICE_PURPLE, DBUS_PATH_PURPLE, DBUS_INTERFACE_PURPLE, "PurpleUserDir"))) + return NULL; + + dbus_error_init(&dbus_error); + reply = dbus_connection_send_with_reply_and_block(dbus_connection, msg, 5000, &dbus_error); + dbus_message_unref(msg); + dbus_error_free(&dbus_error); + + if (NULL != reply) + { + dbus_error_init(&dbus_error); + dbus_message_get_args(reply, &dbus_error, DBUS_TYPE_STRING, &remote_user_dir, DBUS_TYPE_INVALID); + if (NULL != remote_user_dir) + remote_user_dir = g_strdup(remote_user_dir); + dbus_error_free(&dbus_error); + dbus_message_unref(reply); + } + + return remote_user_dir; +} + +static void purple_dbus_owner_show_buddy_list(void) +{ + DBusError dbus_error; + DBusMessage *msg = NULL, *reply = NULL; + DBusConnection *dbus_connection = purple_dbus_get_connection(); + + if (NULL == dbus_connection) return; + + if (NULL == (msg = dbus_message_new_method_call(DBUS_SERVICE_PURPLE, DBUS_PATH_PURPLE, DBUS_INTERFACE_PURPLE, "PurpleBlistShow"))) + return ; + + dbus_error_init(&dbus_error); + if (NULL != (reply = dbus_connection_send_with_reply_and_block(dbus_connection, msg, 5000, &dbus_error))) + dbus_message_unref(msg); + dbus_error_free(&dbus_error); +} +#endif /* HAVE_DBUS */ + +gboolean purple_core_ensure_single_instance() +{ +gboolean is_single_instance = TRUE; +#ifdef HAVE_DBUS + if (is_single_instance) /* in the future, other mechanisms might have already set this to FALSE */ + if (!purple_dbus_is_owner()) { + const char *user_dir = purple_user_dir(); + char *dbus_owner_user_dir = purple_dbus_owner_user_dir(); + + if (NULL == user_dir && NULL != dbus_owner_user_dir) + is_single_instance = TRUE; + else + if (NULL != user_dir && NULL == dbus_owner_user_dir) + is_single_instance = TRUE; + else + if (NULL == user_dir && NULL == dbus_owner_user_dir) + is_single_instance = FALSE; + else + is_single_instance = strcmp(dbus_owner_user_dir, user_dir); + + if (!is_single_instance) + purple_dbus_owner_show_buddy_list(); + + g_free(dbus_owner_user_dir); + } +#endif /* HAVE_DBUS */ + return is_single_instance; +} + static gboolean move_and_symlink_dir(const char *path, const char *basename, const char *old_base, const char *new_base, const char *relative) { diff -r 9f5c9df30287 -r 176d0fc8bc16 libpurple/core.h --- a/libpurple/core.h Sun May 13 19:52:05 2007 +0000 +++ b/libpurple/core.h Tue May 15 20:41:36 2007 +0000 @@ -121,6 +121,14 @@ */ gboolean purple_core_migrate(void); +/** + * Ensures that only one instance is running. + * + * @return A boolean such that success indicates that this is the first instance, + * whereas failure indicates that there is another instance running. + */ +gboolean purple_core_ensure_single_instance(void); + #ifdef __cplusplus } #endif diff -r 9f5c9df30287 -r 176d0fc8bc16 libpurple/dbus-server.c --- a/libpurple/dbus-server.c Sun May 13 19:52:05 2007 +0000 +++ b/libpurple/dbus-server.c Tue May 15 20:41:36 2007 +0000 @@ -65,6 +65,12 @@ static GHashTable *map_id_type; static gchar *init_error; +static int dbus_request_name_reply = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER; + +gboolean purple_dbus_is_owner(void) +{ + return(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER == dbus_request_name_reply); +} /** * This function initializes the pointer-id traslation system. It @@ -592,6 +598,7 @@ return; } + dbus_request_name_reply = result = dbus_bus_request_name(purple_dbus_connection, DBUS_SERVICE_PURPLE, 0, &error); @@ -604,25 +611,6 @@ return; } - if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - DBusMessage *msg = dbus_message_new_method_call(DBUS_SERVICE_PURPLE, DBUS_PATH_PURPLE, DBUS_INTERFACE_PURPLE, "PurpleBlistShow") ; - - if (NULL != msg) { - DBusMessage *reply = NULL ; - DBusError dbus_error ; - - dbus_error_init(&dbus_error) ; - reply = dbus_connection_send_with_reply_and_block(purple_dbus_connection, msg, 5000, &dbus_error) ; - dbus_message_unref(msg) ; - if (NULL != reply) - dbus_message_unref(reply) ; - dbus_error_free(&dbus_error) ; - } - - purple_core_quit() ; - _exit(0) ; - } - dbus_connection_setup_with_g_main(purple_dbus_connection, NULL); purple_debug_misc("dbus", "okkk\n"); diff -r 9f5c9df30287 -r 176d0fc8bc16 libpurple/dbus-server.h --- a/libpurple/dbus-server.h Sun May 13 19:52:05 2007 +0000 +++ b/libpurple/dbus-server.h Tue May 15 20:41:36 2007 +0000 @@ -169,6 +169,11 @@ void *purple_dbus_get_handle(void); /** + * Determines whether this instance owns the DBus service name + */ +gboolean purple_dbus_is_owner(); + +/** * Starts Purple's D-BUS server. It is responsible for handling DBUS * requests from other applications. */ diff -r 9f5c9df30287 -r 176d0fc8bc16 pidgin/gtkmain.c --- a/pidgin/gtkmain.c Sun May 13 19:52:05 2007 +0000 +++ b/pidgin/gtkmain.c Tue May 15 20:41:36 2007 +0000 @@ -730,6 +730,15 @@ abort(); } + if (!purple_core_ensure_single_instance ()) + { +#ifdef HAVE_SIGNAL_H + g_free(segfault_message); +#endif + return 0 ; + } + + /* TODO: Move blist loading into purple_blist_init() */ purple_set_blist(purple_blist_new()); purple_blist_load();