gvfs r1146 - in trunk: . common daemon programs



Author: gicmo
Date: Thu Jan 17 19:00:39 2008
New Revision: 1146
URL: http://svn.gnome.org/viewvc/gvfs?rev=1146&view=rev

Log:
2008-01-17  Christian Kellner  <gicmo gnome org>

	* common/gmountsource.c:
	* common/gmountsource.h:
	Make g_mount_source_ask_password_async () public and add
	g_mount_source_ask_password_finish (). 

	* daemon/gvfsbackenddav.c: 
	Use g_mount_source_ask_password_async instead of the sync
	version so we don't hang during auth. Few cleanups.

	* programs/gvfs-mount.c: 
	Don't echo the password, if possible.


Modified:
   trunk/ChangeLog
   trunk/common/gmountsource.c
   trunk/common/gmountsource.h
   trunk/daemon/gvfsbackenddav.c
   trunk/programs/gvfs-mount.c

Modified: trunk/common/gmountsource.c
==============================================================================
--- trunk/common/gmountsource.c	(original)
+++ trunk/common/gmountsource.c	Thu Jan 17 19:00:39 2008
@@ -122,33 +122,55 @@
 typedef struct AskPasswordData AskPasswordData;
 
 struct AskPasswordData {
-  void (*callback)(AskPasswordData *data);
+
+  /* results: */
+  gboolean  aborted;
+  char     *password;
+  char     *username;
+  char     *domain;
+};
+
+typedef struct AskPasswordSyncData AskPasswordSyncData;
+
+struct AskPasswordSyncData {
+
   /* For sync calls */
   GMutex *mutex;
   GCond *cond;
-  /* For async calls */
-  GMountOperation *op;
 
   /* results: */
-  gboolean handled;
-  gboolean aborted;
-  char *password;
-  char *username;
-  char *domain;
-} ;
+  GAsyncResult *result;
+};
 
 static void
+ask_password_data_free (gpointer _data)
+{
+  AskPasswordData *data = (AskPasswordData *) _data;
+  g_free (data->password);
+  g_free (data->username);
+  g_free (data->domain);
+  g_free (data);
+}
+
+/* the callback from dbus -> main thread */
+static void
 ask_password_reply (DBusMessage *reply,
-		    GError *error,
-		    gpointer _data)
+		    GError      *error,
+		    gpointer     _data)
 {
-  AskPasswordData *data = _data;
+  GSimpleAsyncResult *result;
+  AskPasswordData *data;
   dbus_bool_t handled, aborted, anonymous;
   guint32 password_save;
   const char *password, *username, *domain;
   DBusMessageIter iter;
 
-  data->handled = TRUE;
+  result = G_SIMPLE_ASYNC_RESULT (_data);
+  handled = TRUE;
+  
+  data = g_new0 (AskPasswordData, 1);
+  g_simple_async_result_set_op_res_gpointer (result, data, ask_password_data_free);
+
   if (reply == NULL)
     {
       data->aborted = TRUE;
@@ -168,7 +190,6 @@
 	data->aborted = TRUE;
       else
 	{
-	  data->handled = handled;
 	  data->aborted = aborted;
 
 	  data->password = g_strdup (password);
@@ -179,38 +200,35 @@
 	}
     }
 
-  data->callback (data);
-}
-
-static gboolean
-password_non_handled_in_idle (gpointer _data)
-{
-  AskPasswordData *data = _data;
+  if (handled == FALSE)
+    {
+      g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_FAILED, NULL);
+    }
 
-  data->callback (data);
-  return FALSE;
+  g_simple_async_result_complete (result);
 }
 
-static void
-g_mount_source_ask_password_async (GMountSource *source,
-				   const char *message_string,
-				   const char *default_user,
-				   const char *default_domain,
-				   GAskPasswordFlags flags,
-				   AskPasswordData *data)
+void
+g_mount_source_ask_password_async (GMountSource              *source,
+                                   const char                *message_string,
+                                   const char                *default_user,
+                                   const char                *default_domain,
+                                   GAskPasswordFlags          flags,
+                                   GAsyncReadyCallback        callback,
+                                   gpointer                   user_data)
 {
+  GSimpleAsyncResult *result;
   DBusMessage *message;
   guint32 flags_as_int;
+ 
 
   /* If no dbus id specified, reply that we weren't handled */
   if (source->dbus_id[0] == 0)
-    {
-      data->handled = FALSE;
-      
-      g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
-		       password_non_handled_in_idle,
-		       data,
-		       NULL);
+    { 
+      g_simple_async_report_error_in_idle (G_OBJECT (source),
+					   callback,
+					   user_data,
+					   G_IO_ERROR, G_IO_ERROR_FAILED, NULL); 
       return;
     }
 
@@ -235,16 +253,72 @@
 			       DBUS_TYPE_UINT32, &flags_as_int,
 			       0);
 
+  result = g_simple_async_result_new (G_OBJECT (source), callback, user_data, 
+                                      g_mount_source_ask_password_async);
   /* 30 minute timeout */
   _g_dbus_connection_call_async (NULL, message, 1000 * 60 * 30,
-				 ask_password_reply, data);
+				 ask_password_reply, result);
   dbus_message_unref (message);
+
+}
+
+gboolean
+g_mount_source_ask_password_finish (GMountSource  *source,
+                                    GAsyncResult  *result,
+                                    gboolean      *aborted,
+                                    char         **password_out,
+                                    char         **user_out,
+                                    char         **domain_out)
+{
+  AskPasswordData *data;
+  GSimpleAsyncResult *simple;
+
+  simple = G_SIMPLE_ASYNC_RESULT (result);
+
+  if (g_simple_async_result_propagate_error (simple, NULL))
+    return FALSE;
+
+  data = (AskPasswordData *) g_simple_async_result_get_op_res_gpointer (simple);
+
+  if (aborted)
+    *aborted = data->aborted;
+
+  if (password_out)
+    {
+      *password_out = data->password;
+      data->password = NULL;
+    }
+
+  if (user_out)
+    {
+      *user_out = data->username;
+      data->username = NULL;
+    }
+
+  if (domain_out)
+    {
+      *domain_out = data->domain;
+      data->domain = NULL;
+    }
+
+  return TRUE;
 }
 
 
 static void
-ask_password_reply_sync (AskPasswordData *data)
+ask_password_reply_sync  (GObject *source_object,
+                          GAsyncResult *res,
+                          gpointer user_data)
 {
+  GMountSource *source;
+  AskPasswordSyncData *data;
+
+  source = G_MOUNT_SOURCE (source_object);
+
+  data = (AskPasswordSyncData *) user_data;
+
+  data->result = g_object_ref (res);
+
   /* Wake up sync call thread */
   g_mutex_lock (data->mutex);
   g_cond_signal (data->cond);
@@ -257,13 +331,15 @@
 			     const char *default_user,
 			     const char *default_domain,
 			     GAskPasswordFlags flags,
-			     gboolean *aborted,
+			     gboolean *aborted_out,
 			     char **password_out,
 			     char **user_out,
 			     char **domain_out)
 {
-  AskPasswordData data = {NULL};
-
+  char *password, *username, *domain;
+  gboolean handled, aborted;
+  AskPasswordSyncData data = {NULL};
+  
   if (password_out)
     *password_out = NULL;
   if (user_out)
@@ -273,17 +349,17 @@
   
   data.mutex = g_mutex_new ();
   data.cond = g_cond_new ();
-  data.callback = ask_password_reply_sync;
 
   g_mutex_lock (data.mutex);
 
 
   g_mount_source_ask_password_async (source,
-				     message_string,
-				     default_user,
-				     default_domain,
-				     flags,
-				     &data);
+                                     message_string,
+                                     default_user,
+                                     default_domain,
+                                     flags,
+                                     ask_password_reply_sync,
+                                     &data);
   
   g_cond_wait(data.cond, data.mutex);
   g_mutex_unlock (data.mutex);
@@ -291,52 +367,80 @@
   g_cond_free (data.cond);
   g_mutex_free (data.mutex);
 
-  if (aborted)
-    *aborted = data.aborted;
+
+  handled = g_mount_source_ask_password_finish (source,
+                                                data.result,
+                                                &aborted,
+                                                &password,
+                                                &username,
+                                                &domain);
+  g_object_unref (data.result);
+
+  if (aborted_out)
+    *aborted_out = aborted;
+
   if (password_out)
-    *password_out = data.password;
+    *password_out = password;
   else
-    g_free (data.password);
+    g_free (password);
+
   if (user_out)
-    *user_out = data.username;
+    *user_out = username;
   else
-    g_free (data.username);
+    g_free (username);
+
   if (domain_out)
-    *domain_out = data.domain;
+    *domain_out = domain;
   else
-    g_free (data.domain);
+    g_free (domain);
   
-  return data.handled;
+  return handled;
 }
 
 static void
-ask_password_reply_async (AskPasswordData *data)
+op_ask_password_reply (GObject *source_object,
+                       GAsyncResult *res,
+                       gpointer user_data)
 {
   GMountOperationResult result;
+  GMountOperation *op;
+  GMountSource *source;
+  gboolean handled, aborted;
+  char *username;
+  char *password;
+  char *domain;
+
+  source = G_MOUNT_SOURCE (source_object);
+  op = G_MOUNT_OPERATION (user_data);
+  username = NULL;
+  password = NULL;
+  domain = NULL;
+
+  handled = g_mount_source_ask_password_finish (source,
+                                                res,
+                                                &aborted,
+                                                &username,
+                                                &password,
+                                                &domain);
 
-  if (!data->handled)
+  if (!handled)
     result = G_MOUNT_OPERATION_UNHANDLED;
-  else if (data->aborted)
+  else if (aborted)
     result = G_MOUNT_OPERATION_ABORTED;
   else
     {
       result = G_MOUNT_OPERATION_HANDLED;
 
-      if (data->password)
-	g_mount_operation_set_password (data->op,
-					data->password);
-      if (data->username)
-	g_mount_operation_set_username (data->op,
-					data->username);
-      if (data->domain)
-	g_mount_operation_set_domain (data->op,
-				      data->domain);
+      if (password)
+	g_mount_operation_set_password (op, password);
+      if (username)
+	g_mount_operation_set_username (op, username);
+      if (domain)
+	g_mount_operation_set_domain (op, domain);
     }
   
-  g_mount_operation_reply (data->op, result);
-
-  g_object_unref (data->op);
-  g_free (data);
+  g_mount_operation_reply (op, result);
+  g_object_unref (op);
 }
 
 static gboolean
@@ -347,18 +451,13 @@
 		 GAskPasswordFlags flags,
 		 GMountSource *mount_source)
 {
-  AskPasswordData *data;
-
-  data = g_new0 (AskPasswordData, 1);
-  data->callback = ask_password_reply_async;
-  data->op = g_object_ref (op);
-  
   g_mount_source_ask_password_async (mount_source,
 				     message,
 				     default_user,
 				     default_domain,
-				     flags,
-				     data);
+                                     flags,
+				     op_ask_password_reply,
+				     g_object_ref (op));
   return TRUE;
 }
 

Modified: trunk/common/gmountsource.h
==============================================================================
--- trunk/common/gmountsource.h	(original)
+++ trunk/common/gmountsource.h	Thu Jan 17 19:00:39 2008
@@ -65,6 +65,23 @@
 						       char                     **password_out,
 						       char                     **user_out,
 						       char                     **domain_out);
+
+void          g_mount_source_ask_password_async       (GMountSource              *mount_source,
+						       const char                *message,
+						       const char                *initial_user,
+						       const char                *initial_domain,
+						       GAskPasswordFlags          flags,
+                                                       GAsyncReadyCallback        callback,
+                                                       gpointer                   user_data);
+
+gboolean     g_mount_source_ask_password_finish       (GMountSource              *source,
+                                                       GAsyncResult              *result,
+                                                       gboolean                  *aborted,
+                                                       char                     **password_out,
+                                                       char                     **user_out,
+                                                       char                     **domain_out);
+
+
 const char *  g_mount_source_get_dbus_id              (GMountSource              *mount_source);
 const char *  g_mount_source_get_obj_path             (GMountSource              *mount_source);
 

Modified: trunk/daemon/gvfsbackenddav.c
==============================================================================
--- trunk/daemon/gvfsbackenddav.c	(original)
+++ trunk/daemon/gvfsbackenddav.c	Thu Jan 17 19:00:39 2008
@@ -64,9 +64,6 @@
 {
   GVfsBackendHttp parent_instance;
 
-  /* Only used during mount: */
-  char         *last_good_path;
-  GMountSource *mount_source;
 };
 
 G_DEFINE_TYPE (GVfsBackendDav, g_vfs_backend_dav, G_VFS_TYPE_BACKEND_HTTP);
@@ -187,9 +184,12 @@
 }
 
 static xmlDocPtr
-multistatus_parse_xml (SoupMessage *msg, xmlNodePtr *root, GError **error)
+parse_xml (SoupMessage  *msg,
+           xmlNodePtr   *root,
+           const char   *name,
+           GError      **error)
 {
-  xmlDocPtr  doc;
+ xmlDocPtr  doc;
 
   if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
     {
@@ -220,7 +220,7 @@
       return NULL;
     }
 
-  if (strcmp ((char *) (*root)->name, "multistatus"))
+  if (strcmp ((char *) (*root)->name, name))
     {
         g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                      _("Unexpected reply from server"));
@@ -230,6 +230,14 @@
   return doc;
 }
 
+
+static xmlDocPtr
+multistatus_parse_xml (SoupMessage *msg, xmlNodePtr *root, GError **error)
+{
+    return parse_xml (msg, root, "multistatus", error);
+}
+
+
 static GFileType
 parse_resourcetype (xmlNodePtr rt)
 {
@@ -256,57 +264,80 @@
   return type;
 }
 
+static const char *
+node_get_content (xmlNodePtr node)
+{
+    if (node == NULL)
+      return NULL;
+
+    switch (node->type)
+      {
+        case XML_ELEMENT_NODE:
+          return node_get_content (node->children);
+          break;
+        case XML_TEXT_NODE:
+          return (const char *) node->content;
+          break;
+        default:
+          return NULL;
+      }
+    return NULL;
+}
+
 static GFileInfo *
 mulitstatus_parse_prop_node (xmlDocPtr doc, xmlNodePtr prop)
 {
   GFileInfo  *info;
   xmlNodePtr  node;
+  const char *text;
+  GTimeVal    tv;
 
   info = g_file_info_new ();
 
+
   for (node = prop->children; node; node = node->next)
     {
      if (node->type != XML_ELEMENT_NODE ||
-          node->name == NULL)
+         node->name == NULL)
         {
           continue;
         }
-     else if (!strcmp ((char *) node->name, "resourcetype"))
+
+     text = node_get_content (node);
+
+     if (node_has_name (node, "resourcetype"))
         {
            GFileType type = parse_resourcetype (node);
            g_file_info_set_file_type (info, type);
         }
-     else if (!strcmp ((char *) node->name, "displayname"))
+     else if (node_has_name (node, "displayname"))
         {
-          xmlChar *text;
-          text = xmlNodeGetContent (node);
-          g_file_info_set_display_name (info, (char *) text);
-          xmlFree (text);
+          g_file_info_set_display_name (info, text);
         }
-     else if (!strcmp ((char *) node->name, "getetag"))
+     else if (node_has_name (node, "getetag"))
         {
-
+          g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_ETAG_VALUE,
+                                            text);
         }
-     else if (!strcmp ((char *) node->name, "creationdate"))
+     else if (node_has_name (node, "creationdate"))
         {
-          
+            
         }
-     else if (!strcmp ((char *) node->name, "getcontenttype"))
+     else if (node_has_name (node, "getcontenttype"))
         {
-          xmlChar *text;
-          text = xmlNodeGetContent (node);
-          g_file_info_set_content_type (info, (char *) text);
-          xmlFree (text);
+          g_file_info_set_content_type (info, text);
         }
-     else if (!strcmp ((char *) node->name, "getcontentlength"))
+     else if (node_has_name (node, "getcontentlength"))
         {
-          gint64 size; 
-          xmlChar *text;
-          text = xmlNodeGetContent (node);
-          size = g_ascii_strtoll ((char *) text, NULL, 10);
-          xmlFree (text);
+          gint64 size;
+          size = g_ascii_strtoll (text, NULL, 10);
           g_file_info_set_size (info, size);
         }
+     else if (node_has_name (node, "getlastmodified"))
+       {
+           if (g_time_val_from_iso8601 (text, &tv))
+             g_file_info_set_modification_time (info, &tv);
+       }
     }
   return info;
 }
@@ -333,11 +364,10 @@
         }
       else if (! strcmp ((char *) node->name, "href"))
         {
-          xmlChar *text;
+          const char *text;
 
-          text = xmlNodeGetContent (node);
-          name = uri_get_basename ((char *) text);
-          xmlFree (text);
+          text = node_get_content (node); 
+          name = uri_get_basename (text);
         }
 
       else if (! strcmp ((char *) node->name, "propstat"))
@@ -449,78 +479,159 @@
     return res;
 }
 
+
 /* ************************************************************************* */
 /*  */
+
+typedef struct _MountOpData {
+
+  SoupSession  *session;
+  GMountSource *mount_source;
+
+  char         *last_good_path;
+
+  /* general authentication */
+
+  SoupMessage *message;
+  SoupAuth    *auth;
+
+     /* for server authentication */
+  char *username;
+  char *password;
+  char *last_realm;
+
+     /* for proxy authentication */
+  char *proxy_user;
+  char *proxy_password;
+
+} MountOpData;
+
+static void
+mount_op_data_free (gpointer _data)
+{
+  MountOpData *data;
+
+  data = (MountOpData *) _data;
+  
+  g_free (data->last_good_path);
+  
+  if (data->mount_source)
+    g_object_unref (data->mount_source);
+  
+  if (data->message)
+    g_object_unref (data->message);
+  
+  if (data->auth)
+    g_object_unref (data->auth);
+  
+  g_free (data->username);
+  g_free (data->password);
+  g_free (data->last_realm);
+  g_free (data->proxy_user);
+  g_free (data->proxy_password);
+
+  g_free (data);
+}
+
+static void
+ask_password_ready (GObject      *source_object,
+                    GAsyncResult *result,
+                    gpointer      user_data)
+{
+  MountOpData *data;
+  char        *username;
+  char        *password;
+  gboolean     aborted;
+  gboolean     res;
+
+  data = (MountOpData *) user_data;
+  username = password = NULL;
+
+  res = g_mount_source_ask_password_finish (data->mount_source,
+                                            result,
+                                            &aborted,
+                                            &password,
+                                            &username,
+                                            NULL);
+
+  if (res && !aborted)
+    soup_auth_authenticate (data->auth, username, password);
+
+  soup_session_unpause_message (data->session, data->message);
+
+  g_free (username);
+  g_free (password);
+
+  g_object_unref (data->message);
+  g_object_unref (data->auth);
+  
+  data->message = NULL;
+  data->auth = NULL;
+}
+
 static void
 soup_authenticate (SoupSession *session,
                    SoupMessage *msg,
 	           SoupAuth    *auth,
                    gboolean     retrying,
-                   gpointer     data)
+                   gpointer     user_data)
 {
-  GVfsBackendDav *backend;
-  GVfsJobMount   *job;
-  SoupURI        *mount_base;
-  gboolean        res;
-  gboolean        aborted;
-  const char     *auth_realm;
+  MountOpData    *data;
+  const char     *username;
+  const char     *password;
   char           *prompt;
-  char           *new_password;
-  char           *new_user;
 
-  job = G_VFS_JOB_MOUNT (data);
-  backend = G_VFS_BACKEND_DAV (job->backend);
-  mount_base = G_VFS_BACKEND_HTTP (backend)->mount_base;
+  data = (MountOpData *) user_data;
 
-  auth_realm = soup_auth_get_realm (auth);
+  if (soup_auth_is_for_proxy (auth))
+    {
+      username = data->proxy_user;
+      password = retrying ? NULL : data->proxy_password;
+    }
+  else
+    {
+      username = data->username;
+      password = retrying ? NULL : data->password;
+    }
+
+  if (username && password)
+    {
+      soup_auth_authenticate (auth, username, password);
+      return;
+    }
+
+  if (soup_auth_is_for_proxy (auth))
+    {
+      prompt = g_strdup (_("Please enter proxy password"));
+    }
+  else
+    {
+      const char *auth_realm;
 
-  if (auth_realm == NULL)
-    auth_realm = _("WebDAV share");
+      auth_realm = soup_auth_get_realm (auth);
 
-  prompt = g_strdup_printf (_("Enter password for %s"), auth_realm);
+      if (auth_realm == NULL)
+        auth_realm = _("WebDAV share");
 
-  new_user = new_password = NULL;
-  
-  res = g_mount_source_ask_password (backend->mount_source,
+      prompt = g_strdup_printf (_("Enter password for %s"), auth_realm);
+    }
+
+  data->auth = g_object_ref (auth);
+  data->message = g_object_ref (msg);
+
+  soup_session_pause_message (data->session, msg);
+
+  g_mount_source_ask_password_async (data->mount_source,
                                      prompt,
-                                     mount_base->user,
+                                     username,
                                      NULL,
                                      G_ASK_PASSWORD_NEED_PASSWORD |
                                      G_ASK_PASSWORD_NEED_USERNAME,
-                                     &aborted,
-                                     &new_password,
-                                     &new_user,
-                                     NULL);
-  if (res && !aborted)
-    {
-      soup_auth_authenticate (auth, new_user, new_password);
-    }
-
-  g_free (new_user);
-  g_free (new_password);
+                                     ask_password_ready,
+                                     data);
   g_free (prompt);
 }
 
-static void discover_mount_root_ready (SoupSession *session,
-                                       SoupMessage *msg,
-                                       gpointer     user_data);
-static void
-discover_mount_root (GVfsBackendDav *backend, GVfsJobMount *job)
-{
-  GVfsBackendHttp *http_backend;
-  SoupMessage     *msg;
-  SoupSession     *session;
-  SoupURI         *mount_base;
-
-  http_backend = G_VFS_BACKEND_HTTP (backend);
-  mount_base = http_backend->mount_base;
-  session = http_backend->session;
-
-  msg = soup_message_new_from_uri (SOUP_METHOD_OPTIONS, mount_base);
-  soup_message_headers_append (msg->request_headers, "User-Agent", "gvfs/" VERSION);
-  soup_session_queue_message (session, msg, discover_mount_root_ready, job);
-}
-
 static void
 discover_mount_root_ready (SoupSession *session,
                            SoupMessage *msg,
@@ -528,6 +639,7 @@
 {
   GVfsBackendDav *backend;
   GVfsJobMount   *job;
+  MountOpData    *data;
   GMountSpec     *mount_spec;
   SoupURI        *mount_base;
   gboolean        is_success;
@@ -536,6 +648,7 @@
   job = G_VFS_JOB_MOUNT (user_data);
   backend = G_VFS_BACKEND_DAV (job->backend);
   mount_base = G_VFS_BACKEND_HTTP (backend)->mount_base;
+  data = (MountOpData *) G_VFS_JOB (job)->backend_data;
 
   is_success = SOUP_STATUS_IS_SUCCESSFUL (msg->status_code);
   is_dav = sm_has_header (msg, "DAV");
@@ -544,12 +657,16 @@
 
   if (is_success && is_dav)
     {
-      backend->last_good_path = mount_base->path;
+
+      data->last_good_path = mount_base->path;
       mount_base->path = path_get_parent_dir (mount_base->path);
 
       if (mount_base->path)
         {
-          discover_mount_root (backend, job);
+          SoupMessage *msg;
+          msg = message_new_from_uri (SOUP_METHOD_OPTIONS, mount_base);
+          soup_session_queue_message (session, msg, 
+                                      discover_mount_root_ready, job);
           return;
         } 
     }
@@ -558,7 +675,7 @@
    * chdir up to (or couldn't chdir up at all) */
   
   /* check if we at all have a good path */
-  if (backend->last_good_path == NULL)
+  if (data->last_good_path == NULL)
     {
       if (!is_success) 
         g_vfs_job_failed (G_VFS_JOB (job),
@@ -572,7 +689,11 @@
       return;
     }
 
+  g_free (mount_base->path);
+  mount_base->path = data->last_good_path;
+  data->last_good_path = NULL;
   mount_spec = g_mount_spec_new ("dav"); 
+  
   g_mount_spec_set (mount_spec, "host", mount_base->host);
 
   if (mount_base->user)
@@ -583,43 +704,16 @@
   else if (mount_base->scheme == SOUP_URI_SCHEME_HTTPS)
     g_mount_spec_set (mount_spec, "ssl", "true");
 
-  g_free (mount_base->path);
-  mount_base->path = backend->last_good_path;
-
   g_mount_spec_set_mount_prefix (mount_spec, mount_base->path);
-  g_vfs_backend_set_mount_spec (G_VFS_BACKEND (backend), mount_spec);
   g_vfs_backend_set_icon_name (G_VFS_BACKEND (backend), "folder-remote");
 
+  g_vfs_backend_set_mount_spec (G_VFS_BACKEND (backend), mount_spec);
   g_mount_spec_unref (mount_spec);
+
   g_print ("- discover_mount_root_ready success: %s \n", mount_base->path);
   g_vfs_job_succeeded (G_VFS_JOB (job));
 }
 
-
-
-static void
-mount (GVfsBackend  *backend,
-       GVfsJobMount *job,
-       GMountSpec   *mount_spec,
-       GMountSource *mount_source,
-       gboolean      is_automount)
-{
-  GVfsBackendDav *op_backend;
-  SoupSession    *session;
-
-  g_print ("+ mount\n");
-
-  op_backend = G_VFS_BACKEND_DAV (backend);
-  session = G_VFS_BACKEND_HTTP (backend)->session;
-
-  g_signal_connect (session, "authenticate",
-                    G_CALLBACK (soup_authenticate), job);
-
-  op_backend->mount_source = mount_source;
-  discover_mount_root (op_backend, job);
-  g_print ("- mount\n");
-}
-
 static gboolean
 try_mount (GVfsBackend  *backend,
            GVfsJobMount *job,
@@ -628,6 +722,9 @@
            gboolean      is_automount)
 {
   GVfsBackendDav *op_backend;
+  MountOpData    *data;
+  SoupSession    *session;
+  SoupMessage    *msg;
   SoupURI        *uri;
   const char     *host;
   const char     *user;
@@ -635,11 +732,7 @@
   const char     *ssl;
   guint           port_num;
 
-  /* We have to override this method since the http backend
-   * has its own try_mount and we don't want that to be used.
-   * We also need to do the dav mounting stuff inside a
-   * thread since the auth callback from soup is getting
-   * called in the main thread otherwise and we would block */
+  g_print ("+ mount\n");
 
   op_backend = G_VFS_BACKEND_DAV (backend);
 
@@ -672,9 +765,24 @@
   soup_uri_set_host (uri, host);
   soup_uri_set_path (uri, mount_spec->mount_prefix);
 
+  session = G_VFS_BACKEND_HTTP (backend)->session;
   G_VFS_BACKEND_HTTP (backend)->mount_base = uri; 
 
-  return FALSE;
+  msg = message_new_from_uri (SOUP_METHOD_OPTIONS, uri);
+  soup_session_queue_message (session, msg, discover_mount_root_ready, job);
+
+  data = g_new0 (MountOpData, 1);
+  data->session = g_object_ref (session);
+  data->mount_source = g_object_ref (mount_source);
+  data->username = g_strdup (user);
+
+  g_signal_connect (session, "authenticate",
+                    G_CALLBACK (soup_authenticate), data);
+
+  g_vfs_job_set_backend_data (G_VFS_JOB (job), data, mount_op_data_free);
+
+  g_print ("- mount\n");
+  return TRUE;
 }
 
 static void
@@ -784,8 +892,8 @@
   return TRUE;
 }
 
-/* *** enumerate *** */
 
+/* *** enumerate *** */
 
 
 static void
@@ -888,7 +996,7 @@
       redirect_header = "T";
 
   soup_message_headers_append (msg->request_headers,
-                           "Apply-To-Redirect-Ref", redirect_header);
+                               "Apply-To-Redirect-Ref", redirect_header);
 
   soup_message_set_request (msg, "application/xml",
                             SOUP_MEMORY_TAKE,
@@ -912,7 +1020,6 @@
   gobject_class->finalize  = g_vfs_backend_dav_finalize;
 
   backend_class = G_VFS_BACKEND_CLASS (klass); 
-  backend_class->mount             = mount;
   backend_class->try_mount         = try_mount;
   backend_class->try_query_info    = try_query_info;
   backend_class->try_enumerate     = try_enumerate;

Modified: trunk/programs/gvfs-mount.c
==============================================================================
--- trunk/programs/gvfs-mount.c	(original)
+++ trunk/programs/gvfs-mount.c	Thu Jan 17 19:00:39 2008
@@ -29,6 +29,12 @@
 #include <locale.h>
 #include <gio/gio.h>
 
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+
+#define STDIN_FILENO 0
+
 static int outstanding_mounts = 0;
 static GMainLoop *main_loop;
 
@@ -48,8 +54,14 @@
 };
 
 static char *
-prompt_for (const char *prompt, const char *default_value)
+prompt_for (const char *prompt, const char *default_value, gboolean echo)
 {
+#ifdef HAVE_TERMIOS_H
+  struct termios term_attr; 
+  int old_flags;
+  int res;
+  gboolean restore_flags;
+#endif
   char data[256];
   int len;
 
@@ -59,7 +71,31 @@
     g_print ("%s: ", prompt);
 
   data[0] = 0;
+
+#ifdef HAVE_TERMIOS_H
+  restore_flags = FALSE;
+  if (!echo && (res = tcgetattr (STDIN_FILENO, &term_attr)) == 0)
+    {
+      old_flags = term_attr.c_lflag; 
+      term_attr.c_lflag &= ~ECHO;
+      restore_flags = TRUE;
+      
+      if (tcsetattr (STDIN_FILENO, TCSAFLUSH, &term_attr) != 0)
+        g_print ("Warning! Password will be echoed");
+    }
+
+#endif
+
   fgets(data, sizeof (data), stdin);
+  
+#ifdef HAVE_TERMIOS_H
+  if (restore_flags)
+    {
+      term_attr.c_lflag = old_flags;
+      tcsetattr (STDIN_FILENO, TCSAFLUSH, &term_attr);
+    }
+#endif
+
   len = strlen (data);
   if (len > 0 && data[len-1] == '\n')
     data[len-1] = 0;
@@ -81,21 +117,21 @@
 
   if (flags & G_ASK_PASSWORD_NEED_USERNAME)
     {
-      s = prompt_for ("User", default_user);
+      s = prompt_for ("User", default_user, TRUE);
       g_mount_operation_set_username (op, s);
       g_free (s);
     }
   
   if (flags & G_ASK_PASSWORD_NEED_DOMAIN)
     {
-      s = prompt_for ("Domain", default_domain);
+      s = prompt_for ("Domain", default_domain, TRUE);
       g_mount_operation_set_domain (op, s);
       g_free (s);
     }
   
   if (flags & G_ASK_PASSWORD_NEED_PASSWORD)
     {
-      s = prompt_for ("Password", NULL);
+      s = prompt_for ("Password", NULL, FALSE);
       g_mount_operation_set_password (op, s);
       g_free (s);
     }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]