Re: Patch for question callback
- From: Mattias Eriksson <snaggen acc umu se>
- To: Alexander Larsson <alexl redhat com>
- Cc: "gnome-vfs-list gnome org" <gnome-vfs-list gnome org>
- Subject: Re: Patch for question callback
- Date: Sun, 18 Apr 2004 22:12:16 +0200
Here is an updated version of the patch where I have fixed the issues
you point out. I now use a primary and secondary message and I have
reversed the button ordering. And I have added alot of spaces :-).
//Snaggen
Index: GNOME_VFS_Daemon.idl
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/GNOME_VFS_Daemon.idl,v
retrieving revision 1.6
diff -u -B -b -r1.6 GNOME_VFS_Daemon.idl
--- GNOME_VFS_Daemon.idl 22 Jan 2004 15:35:01 -0000 1.6
+++ GNOME_VFS_Daemon.idl 18 Apr 2004 20:00:03 -0000
@@ -67,6 +67,14 @@
/* Standard module callbacks: */
+ struct ModuleCallbackQuestionIn {
+ string primary_message;
+ string secondary_message;
+ sequence<string> choices;
+ };
+ struct ModuleCallbackQuestionOut {
+ short answer;
+ };
struct ModuleCallbackAuthenticationIn {
string uri;
string realm;
Index: gnome-vfs-module-callback-marshall.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-module-callback-marshall.c,v
retrieving revision 1.4
diff -u -B -b -r1.4 gnome-vfs-module-callback-marshall.c
--- gnome-vfs-module-callback-marshall.c 10 Dec 2003 12:39:23 -0000 1.4
+++ gnome-vfs-module-callback-marshall.c 18 Apr 2004 20:00:03 -0000
@@ -603,6 +603,142 @@
g_free (auth_out);
}
+static CORBA_any *
+question_marshal_in (gconstpointer in, gsize in_size)
+{
+ CORBA_any *retval;
+ GNOME_VFS_ModuleCallbackQuestionIn *ret_in;
+ const GnomeVFSModuleCallbackQuestionIn *question_in;
+ int cnt;
+
+ if (in_size != sizeof (GnomeVFSModuleCallbackQuestionIn)) {
+ return NULL;
+ }
+ question_in = in;
+
+ retval = CORBA_any_alloc ();
+ retval->_type = TC_GNOME_VFS_ModuleCallbackQuestionIn;
+ retval->_value = GNOME_VFS_ModuleCallbackQuestionIn__alloc ();
+ ret_in = retval->_value;
+
+ /* Set the values in ret_in, like ret_in->stuff=question_in->stuff */
+ ret_in->primary_message = corba_string_or_null_dup (question_in->primary_message);
+ ret_in->secondary_message = corba_string_or_null_dup (question_in->secondary_message);
+ if (question_in->choices) {
+
+ /* Just count the number of elements and allocate the memory */
+ for (cnt=0; question_in->choices[cnt] != NULL; cnt++);
+ ret_in->choices._maximum = cnt;
+ ret_in->choices._length = cnt;
+ ret_in->choices._buffer = CORBA_sequence_CORBA_string_allocbuf (cnt);
+ CORBA_sequence_set_release (&ret_in->choices, TRUE);
+
+ /* Insert the strings into the sequence */
+ for (cnt=0; question_in->choices[cnt] != NULL; cnt++) {
+ ret_in->choices._buffer[cnt] = corba_string_or_null_dup (question_in->choices[cnt]);
+ }
+ }
+ return retval;
+}
+
+static gboolean
+question_demarshal_in (const CORBA_any *any_in,
+ gpointer *in, gsize *in_size,
+ gpointer *out, gsize *out_size)
+{
+ GNOME_VFS_ModuleCallbackQuestionIn *corba_in;
+ GnomeVFSModuleCallbackQuestionIn *question_in;
+ GnomeVFSModuleCallbackQuestionOut *question_out;
+ int cnt;
+
+ if (!CORBA_TypeCode_equal (any_in->_type, TC_GNOME_VFS_ModuleCallbackQuestionIn, NULL)) {
+ return FALSE;
+ }
+
+ question_in = *in = g_new0 (GnomeVFSModuleCallbackQuestionIn, 1);
+ *in_size = sizeof (GnomeVFSModuleCallbackQuestionIn);
+ question_out = *out = g_new0 (GnomeVFSModuleCallbackQuestionOut, 1);
+ *out_size = sizeof (GnomeVFSModuleCallbackQuestionOut);
+
+ corba_in = (GNOME_VFS_ModuleCallbackQuestionIn *)any_in->_value;
+
+ if (corba_in) {
+ question_in->primary_message = decode_corba_string_or_null (corba_in->primary_message, FALSE);
+ question_in->secondary_message = decode_corba_string_or_null (corba_in->secondary_message, FALSE);
+ question_in->choices = g_new (char *, corba_in->choices._length+1);
+ for (cnt=0; cnt<corba_in->choices._length; cnt++){
+ question_in->choices[cnt] = g_strdup (corba_in->choices._buffer[cnt]);
+ }
+ question_in->choices[corba_in->choices._length] = NULL;
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static CORBA_any *
+question_marshal_out (gconstpointer out, gsize out_size)
+{
+ CORBA_any *retval;
+ GNOME_VFS_ModuleCallbackQuestionOut *ret_out;
+ const GnomeVFSModuleCallbackQuestionOut *question_out;
+
+ if (out_size != sizeof (GnomeVFSModuleCallbackQuestionOut)) {
+ return NULL;
+ }
+ question_out = out;
+
+ retval = CORBA_any_alloc();
+ retval->_type = TC_GNOME_VFS_ModuleCallbackQuestionOut;
+ retval->_value = GNOME_VFS_ModuleCallbackQuestionOut__alloc ();
+ ret_out = retval->_value;
+
+ ret_out->answer = question_out->answer;
+
+ return retval;
+}
+
+static gboolean
+question_demarshal_out (CORBA_any *any_out, gpointer out, gsize out_size)
+{
+ GNOME_VFS_ModuleCallbackQuestionOut *corba_out;
+ GnomeVFSModuleCallbackQuestionOut *question_out;
+
+ if (!CORBA_TypeCode_equal (any_out->_type, TC_GNOME_VFS_ModuleCallbackQuestionOut, NULL) ||
+ out_size != sizeof (GnomeVFSModuleCallbackQuestionOut)) {
+ return FALSE;
+ }
+ question_out = out;
+
+ corba_out = (GNOME_VFS_ModuleCallbackQuestionOut *)any_out->_value;
+
+ question_out->answer = corba_out->answer;
+
+ return TRUE;
+}
+
+static void
+question_free_in (gpointer in)
+{
+ GnomeVFSModuleCallbackQuestionIn *question_in;
+
+ question_in = in;
+
+ g_free (question_in->primary_message);
+ g_free (question_in->secondary_message);
+ g_strfreev (question_in->choices);
+ g_free (question_in);
+}
+
+static void
+question_free_out (gpointer out)
+{
+ GnomeVFSModuleCallbackQuestionOut *question_out;
+
+ question_out = out;
+ g_free (question_out);
+}
+
struct ModuleCallbackMarshaller {
char *name;
CORBA_any *(*marshal_in)(gconstpointer in, gsize in_size);
@@ -654,6 +790,14 @@
save_auth_free_in,
save_auth_free_out
},
+ { GNOME_VFS_MODULE_CALLBACK_QUESTION,
+ question_marshal_in,
+ question_demarshal_in,
+ question_marshal_out,
+ question_demarshal_out,
+ question_free_in,
+ question_free_out
+ },
};
Index: gnome-vfs-standard-callbacks.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-standard-callbacks.h,v
retrieving revision 1.10
diff -u -B -b -r1.10 gnome-vfs-standard-callbacks.h
--- gnome-vfs-standard-callbacks.h 8 Jan 2004 19:46:37 -0000 1.10
+++ gnome-vfs-standard-callbacks.h 18 Apr 2004 20:00:03 -0000
@@ -83,6 +83,15 @@
*/
#define GNOME_VFS_MODULE_CALLBACK_HTTP_PROXY_AUTHENTICATION "http:proxy-authentication"
+/*
+ * hook name: "ask-question"
+ * In arg: GnomeVFSModuleCallbackQuestionIn *
+ * Out arg: GnomeVFSModuleCallbackQuestionOut *
+ *
+ * Called when access to a URI requires the user to make a choise
+ */
+#define GNOME_VFS_MODULE_CALLBACK_QUESTION "ask-question"
+
typedef struct {
char *uri; /* Full URI of operation */
char *protocol; /* The protocol of the request */
@@ -300,6 +309,34 @@
void *reserved2;
} GnomeVFSModuleCallbackStatusMessageOut;
+typedef struct {
+ char *primary_message; /* A short message explaining the question to
+ the user or NULL if there is no message */
+ char *secondary_message; /* The long version of the message, containing
+ more details. Or Null if there is no message
+ */
+ char **choices; /* The list of choices the user have to choose from,
+ the list must be NULL terminated.
+ The choices will be displayes so that choises[0]
+ will be to the right and choises[n] will be to the
+ left.
+ The first choice in the list should be affirmative
+ to comply with the button ordering in gnome */
+
+ /* Reserved "padding" to avoid future breaks in ABI compatibility */
+ void *reserved1;
+ void *reserved2;
+} GnomeVFSModuleCallbackQuestionIn;
+
+typedef struct {
+ int answer; /* The index of the choice in the choices list sent in
+ to the callback */
+
+ /* Reserved "padding" to avoid future breaks in ABI compatibility */
+ void *reserved1;
+ void *reserved2;
+} GnomeVFSModuleCallbackQuestionOut;
+
G_END_DECLS
#endif /* GNOME_VFS_STANDARD_CALLBACKS_H */
Index: sftp-method.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/sftp-method.c,v
retrieving revision 1.5
diff -u -B -b -r1.5 sftp-method.c
--- sftp-method.c 8 Mar 2004 18:53:47 -0000 1.5
+++ sftp-method.c 18 Apr 2004 20:07:05 -0000
@@ -51,6 +51,7 @@
#include <config.h>
+#include <libgnomevfs/gnome-vfs-i18n.h>
#include <libgnomevfs/gnome-vfs-context.h>
#include <libgnomevfs/gnome-vfs-method.h>
#include <libgnomevfs/gnome-vfs-module.h>
@@ -944,6 +945,9 @@
GError *error = NULL;
gchar *args[20]; /* Enough for now, extend if you add more args */
+ gboolean invoked;
+ GnomeVFSModuleCallbackQuestionIn in_args;
+ GnomeVFSModuleCallbackQuestionOut out_args;
DEBUG (gchar *tmp);
@@ -1046,6 +1050,12 @@
char buffer[1024];
gsize len;
char *password;
+ char *choices[3];
+ char *pos;
+ char *startpos;
+ char *endpos;
+ char hostname[256];
+ char fingerprint[256];
FD_ZERO (&ifds);
FD_SET (in_fd, &ifds);
@@ -1082,12 +1092,77 @@
goto bail;
}
done_auth = TRUE;
- } else if (g_str_has_prefix (buffer, "The authenticity of host")) {
- /* FIXME: This should do a callback asking the user if the host id is ok */
- /* For now we just fail */
+ } else if (g_str_has_prefix (buffer, "The authenticity of host '")) {
+
+ pos = strchr(&buffer[26],'\'');
+ if (!pos) {
+ g_message("No pos\n");
+ res = GNOME_VFS_ERROR_GENERIC;
+ goto bail;
+ }
+
+ if (pos-(&buffer[26])<255) {
+ strncpy (hostname, &buffer[26], pos-(&buffer[26]));
+ hostname[pos-(&buffer[26])]='\0';
+ } else {
+ strncpy (hostname, &buffer[26], 255);
+ hostname[255]='\0';
+ }
+
+ startpos = strstr (pos, "RSA key fingerprint is ");
+ if (!startpos) {
+ res = GNOME_VFS_ERROR_GENERIC;
+ goto bail;
+ }
+
+ startpos = startpos + 23;
+ endpos = strchr(startpos, '.');
+ if (!endpos) {
+ res = GNOME_VFS_ERROR_GENERIC;
+ goto bail;
+ }
+
+ if (endpos-startpos<255) {
+ strncpy(fingerprint, startpos, endpos-startpos);
+ fingerprint[endpos-startpos]='\0';
+ } else {
+ strncpy(fingerprint, startpos, 255);
+ fingerprint[255]='\0';
+ }
+
+ in_args.primary_message = g_strdup_printf (_("Error while logging in to %s"), hostname);
+ in_args.secondary_message = g_strdup_printf (_("The identity of the remote computer seems to have changed since the last time it was accessed. This can happen in normal situations, such as a computer being upgraded. However, there is also a possibility that someone is maliciously impersonating the remote computer.\n \nThe identity sent by the remote host is:\n%s.\nIf you want to be sure it is safe to continue, contact the system administrator."), fingerprint);
+
+ in_args.choices = choices;
+ in_args.choices[0] = _("Accept New Host Key");
+ in_args.choices[1] = _("Cancel");
+ in_args.choices[2] = NULL;
+
+ invoked = gnome_vfs_module_callback_invoke
+ (GNOME_VFS_MODULE_CALLBACK_QUESTION,
+ &in_args, sizeof (in_args),
+ &out_args, sizeof (out_args));
+
+ if (invoked) {
+ if (out_args.answer == 0) {
+ g_io_channel_write_chars (tty_channel, "yes\n", -1, &len, NULL);
+ } else {
+ g_io_channel_write_chars (tty_channel, "no\n", -1, &len, NULL);
+ res = GNOME_VFS_ERROR_ACCESS_DENIED;
+ }
+ g_io_channel_flush (tty_channel, NULL);
+ buffer[0]='\0';
+ } else {
+ g_io_channel_write_chars (tty_channel, "no\n", -1, &len, NULL);
+ g_io_channel_flush (tty_channel, NULL);
+ buffer[0]='\0';
res = GNOME_VFS_ERROR_ACCESS_DENIED;
goto bail;
}
+ g_free(in_args.primary_message);
+ g_free(in_args.secondary_message);
+ }
+
}
}
Index: libgnomeui/gnome-authentication-manager.c
===================================================================
RCS file: /cvs/gnome/libgnomeui/libgnomeui/gnome-authentication-manager.c,v
retrieving revision 1.7
diff -u -B -b -r1.7 gnome-authentication-manager.c
--- libgnomeui/gnome-authentication-manager.c 24 Mar 2004 10:40:55 -0000 1.7
+++ libgnomeui/gnome-authentication-manager.c 18 Apr 2004 20:06:17 -0000
@@ -703,6 +703,151 @@
DEBUG_MSG (("-%s\n", G_GNUC_FUNCTION));
}
+typedef struct {
+ const GnomeVFSModuleCallbackQuestionIn *in_args;
+ GnomeVFSModuleCallbackQuestionOut *out_args;
+
+ GnomeVFSModuleCallbackResponse response;
+ gpointer response_data;
+} QuestionCallbackInfo;
+
+static void
+question_dialog_button_clicked (GtkDialog *dialog,
+ gint button_number,
+ QuestionCallbackInfo *info)
+{
+ info->out_args->answer = button_number;
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+
+static void
+question_dialog_destroyed (GtkDialog *dialog, QuestionCallbackInfo *info)
+{
+ info->response (info->response_data);
+ g_free (info);
+}
+
+static void
+question_dialog_closed (GtkDialog *dialog, QuestionCallbackInfo *info)
+{
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static GtkWidget *
+create_question_dialog (char *prim_msg, char *sec_msg, char **choices)
+{
+ GtkWidget *dialog;
+ int cnt, len;
+
+ dialog = gtk_message_dialog_new_with_markup (NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, "<span weight=\"bold\" size=\"larger\">%s</span>\n\n%s",prim_msg, sec_msg);
+
+ if (choices) {
+ /* First count the items in the list then
+ * add the buttons in reverse order */
+ for (len=0; choices[len] != NULL; len++);
+ for (cnt=len-1; cnt >= 0; cnt--) {
+ /* Maybe we should define some gnome-vfs stockbuttons and
+ * then replace them here with gtk-stockbuttons */
+ gtk_dialog_add_button (GTK_DIALOG(dialog), choices[cnt], cnt);
+ }
+ }
+ return (dialog);
+}
+
+static gint /* GtkFunction */
+present_question_dialog_nonblocking (QuestionCallbackInfo *info)
+{
+ GtkWidget *dialog;
+ GtkWidget *toplevel, *current_grab;
+
+ g_return_val_if_fail (info != NULL, 0);
+
+ dialog = create_question_dialog (info->in_args->primary_message, info->in_args->secondary_message, info->in_args->choices);
+
+ toplevel = NULL;
+ current_grab = gtk_grab_get_current ();
+ if (current_grab) {
+ toplevel = gtk_widget_get_toplevel (current_grab);
+ }
+ if (toplevel && GTK_WIDGET_TOPLEVEL (toplevel)) {
+ /* There is a modal window, so we need to be modal too in order to
+ * get input. We set the other modal dialog as parent, which
+ * hopefully gives us better window management.
+ */
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+ gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (toplevel));
+ }
+
+ g_signal_connect (GTK_OBJECT(dialog), "response",
+ G_CALLBACK (question_dialog_button_clicked), info);
+ g_signal_connect (dialog, "close",
+ G_CALLBACK (question_dialog_closed), info);
+ g_signal_connect (dialog, "destroy",
+ G_CALLBACK (question_dialog_destroyed), info);
+
+ gtk_widget_show (GTK_WIDGET (dialog));
+ return 0;
+}
+
+
+static void /* GnomeVFSAsyncModuleCallback */
+vfs_async_question_callback (gconstpointer in, size_t in_size,
+ gpointer out, size_t out_size,
+ gpointer user_data,
+ GnomeVFSModuleCallbackResponse response,
+ gpointer response_data)
+{
+ GnomeVFSModuleCallbackQuestionIn *in_real;
+ GnomeVFSModuleCallbackQuestionOut *out_real;
+ QuestionCallbackInfo *info;
+
+ g_return_if_fail (sizeof (GnomeVFSModuleCallbackQuestionIn) == in_size
+ && sizeof (GnomeVFSModuleCallbackQuestionOut) == out_size);
+
+ g_return_if_fail (in != NULL);
+ g_return_if_fail (out != NULL);
+
+ in_real = (GnomeVFSModuleCallbackQuestionIn *)in;
+ out_real = (GnomeVFSModuleCallbackQuestionOut *)out;
+
+ out_real->answer = -1; /* Set a default value */
+
+ info = g_new (QuestionCallbackInfo, 1);
+
+ info->in_args = in_real;
+ info->out_args = out_real;
+ info->response = response;
+ info->response_data = response_data;
+
+ present_question_dialog_nonblocking (info);
+}
+
+static void /* GnomeVFSModuleCallback */
+vfs_question_callback (gconstpointer in, size_t in_size,
+ gpointer out, size_t out_size,
+ gpointer user_data)
+{
+ GnomeVFSModuleCallbackQuestionIn *in_real;
+ GnomeVFSModuleCallbackQuestionOut *out_real;
+ GtkWidget *dialog;
+
+ g_return_if_fail (sizeof (GnomeVFSModuleCallbackQuestionIn) == in_size
+ && sizeof (GnomeVFSModuleCallbackQuestionOut) == out_size);
+
+ g_return_if_fail (in != NULL);
+ g_return_if_fail (out != NULL);
+
+ in_real = (GnomeVFSModuleCallbackQuestionIn *)in;
+ out_real = (GnomeVFSModuleCallbackQuestionOut *)out;
+
+ out_real->answer = -1; /* Set a default value */
+ dialog = create_question_dialog (in_real->primary_message, in_real->secondary_message, in_real->choices);
+ out_real->answer = gtk_dialog_run (GTK_DIALOG(dialog));
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
void
gnome_authentication_manager_init (void)
{
@@ -731,6 +876,10 @@
vfs_async_save_authentication_callback,
GINT_TO_POINTER (0),
NULL);
+ gnome_vfs_async_module_callback_set_default (GNOME_VFS_MODULE_CALLBACK_QUESTION,
+ vfs_async_question_callback,
+ GINT_TO_POINTER (0),
+ NULL);
/* These are in case someone makes a synchronous http call for
* some reason.
@@ -757,6 +906,10 @@
vfs_save_authentication_callback,
GINT_TO_POINTER (0),
NULL);
+ gnome_vfs_module_callback_set_default (GNOME_VFS_MODULE_CALLBACK_QUESTION,
+ vfs_question_callback,
+ GINT_TO_POINTER (0),
+ NULL);
}
@@ -784,6 +937,10 @@
vfs_async_save_authentication_callback,
GINT_TO_POINTER (0),
NULL);
+ gnome_vfs_async_module_callback_push (GNOME_VFS_MODULE_CALLBACK_QUESTION,
+ vfs_async_question_callback,
+ GINT_TO_POINTER (0),
+ NULL);
}
void
@@ -794,6 +951,7 @@
gnome_vfs_async_module_callback_pop (GNOME_VFS_MODULE_CALLBACK_FILL_AUTHENTICATION);
gnome_vfs_async_module_callback_pop (GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION);
gnome_vfs_async_module_callback_pop (GNOME_VFS_MODULE_CALLBACK_SAVE_AUTHENTICATION);
+ gnome_vfs_async_module_callback_pop (GNOME_VFS_MODULE_CALLBACK_QUESTION);
}
void
@@ -821,6 +979,10 @@
vfs_save_authentication_callback,
GINT_TO_POINTER (0),
NULL);
+ gnome_vfs_module_callback_push (GNOME_VFS_MODULE_CALLBACK_QUESTION,
+ vfs_question_callback,
+ GINT_TO_POINTER (0),
+ NULL);
}
void
@@ -831,5 +993,6 @@
gnome_vfs_module_callback_pop (GNOME_VFS_MODULE_CALLBACK_FILL_AUTHENTICATION);
gnome_vfs_module_callback_pop (GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION);
gnome_vfs_module_callback_pop (GNOME_VFS_MODULE_CALLBACK_SAVE_AUTHENTICATION);
+ gnome_vfs_module_callback_pop (GNOME_VFS_MODULE_CALLBACK_QUESTION);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]