[gnome-keyring] [daemon] Add --replace option to daemon.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] [daemon] Add --replace option to daemon.
- Date: Fri, 30 Jul 2010 09:11:20 +0000 (UTC)
commit 034d6fe69bc91722c242659a9d27c429c85a3fad
Author: Stef Walter <stef memberwebs com>
Date: Fri Jul 30 10:33:12 2010 +0200
[daemon] Add --replace option to daemon.
* Allows one gnome-keyring-daemon to replace another, including
using the same environment variables etc.
daemon/control/gkd-control-client.c | 30 +++++++++++++
daemon/control/gkd-control-codes.h | 1 +
daemon/control/gkd-control-server.c | 13 ++++++
daemon/control/gkd-control.h | 2 +
daemon/control/tests/.gitignore | 1 +
daemon/control/tests/Makefile.am | 12 +++++-
daemon/control/tests/test-control-quit.c | 25 +++++++++++
daemon/dbus/gkd-dbus.c | 9 ++--
daemon/gkd-main.c | 69 +++++++++++++++++++++---------
9 files changed, 137 insertions(+), 25 deletions(-)
---
diff --git a/daemon/control/gkd-control-client.c b/daemon/control/gkd-control-client.c
index 58d7d62..a52dc0f 100644
--- a/daemon/control/gkd-control-client.c
+++ b/daemon/control/gkd-control-client.c
@@ -277,3 +277,33 @@ gkd_control_change_lock (const gchar *directory, const gchar *original,
return TRUE;
}
+
+gboolean
+gkd_control_quit (const gchar *directory)
+{
+ EggBuffer buffer;
+ gsize offset = 4;
+ gboolean ret;
+ guint32 res;
+
+ egg_buffer_init_full (&buffer, 128, egg_secure_realloc);
+ egg_buffer_add_uint32 (&buffer, 0);
+ egg_buffer_add_uint32 (&buffer, GKD_CONTROL_OP_QUIT);
+ egg_buffer_set_uint32 (&buffer, 0, buffer.len);
+
+ g_return_val_if_fail (!egg_buffer_has_error (&buffer), FALSE);
+
+ ret = control_chat (directory, &buffer);
+
+ if (ret)
+ ret = egg_buffer_get_uint32 (&buffer, offset, &offset, &res);
+
+ egg_buffer_uninit (&buffer);
+
+ if (!ret || res != GKD_CONTROL_RESULT_OK) {
+ g_message ("couldn't quit running keyring daemon");
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/daemon/control/gkd-control-codes.h b/daemon/control/gkd-control-codes.h
index 159ac48..696200d 100644
--- a/daemon/control/gkd-control-codes.h
+++ b/daemon/control/gkd-control-codes.h
@@ -26,6 +26,7 @@ enum {
GKD_CONTROL_OP_INITIALIZE,
GKD_CONTROL_OP_UNLOCK,
GKD_CONTROL_OP_CHANGE,
+ GKD_CONTROL_OP_QUIT
};
enum {
diff --git a/daemon/control/gkd-control-server.c b/daemon/control/gkd-control-server.c
index 18d4bf7..8ec34c5 100644
--- a/daemon/control/gkd-control-server.c
+++ b/daemon/control/gkd-control-server.c
@@ -114,6 +114,13 @@ control_change_login (EggBuffer *buffer)
}
static guint32
+control_quit (EggBuffer *buffer)
+{
+ gkd_main_quit ();
+ return GKD_CONTROL_RESULT_OK;
+}
+
+static guint32
control_initialize_components (EggBuffer *buffer)
{
gchar *components;
@@ -218,6 +225,12 @@ control_process (EggBuffer *req, GIOChannel *channel)
egg_buffer_add_uint32 (&cdata->buffer, res);
egg_buffer_add_stringv (&cdata->buffer, gkd_util_get_environment ());
break;
+ case GKD_CONTROL_OP_QUIT:
+ res = control_quit (req);
+ cdata = control_data_new ();
+ egg_buffer_add_uint32 (&cdata->buffer, 0);
+ egg_buffer_add_uint32 (&cdata->buffer, res);
+ break;
default:
g_message ("received unsupported request operation on control socket: %d", (int)op);
break;
diff --git a/daemon/control/gkd-control.h b/daemon/control/gkd-control.h
index d7f7e66..17dd028 100644
--- a/daemon/control/gkd-control.h
+++ b/daemon/control/gkd-control.h
@@ -37,4 +37,6 @@ gboolean gkd_control_change_lock (const gchar *directory,
const gchar *original,
const gchar *password);
+gboolean gkd_control_quit (const gchar *directory);
+
#endif /* __GKD_CONTROL_H__ */
diff --git a/daemon/control/tests/.gitignore b/daemon/control/tests/.gitignore
index 79b439f..cf0cce4 100644
--- a/daemon/control/tests/.gitignore
+++ b/daemon/control/tests/.gitignore
@@ -1,3 +1,4 @@
/test-control-change
/test-control-init
/test-control-unlock
+/test-control-quit
diff --git a/daemon/control/tests/Makefile.am b/daemon/control/tests/Makefile.am
index 78f8ae8..2ab531a 100644
--- a/daemon/control/tests/Makefile.am
+++ b/daemon/control/tests/Makefile.am
@@ -14,7 +14,8 @@ LIBS = \
noinst_PROGRAMS= \
test-control-change \
test-control-init \
- test-control-unlock
+ test-control-unlock \
+ test-control-quit
# ------------------------------------------------------------------------------
# Test unlocking the login keyring
@@ -37,6 +38,15 @@ test_control_init_LDADD = \
$(top_builddir)/egg/libegg-creds.la \
$(top_builddir)/egg/libegg-secure.la
+test_control_quit_SOURCES = \
+ test-control-quit.c
+
+test_control_quit_LDADD = \
+ $(top_builddir)/daemon/control/libgkd-control-client.la \
+ $(top_builddir)/egg/libegg-buffer.la \
+ $(top_builddir)/egg/libegg-creds.la \
+ $(top_builddir)/egg/libegg-secure.la
+
test_control_unlock_SOURCES = \
test-control-unlock.c
diff --git a/daemon/control/tests/test-control-quit.c b/daemon/control/tests/test-control-quit.c
new file mode 100644
index 0000000..f3ec3cc
--- /dev/null
+++ b/daemon/control/tests/test-control-quit.c
@@ -0,0 +1,25 @@
+
+#include "control/gkd-control.h"
+#include "testing/testing.h"
+
+#include <pwd.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int
+run (void)
+{
+ const char *directory;
+
+ directory = g_getenv ("GNOME_KEYRING_CONTROL");
+ g_return_val_if_fail (directory, 1);
+
+ if (!gkd_control_quit (directory))
+ return 1;
+
+ g_printerr ("success quitting daemon\n");
+
+ return 0;
+}
+
+#include "testing/testing.c"
diff --git a/daemon/dbus/gkd-dbus.c b/daemon/dbus/gkd-dbus.c
index 4688d18..8461226 100644
--- a/daemon/dbus/gkd-dbus.c
+++ b/daemon/dbus/gkd-dbus.c
@@ -230,11 +230,10 @@ gkd_dbus_singleton_control (void)
gchar *control = NULL;
const char *path;
- /* Must have tried to aquire the service, and failed */
- g_return_val_if_fail (acquired_asked, NULL);
+ /* If tried to aquire the service must have failed */
g_return_val_if_fail (!acquired_service, NULL);
- if (!connect_to_session_bus())
+ if (!connect_to_session_bus ())
return NULL;
msg = dbus_message_new_method_call (GNOME_KEYRING_DAEMON_SERVICE,
@@ -242,13 +241,15 @@ gkd_dbus_singleton_control (void)
GNOME_KEYRING_DAEMON_INTERFACE,
"GetControlDirectory");
g_return_val_if_fail (msg, NULL);
+ dbus_message_set_auto_start (msg, FALSE);
/* Send message and get a handle for a reply */
reply = dbus_connection_send_with_reply_and_block (dbus_conn, msg, 1000, &derr);
dbus_message_unref (msg);
if (!reply) {
- g_message ("couldn't communicate with already running daemon: %s", derr.message);
+ if (!dbus_error_has_name (&derr, "org.freedesktop.DBus.Error.NameHasNoOwner"))
+ g_message ("couldn't communicate with already running daemon: %s", derr.message);
dbus_error_free (&derr);
return NULL;
}
diff --git a/daemon/gkd-main.c b/daemon/gkd-main.c
index 8219f19..a19ceef 100644
--- a/daemon/gkd-main.c
+++ b/daemon/gkd-main.c
@@ -100,21 +100,24 @@ static gboolean run_foreground = FALSE;
static gboolean run_daemonized = FALSE;
static gboolean run_for_login = FALSE;
static gboolean run_for_start = FALSE;
+static gboolean run_for_replace = FALSE;
static gchar* login_password = NULL;
-static const gchar* control_directory = NULL;
+static gchar* control_directory = NULL;
static gboolean initialization_completed = FALSE;
static gboolean sig_thread_valid = FALSE;
static pthread_t sig_thread;
static GOptionEntry option_entries[] = {
+ { "start", 's', 0, G_OPTION_ARG_NONE, &run_for_start,
+ "Start a dameon or initialize an already running daemon." },
+ { "replace", 'r', 0, G_OPTION_ARG_NONE, &run_for_replace,
+ "Replace the daemon for this desktop login environment." },
{ "foreground", 'f', 0, G_OPTION_ARG_NONE, &run_foreground,
"Run in the foreground", NULL },
{ "daemonize", 'd', 0, G_OPTION_ARG_NONE, &run_daemonized,
"Run as a daemon", NULL },
{ "login", 'l', 0, G_OPTION_ARG_NONE, &run_for_login,
"Run for a user login. Read login password from stdin", NULL },
- { "start", 's', 0, G_OPTION_ARG_NONE, &run_for_start,
- "Start a dameon or initialize an already running daemon." },
{ "components", 'c', 0, G_OPTION_ARG_STRING, &run_components,
"The optional components to run", DEFAULT_COMPONENTS },
{ "control-directory", 'l', 0, G_OPTION_ARG_FILENAME, &control_directory,
@@ -149,6 +152,16 @@ parse_arguments (int *argc, char** argv[])
run_for_login = FALSE;
}
+ if (run_for_login && run_for_replace) {
+ g_printerr ("gnome-keyring-daemon: The --replace option is incompatible with --login");
+ run_for_login = FALSE;
+ }
+
+ if (run_for_start && run_for_replace) {
+ g_printerr ("gnome-keyring-daemon: The --replace option is incompatible with --start");
+ run_for_start = FALSE;
+ }
+
g_option_context_free (context);
}
@@ -487,42 +500,50 @@ initialize_daemon_at (const gchar *directory)
}
static gboolean
-initialize_daemon (const gchar *directory)
+replace_daemon_at (const gchar *directory)
{
+ g_free (control_directory);
+ control_directory = g_strdup (directory);
+ return gkd_control_quit (directory);
+}
+
+typedef gboolean (*DiscoverFunc) (const gchar *control_directory);
+
+static gboolean
+discover_other_daemon (DiscoverFunc callback, gboolean acquire)
+{
+ const gchar *control_env;
gchar *control = NULL;
- gboolean acquired, ret;
+ gboolean acquired = FALSE;
+ gboolean ret;
- /* A pre-specified directory to control at */
- if (directory) {
- if (initialize_daemon_at (directory))
- return TRUE;
- }
+ /* A pre-specified directory to control at, don't try anything else */
+ if (control_directory)
+ return (callback) (control_directory);
/* An environment variable from an already running daemon */
- directory = g_getenv (GKD_UTIL_ENV_CONTROL);
- if (directory && directory[0]) {
- if (initialize_daemon_at (directory))
+ control_env = g_getenv (GKD_UTIL_ENV_CONTROL);
+ if (control_env && control_env[0]) {
+ if ((callback)(control_env))
return TRUE;
}
/* See if we can contact a daemon running, that didn't set an env variable */
- if (!gkd_dbus_singleton_acquire (&acquired))
+ if (acquire && !gkd_dbus_singleton_acquire (&acquired))
return FALSE;
/* We're the main daemon */
if (acquired)
return FALSE;
- /* Figure out the path to the other daemon's control directory */
- directory = control = gkd_dbus_singleton_control ();
- if (directory) {
- ret = initialize_daemon_at (directory);
+ control = gkd_dbus_singleton_control ();
+ if (control) {
+ ret = (callback) (control);
g_free (control);
if (ret == TRUE)
return TRUE;
}
- g_message ("couldn't initialize running daemon");
return FALSE;
}
@@ -768,7 +789,7 @@ main (int argc, char *argv[])
/* The --start option */
if (run_for_start) {
- if (initialize_daemon (control_directory)) {
+ if (discover_other_daemon (initialize_daemon_at, TRUE)) {
/*
* Another daemon was initialized, print out environment
* for any callers, and quit or go comatose.
@@ -778,6 +799,12 @@ main (int argc, char *argv[])
while (sleep(0x08000000) == 0);
cleanup_and_exit (0);
}
+
+ /* The --replace option */
+ } else if (run_for_replace) {
+ discover_other_daemon (replace_daemon_at, FALSE);
+ if (control_directory)
+ g_message ("replacing daemon at: %s", control_directory);
}
/* Initialize the main directory */
@@ -824,5 +851,7 @@ main (int argc, char *argv[])
/* Wrap up signal handling here */
cleanup_signal_handling ();
+ g_free (control_directory);
+
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]