summaryrefslogtreecommitdiff
path: root/components/services/trilobite/libtrilobite
diff options
context:
space:
mode:
authorRobey Pointer <robey@src.gnome.org>2000-08-29 06:39:41 +0000
committerRobey Pointer <robey@src.gnome.org>2000-08-29 06:39:41 +0000
commit109cc17d644a559df5609cbad5a12226780a4b6d (patch)
treeea83b01391dc089ae0c0f3739af44a4c4ee5fe91 /components/services/trilobite/libtrilobite
parenta9ddcb90bfdb5a29824c4cc6fcc3a6476bf6a5e7 (diff)
downloadnautilus-109cc17d644a559df5609cbad5a12226780a4b6d.tar.gz
add try_again signal to the root-client, root-helper, and PasswordQueryClient APIs
Diffstat (limited to 'components/services/trilobite/libtrilobite')
-rw-r--r--components/services/trilobite/libtrilobite/trilobite-root-client.c16
-rw-r--r--components/services/trilobite/libtrilobite/trilobite-root-helper.c110
-rw-r--r--components/services/trilobite/libtrilobite/trilobite-root-helper.h8
-rw-r--r--components/services/trilobite/libtrilobite/trilobite-service-passwordquery.c29
4 files changed, 129 insertions, 34 deletions
diff --git a/components/services/trilobite/libtrilobite/trilobite-root-client.c b/components/services/trilobite/libtrilobite/trilobite-root-client.c
index a9a7cecca..0ce9a6701 100644
--- a/components/services/trilobite/libtrilobite/trilobite-root-client.c
+++ b/components/services/trilobite/libtrilobite/trilobite-root-client.c
@@ -40,6 +40,7 @@ static GtkObject *parent_class;
/* LAST_SIGNAL is just a sentinel marking the end of the list */
enum {
NEED_PASSWORD,
+ TRY_AGAIN,
LAST_SIGNAL
};
static guint root_client_signals[LAST_SIGNAL] = { 0 };
@@ -78,6 +79,17 @@ impl_Trilobite_PasswordQueryClient_get_password (impl_POA_Trilobite_PasswordQuer
return result;
};
+static CORBA_boolean
+impl_Trilobite_PasswordQueryClient_try_again (impl_POA_Trilobite_PasswordQueryClient *trilobite,
+ CORBA_Environment *ev)
+{
+ gboolean result;
+
+ result = FALSE;
+ gtk_signal_emit (GTK_OBJECT (trilobite->bonobo_object), root_client_signals[TRY_AGAIN], &result);
+ return (CORBA_boolean)result;
+}
+
POA_Trilobite_PasswordQueryClient__epv *
trilobite_root_client_get_epv(void)
{
@@ -85,6 +97,7 @@ trilobite_root_client_get_epv(void)
epv = g_new0 (POA_Trilobite_PasswordQueryClient__epv, 1);
epv->get_password = (gpointer)&impl_Trilobite_PasswordQueryClient_get_password;
+ epv->try_again = (gpointer)&impl_Trilobite_PasswordQueryClient_try_again;
return epv;
};
@@ -193,6 +206,9 @@ trilobite_root_client_class_initialize (TrilobiteRootClientClass *klass)
root_client_signals[NEED_PASSWORD] =
gtk_signal_new ("need_password", 0, object_class->type, 0,
gtk_marshal_STRING__STRING, GTK_TYPE_STRING, 1, GTK_TYPE_STRING);
+ root_client_signals[TRY_AGAIN] =
+ gtk_signal_new ("try_again", 0, object_class->type, 0,
+ gtk_marshal_BOOL__NONE, GTK_TYPE_BOOL, 0);
gtk_object_class_add_signals (object_class, root_client_signals, LAST_SIGNAL);
}
diff --git a/components/services/trilobite/libtrilobite/trilobite-root-helper.c b/components/services/trilobite/libtrilobite/trilobite-root-helper.c
index 6aa5bb4dd..ff91d8aee 100644
--- a/components/services/trilobite/libtrilobite/trilobite-root-helper.c
+++ b/components/services/trilobite/libtrilobite/trilobite-root-helper.c
@@ -33,6 +33,8 @@
#include <string.h>
#include <fcntl.h>
#include <sys/poll.h>
+#include <sys/types.h>
+#include <signal.h>
#include <time.h>
#include <gtk/gtk.h>
#include "trilobite-core-utils.h"
@@ -48,6 +50,7 @@ static GtkObject *parent_class;
/* LAST_SIGNAL is just a sentinel marking the end of the list */
enum {
NEED_PASSWORD,
+ TRY_AGAIN,
LAST_SIGNAL
};
static guint root_helper_signals[LAST_SIGNAL] = { 0 };
@@ -72,6 +75,7 @@ void
trilobite_root_helper_destroy (GtkObject *object)
{
TrilobiteRootHelper *root_helper;
+ GList *iter;
g_return_if_fail (object != NULL);
g_return_if_fail (TRILOBITE_IS_ROOT_HELPER (object));
@@ -80,6 +84,11 @@ trilobite_root_helper_destroy (GtkObject *object)
root_helper = TRILOBITE_ROOT_HELPER (object);
/* anything that needs to be freed? */
+ for (iter = g_list_first (root_helper->old_fd_list); iter; iter = g_list_next (iter)) {
+ trilobite_debug ("roothelper: tossing old fd %d", (int)(iter->data));
+ close ((int)(iter->data));
+ }
+ g_list_free (root_helper->old_fd_list);
/* call parent destructor */
if (GTK_OBJECT_CLASS (parent_class)->destroy) {
@@ -102,9 +111,14 @@ trilobite_root_helper_class_initialize (TrilobiteRootHelperClass *klass)
gtk_signal_new ("need_password", 0, object_class->type,
GTK_SIGNAL_OFFSET (TrilobiteRootHelperClass, need_password),
gtk_marshal_STRING__NONE, GTK_TYPE_STRING, 0);
+ root_helper_signals[TRY_AGAIN] =
+ gtk_signal_new ("try_again", 0, object_class->type,
+ GTK_SIGNAL_OFFSET (TrilobiteRootHelperClass, try_again),
+ gtk_marshal_BOOL__NONE, GTK_TYPE_BOOL, 0);
gtk_object_class_add_signals (object_class, root_helper_signals, LAST_SIGNAL);
klass->need_password = NULL;
+ klass->try_again = NULL;
}
/* object initializer */
@@ -206,7 +220,7 @@ eazel_helper_response (int pipe_stdout)
* eazel-helper
*/
static TrilobiteRootHelperStatus
-eazel_helper_start (int *pipe_stdin, int *pipe_stdout)
+eazel_helper_start (int *pipe_stdin, int *pipe_stdout, int *child_pid)
{
char *pipe_argv[4];
int useless_stderr;
@@ -217,7 +231,8 @@ eazel_helper_start (int *pipe_stdin, int *pipe_stdout)
pipe_argv[1] = "-w";
pipe_argv[2] = EAZEL_HELPER;
pipe_argv[3] = NULL;
- if (trilobite_pexec (USERHELPER_PATH, pipe_argv, pipe_stdin, pipe_stdout, &useless_stderr) != 0) {
+ *child_pid = trilobite_pexec (USERHELPER_PATH, pipe_argv, pipe_stdin, pipe_stdout, &useless_stderr);
+ if (*child_pid == 0) {
trilobite_debug ("roothelper: system userhelper utility not found");
return TRILOBITE_ROOT_HELPER_NO_USERHELPER;
}
@@ -228,7 +243,8 @@ eazel_helper_start (int *pipe_stdin, int *pipe_stdout)
/* if the first thing from the pipe is a "2", we need the root password */
buffer[0] = eazel_helper_response (*pipe_stdout);
if (buffer[0] == '\0') {
- trilobite_debug ("roothelper: userhelper died");
+ trilobite_debug ("roothelper: userhelper died (stdin: %d, stdout: %d, pid: %d",
+ *pipe_stdin, *pipe_stdout, *child_pid);
err = TRILOBITE_ROOT_HELPER_NO_USERHELPER;
goto give_up;
} else if (buffer[0] == '2') {
@@ -282,7 +298,9 @@ eazel_helper_password (int pipe_stdin, int pipe_stdout, const char *password)
} else if (buffer[0] == '2') {
trilobite_debug ("roothelper: bad password");
err = TRILOBITE_ROOT_HELPER_BAD_PASSWORD;
- goto give_up;
+ /* don't close the pipe, let them try again if they want */
+ read (pipe_stdout, buffer, 256);
+ goto done;
} else if (buffer[0] == '5') {
/* sometimes a leftover status message from the last stage */
/* read 2 chars, then continue */
@@ -321,12 +339,12 @@ trilobite_root_helper_start (TrilobiteRootHelper *root_helper)
{
TrilobiteRootHelperStatus err;
char *password;
+ gboolean try_again;
+ int child_pid;
g_return_val_if_fail (root_helper != NULL, FALSE);
g_return_val_if_fail (TRILOBITE_IS_ROOT_HELPER (root_helper), FALSE);
- password = NULL;
-
if (root_helper->state == TRILOBITE_ROOT_HELPER_STATE_CONNECTED) {
/* already connected, dude. */
return TRILOBITE_ROOT_HELPER_SUCCESS;
@@ -340,36 +358,60 @@ trilobite_root_helper_start (TrilobiteRootHelper *root_helper)
root_helper->state = TRILOBITE_ROOT_HELPER_STATE_NEW;
}
- err = eazel_helper_start (&root_helper->pipe_stdin, &root_helper->pipe_stdout);
- switch (err) {
- case TRILOBITE_ROOT_HELPER_SUCCESS:
- /* already done -- nice! */
- goto connected;
- case TRILOBITE_ROOT_HELPER_NEED_PASSWORD:
- /* the expected case -- continue */
- break;
- default:
- /* anything else is an error */
- goto failed;
- }
+ while (1) {
+ err = eazel_helper_start (&root_helper->pipe_stdin, &root_helper->pipe_stdout, &child_pid);
+ switch (err) {
+ case TRILOBITE_ROOT_HELPER_SUCCESS:
+ /* already done -- nice! */
+ goto connected;
+ case TRILOBITE_ROOT_HELPER_NEED_PASSWORD:
+ /* the expected case -- continue */
+ break;
+ default:
+ /* anything else is an error */
+ goto failed;
+ }
- /* now emit a signal and get the password */
- trilobite_debug ("roothelper: asking for password");
- gtk_signal_emit (GTK_OBJECT (root_helper), root_helper_signals[NEED_PASSWORD], &password);
- if (password == NULL) {
- /* bummer. nobody caught the signal. */
- err = TRILOBITE_ROOT_HELPER_NEED_PASSWORD;
- goto failed;
- }
+ /* now emit a signal and get the password */
+ trilobite_debug ("roothelper: asking for password");
+ password = NULL;
+ gtk_signal_emit (GTK_OBJECT (root_helper), root_helper_signals[NEED_PASSWORD], &password);
+ if (password == NULL) {
+ /* bummer. nobody caught the signal. */
+ err = TRILOBITE_ROOT_HELPER_NEED_PASSWORD;
+ goto failed;
+ }
- err = eazel_helper_password (root_helper->pipe_stdin, root_helper->pipe_stdout, password);
- switch (err) {
- case TRILOBITE_ROOT_HELPER_SUCCESS:
- /* yeah! set! */
- goto connected;
- default:
- /* all else is error */
- goto failed;
+ err = eazel_helper_password (root_helper->pipe_stdin, root_helper->pipe_stdout, password);
+ switch (err) {
+ case TRILOBITE_ROOT_HELPER_SUCCESS:
+ /* yeah! set! */
+ goto connected;
+ case TRILOBITE_ROOT_HELPER_BAD_PASSWORD:
+ try_again = FALSE;
+ gtk_signal_emit (GTK_OBJECT (root_helper), root_helper_signals[TRY_AGAIN], &try_again);
+ if (! try_again) {
+ trilobite_debug ("roothelper: not going to try again.");
+ /* then we fail. */
+ close (root_helper->pipe_stdout);
+ close (root_helper->pipe_stdin);
+ goto failed;
+ } else {
+ g_free (password);
+ /* for some reason, userhelper will spaz out if we close stdin. */
+ /* so we have this awful hack where we push stdin onto a stack to close in the
+ * destructor. pathetic! :(
+ */
+ close (root_helper->pipe_stdout);
+ root_helper->old_fd_list = g_list_append(root_helper->old_fd_list,
+ (void *)root_helper->pipe_stdin);
+ root_helper->pipe_stdin = root_helper->pipe_stdout = -1;
+ }
+ break;
+ default:
+ /* all else is error */
+ goto failed;
+ }
}
connected:
diff --git a/components/services/trilobite/libtrilobite/trilobite-root-helper.h b/components/services/trilobite/libtrilobite/trilobite-root-helper.h
index 802689465..264a43599 100644
--- a/components/services/trilobite/libtrilobite/trilobite-root-helper.h
+++ b/components/services/trilobite/libtrilobite/trilobite-root-helper.h
@@ -73,14 +73,22 @@ struct _TrilobiteRootHelperClass
GtkObjectClass parent_class;
gchar *(*need_password) (TrilobiteRootHelper *helper);
+ gboolean (*try_again) (TrilobiteRootHelper *helper);
};
+/*
+ * the first time a password is needed, 'need_password' is emitted. it should return the root password.
+ * if that password is wrong, 'try_again' will be emitted. if it returns true, 'need_password' will be
+ * called again. the loop continues until the password is correct, or 'try_again' returns false.
+ */
+
struct _TrilobiteRootHelper
{
GtkObject parent;
TrilobiteRootHelperState state;
int pipe_stdin; /* pipe to/from the eazel-helper utility */
int pipe_stdout;
+ GList *old_fd_list; /* part of hack to avoid userhelper bug: fd's to close later */
};
diff --git a/components/services/trilobite/libtrilobite/trilobite-service-passwordquery.c b/components/services/trilobite/libtrilobite/trilobite-service-passwordquery.c
index 3ffc77763..a948530e9 100644
--- a/components/services/trilobite/libtrilobite/trilobite-service-passwordquery.c
+++ b/components/services/trilobite/libtrilobite/trilobite-service-passwordquery.c
@@ -43,6 +43,8 @@ enum {
static char* trilobite_passwordquery_get_password (TrilobiteRootHelper *roothelper,
TrilobitePasswordQuery *trilobite);
+static gboolean trilobite_passwordquery_try_again (TrilobiteRootHelper *roothelper,
+ TrilobitePasswordQuery *trilobite);
/* static guint trilobite_passwordquery_signals[LAST_SIGNAL] = { 0 }; */
@@ -245,6 +247,10 @@ trilobite_passwordquery_initialize (TrilobitePasswordQuery *trilobite)
"need_password",
(GFunc)trilobite_passwordquery_get_password,
trilobite);
+ gtk_signal_connect (GTK_OBJECT (trilobite->private->root_helper),
+ "try_again",
+ (GFunc)trilobite_passwordquery_try_again,
+ trilobite);
}
GtkType
@@ -332,6 +338,29 @@ trilobite_passwordquery_get_password (TrilobiteRootHelper *roothelper,
}
}
+static gboolean
+trilobite_passwordquery_try_again (TrilobiteRootHelper *roothelper,
+ TrilobitePasswordQuery *trilobite)
+{
+ if (trilobite->private->client == CORBA_OBJECT_NIL) {
+ /* you lose. */
+ return FALSE;
+ } else {
+ CORBA_Environment ev;
+ CORBA_boolean result;
+
+ CORBA_exception_init (&ev);
+ result = Trilobite_PasswordQueryClient_try_again (trilobite->private->client, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("Error during query of try-again from client: %s",
+ CORBA_exception_id (&ev));
+ }
+ CORBA_exception_free (&ev);
+
+ return (gboolean)result;
+ }
+}
+
/* Sets the prompt */
void
trilobite_passwordquery_set_prompt (TrilobitePasswordQuery *trilobite,