- Bump version requirements
- Backport FTP and Computer backend patches from master
This commit is contained in:
parent
23deddcfda
commit
32d84ada85
205
0001-FTP-prepare-the-code-for-active-FTP-support.patch
Normal file
205
0001-FTP-prepare-the-code-for-active-FTP-support.patch
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
From 7f2ac23d150aa779310a37534fc8564bbfc93b86 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Otte <otte@gnome.org>
|
||||||
|
Date: Mon, 15 Jun 2009 22:02:34 +0200
|
||||||
|
Subject: [PATCH 01/13] [FTP] prepare the code for active FTP support
|
||||||
|
|
||||||
|
adds a bunch of new APIs necessary for supporting active FTP. These APIs
|
||||||
|
don't do anything yet, as active FTP is still unsupported, it's just
|
||||||
|
refactoring of code.
|
||||||
|
---
|
||||||
|
daemon/gvfsbackendftp.c | 11 +++++++--
|
||||||
|
daemon/gvfsftpdircache.c | 4 +-
|
||||||
|
daemon/gvfsftptask.c | 47 ++++++++++++++++++++++++++++++++-------------
|
||||||
|
daemon/gvfsftptask.h | 1 +
|
||||||
|
4 files changed, 44 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gvfsbackendftp.c b/daemon/gvfsbackendftp.c
|
||||||
|
index ba6acd4..913eb1c 100644
|
||||||
|
--- a/daemon/gvfsbackendftp.c
|
||||||
|
+++ b/daemon/gvfsbackendftp.c
|
||||||
|
@@ -642,7 +642,7 @@ do_open_for_read (GVfsBackend *backend,
|
||||||
|
error_550_permission_or_not_found,
|
||||||
|
NULL };
|
||||||
|
|
||||||
|
- g_vfs_ftp_task_open_data_connection (&task);
|
||||||
|
+ g_vfs_ftp_task_setup_data_connection (&task);
|
||||||
|
file = g_vfs_ftp_file_new_from_gvfs (ftp, filename);
|
||||||
|
|
||||||
|
g_vfs_ftp_task_send_and_check (&task,
|
||||||
|
@@ -653,6 +653,8 @@ do_open_for_read (GVfsBackend *backend,
|
||||||
|
"RETR %s", g_vfs_ftp_file_get_ftp_path (file));
|
||||||
|
g_vfs_ftp_file_free (file);
|
||||||
|
|
||||||
|
+ g_vfs_ftp_task_open_data_connection (&task);
|
||||||
|
+
|
||||||
|
if (!g_vfs_ftp_task_is_in_error (&task))
|
||||||
|
{
|
||||||
|
/* don't push the connection back, it's our handle now */
|
||||||
|
@@ -722,7 +724,7 @@ do_start_write (GVfsFtpTask *task,
|
||||||
|
|
||||||
|
/* FIXME: can we honour the flags? */
|
||||||
|
|
||||||
|
- g_vfs_ftp_task_open_data_connection (task);
|
||||||
|
+ g_vfs_ftp_task_setup_data_connection (task);
|
||||||
|
|
||||||
|
va_start (varargs, format);
|
||||||
|
g_vfs_ftp_task_sendv (task,
|
||||||
|
@@ -732,6 +734,8 @@ do_start_write (GVfsFtpTask *task,
|
||||||
|
varargs);
|
||||||
|
va_end (varargs);
|
||||||
|
|
||||||
|
+ g_vfs_ftp_task_open_data_connection (task);
|
||||||
|
+
|
||||||
|
if (!g_vfs_ftp_task_is_in_error (task))
|
||||||
|
{
|
||||||
|
/* don't push the connection back, it's our handle now */
|
||||||
|
@@ -1280,13 +1284,14 @@ do_pull (GVfsBackend * backend,
|
||||||
|
}
|
||||||
|
else
|
||||||
|
total_size = 0;
|
||||||
|
- g_vfs_ftp_task_open_data_connection (&task);
|
||||||
|
+ g_vfs_ftp_task_setup_data_connection (&task);
|
||||||
|
g_vfs_ftp_task_send_and_check (&task,
|
||||||
|
G_VFS_FTP_PASS_100 | G_VFS_FTP_FAIL_200,
|
||||||
|
&open_read_handlers[0],
|
||||||
|
src,
|
||||||
|
NULL,
|
||||||
|
"RETR %s", g_vfs_ftp_file_get_ftp_path (src));
|
||||||
|
+ g_vfs_ftp_task_open_data_connection (&task);
|
||||||
|
if (g_vfs_ftp_task_is_in_error (&task))
|
||||||
|
{
|
||||||
|
g_vfs_ftp_file_free (src);
|
||||||
|
diff --git a/daemon/gvfsftpdircache.c b/daemon/gvfsftpdircache.c
|
||||||
|
index 26984f4..8e6de25 100644
|
||||||
|
--- a/daemon/gvfsftpdircache.c
|
||||||
|
+++ b/daemon/gvfsftpdircache.c
|
||||||
|
@@ -153,11 +153,11 @@ g_vfs_ftp_dir_cache_lookup_entry (GVfsFtpDirCache * cache,
|
||||||
|
G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY,
|
||||||
|
_("The file is not a directory"));
|
||||||
|
}
|
||||||
|
- g_vfs_ftp_task_open_data_connection (task);
|
||||||
|
-
|
||||||
|
+ g_vfs_ftp_task_setup_data_connection (task);
|
||||||
|
g_vfs_ftp_task_send (task,
|
||||||
|
G_VFS_FTP_PASS_100 | G_VFS_FTP_FAIL_200,
|
||||||
|
"%s", cache->funcs->command);
|
||||||
|
+ g_vfs_ftp_task_open_data_connection (task);
|
||||||
|
if (g_vfs_ftp_task_is_in_error (task))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
diff --git a/daemon/gvfsftptask.c b/daemon/gvfsftptask.c
|
||||||
|
index 118f80d..37f2b59 100644
|
||||||
|
--- a/daemon/gvfsftptask.c
|
||||||
|
+++ b/daemon/gvfsftptask.c
|
||||||
|
@@ -747,7 +747,7 @@ g_vfs_ftp_task_create_remote_address (GVfsFtpTask *task, guint port)
|
||||||
|
}
|
||||||
|
|
||||||
|
static GVfsFtpMethod
|
||||||
|
-g_vfs_ftp_task_open_data_connection_epsv (GVfsFtpTask *task, GVfsFtpMethod method)
|
||||||
|
+g_vfs_ftp_task_setup_data_connection_epsv (GVfsFtpTask *task, GVfsFtpMethod method)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
char **reply;
|
||||||
|
@@ -790,7 +790,7 @@ fail:
|
||||||
|
}
|
||||||
|
|
||||||
|
static GVfsFtpMethod
|
||||||
|
-g_vfs_ftp_task_open_data_connection_pasv (GVfsFtpTask *task, GVfsFtpMethod method)
|
||||||
|
+g_vfs_ftp_task_setup_data_connection_pasv (GVfsFtpTask *task, GVfsFtpMethod method)
|
||||||
|
{
|
||||||
|
guint ip1, ip2, ip3, ip4, port1, port2;
|
||||||
|
char **reply;
|
||||||
|
@@ -875,14 +875,14 @@ g_vfs_ftp_task_open_data_connection_pasv (GVfsFtpTask *task, GVfsFtpMethod metho
|
||||||
|
typedef GVfsFtpMethod (* GVfsFtpOpenDataConnectionFunc) (GVfsFtpTask *task, GVfsFtpMethod method);
|
||||||
|
|
||||||
|
static GVfsFtpMethod
|
||||||
|
-g_vfs_ftp_task_open_data_connection_any (GVfsFtpTask *task, GVfsFtpMethod unused)
|
||||||
|
+g_vfs_ftp_task_setup_data_connection_any (GVfsFtpTask *task, GVfsFtpMethod unused)
|
||||||
|
{
|
||||||
|
static const struct {
|
||||||
|
GVfsFtpFeature required_feature;
|
||||||
|
GVfsFtpOpenDataConnectionFunc func;
|
||||||
|
} funcs_ordered[] = {
|
||||||
|
- { G_VFS_FTP_FEATURE_EPSV, g_vfs_ftp_task_open_data_connection_epsv },
|
||||||
|
- { 0, g_vfs_ftp_task_open_data_connection_pasv }
|
||||||
|
+ { G_VFS_FTP_FEATURE_EPSV, g_vfs_ftp_task_setup_data_connection_epsv },
|
||||||
|
+ { 0, g_vfs_ftp_task_setup_data_connection_pasv }
|
||||||
|
};
|
||||||
|
GVfsFtpMethod method;
|
||||||
|
guint i;
|
||||||
|
@@ -918,20 +918,23 @@ g_vfs_ftp_task_open_data_connection_any (GVfsFtpTask *task, GVfsFtpMethod unused
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
- * g_vfs_ftp_task_open_data_connection:
|
||||||
|
+ * g_vfs_ftp_task_setup_data_connection:
|
||||||
|
* @task: a task not having an open data connection
|
||||||
|
*
|
||||||
|
- * Tries to open a data connection to the ftp server. If the operation fails,
|
||||||
|
- * @task will be set into an error state.
|
||||||
|
+ * Sets up a data connection to the ftp server with using the best method for
|
||||||
|
+ * this task. If the operation fails, @task will be set into an error state.
|
||||||
|
+ * You must call g_vfs_ftp_task_open_data_connection() to finish setup and
|
||||||
|
+ * ensure the data connection actually gets opened. Usually, this requires
|
||||||
|
+ * sending an FTP command down the stream.
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
-g_vfs_ftp_task_open_data_connection (GVfsFtpTask *task)
|
||||||
|
+g_vfs_ftp_task_setup_data_connection (GVfsFtpTask *task)
|
||||||
|
{
|
||||||
|
static const GVfsFtpOpenDataConnectionFunc connect_funcs[] = {
|
||||||
|
- [G_VFS_FTP_METHOD_ANY] = g_vfs_ftp_task_open_data_connection_any,
|
||||||
|
- [G_VFS_FTP_METHOD_EPSV] = g_vfs_ftp_task_open_data_connection_epsv,
|
||||||
|
- [G_VFS_FTP_METHOD_PASV] = g_vfs_ftp_task_open_data_connection_pasv,
|
||||||
|
- [G_VFS_FTP_METHOD_PASV_ADDR] = g_vfs_ftp_task_open_data_connection_pasv,
|
||||||
|
+ [G_VFS_FTP_METHOD_ANY] = g_vfs_ftp_task_setup_data_connection_any,
|
||||||
|
+ [G_VFS_FTP_METHOD_EPSV] = g_vfs_ftp_task_setup_data_connection_epsv,
|
||||||
|
+ [G_VFS_FTP_METHOD_PASV] = g_vfs_ftp_task_setup_data_connection_pasv,
|
||||||
|
+ [G_VFS_FTP_METHOD_PASV_ADDR] = g_vfs_ftp_task_setup_data_connection_pasv,
|
||||||
|
[G_VFS_FTP_METHOD_EPRT] = NULL,
|
||||||
|
[G_VFS_FTP_METHOD_PORT] = NULL
|
||||||
|
};
|
||||||
|
@@ -953,7 +956,7 @@ g_vfs_ftp_task_open_data_connection (GVfsFtpTask *task)
|
||||||
|
if (result == G_VFS_FTP_METHOD_ANY &&
|
||||||
|
method != G_VFS_FTP_METHOD_ANY &&
|
||||||
|
!g_vfs_ftp_task_is_in_error (task))
|
||||||
|
- result = g_vfs_ftp_task_open_data_connection_any (task, G_VFS_FTP_METHOD_ANY);
|
||||||
|
+ result = g_vfs_ftp_task_setup_data_connection_any (task, G_VFS_FTP_METHOD_ANY);
|
||||||
|
|
||||||
|
g_assert (result < G_N_ELEMENTS (connect_funcs) && connect_funcs[result]);
|
||||||
|
if (result != method)
|
||||||
|
@@ -972,3 +975,19 @@ g_vfs_ftp_task_open_data_connection (GVfsFtpTask *task)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * g_vfs_ftp_task_open_data_connection:
|
||||||
|
+ * @task: a task
|
||||||
|
+ *
|
||||||
|
+ * Tries to open a data connection to the ftp server. If the operation fails,
|
||||||
|
+ * @task will be set into an error state.
|
||||||
|
+ **/
|
||||||
|
+void
|
||||||
|
+g_vfs_ftp_task_open_data_connection (GVfsFtpTask *task)
|
||||||
|
+{
|
||||||
|
+ g_return_if_fail (task != NULL);
|
||||||
|
+
|
||||||
|
+ if (g_vfs_ftp_task_is_in_error (task))
|
||||||
|
+ return;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
diff --git a/daemon/gvfsftptask.h b/daemon/gvfsftptask.h
|
||||||
|
index 6453f41..8345535 100644
|
||||||
|
--- a/daemon/gvfsftptask.h
|
||||||
|
+++ b/daemon/gvfsftptask.h
|
||||||
|
@@ -82,6 +82,7 @@ guint g_vfs_ftp_task_sendv (GVfsFtpTask *
|
||||||
|
guint g_vfs_ftp_task_receive (GVfsFtpTask * task,
|
||||||
|
GVfsFtpResponseFlags flags,
|
||||||
|
char *** reply);
|
||||||
|
+void g_vfs_ftp_task_setup_data_connection (GVfsFtpTask * task);
|
||||||
|
void g_vfs_ftp_task_open_data_connection (GVfsFtpTask * task);
|
||||||
|
void g_vfs_ftp_task_close_data_connection (GVfsFtpTask * task);
|
||||||
|
|
||||||
|
--
|
||||||
|
1.6.3.2
|
||||||
|
|
361
0002-FTP-Bug-516704-Be-able-to-connect-to-an-Active-FTP-S.patch
Normal file
361
0002-FTP-Bug-516704-Be-able-to-connect-to-an-Active-FTP-S.patch
Normal file
@ -0,0 +1,361 @@
|
|||||||
|
From 2839922c259b848d7689d245a055c628754dc116 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Otte <otte@gnome.org>
|
||||||
|
Date: Mon, 15 Jun 2009 23:03:26 +0200
|
||||||
|
Subject: [PATCH 02/13] =?utf-8?q?[FTP]=20Bug=20516704=20=E2=80=93=20Be=20able=20to=20connect=20to=20an=20Active=20FTP=20Site?=
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=utf-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Add initial support for the PORT command. Support for EPRT and a
|
||||||
|
non-ugly API are still missing.
|
||||||
|
---
|
||||||
|
daemon/gvfsftpconnection.c | 157 +++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
daemon/gvfsftpconnection.h | 7 ++
|
||||||
|
daemon/gvfsftptask.c | 56 ++++++++++++++--
|
||||||
|
daemon/gvfsftptask.h | 1 +
|
||||||
|
4 files changed, 215 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gvfsftpconnection.c b/daemon/gvfsftpconnection.c
|
||||||
|
index ac5418f..521664c 100644
|
||||||
|
--- a/daemon/gvfsftpconnection.c
|
||||||
|
+++ b/daemon/gvfsftpconnection.c
|
||||||
|
@@ -22,10 +22,12 @@
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
+#include "gvfsftpconnection.h"
|
||||||
|
+
|
||||||
|
#include <string.h>
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
|
-#include "gvfsftpconnection.h"
|
||||||
|
+#include "gvfsbackendftp.h"
|
||||||
|
|
||||||
|
/* used for identifying the connection during debugging */
|
||||||
|
static volatile int debug_id = 0;
|
||||||
|
@@ -37,6 +39,7 @@ struct _GVfsFtpConnection
|
||||||
|
GIOStream * commands; /* ftp command stream */
|
||||||
|
GDataInputStream * commands_in; /* wrapper around in stream to allow line-wise reading */
|
||||||
|
|
||||||
|
+ GSocket * listen_socket; /* socket we are listening on for active FTP connections */
|
||||||
|
GIOStream * data; /* ftp data stream or NULL if not in use */
|
||||||
|
|
||||||
|
int debug_id; /* unique id for debugging purposes */
|
||||||
|
@@ -71,11 +74,22 @@ g_vfs_ftp_connection_new (GSocketConnectable *addr,
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+g_vfs_ftp_connection_stop_listening (GVfsFtpConnection *conn)
|
||||||
|
+{
|
||||||
|
+ if (conn->listen_socket)
|
||||||
|
+ {
|
||||||
|
+ g_object_unref (conn->listen_socket);
|
||||||
|
+ conn->listen_socket = NULL;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
g_vfs_ftp_connection_free (GVfsFtpConnection *conn)
|
||||||
|
{
|
||||||
|
g_return_if_fail (conn != NULL);
|
||||||
|
|
||||||
|
+ g_vfs_ftp_connection_stop_listening (conn);
|
||||||
|
if (conn->data)
|
||||||
|
g_vfs_ftp_connection_close_data_connection (conn);
|
||||||
|
|
||||||
|
@@ -218,6 +232,8 @@ g_vfs_ftp_connection_open_data_connection (GVfsFtpConnection *conn,
|
||||||
|
g_return_val_if_fail (conn != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (conn->data == NULL, FALSE);
|
||||||
|
|
||||||
|
+ g_vfs_ftp_connection_stop_listening (conn);
|
||||||
|
+
|
||||||
|
conn->data = G_IO_STREAM (g_socket_client_connect (conn->client,
|
||||||
|
G_SOCKET_CONNECTABLE (addr),
|
||||||
|
cancellable,
|
||||||
|
@@ -226,6 +242,145 @@ g_vfs_ftp_connection_open_data_connection (GVfsFtpConnection *conn,
|
||||||
|
return conn->data != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * g_vfs_ftp_connection_listen_data_connection:
|
||||||
|
+ * @conn: a connection
|
||||||
|
+ * @error: %NULL or location to take potential errors
|
||||||
|
+ *
|
||||||
|
+ * Initiates a listening socket that the FTP server can connect to. To accept
|
||||||
|
+ * connections and initialize data transfers, use
|
||||||
|
+ * g_vfs_ftp_connection_accept_data_connection().
|
||||||
|
+ * This function supports what is known as "active FTP", while
|
||||||
|
+ * g_vfs_ftp_connection_open_data_connection() is to be used for "passive FTP".
|
||||||
|
+ *
|
||||||
|
+ * Returns: the actual address the socket is listening on or %NULL on error
|
||||||
|
+ **/
|
||||||
|
+GSocketAddress *
|
||||||
|
+g_vfs_ftp_connection_listen_data_connection (GVfsFtpConnection *conn,
|
||||||
|
+ GError ** error)
|
||||||
|
+{
|
||||||
|
+ GSocketAddress *local, *addr;
|
||||||
|
+
|
||||||
|
+ g_return_val_if_fail (conn != NULL, NULL);
|
||||||
|
+ g_return_val_if_fail (conn->data == NULL, FALSE);
|
||||||
|
+
|
||||||
|
+ g_vfs_ftp_connection_stop_listening (conn);
|
||||||
|
+
|
||||||
|
+ local = g_socket_connection_get_local_address (G_SOCKET_CONNECTION (conn->commands), error);
|
||||||
|
+ if (local == NULL)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ conn->listen_socket = g_socket_new (g_socket_address_get_family (local),
|
||||||
|
+ G_SOCKET_TYPE_STREAM,
|
||||||
|
+ G_SOCKET_PROTOCOL_TCP,
|
||||||
|
+ error);
|
||||||
|
+ if (conn->listen_socket == NULL)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ g_assert (G_IS_INET_SOCKET_ADDRESS (local));
|
||||||
|
+ addr = g_inet_socket_address_new (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (local)), 0);
|
||||||
|
+ g_object_unref (local);
|
||||||
|
+
|
||||||
|
+ if (!g_socket_bind (conn->listen_socket, addr, TRUE, error) ||
|
||||||
|
+ !g_socket_listen (conn->listen_socket, error) ||
|
||||||
|
+ !(local = g_socket_get_local_address (conn->listen_socket, error)))
|
||||||
|
+ {
|
||||||
|
+ g_object_unref (addr);
|
||||||
|
+ g_vfs_ftp_connection_stop_listening (conn);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ g_object_unref (addr);
|
||||||
|
+ return local;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+cancel_timer_cb (GCancellable *orig, GCancellable *to_cancel)
|
||||||
|
+{
|
||||||
|
+ g_cancellable_cancel (to_cancel);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static gboolean
|
||||||
|
+cancel_cancellable (gpointer cancellable)
|
||||||
|
+{
|
||||||
|
+ g_cancellable_cancel (cancellable);
|
||||||
|
+ return FALSE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * g_vfs_ftp_connection_accept_data_connection:
|
||||||
|
+ * @conn: a listening connection
|
||||||
|
+ * @cancellable: cancellable to interrupt wait
|
||||||
|
+ * @error: %NULL or location to take a potential error
|
||||||
|
+ *
|
||||||
|
+ * Opens a data connection for @conn by accepting an incoming connection on the
|
||||||
|
+ * address it is listening on via g_vfs_ftp_connection_listen_data_connection(),
|
||||||
|
+ * which must have been called prior to this function.
|
||||||
|
+ * If this function succeeds, a data connection will have been opened, and calls
|
||||||
|
+ * to g_vfs_ftp_connection_get_data_stream() will work.
|
||||||
|
+ *
|
||||||
|
+ * Returns: %TRUE if a connection was successfully acquired
|
||||||
|
+ **/
|
||||||
|
+gboolean
|
||||||
|
+g_vfs_ftp_connection_accept_data_connection (GVfsFtpConnection *conn,
|
||||||
|
+ GCancellable * cancellable,
|
||||||
|
+ GError ** error)
|
||||||
|
+{
|
||||||
|
+ GSocket *accepted;
|
||||||
|
+ GCancellable *timer;
|
||||||
|
+ gulong cancel_cb_id;
|
||||||
|
+ GIOCondition condition;
|
||||||
|
+
|
||||||
|
+ g_return_val_if_fail (conn != NULL, FALSE);
|
||||||
|
+ g_return_val_if_fail (conn->data == NULL, FALSE);
|
||||||
|
+ g_return_val_if_fail (G_IS_SOCKET (conn->listen_socket), FALSE);
|
||||||
|
+
|
||||||
|
+ timer = g_cancellable_new ();
|
||||||
|
+ cancel_cb_id = g_cancellable_connect (cancellable,
|
||||||
|
+ G_CALLBACK (cancel_timer_cb),
|
||||||
|
+ timer,
|
||||||
|
+ NULL);
|
||||||
|
+ g_object_ref (timer);
|
||||||
|
+ g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
|
||||||
|
+ G_VFS_FTP_TIMEOUT_IN_SECONDS,
|
||||||
|
+ cancel_cancellable,
|
||||||
|
+ timer,
|
||||||
|
+ g_object_unref);
|
||||||
|
+
|
||||||
|
+ condition = g_socket_condition_wait (conn->listen_socket, G_IO_IN, timer, error);
|
||||||
|
+
|
||||||
|
+ g_cancellable_disconnect (cancellable, cancel_cb_id);
|
||||||
|
+ g_object_unref (timer);
|
||||||
|
+
|
||||||
|
+ if ((condition & G_IO_IN) == 0)
|
||||||
|
+ {
|
||||||
|
+ if (g_cancellable_is_cancelled (timer) &&
|
||||||
|
+ !g_cancellable_is_cancelled (cancellable))
|
||||||
|
+ {
|
||||||
|
+ g_clear_error (error);
|
||||||
|
+ g_set_error_literal (error,
|
||||||
|
+ G_IO_ERROR, G_IO_ERROR_HOST_NOT_FOUND,
|
||||||
|
+ _("Failed to create active FTP connection. "
|
||||||
|
+ "Maybe your router does not support this?"));
|
||||||
|
+ }
|
||||||
|
+ else if (error && *error == NULL)
|
||||||
|
+ {
|
||||||
|
+ g_set_error_literal (error,
|
||||||
|
+ G_IO_ERROR, G_IO_ERROR_HOST_NOT_FOUND,
|
||||||
|
+ _("Failed to create active FTP connection."));
|
||||||
|
+ }
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ accepted = g_socket_accept (conn->listen_socket, error);
|
||||||
|
+ if (accepted == NULL)
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
+ conn->data = G_IO_STREAM (g_socket_connection_factory_create_connection (accepted));
|
||||||
|
+ g_object_unref (accepted);
|
||||||
|
+ return TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
g_vfs_ftp_connection_close_data_connection (GVfsFtpConnection *conn)
|
||||||
|
{
|
||||||
|
diff --git a/daemon/gvfsftpconnection.h b/daemon/gvfsftpconnection.h
|
||||||
|
index 3605f26..7d0c697 100644
|
||||||
|
--- a/daemon/gvfsftpconnection.h
|
||||||
|
+++ b/daemon/gvfsftpconnection.h
|
||||||
|
@@ -55,6 +55,13 @@ gboolean g_vfs_ftp_connection_open_data_connection
|
||||||
|
GSocketAddress * addr,
|
||||||
|
GCancellable * cancellable,
|
||||||
|
GError ** error);
|
||||||
|
+GSocketAddress * g_vfs_ftp_connection_listen_data_connection
|
||||||
|
+ (GVfsFtpConnection * conn,
|
||||||
|
+ GError ** error);
|
||||||
|
+gboolean g_vfs_ftp_connection_accept_data_connection
|
||||||
|
+ (GVfsFtpConnection * conn,
|
||||||
|
+ GCancellable * cancellable,
|
||||||
|
+ GError ** error);
|
||||||
|
void g_vfs_ftp_connection_close_data_connection
|
||||||
|
(GVfsFtpConnection * conn);
|
||||||
|
GIOStream * g_vfs_ftp_connection_get_data_stream (GVfsFtpConnection * conn);
|
||||||
|
diff --git a/daemon/gvfsftptask.c b/daemon/gvfsftptask.c
|
||||||
|
index 37f2b59..879b912 100644
|
||||||
|
--- a/daemon/gvfsftptask.c
|
||||||
|
+++ b/daemon/gvfsftptask.c
|
||||||
|
@@ -799,7 +799,6 @@ g_vfs_ftp_task_setup_data_connection_pasv (GVfsFtpTask *task, GVfsFtpMethod meth
|
||||||
|
guint status;
|
||||||
|
gboolean success;
|
||||||
|
|
||||||
|
- /* only binary transfers please */
|
||||||
|
status = g_vfs_ftp_task_send_and_check (task, 0, NULL, NULL, &reply, "PASV");
|
||||||
|
if (status == 0)
|
||||||
|
return G_VFS_FTP_METHOD_ANY;
|
||||||
|
@@ -872,6 +871,45 @@ g_vfs_ftp_task_setup_data_connection_pasv (GVfsFtpTask *task, GVfsFtpMethod meth
|
||||||
|
return G_VFS_FTP_METHOD_ANY;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static GVfsFtpMethod
|
||||||
|
+g_vfs_ftp_task_open_data_connection_port (GVfsFtpTask *task, GVfsFtpMethod unused)
|
||||||
|
+{
|
||||||
|
+ GSocketAddress *addr;
|
||||||
|
+ guint status, i, port;
|
||||||
|
+ char *ip_string;
|
||||||
|
+
|
||||||
|
+ /* workaround for the task not having a connection yet */
|
||||||
|
+ if (task->conn == NULL &&
|
||||||
|
+ g_vfs_ftp_task_send (task, 0, "NOOP") == 0)
|
||||||
|
+ return G_VFS_FTP_METHOD_ANY;
|
||||||
|
+
|
||||||
|
+ addr = g_vfs_ftp_connection_listen_data_connection (task->conn, &task->error);
|
||||||
|
+ if (addr == NULL)
|
||||||
|
+ return G_VFS_FTP_METHOD_ANY;
|
||||||
|
+ /* the PORT command only supports IPv4 */
|
||||||
|
+ if (g_socket_address_get_family (addr) != G_SOCKET_FAMILY_IPV4)
|
||||||
|
+ {
|
||||||
|
+ g_object_unref (addr);
|
||||||
|
+ return G_VFS_FTP_METHOD_ANY;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ip_string = g_inet_address_to_string (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (addr)));
|
||||||
|
+ for (i = 0; ip_string[i]; i++)
|
||||||
|
+ {
|
||||||
|
+ if (ip_string[i] == '.')
|
||||||
|
+ ip_string[i] = ',';
|
||||||
|
+ }
|
||||||
|
+ port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr));
|
||||||
|
+
|
||||||
|
+ status = g_vfs_ftp_task_send (task, 0, "PORT %s,%u,%u", ip_string, port >> 8, port & 0xFF);
|
||||||
|
+ g_free (ip_string);
|
||||||
|
+ g_object_unref (addr);
|
||||||
|
+ if (status == 0)
|
||||||
|
+ return G_VFS_FTP_METHOD_ANY;
|
||||||
|
+
|
||||||
|
+ return G_VFS_FTP_METHOD_PORT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
typedef GVfsFtpMethod (* GVfsFtpOpenDataConnectionFunc) (GVfsFtpTask *task, GVfsFtpMethod method);
|
||||||
|
|
||||||
|
static GVfsFtpMethod
|
||||||
|
@@ -882,7 +920,8 @@ g_vfs_ftp_task_setup_data_connection_any (GVfsFtpTask *task, GVfsFtpMethod unuse
|
||||||
|
GVfsFtpOpenDataConnectionFunc func;
|
||||||
|
} funcs_ordered[] = {
|
||||||
|
{ G_VFS_FTP_FEATURE_EPSV, g_vfs_ftp_task_setup_data_connection_epsv },
|
||||||
|
- { 0, g_vfs_ftp_task_setup_data_connection_pasv }
|
||||||
|
+ { 0, g_vfs_ftp_task_setup_data_connection_pasv },
|
||||||
|
+ { 0, g_vfs_ftp_task_open_data_connection_port }
|
||||||
|
};
|
||||||
|
GVfsFtpMethod method;
|
||||||
|
guint i;
|
||||||
|
@@ -936,15 +975,15 @@ g_vfs_ftp_task_setup_data_connection (GVfsFtpTask *task)
|
||||||
|
[G_VFS_FTP_METHOD_PASV] = g_vfs_ftp_task_setup_data_connection_pasv,
|
||||||
|
[G_VFS_FTP_METHOD_PASV_ADDR] = g_vfs_ftp_task_setup_data_connection_pasv,
|
||||||
|
[G_VFS_FTP_METHOD_EPRT] = NULL,
|
||||||
|
- [G_VFS_FTP_METHOD_PORT] = NULL
|
||||||
|
+ [G_VFS_FTP_METHOD_PORT] = g_vfs_ftp_task_open_data_connection_port
|
||||||
|
};
|
||||||
|
GVfsFtpMethod method, result;
|
||||||
|
|
||||||
|
g_return_if_fail (task != NULL);
|
||||||
|
|
||||||
|
- /* FIXME: get the method from elsewhere */
|
||||||
|
+ task->method = G_VFS_FTP_METHOD_ANY;
|
||||||
|
+
|
||||||
|
method = g_atomic_int_get (&task->backend->method);
|
||||||
|
-
|
||||||
|
g_assert (method < G_N_ELEMENTS (connect_funcs) && connect_funcs[method]);
|
||||||
|
|
||||||
|
if (g_vfs_ftp_task_is_in_error (task))
|
||||||
|
@@ -973,6 +1012,7 @@ g_vfs_ftp_task_setup_data_connection (GVfsFtpTask *task)
|
||||||
|
g_debug ("# set default data connection method from %s to %s\n",
|
||||||
|
methods[method], methods[result]);
|
||||||
|
}
|
||||||
|
+ task->method = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -989,5 +1029,11 @@ g_vfs_ftp_task_open_data_connection (GVfsFtpTask *task)
|
||||||
|
|
||||||
|
if (g_vfs_ftp_task_is_in_error (task))
|
||||||
|
return;
|
||||||
|
+
|
||||||
|
+ if (task->method == G_VFS_FTP_METHOD_EPRT ||
|
||||||
|
+ task->method == G_VFS_FTP_METHOD_PORT)
|
||||||
|
+ g_vfs_ftp_connection_accept_data_connection (task->conn,
|
||||||
|
+ task->cancellable,
|
||||||
|
+ &task->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/daemon/gvfsftptask.h b/daemon/gvfsftptask.h
|
||||||
|
index 8345535..ac0bd74 100644
|
||||||
|
--- a/daemon/gvfsftptask.h
|
||||||
|
+++ b/daemon/gvfsftptask.h
|
||||||
|
@@ -47,6 +47,7 @@ struct _GVfsFtpTask
|
||||||
|
|
||||||
|
GError * error; /* NULL or current error - will be propagated to task */
|
||||||
|
GVfsFtpConnection * conn; /* connection in use by this task or NULL if none */
|
||||||
|
+ GVfsFtpMethod method; /* method currently in use (only valid after call to _setup_data_connection() */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (* GVfsFtpErrorFunc) (GVfsFtpTask *task, gpointer data);
|
||||||
|
--
|
||||||
|
1.6.3.2
|
||||||
|
|
27
0004-FTP-add-the-error-code-for-EPRT-s-522-error.patch
Normal file
27
0004-FTP-add-the-error-code-for-EPRT-s-522-error.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From 81fb75b2dc11a969d890f58bc3255ceae3f7bfde Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Otte <otte@gnome.org>
|
||||||
|
Date: Tue, 16 Jun 2009 11:00:30 +0200
|
||||||
|
Subject: [PATCH 04/13] [FTP] add the error code for EPRT's 522 error
|
||||||
|
|
||||||
|
---
|
||||||
|
daemon/gvfsftptask.c | 4 ++++
|
||||||
|
1 files changed, 4 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gvfsftptask.c b/daemon/gvfsftptask.c
|
||||||
|
index 879b912..318dde4 100644
|
||||||
|
--- a/daemon/gvfsftptask.c
|
||||||
|
+++ b/daemon/gvfsftptask.c
|
||||||
|
@@ -382,6 +382,10 @@ g_vfs_ftp_task_set_error_from_response (GVfsFtpTask *task, guint response)
|
||||||
|
code = G_IO_ERROR_NOT_SUPPORTED;
|
||||||
|
msg = _("Operation unsupported");
|
||||||
|
break;
|
||||||
|
+ case 522: /* EPRT: unsupported network protocol */
|
||||||
|
+ code = G_IO_ERROR_NOT_SUPPORTED;
|
||||||
|
+ msg = _("Unsupported network protocol");
|
||||||
|
+ break;
|
||||||
|
case 530: /* Not logged in. */
|
||||||
|
code = G_IO_ERROR_PERMISSION_DENIED;
|
||||||
|
msg = _("Permission denied");
|
||||||
|
--
|
||||||
|
1.6.3.2
|
||||||
|
|
101
0005-FTP-add-EPRT-support.patch
Normal file
101
0005-FTP-add-EPRT-support.patch
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
From 19a6bf345fdb8d445e4c3683e4ca0af0a0031f0b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Otte <otte@gnome.org>
|
||||||
|
Date: Tue, 16 Jun 2009 11:16:27 +0200
|
||||||
|
Subject: [PATCH 05/13] [FTP] add EPRT support
|
||||||
|
|
||||||
|
The code does not support some corner cases that are listed in the RFC
|
||||||
|
(see inline comments), but I suspect those will never be hit. We can add
|
||||||
|
those when they are hit.
|
||||||
|
---
|
||||||
|
daemon/gvfsftptask.c | 60 ++++++++++++++++++++++++++++++++++++++++++++-----
|
||||||
|
1 files changed, 53 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gvfsftptask.c b/daemon/gvfsftptask.c
|
||||||
|
index 318dde4..9cab5a8 100644
|
||||||
|
--- a/daemon/gvfsftptask.c
|
||||||
|
+++ b/daemon/gvfsftptask.c
|
||||||
|
@@ -876,7 +876,52 @@ g_vfs_ftp_task_setup_data_connection_pasv (GVfsFtpTask *task, GVfsFtpMethod meth
|
||||||
|
}
|
||||||
|
|
||||||
|
static GVfsFtpMethod
|
||||||
|
-g_vfs_ftp_task_open_data_connection_port (GVfsFtpTask *task, GVfsFtpMethod unused)
|
||||||
|
+g_vfs_ftp_task_setup_data_connection_eprt (GVfsFtpTask *task, GVfsFtpMethod unused)
|
||||||
|
+{
|
||||||
|
+ GSocketAddress *addr;
|
||||||
|
+ guint status, port, family;
|
||||||
|
+ char *ip_string;
|
||||||
|
+
|
||||||
|
+ /* workaround for the task not having a connection yet */
|
||||||
|
+ if (task->conn == NULL &&
|
||||||
|
+ g_vfs_ftp_task_send (task, 0, "NOOP") == 0)
|
||||||
|
+ return G_VFS_FTP_METHOD_ANY;
|
||||||
|
+
|
||||||
|
+ addr = g_vfs_ftp_connection_listen_data_connection (task->conn, &task->error);
|
||||||
|
+ if (addr == NULL)
|
||||||
|
+ return G_VFS_FTP_METHOD_ANY;
|
||||||
|
+ switch (g_socket_address_get_family (addr))
|
||||||
|
+ {
|
||||||
|
+ case G_SOCKET_FAMILY_IPV4:
|
||||||
|
+ family = 1;
|
||||||
|
+ break;
|
||||||
|
+ case G_SOCKET_FAMILY_IPV6:
|
||||||
|
+ family = 2;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ g_object_unref (addr);
|
||||||
|
+ return G_VFS_FTP_METHOD_ANY;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ip_string = g_inet_address_to_string (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (addr)));
|
||||||
|
+ /* if this ever happens (and it must not for IP4 and IP6 addresses),
|
||||||
|
+ * we need to add support for using a different separator */
|
||||||
|
+ g_assert (strchr (ip_string, '|') == NULL);
|
||||||
|
+ port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr));
|
||||||
|
+
|
||||||
|
+ /* we could handle the 522 response here, (unsupported network family),
|
||||||
|
+ * but I don't think that will buy us anything */
|
||||||
|
+ status = g_vfs_ftp_task_send (task, 0, "EPRT |%u|%s|%u|", family, ip_string, port);
|
||||||
|
+ g_free (ip_string);
|
||||||
|
+ g_object_unref (addr);
|
||||||
|
+ if (status == 0)
|
||||||
|
+ return G_VFS_FTP_METHOD_ANY;
|
||||||
|
+
|
||||||
|
+ return G_VFS_FTP_METHOD_EPRT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static GVfsFtpMethod
|
||||||
|
+g_vfs_ftp_task_setup_data_connection_port (GVfsFtpTask *task, GVfsFtpMethod unused)
|
||||||
|
{
|
||||||
|
GSocketAddress *addr;
|
||||||
|
guint status, i, port;
|
||||||
|
@@ -925,7 +970,8 @@ g_vfs_ftp_task_setup_data_connection_any (GVfsFtpTask *task, GVfsFtpMethod unuse
|
||||||
|
} funcs_ordered[] = {
|
||||||
|
{ G_VFS_FTP_FEATURE_EPSV, g_vfs_ftp_task_setup_data_connection_epsv },
|
||||||
|
{ 0, g_vfs_ftp_task_setup_data_connection_pasv },
|
||||||
|
- { 0, g_vfs_ftp_task_open_data_connection_port }
|
||||||
|
+ { G_VFS_FTP_FEATURE_EPSV, g_vfs_ftp_task_setup_data_connection_eprt },
|
||||||
|
+ { 0, g_vfs_ftp_task_setup_data_connection_port }
|
||||||
|
};
|
||||||
|
GVfsFtpMethod method;
|
||||||
|
guint i;
|
||||||
|
@@ -974,12 +1020,12 @@ void
|
||||||
|
g_vfs_ftp_task_setup_data_connection (GVfsFtpTask *task)
|
||||||
|
{
|
||||||
|
static const GVfsFtpOpenDataConnectionFunc connect_funcs[] = {
|
||||||
|
- [G_VFS_FTP_METHOD_ANY] = g_vfs_ftp_task_setup_data_connection_any,
|
||||||
|
- [G_VFS_FTP_METHOD_EPSV] = g_vfs_ftp_task_setup_data_connection_epsv,
|
||||||
|
- [G_VFS_FTP_METHOD_PASV] = g_vfs_ftp_task_setup_data_connection_pasv,
|
||||||
|
+ [G_VFS_FTP_METHOD_ANY] = g_vfs_ftp_task_setup_data_connection_any,
|
||||||
|
+ [G_VFS_FTP_METHOD_EPSV] = g_vfs_ftp_task_setup_data_connection_epsv,
|
||||||
|
+ [G_VFS_FTP_METHOD_PASV] = g_vfs_ftp_task_setup_data_connection_pasv,
|
||||||
|
[G_VFS_FTP_METHOD_PASV_ADDR] = g_vfs_ftp_task_setup_data_connection_pasv,
|
||||||
|
- [G_VFS_FTP_METHOD_EPRT] = NULL,
|
||||||
|
- [G_VFS_FTP_METHOD_PORT] = g_vfs_ftp_task_open_data_connection_port
|
||||||
|
+ [G_VFS_FTP_METHOD_EPRT] = g_vfs_ftp_task_setup_data_connection_eprt,
|
||||||
|
+ [G_VFS_FTP_METHOD_PORT] = g_vfs_ftp_task_setup_data_connection_port
|
||||||
|
};
|
||||||
|
GVfsFtpMethod method, result;
|
||||||
|
|
||||||
|
--
|
||||||
|
1.6.3.2
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
From 5d3ab40b5b0a574f207e7177d2f4c3bd329458a4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Zeuthen <davidz@redhat.com>
|
||||||
|
Date: Tue, 16 Jun 2009 17:41:45 -0400
|
||||||
|
Subject: [PATCH 06/13] =?utf-8?q?Bug=20582772=20=E2=80=93=20gvfsd-computer=20crashes=20with=20SEGSEV=20in=20recompute=5Ffiles?=
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=utf-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Never use blank/empty drive names.
|
||||||
|
---
|
||||||
|
monitor/gdu/ggdudrive.c | 9 +++++++++
|
||||||
|
1 files changed, 9 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/monitor/gdu/ggdudrive.c b/monitor/gdu/ggdudrive.c
|
||||||
|
index 8e04104..6195f97 100644
|
||||||
|
--- a/monitor/gdu/ggdudrive.c
|
||||||
|
+++ b/monitor/gdu/ggdudrive.c
|
||||||
|
@@ -177,6 +177,15 @@ update_drive (GGduDrive *drive)
|
||||||
|
if (device != NULL)
|
||||||
|
g_object_unref (device);
|
||||||
|
|
||||||
|
+ /* Never use empty/blank names (#582772) */
|
||||||
|
+ if (drive->name == NULL || strlen (drive->name) == 0)
|
||||||
|
+ {
|
||||||
|
+ if (drive->device_file != NULL)
|
||||||
|
+ drive->name = g_strdup_printf (_("Unnamed Drive (%s)"), drive->device_file);
|
||||||
|
+ else
|
||||||
|
+ drive->name = g_strdup (_("Unnamed Drive"));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* compute whether something changed */
|
||||||
|
changed = !((old_is_media_removable == drive->is_media_removable) &&
|
||||||
|
(old_has_media == drive->has_media) &&
|
||||||
|
--
|
||||||
|
1.6.3.2
|
||||||
|
|
117
0007-Better-handling-of-PC-floppy-drives.patch
Normal file
117
0007-Better-handling-of-PC-floppy-drives.patch
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
From c6405c6653c27b247f1fbb59c01b95938fb6b2d8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Zeuthen <davidz@redhat.com>
|
||||||
|
Date: Tue, 16 Jun 2009 19:49:38 -0400
|
||||||
|
Subject: [PATCH 07/13] Better handling of PC floppy drives
|
||||||
|
|
||||||
|
PC Floppy Drives are handled in a special way since we don't poll for
|
||||||
|
media (it would make a lot of noise). Specifically we never probe for
|
||||||
|
the filesystem type. So if encountering a PC Floppy Drive, just always
|
||||||
|
show all volumes from it. Since we already have working support for
|
||||||
|
g_drive_poll_for_media() in Nautilus, things Just Work(tm)
|
||||||
|
|
||||||
|
http://people.freedesktop.org/~david/dkd-gnome-floppy-welcome-to-the-1980s.png
|
||||||
|
|
||||||
|
E.g. you can use the "Rescan" menu option to force media detection.
|
||||||
|
|
||||||
|
Welcome to the 1980s.
|
||||||
|
---
|
||||||
|
monitor/gdu/ggdudrive.c | 5 ++++-
|
||||||
|
monitor/gdu/ggduvolume.c | 5 ++++-
|
||||||
|
monitor/gdu/ggduvolumemonitor.c | 28 +++++++++++++++++++++++++++-
|
||||||
|
monitor/gdu/ggduvolumemonitor.h | 2 ++
|
||||||
|
4 files changed, 37 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/monitor/gdu/ggdudrive.c b/monitor/gdu/ggdudrive.c
|
||||||
|
index 6195f97..d332e14 100644
|
||||||
|
--- a/monitor/gdu/ggdudrive.c
|
||||||
|
+++ b/monitor/gdu/ggdudrive.c
|
||||||
|
@@ -148,7 +148,10 @@ update_drive (GGduDrive *drive)
|
||||||
|
drive->icon = gdu_presentable_get_icon (drive->presentable);
|
||||||
|
|
||||||
|
g_free (drive->name);
|
||||||
|
- drive->name = gdu_presentable_get_name (drive->presentable);
|
||||||
|
+ if (_is_pc_floppy_drive (device))
|
||||||
|
+ drive->name = g_strdup (_("Floppy Drive"));
|
||||||
|
+ else
|
||||||
|
+ drive->name = gdu_presentable_get_name (drive->presentable);
|
||||||
|
|
||||||
|
/* the GduDevice for an activatable drive (such as RAID) is NULL if the drive is not activated */
|
||||||
|
if (device == NULL)
|
||||||
|
diff --git a/monitor/gdu/ggduvolume.c b/monitor/gdu/ggduvolume.c
|
||||||
|
index 8f75247..73ad0fc 100644
|
||||||
|
--- a/monitor/gdu/ggduvolume.c
|
||||||
|
+++ b/monitor/gdu/ggduvolume.c
|
||||||
|
@@ -304,7 +304,10 @@ update_volume (GGduVolume *volume)
|
||||||
|
volume->icon = gdu_presentable_get_icon (GDU_PRESENTABLE (volume->gdu_volume));
|
||||||
|
|
||||||
|
g_free (volume->name);
|
||||||
|
- volume->name = gdu_presentable_get_name (GDU_PRESENTABLE (volume->gdu_volume));
|
||||||
|
+ if (_is_pc_floppy_drive (device))
|
||||||
|
+ volume->name = g_strdup (_("Floppy Disk"));
|
||||||
|
+ else
|
||||||
|
+ volume->name = gdu_presentable_get_name (GDU_PRESENTABLE (volume->gdu_volume));
|
||||||
|
|
||||||
|
/* special case the name and icon for audio discs */
|
||||||
|
activation_uri = volume->activation_root != NULL ? g_file_get_uri (volume->activation_root) : NULL;
|
||||||
|
diff --git a/monitor/gdu/ggduvolumemonitor.c b/monitor/gdu/ggduvolumemonitor.c
|
||||||
|
index 5c80f64..6da7393 100644
|
||||||
|
--- a/monitor/gdu/ggduvolumemonitor.c
|
||||||
|
+++ b/monitor/gdu/ggduvolumemonitor.c
|
||||||
|
@@ -744,6 +744,32 @@ should_mount_be_ignored (GduPool *pool, GduDevice *d)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+gboolean
|
||||||
|
+_is_pc_floppy_drive (GduDevice *device)
|
||||||
|
+{
|
||||||
|
+ gboolean ret;
|
||||||
|
+ gchar **drive_media_compat;
|
||||||
|
+ const gchar *drive_connection_interface;
|
||||||
|
+
|
||||||
|
+ ret = FALSE;
|
||||||
|
+
|
||||||
|
+ if (device != NULL)
|
||||||
|
+ {
|
||||||
|
+ drive_media_compat = gdu_device_drive_get_media_compatibility (device);
|
||||||
|
+ drive_connection_interface = gdu_device_drive_get_connection_interface (device);
|
||||||
|
+
|
||||||
|
+ if (g_strcmp0 (drive_connection_interface, "platform") == 0 &&
|
||||||
|
+ (drive_media_compat != NULL &&
|
||||||
|
+ g_strv_length (drive_media_compat) > 0 &&
|
||||||
|
+ g_strcmp0 (drive_media_compat[0], "floppy") == 0))
|
||||||
|
+ {
|
||||||
|
+ ret = TRUE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static gboolean
|
||||||
|
should_volume_be_ignored (GduPool *pool, GduVolume *volume, GList *fstab_mount_points)
|
||||||
|
{
|
||||||
|
@@ -763,7 +789,7 @@ should_volume_be_ignored (GduPool *pool, GduVolume *volume, GList *fstab_mount_p
|
||||||
|
usage = gdu_device_id_get_usage (device);
|
||||||
|
type = gdu_device_id_get_type (device);
|
||||||
|
|
||||||
|
- if (g_strcmp0 (usage, "filesystem") == 0)
|
||||||
|
+ if (_is_pc_floppy_drive (device) || g_strcmp0 (usage, "filesystem") == 0)
|
||||||
|
{
|
||||||
|
GUnixMountPoint *mount_point;
|
||||||
|
|
||||||
|
diff --git a/monitor/gdu/ggduvolumemonitor.h b/monitor/gdu/ggduvolumemonitor.h
|
||||||
|
index ec559c4..b91ceb9 100644
|
||||||
|
--- a/monitor/gdu/ggduvolumemonitor.h
|
||||||
|
+++ b/monitor/gdu/ggduvolumemonitor.h
|
||||||
|
@@ -55,6 +55,8 @@ GType g_gdu_volume_monitor_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
GVolumeMonitor *g_gdu_volume_monitor_new (void);
|
||||||
|
|
||||||
|
+gboolean _is_pc_floppy_drive (GduDevice *device);
|
||||||
|
+
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __G_GDU_VOLUME_MONITOR_H__ */
|
||||||
|
--
|
||||||
|
1.6.3.2
|
||||||
|
|
@ -0,0 +1,51 @@
|
|||||||
|
From acb3f8029d9f9a7054e3f138fd978e24233573a3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Otte <otte@gnome.org>
|
||||||
|
Date: Wed, 17 Jun 2009 10:04:42 +0200
|
||||||
|
Subject: [PATCH 08/13] [FTP] use the EPRT feature response for EPRT support, not EPSV
|
||||||
|
|
||||||
|
---
|
||||||
|
daemon/gvfsbackendftp.c | 1 +
|
||||||
|
daemon/gvfsbackendftp.h | 1 +
|
||||||
|
daemon/gvfsftptask.c | 2 +-
|
||||||
|
3 files changed, 3 insertions(+), 1 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gvfsbackendftp.c b/daemon/gvfsbackendftp.c
|
||||||
|
index 913eb1c..aef5687 100644
|
||||||
|
--- a/daemon/gvfsbackendftp.c
|
||||||
|
+++ b/daemon/gvfsbackendftp.c
|
||||||
|
@@ -99,6 +99,7 @@ gvfs_backend_ftp_determine_features (GVfsFtpTask *task)
|
||||||
|
{ "MDTM", G_VFS_FTP_FEATURE_MDTM },
|
||||||
|
{ "SIZE", G_VFS_FTP_FEATURE_SIZE },
|
||||||
|
{ "TVFS", G_VFS_FTP_FEATURE_TVFS },
|
||||||
|
+ { "EPRT", G_VFS_FTP_FEATURE_EPRT },
|
||||||
|
{ "EPSV", G_VFS_FTP_FEATURE_EPSV },
|
||||||
|
{ "UTF8", G_VFS_FTP_FEATURE_UTF8 },
|
||||||
|
};
|
||||||
|
diff --git a/daemon/gvfsbackendftp.h b/daemon/gvfsbackendftp.h
|
||||||
|
index 89b2769..0a7bcf5 100644
|
||||||
|
--- a/daemon/gvfsbackendftp.h
|
||||||
|
+++ b/daemon/gvfsbackendftp.h
|
||||||
|
@@ -34,6 +34,7 @@ typedef enum {
|
||||||
|
G_VFS_FTP_FEATURE_MDTM,
|
||||||
|
G_VFS_FTP_FEATURE_SIZE,
|
||||||
|
G_VFS_FTP_FEATURE_TVFS,
|
||||||
|
+ G_VFS_FTP_FEATURE_EPRT,
|
||||||
|
G_VFS_FTP_FEATURE_EPSV,
|
||||||
|
G_VFS_FTP_FEATURE_UTF8
|
||||||
|
} GVfsFtpFeature;
|
||||||
|
diff --git a/daemon/gvfsftptask.c b/daemon/gvfsftptask.c
|
||||||
|
index 9cab5a8..4c46c0c 100644
|
||||||
|
--- a/daemon/gvfsftptask.c
|
||||||
|
+++ b/daemon/gvfsftptask.c
|
||||||
|
@@ -970,7 +970,7 @@ g_vfs_ftp_task_setup_data_connection_any (GVfsFtpTask *task, GVfsFtpMethod unuse
|
||||||
|
} funcs_ordered[] = {
|
||||||
|
{ G_VFS_FTP_FEATURE_EPSV, g_vfs_ftp_task_setup_data_connection_epsv },
|
||||||
|
{ 0, g_vfs_ftp_task_setup_data_connection_pasv },
|
||||||
|
- { G_VFS_FTP_FEATURE_EPSV, g_vfs_ftp_task_setup_data_connection_eprt },
|
||||||
|
+ { G_VFS_FTP_FEATURE_EPRT, g_vfs_ftp_task_setup_data_connection_eprt },
|
||||||
|
{ 0, g_vfs_ftp_task_setup_data_connection_port }
|
||||||
|
};
|
||||||
|
GVfsFtpMethod method;
|
||||||
|
--
|
||||||
|
1.6.3.2
|
||||||
|
|
27
0009-FTP-remove-EPSV-as-default-feature.patch
Normal file
27
0009-FTP-remove-EPSV-as-default-feature.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From 056cfe684e3db4f83c176bb723c264ecfe60837f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Otte <otte@gnome.org>
|
||||||
|
Date: Wed, 17 Jun 2009 10:05:29 +0200
|
||||||
|
Subject: [PATCH 09/13] [FTP] remove EPSV as default feature
|
||||||
|
|
||||||
|
now that we try EPSV anyway, we can omit assuming it exists and try PASV
|
||||||
|
first.
|
||||||
|
---
|
||||||
|
daemon/gvfsbackendftp.h | 2 +-
|
||||||
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gvfsbackendftp.h b/daemon/gvfsbackendftp.h
|
||||||
|
index 0a7bcf5..5923d17 100644
|
||||||
|
--- a/daemon/gvfsbackendftp.h
|
||||||
|
+++ b/daemon/gvfsbackendftp.h
|
||||||
|
@@ -38,7 +38,7 @@ typedef enum {
|
||||||
|
G_VFS_FTP_FEATURE_EPSV,
|
||||||
|
G_VFS_FTP_FEATURE_UTF8
|
||||||
|
} GVfsFtpFeature;
|
||||||
|
-#define G_VFS_FTP_FEATURES_DEFAULT (1 << G_VFS_FTP_FEATURE_EPSV)
|
||||||
|
+#define G_VFS_FTP_FEATURES_DEFAULT (0)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
G_VFS_FTP_SYSTEM_UNKNOWN = 0,
|
||||||
|
--
|
||||||
|
1.6.3.2
|
||||||
|
|
@ -1,59 +0,0 @@
|
|||||||
From 3f3f21fe6e2bdac8fd6acf048da6fb228adde092 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Zeuthen <davidz@redhat.com>
|
|
||||||
Date: Fri, 01 May 2009 19:59:54 +0000
|
|
||||||
Subject: Use new gnome-disk-utility API to figure out when media was inserted
|
|
||||||
|
|
||||||
This fixes a problem with Nautilus automounting newly created volumes
|
|
||||||
appearing as a result of formatting/partitioning.
|
|
||||||
---
|
|
||||||
diff --git a/monitor/gdu/ggdudrive.c b/monitor/gdu/ggdudrive.c
|
|
||||||
index 29e108d..c2c8b76 100644
|
|
||||||
--- a/monitor/gdu/ggdudrive.c
|
|
||||||
+++ b/monitor/gdu/ggdudrive.c
|
|
||||||
@@ -51,7 +51,6 @@ struct _GGduDrive {
|
|
||||||
gboolean can_eject;
|
|
||||||
gboolean can_poll_for_media;
|
|
||||||
gboolean is_media_check_automatic;
|
|
||||||
- time_t time_of_last_media_insertion;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void g_gdu_drive_drive_iface_init (GDriveIface *iface);
|
|
||||||
@@ -178,9 +177,6 @@ update_drive (GGduDrive *drive)
|
|
||||||
if (device != NULL)
|
|
||||||
g_object_unref (device);
|
|
||||||
|
|
||||||
- if (drive->has_media != old_has_media)
|
|
||||||
- drive->time_of_last_media_insertion = time (NULL);
|
|
||||||
-
|
|
||||||
/* compute whether something changed */
|
|
||||||
changed = !((old_is_media_removable == drive->is_media_removable) &&
|
|
||||||
(old_has_media == drive->has_media) &&
|
|
||||||
@@ -233,8 +229,6 @@ g_gdu_drive_new (GVolumeMonitor *volume_monitor,
|
|
||||||
|
|
||||||
drive->presentable = g_object_ref (presentable);
|
|
||||||
|
|
||||||
- drive->time_of_last_media_insertion = time (NULL);
|
|
||||||
-
|
|
||||||
g_signal_connect (drive->presentable, "changed", G_CALLBACK (presentable_changed), drive);
|
|
||||||
g_signal_connect (drive->presentable, "job-changed", G_CALLBACK (presentable_job_changed), drive);
|
|
||||||
|
|
||||||
@@ -685,7 +679,16 @@ g_gdu_drive_has_presentable (GGduDrive *drive,
|
|
||||||
time_t
|
|
||||||
g_gdu_drive_get_time_of_last_media_insertion (GGduDrive *drive)
|
|
||||||
{
|
|
||||||
- return drive->time_of_last_media_insertion;
|
|
||||||
+ GduDevice *device;
|
|
||||||
+ time_t ret;
|
|
||||||
+
|
|
||||||
+ ret = 0;
|
|
||||||
+ device = gdu_presentable_get_device (drive->presentable);
|
|
||||||
+ if (device != NULL) {
|
|
||||||
+ ret = gdu_device_get_media_detection_time (device);
|
|
||||||
+ g_object_unref (device);
|
|
||||||
+ }
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
GduPresentable *
|
|
||||||
--
|
|
||||||
cgit v0.8.2
|
|
@ -1,29 +0,0 @@
|
|||||||
From 59dd3b33a71a930651f23142e2a7d7e57727144f Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Zeuthen <davidz@redhat.com>
|
|
||||||
Date: Fri, 01 May 2009 21:23:01 +0000
|
|
||||||
Subject: Fix bug where drives are not ignored as they ought to be
|
|
||||||
|
|
||||||
This should fix part of
|
|
||||||
|
|
||||||
https://bugzilla.redhat.com/show_bug.cgi?id=498649#c14
|
|
||||||
|
|
||||||
(the other part is fixed in the Fedora livecd scripts)
|
|
||||||
---
|
|
||||||
diff --git a/monitor/gdu/ggduvolumemonitor.c b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
index 2c1f727..df42249 100644
|
|
||||||
--- a/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
+++ b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
@@ -833,8 +833,10 @@ should_drive_be_ignored (GduPool *pool, GduDrive *d, GList *fstab_mount_points)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (gdu_device_get_presentation_hide (device))
|
|
||||||
+ if (gdu_device_get_presentation_hide (device)) {
|
|
||||||
+ ignored = TRUE;
|
|
||||||
goto out;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
has_volumes = FALSE;
|
|
||||||
all_volumes_are_ignored = TRUE;
|
|
||||||
--
|
|
||||||
cgit v0.8.2
|
|
File diff suppressed because it is too large
Load Diff
@ -1,69 +0,0 @@
|
|||||||
From 94707c12442ed9ce099f110ec7089309133727ae Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tomas Bzatek <tbzatek@redhat.com>
|
|
||||||
Date: Thu, 9 Apr 2009 19:03:16 -0400
|
|
||||||
Subject: [PATCH 2/7] Fix how we determine if a volume is ignored
|
|
||||||
|
|
||||||
This fixes a typo - wrong assignment of device file when testing whether the
|
|
||||||
volume should be ignored or not. It led to empty GVolume list associated to a
|
|
||||||
GDrive and thus inability to mount anything via computer://
|
|
||||||
|
|
||||||
Signed-off-by: David Zeuthen <davidz@redhat.com>
|
|
||||||
---
|
|
||||||
monitor/gdu/ggduvolumemonitor.c | 18 +++++++++---------
|
|
||||||
1 files changed, 9 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/monitor/gdu/ggduvolumemonitor.c b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
index 32604d0..b52ee11 100644
|
|
||||||
--- a/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
+++ b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
@@ -617,7 +617,7 @@ get_mount_point_for_device (GduDevice *d, GList *fstab_mount_points)
|
|
||||||
for (l = fstab_mount_points; l != NULL; l = l->next)
|
|
||||||
{
|
|
||||||
GUnixMountPoint *mount_point = l->data;
|
|
||||||
- const gchar *device_file;
|
|
||||||
+ const gchar *fstab_device_file;
|
|
||||||
const gchar *fstab_mount_path;
|
|
||||||
|
|
||||||
fstab_mount_path = g_unix_mount_point_get_mount_path (mount_point);
|
|
||||||
@@ -627,18 +627,18 @@ get_mount_point_for_device (GduDevice *d, GList *fstab_mount_points)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
- device_file = g_unix_mount_point_get_device_path (mount_point);
|
|
||||||
- if (g_str_has_prefix (device_file, "LABEL="))
|
|
||||||
+ fstab_device_file = g_unix_mount_point_get_device_path (mount_point);
|
|
||||||
+ if (g_str_has_prefix (fstab_device_file, "LABEL="))
|
|
||||||
{
|
|
||||||
- if (g_strcmp0 (device_file + 6, gdu_device_id_get_label (d)) == 0)
|
|
||||||
+ if (g_strcmp0 (fstab_device_file + 6, gdu_device_id_get_label (d)) == 0)
|
|
||||||
{
|
|
||||||
ret = mount_point;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- else if (g_str_has_prefix (device_file, "UUID="))
|
|
||||||
+ else if (g_str_has_prefix (fstab_device_file, "UUID="))
|
|
||||||
{
|
|
||||||
- if (g_ascii_strcasecmp (device_file + 5, gdu_device_id_get_uuid (d)) == 0)
|
|
||||||
+ if (g_ascii_strcasecmp (fstab_device_file + 5, gdu_device_id_get_uuid (d)) == 0)
|
|
||||||
{
|
|
||||||
ret = mount_point;
|
|
||||||
goto out;
|
|
||||||
@@ -646,11 +646,11 @@ get_mount_point_for_device (GduDevice *d, GList *fstab_mount_points)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
- char resolved_device_file[PATH_MAX];
|
|
||||||
+ char resolved_fstab_device_file[PATH_MAX];
|
|
||||||
|
|
||||||
/* handle symlinks such as /dev/disk/by-uuid/47C2-1994 */
|
|
||||||
- if (realpath (device_file, resolved_device_file) != NULL &&
|
|
||||||
- g_strcmp0 (resolved_device_file, device_file) == 0)
|
|
||||||
+ if (realpath (fstab_device_file, resolved_fstab_device_file) != NULL &&
|
|
||||||
+ g_strcmp0 (resolved_fstab_device_file, device_file) == 0)
|
|
||||||
{
|
|
||||||
ret = mount_point;
|
|
||||||
goto out;
|
|
||||||
--
|
|
||||||
1.6.2.2
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
|||||||
From 47a663c7ad7b9de9942b9b740abff6610968a402 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Zeuthen <davidz@redhat.com>
|
|
||||||
Date: Thu, 9 Apr 2009 19:05:37 -0400
|
|
||||||
Subject: [PATCH 3/7] Avoid automounting volumes on virtual and unknown buses
|
|
||||||
|
|
||||||
Basically we want to avoid automounting volumes from
|
|
||||||
|
|
||||||
1. drives on a 'virtual' or unset bus
|
|
||||||
2. volumes without a drive
|
|
||||||
|
|
||||||
This is to avoid interference with things like Fedora's livecd-tools
|
|
||||||
that use device-mapper to set up images. See
|
|
||||||
|
|
||||||
https://bugzilla.redhat.com/show_bug.cgi?id=494144 for more
|
|
||||||
|
|
||||||
background.
|
|
||||||
|
|
||||||
In the future we might want to relax 1. so automounting things like
|
|
||||||
Linux MD and LVM2 devices work.
|
|
||||||
---
|
|
||||||
monitor/gdu/ggduvolume.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
1 files changed, 50 insertions(+), 0 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/monitor/gdu/ggduvolume.c b/monitor/gdu/ggduvolume.c
|
|
||||||
index b540325..a5a3321 100644
|
|
||||||
--- a/monitor/gdu/ggduvolume.c
|
|
||||||
+++ b/monitor/gdu/ggduvolume.c
|
|
||||||
@@ -293,6 +293,56 @@ update_volume (GGduVolume *volume)
|
|
||||||
volume->should_automount = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* Avoid automounting volumes from
|
|
||||||
+ *
|
|
||||||
+ * 1. drives on a 'virtual' or unset bus
|
|
||||||
+ * 2. volumes without a drive
|
|
||||||
+ *
|
|
||||||
+ * This is to avoid interference with things like Fedora's
|
|
||||||
+ * livecd-tools that use device-mapper to set up images. See
|
|
||||||
+ * https://bugzilla.redhat.com/show_bug.cgi?id=494144 for more
|
|
||||||
+ * background.
|
|
||||||
+ *
|
|
||||||
+ * In the future we might want to relax 1. so automounting
|
|
||||||
+ * things like Linux MD and LVM2 devices work.
|
|
||||||
+ */
|
|
||||||
+ if (volume->drive != NULL)
|
|
||||||
+ {
|
|
||||||
+ GduPresentable *drive_presentable;
|
|
||||||
+ drive_presentable = g_gdu_drive_get_presentable (volume->drive);
|
|
||||||
+ if (drive_presentable != NULL)
|
|
||||||
+ {
|
|
||||||
+ GduDevice *drive_device;
|
|
||||||
+ drive_device = gdu_presentable_get_device (drive_presentable);
|
|
||||||
+ if (drive_device != NULL)
|
|
||||||
+ {
|
|
||||||
+ const gchar *bus;
|
|
||||||
+ bus = gdu_device_drive_get_connection_interface (drive_device);
|
|
||||||
+ if (bus == NULL || strlen (bus) == 0 || g_strcmp0 (bus, "virtual") == 0)
|
|
||||||
+ {
|
|
||||||
+ volume->should_automount = FALSE;
|
|
||||||
+ }
|
|
||||||
+ g_object_unref (drive_device);
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ volume->should_automount = FALSE;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ volume->should_automount = FALSE;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ volume->should_automount = FALSE;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ g_debug ("should_automount = %d for %s",
|
|
||||||
+ volume->should_automount,
|
|
||||||
+ device != NULL ? gdu_device_get_device_file (device) : "(none)");
|
|
||||||
+
|
|
||||||
g_free (activation_uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
1.6.2.2
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
From 82202f50bb76248f5a6368fe08de947758674acd Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Zeuthen <davidz@redhat.com>
|
|
||||||
Date: Thu, 9 Apr 2009 19:14:25 -0400
|
|
||||||
Subject: [PATCH 4/7] Remove debug spew
|
|
||||||
|
|
||||||
---
|
|
||||||
monitor/gdu/ggduvolume.c | 4 ----
|
|
||||||
1 files changed, 0 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/monitor/gdu/ggduvolume.c b/monitor/gdu/ggduvolume.c
|
|
||||||
index a5a3321..6779f0f 100644
|
|
||||||
--- a/monitor/gdu/ggduvolume.c
|
|
||||||
+++ b/monitor/gdu/ggduvolume.c
|
|
||||||
@@ -339,10 +339,6 @@ update_volume (GGduVolume *volume)
|
|
||||||
volume->should_automount = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
- g_debug ("should_automount = %d for %s",
|
|
||||||
- volume->should_automount,
|
|
||||||
- device != NULL ? gdu_device_get_device_file (device) : "(none)");
|
|
||||||
-
|
|
||||||
g_free (activation_uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
1.6.2.2
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
|||||||
From d9a00cc6172e2bf82f6825023c7a619be7f56747 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Zeuthen <davidz@redhat.com>
|
|
||||||
Date: Thu, 9 Apr 2009 19:33:35 -0400
|
|
||||||
Subject: [PATCH 5/7] Don't add a volume if the device is mounted and ignored
|
|
||||||
|
|
||||||
This fixes a problem where e.g. /dev/sdb1 a) is not referenced in
|
|
||||||
/etc/fstab; and b) is mounted in an ignored location e.g. /mnt/live.
|
|
||||||
|
|
||||||
Specifically this bug affects the Fedora Live CD, see
|
|
||||||
https://bugzilla.redhat.com/show_bug.cgi?id=495033 for details.
|
|
||||||
---
|
|
||||||
monitor/gdu/ggduvolumemonitor.c | 3 ---
|
|
||||||
1 files changed, 0 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/monitor/gdu/ggduvolumemonitor.c b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
index b52ee11..93aaf03 100644
|
|
||||||
--- a/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
+++ b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
@@ -671,9 +671,6 @@ should_mount_be_ignored (GduPool *pool, GduDevice *d)
|
|
||||||
|
|
||||||
ret = FALSE;
|
|
||||||
|
|
||||||
- if (gdu_device_is_mounted (d))
|
|
||||||
- goto out;
|
|
||||||
-
|
|
||||||
mount_path = gdu_device_get_mount_path (d);
|
|
||||||
if (mount_path == NULL || strlen (mount_path) == 0)
|
|
||||||
goto out;
|
|
||||||
--
|
|
||||||
1.6.2.2
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
|||||||
From 346fdc3ddf383228ed58a48252e70919f6636b6e Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Zeuthen <davidz@redhat.com>
|
|
||||||
Date: Thu, 9 Apr 2009 19:39:55 -0400
|
|
||||||
Subject: [PATCH 6/7] Ignore drives if all volumes of the drive are ignored
|
|
||||||
|
|
||||||
---
|
|
||||||
monitor/gdu/ggduvolumemonitor.c | 16 +++++++++-------
|
|
||||||
1 files changed, 9 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/monitor/gdu/ggduvolumemonitor.c b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
index 93aaf03..9ecee8b 100644
|
|
||||||
--- a/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
+++ b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
@@ -763,15 +763,17 @@ should_drive_be_ignored (GduPool *pool, GduDrive *d, GList *fstab_mount_points)
|
|
||||||
|
|
||||||
device = gdu_presentable_get_device (GDU_PRESENTABLE (d));
|
|
||||||
|
|
||||||
- /* the GduDevice for an activatable drive (such as RAID) is NULL if the drive is not
|
|
||||||
- * activated; never ignore these
|
|
||||||
+ /* If there is no GduDevice for a drive, then ignore it.
|
|
||||||
+ *
|
|
||||||
+ * Note that right now the only drives without a GduDevice are Linux
|
|
||||||
+ * MD arrays not yet activated. In the future we might want to
|
|
||||||
+ * display these so the user can start the array.
|
|
||||||
*/
|
|
||||||
if (device == NULL)
|
|
||||||
- goto out;
|
|
||||||
-
|
|
||||||
- /* never ignore drives with removable media */
|
|
||||||
- if (gdu_device_is_removable (device))
|
|
||||||
- goto out;
|
|
||||||
+ {
|
|
||||||
+ ret = TRUE;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
has_volumes = FALSE;
|
|
||||||
all_volumes_are_ignored = TRUE;
|
|
||||||
--
|
|
||||||
1.6.2.2
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
|||||||
From 303cfd43578f0a4198c063f1a5fbcd16fec2b0bf Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Zeuthen <davidz@redhat.com>
|
|
||||||
Date: Thu, 9 Apr 2009 21:04:24 -0400
|
|
||||||
Subject: [PATCH 7/7] =?utf-8?q?Bug=20576587=20=E2=80=93=20allow=20eject=20even=20on=20non-ejectable=20volumes?=
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=utf-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
This fixes a host of problems with e.g. Kindle or iPod devices
|
|
||||||
requiring to be "ejected" to display messages such as
|
|
||||||
|
|
||||||
"If you want to use your Kindle and continue charging, please eject
|
|
||||||
your Kindle from your computer."
|
|
||||||
|
|
||||||
to the user.
|
|
||||||
|
|
||||||
Previously we relied on HAL fdi files or similar to tag that such
|
|
||||||
devices needed to be ejectable. Now we just set everything as
|
|
||||||
ejectable.
|
|
||||||
|
|
||||||
For this to really work well the Nautilus patch in
|
|
||||||
|
|
||||||
http://bugzilla.gnome.org/show_bug.cgi?id=574067
|
|
||||||
|
|
||||||
needs to be reverted.
|
|
||||||
---
|
|
||||||
monitor/gdu/ggdudrive.c | 6 +++++-
|
|
||||||
1 files changed, 5 insertions(+), 1 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/monitor/gdu/ggdudrive.c b/monitor/gdu/ggdudrive.c
|
|
||||||
index 257a113..29e108d 100644
|
|
||||||
--- a/monitor/gdu/ggdudrive.c
|
|
||||||
+++ b/monitor/gdu/ggdudrive.c
|
|
||||||
@@ -166,7 +166,11 @@ update_drive (GGduDrive *drive)
|
|
||||||
drive->device_file = g_strdup (gdu_device_get_device_file (device));
|
|
||||||
drive->is_media_removable = gdu_device_is_removable (device);
|
|
||||||
drive->has_media = gdu_device_is_media_available (device);
|
|
||||||
- drive->can_eject = gdu_device_drive_get_is_media_ejectable (device) || gdu_device_drive_get_requires_eject (device);
|
|
||||||
+ /* All drives with removable media are ejectable
|
|
||||||
+ *
|
|
||||||
+ * See http://bugzilla.gnome.org/show_bug.cgi?id=576587 for why we want this.
|
|
||||||
+ */
|
|
||||||
+ drive->can_eject = gdu_device_drive_get_is_media_ejectable (device) || gdu_device_drive_get_requires_eject (device) || gdu_device_is_removable (device);
|
|
||||||
drive->is_media_check_automatic = gdu_device_is_media_change_detected (device);
|
|
||||||
drive->can_poll_for_media = TRUE;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
1.6.2.2
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
|||||||
From 9a265228542de72df41caef8bd31402841ac389c Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Zeuthen <davidz@redhat.com>
|
|
||||||
Date: Sat, 11 Apr 2009 12:43:06 -0400
|
|
||||||
Subject: [PATCH] ignore drives without volumes
|
|
||||||
|
|
||||||
This fixes a problem on some dmraid setups where we have drives
|
|
||||||
without any partitions (the dmraid boot scripts removes all partitions
|
|
||||||
(!)). See https://bugzilla.redhat.com/show_bug.cgi?id=495152 for more
|
|
||||||
details.
|
|
||||||
|
|
||||||
This fix is also consistent with the policy of ignoring drives where
|
|
||||||
all volumes are ignored. E.g. prior to this patch we didn't shown
|
|
||||||
neither sdb if sdb1 was a the only unrecognized partition on sdb.. so
|
|
||||||
if you delete sdb1, it would be natural to keep hiding sdb (which is
|
|
||||||
what this patch does).
|
|
||||||
---
|
|
||||||
monitor/gdu/ggduvolumemonitor.c | 8 +++++++-
|
|
||||||
1 files changed, 7 insertions(+), 1 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/monitor/gdu/ggduvolumemonitor.c b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
index 9ecee8b..0e7ce6f 100644
|
|
||||||
--- a/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
+++ b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
@@ -799,7 +799,13 @@ should_drive_be_ignored (GduPool *pool, GduDrive *d, GList *fstab_mount_points)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- ret = has_volumes && all_volumes_are_ignored;
|
|
||||||
+ /* we ignore a drive if
|
|
||||||
+ *
|
|
||||||
+ * a) it doesn't have any volumes; or
|
|
||||||
+ *
|
|
||||||
+ * b) the volumes of the drive are all ignored
|
|
||||||
+ */
|
|
||||||
+ ret = (!has_volumes) || (has_volumes && all_volumes_are_ignored);
|
|
||||||
|
|
||||||
out:
|
|
||||||
g_list_foreach (enclosed, (GFunc) g_object_unref, NULL);
|
|
||||||
--
|
|
||||||
1.6.2.2
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
|||||||
From c54217a58f71f3ca7a85ce81fb96f363255c6110 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Zeuthen <davidz@redhat.com>
|
|
||||||
Date: Sat, 11 Apr 2009 12:57:55 -0400
|
|
||||||
Subject: [PATCH] never ignore drives without media
|
|
||||||
|
|
||||||
---
|
|
||||||
monitor/gdu/ggduvolumemonitor.c | 21 +++++++++++++++------
|
|
||||||
1 files changed, 15 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/monitor/gdu/ggduvolumemonitor.c b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
index 0e7ce6f..caa25a0 100644
|
|
||||||
--- a/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
+++ b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
@@ -751,13 +751,13 @@ static gboolean
|
|
||||||
should_drive_be_ignored (GduPool *pool, GduDrive *d, GList *fstab_mount_points)
|
|
||||||
{
|
|
||||||
GduDevice *device;
|
|
||||||
- gboolean ret;
|
|
||||||
+ gboolean ignored;
|
|
||||||
gboolean has_volumes;
|
|
||||||
gboolean all_volumes_are_ignored;
|
|
||||||
GList *enclosed;
|
|
||||||
GList *l;
|
|
||||||
|
|
||||||
- ret = FALSE;
|
|
||||||
+ ignored = FALSE;
|
|
||||||
device = NULL;
|
|
||||||
enclosed = NULL;
|
|
||||||
|
|
||||||
@@ -771,7 +771,7 @@ should_drive_be_ignored (GduPool *pool, GduDrive *d, GList *fstab_mount_points)
|
|
||||||
*/
|
|
||||||
if (device == NULL)
|
|
||||||
{
|
|
||||||
- ret = TRUE;
|
|
||||||
+ ignored = TRUE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -801,11 +801,20 @@ should_drive_be_ignored (GduPool *pool, GduDrive *d, GList *fstab_mount_points)
|
|
||||||
|
|
||||||
/* we ignore a drive if
|
|
||||||
*
|
|
||||||
- * a) it doesn't have any volumes; or
|
|
||||||
+ * a) no volumes are available AND media is available; OR
|
|
||||||
*
|
|
||||||
* b) the volumes of the drive are all ignored
|
|
||||||
*/
|
|
||||||
- ret = (!has_volumes) || (has_volumes && all_volumes_are_ignored);
|
|
||||||
+ if (!has_volumes)
|
|
||||||
+ {
|
|
||||||
+ if (gdu_device_is_media_available (device))
|
|
||||||
+ ignored = TRUE;
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ if (all_volumes_are_ignored)
|
|
||||||
+ ignored = TRUE;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
out:
|
|
||||||
g_list_foreach (enclosed, (GFunc) g_object_unref, NULL);
|
|
||||||
@@ -814,7 +823,7 @@ should_drive_be_ignored (GduPool *pool, GduDrive *d, GList *fstab_mount_points)
|
|
||||||
if (device != NULL)
|
|
||||||
g_object_unref (device);
|
|
||||||
|
|
||||||
- return ret;
|
|
||||||
+ return ignored;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
--
|
|
||||||
1.6.2.2
|
|
||||||
|
|
@ -1,876 +0,0 @@
|
|||||||
From 0f7a44dd0eac01f9783879af4ca3d3fe4a53af14 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Zeuthen <davidz@redhat.com>
|
|
||||||
Date: Mon, 13 Apr 2009 10:57:38 -0400
|
|
||||||
Subject: [PATCH 10/13] show user-mountable fstab entries
|
|
||||||
|
|
||||||
Show all entries from /etc/fstab for which
|
|
||||||
|
|
||||||
- the entry is user mountable
|
|
||||||
- the mount point is in /media or $HOME
|
|
||||||
- if it's a /dev file make sure it exists and is not handled
|
|
||||||
by DeviceKit-disks already
|
|
||||||
|
|
||||||
For example this /etc/fstab entry
|
|
||||||
|
|
||||||
"quad.local:/media/FusionMedia /media/FusionMedia nfs defaults,users 0 0"
|
|
||||||
|
|
||||||
makes Nautilus display this when unmounted
|
|
||||||
|
|
||||||
http://people.freedesktop.org/~david/gvfs-user-mountable-fstab-entries.png
|
|
||||||
|
|
||||||
and these GVolume and GMount objects to appear when mounted
|
|
||||||
|
|
||||||
Volume(0): FusionMedia
|
|
||||||
Type: GProxyVolume (GProxyVolumeMonitorGdu)
|
|
||||||
themed icons: [folder-remote] [folder]
|
|
||||||
can_mount=1
|
|
||||||
can_eject=0
|
|
||||||
Mount(0): FusionMedia -> file:///media/FusionMedia
|
|
||||||
Type: GProxyMount (GProxyVolumeMonitorGdu)
|
|
||||||
themed icons: [folder-remote] [folder]
|
|
||||||
can_unmount=1
|
|
||||||
can_eject=0
|
|
||||||
is_shadowed=0
|
|
||||||
|
|
||||||
This should resolve http://bugzilla.gnome.org/show_bug.cgi?id=536292
|
|
||||||
---
|
|
||||||
monitor/gdu/ggdumount.c | 29 +++-
|
|
||||||
monitor/gdu/ggduvolume.c | 374 ++++++++++++++++++++++++++++++++++++---
|
|
||||||
monitor/gdu/ggduvolume.h | 7 +-
|
|
||||||
monitor/gdu/ggduvolumemonitor.c | 174 ++++++++++++++++++-
|
|
||||||
4 files changed, 548 insertions(+), 36 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/monitor/gdu/ggdumount.c b/monitor/gdu/ggdumount.c
|
|
||||||
index 27c22d9..e074a20 100644
|
|
||||||
--- a/monitor/gdu/ggdumount.c
|
|
||||||
+++ b/monitor/gdu/ggdumount.c
|
|
||||||
@@ -696,8 +696,13 @@ g_gdu_mount_unmount (GMount *_mount,
|
|
||||||
{
|
|
||||||
GGduMount *mount = G_GDU_MOUNT (_mount);
|
|
||||||
GSimpleAsyncResult *simple;
|
|
||||||
+ GduPresentable *gdu_volume;
|
|
||||||
|
|
||||||
- if (mount->volume == NULL)
|
|
||||||
+ gdu_volume = NULL;
|
|
||||||
+ if (mount->volume != NULL)
|
|
||||||
+ gdu_volume = g_gdu_volume_get_presentable_with_cleartext (mount->volume);
|
|
||||||
+
|
|
||||||
+ if (mount->volume == NULL || gdu_volume == NULL)
|
|
||||||
{
|
|
||||||
gchar *argv[] = {"umount", NULL, NULL};
|
|
||||||
|
|
||||||
@@ -710,7 +715,7 @@ g_gdu_mount_unmount (GMount *_mount,
|
|
||||||
|
|
||||||
eject_unmount_do (_mount, cancellable, callback, user_data, argv);
|
|
||||||
}
|
|
||||||
- else
|
|
||||||
+ else if (gdu_volume != NULL)
|
|
||||||
{
|
|
||||||
simple = g_simple_async_result_new (G_OBJECT (mount),
|
|
||||||
callback,
|
|
||||||
@@ -726,18 +731,25 @@ g_gdu_mount_unmount (GMount *_mount,
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GduDevice *device;
|
|
||||||
- GduPresentable *volume;
|
|
||||||
|
|
||||||
/* TODO: honor flags */
|
|
||||||
|
|
||||||
- volume = g_gdu_volume_get_presentable_with_cleartext (mount->volume);
|
|
||||||
- device = gdu_presentable_get_device (volume);
|
|
||||||
-
|
|
||||||
+ device = gdu_presentable_get_device (gdu_volume);
|
|
||||||
gdu_device_op_filesystem_unmount (device, unmount_cb, simple);
|
|
||||||
-
|
|
||||||
g_object_unref (device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ simple = g_simple_async_result_new_error (G_OBJECT (mount),
|
|
||||||
+ callback,
|
|
||||||
+ user_data,
|
|
||||||
+ G_IO_ERROR,
|
|
||||||
+ G_IO_ERROR_FAILED,
|
|
||||||
+ _("Operation not supported by backend"));
|
|
||||||
+ g_simple_async_result_complete (simple);
|
|
||||||
+ g_object_unref (simple);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
@@ -855,7 +867,8 @@ g_gdu_mount_guess_content_type_sync (GMount *_mount,
|
|
||||||
{
|
|
||||||
GduPresentable *presentable;
|
|
||||||
presentable = g_gdu_volume_get_presentable_with_cleartext (mount->volume);
|
|
||||||
- device = gdu_presentable_get_device (presentable);
|
|
||||||
+ if (presentable != NULL)
|
|
||||||
+ device = gdu_presentable_get_device (presentable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* doesn't make sense to probe blank discs - look at the disc type instead */
|
|
||||||
diff --git a/monitor/gdu/ggduvolume.c b/monitor/gdu/ggduvolume.c
|
|
||||||
index 6779f0f..49494a1 100644
|
|
||||||
--- a/monitor/gdu/ggduvolume.c
|
|
||||||
+++ b/monitor/gdu/ggduvolume.c
|
|
||||||
@@ -35,12 +35,22 @@
|
|
||||||
#include "ggduvolume.h"
|
|
||||||
#include "ggdumount.h"
|
|
||||||
|
|
||||||
+/* for BUFSIZ */
|
|
||||||
+#include <stdio.h>
|
|
||||||
+
|
|
||||||
#include "polkit.h"
|
|
||||||
|
|
||||||
typedef struct MountOpData MountOpData;
|
|
||||||
|
|
||||||
static void cancel_pending_mount_op (MountOpData *data);
|
|
||||||
|
|
||||||
+static void g_gdu_volume_mount_unix_mount_point (GGduVolume *volume,
|
|
||||||
+ GMountMountFlags flags,
|
|
||||||
+ GMountOperation *mount_operation,
|
|
||||||
+ GCancellable *cancellable,
|
|
||||||
+ GAsyncReadyCallback callback,
|
|
||||||
+ gpointer user_data);
|
|
||||||
+
|
|
||||||
struct _GGduVolume
|
|
||||||
{
|
|
||||||
GObject parent;
|
|
||||||
@@ -49,8 +59,12 @@ struct _GGduVolume
|
|
||||||
GGduMount *mount; /* owned by volume monitor */
|
|
||||||
GGduDrive *drive; /* owned by volume monitor */
|
|
||||||
|
|
||||||
+ /* only set if constructed via new() */
|
|
||||||
GduVolume *gdu_volume;
|
|
||||||
|
|
||||||
+ /* only set if constructed via new_for_unix_mount_point() */
|
|
||||||
+ GUnixMountPoint *unix_mount_point;
|
|
||||||
+
|
|
||||||
/* if the volume is encrypted, this is != NULL when unlocked */
|
|
||||||
GduVolume *cleartext_gdu_volume;
|
|
||||||
|
|
||||||
@@ -60,7 +74,7 @@ struct _GGduVolume
|
|
||||||
*/
|
|
||||||
MountOpData *pending_mount_op;
|
|
||||||
|
|
||||||
- /* the following members need to be set upon construction */
|
|
||||||
+ /* the following members need to be set upon construction, see constructors and update_volume() */
|
|
||||||
GIcon *icon;
|
|
||||||
GFile *activation_root;
|
|
||||||
gchar *name;
|
|
||||||
@@ -110,6 +124,11 @@ g_gdu_volume_finalize (GObject *object)
|
|
||||||
g_object_unref (volume->gdu_volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (volume->unix_mount_point != NULL)
|
|
||||||
+ {
|
|
||||||
+ g_unix_mount_point_free (volume->unix_mount_point);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (volume->cleartext_gdu_volume != NULL)
|
|
||||||
{
|
|
||||||
g_signal_handlers_disconnect_by_func (volume->cleartext_gdu_volume, gdu_cleartext_volume_removed, volume);
|
|
||||||
@@ -174,6 +193,30 @@ update_volume (GGduVolume *volume)
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
+ /* if the volume is a fstab mount point, get the data from there */
|
|
||||||
+ if (volume->unix_mount_point != NULL)
|
|
||||||
+ {
|
|
||||||
+ volume->can_mount = TRUE;
|
|
||||||
+ volume->should_automount = FALSE;
|
|
||||||
+
|
|
||||||
+ g_free (volume->device_file);
|
|
||||||
+ volume->device_file = g_strdup (g_unix_mount_point_get_device_path (volume->unix_mount_point));
|
|
||||||
+
|
|
||||||
+ if (volume->icon != NULL)
|
|
||||||
+ g_object_unref (volume->icon);
|
|
||||||
+ if (g_strcmp0 (g_unix_mount_point_get_fs_type (volume->unix_mount_point), "nfs") == 0)
|
|
||||||
+ volume->icon = g_themed_icon_new_with_default_fallbacks ("folder-remote");
|
|
||||||
+ else
|
|
||||||
+ volume->icon = g_unix_mount_point_guess_icon (volume->unix_mount_point);
|
|
||||||
+
|
|
||||||
+ g_free (volume->name);
|
|
||||||
+ volume->name = g_unix_mount_point_guess_name (volume->unix_mount_point);
|
|
||||||
+
|
|
||||||
+ //volume->can_eject = g_unix_mount_point_guess_can_eject (volume->unix_mount_point);
|
|
||||||
+
|
|
||||||
+ goto update_done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* in with the new */
|
|
||||||
device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume));
|
|
||||||
pool = gdu_device_get_pool (device);
|
|
||||||
@@ -347,6 +390,8 @@ update_volume (GGduVolume *volume)
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
+ update_done:
|
|
||||||
+
|
|
||||||
/* compute whether something changed */
|
|
||||||
changed = !((old_can_mount == volume->can_mount) &&
|
|
||||||
(old_should_automount == volume->should_automount) &&
|
|
||||||
@@ -412,6 +457,23 @@ gdu_cleartext_volume_job_changed (GduPresentable *presentable,
|
|
||||||
}
|
|
||||||
|
|
||||||
GGduVolume *
|
|
||||||
+g_gdu_volume_new_for_unix_mount_point (GVolumeMonitor *volume_monitor,
|
|
||||||
+ GUnixMountPoint *unix_mount_point)
|
|
||||||
+{
|
|
||||||
+ GGduVolume *volume;
|
|
||||||
+
|
|
||||||
+ volume = g_object_new (G_TYPE_GDU_VOLUME, NULL);
|
|
||||||
+ volume->volume_monitor = volume_monitor;
|
|
||||||
+ g_object_add_weak_pointer (G_OBJECT (volume_monitor), (gpointer) &(volume->volume_monitor));
|
|
||||||
+
|
|
||||||
+ volume->unix_mount_point = unix_mount_point;
|
|
||||||
+
|
|
||||||
+ update_volume (volume);
|
|
||||||
+
|
|
||||||
+ return volume;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+GGduVolume *
|
|
||||||
g_gdu_volume_new (GVolumeMonitor *volume_monitor,
|
|
||||||
GduVolume *gdu_volume,
|
|
||||||
GGduDrive *drive,
|
|
||||||
@@ -1084,6 +1146,18 @@ g_gdu_volume_mount (GVolume *_volume,
|
|
||||||
pool = NULL;
|
|
||||||
device = NULL;
|
|
||||||
|
|
||||||
+ /* for fstab mounts, call the native mount command */
|
|
||||||
+ if (volume->unix_mount_point != NULL)
|
|
||||||
+ {
|
|
||||||
+ g_gdu_volume_mount_unix_mount_point (volume,
|
|
||||||
+ flags,
|
|
||||||
+ mount_operation,
|
|
||||||
+ cancellable,
|
|
||||||
+ callback,
|
|
||||||
+ user_data);
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (volume->pending_mount_op != NULL)
|
|
||||||
{
|
|
||||||
simple = g_simple_async_result_new_error (G_OBJECT (volume),
|
|
||||||
@@ -1204,7 +1278,7 @@ g_gdu_volume_mount_finish (GVolume *volume,
|
|
||||||
{
|
|
||||||
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
|
|
||||||
|
|
||||||
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_gdu_volume_mount);
|
|
||||||
+ //g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_gdu_volume_mount);
|
|
||||||
|
|
||||||
return !g_simple_async_result_propagate_error (simple, error);
|
|
||||||
}
|
|
||||||
@@ -1212,6 +1286,247 @@ g_gdu_volume_mount_finish (GVolume *volume,
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
+ GGduVolume *volume;
|
|
||||||
+ GAsyncReadyCallback callback;
|
|
||||||
+ gpointer user_data;
|
|
||||||
+ GCancellable *cancellable;
|
|
||||||
+ int error_fd;
|
|
||||||
+ GIOChannel *error_channel;
|
|
||||||
+ guint error_channel_source_id;
|
|
||||||
+ GString *error_string;
|
|
||||||
+
|
|
||||||
+ guint wait_for_mount_timeout_id;
|
|
||||||
+ gulong wait_for_mount_changed_signal_handler_id;
|
|
||||||
+} MountPointOp;
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+mount_point_op_free (MountPointOp *data)
|
|
||||||
+{
|
|
||||||
+ if (data->error_channel_source_id > 0)
|
|
||||||
+ g_source_remove (data->error_channel_source_id);
|
|
||||||
+ if (data->error_channel != NULL)
|
|
||||||
+ g_io_channel_unref (data->error_channel);
|
|
||||||
+ if (data->error_string != NULL)
|
|
||||||
+ g_string_free (data->error_string, TRUE);
|
|
||||||
+ if (data->error_fd > 0)
|
|
||||||
+ close (data->error_fd);
|
|
||||||
+ g_free (data);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+mount_point_op_changed_cb (GVolume *volume,
|
|
||||||
+ gpointer user_data)
|
|
||||||
+{
|
|
||||||
+ MountPointOp *data = user_data;
|
|
||||||
+ GSimpleAsyncResult *simple;
|
|
||||||
+
|
|
||||||
+ /* keep waiting if the mount hasn't appeared */
|
|
||||||
+ if (data->volume->mount == NULL)
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
+ simple = g_simple_async_result_new (G_OBJECT (data->volume),
|
|
||||||
+ data->callback,
|
|
||||||
+ data->user_data,
|
|
||||||
+ NULL);
|
|
||||||
+ /* complete in idle to make sure the mount is added before we return */
|
|
||||||
+ g_simple_async_result_complete_in_idle (simple);
|
|
||||||
+ g_object_unref (simple);
|
|
||||||
+
|
|
||||||
+ g_signal_handler_disconnect (data->volume, data->wait_for_mount_changed_signal_handler_id);
|
|
||||||
+ g_source_remove (data->wait_for_mount_timeout_id);
|
|
||||||
+
|
|
||||||
+ mount_point_op_free (data);
|
|
||||||
+
|
|
||||||
+ out:
|
|
||||||
+ ;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static gboolean
|
|
||||||
+mount_point_op_never_appeared_cb (gpointer user_data)
|
|
||||||
+{
|
|
||||||
+ MountPointOp *data = user_data;
|
|
||||||
+ GSimpleAsyncResult *simple;
|
|
||||||
+
|
|
||||||
+ simple = g_simple_async_result_new_error (G_OBJECT (data->volume),
|
|
||||||
+ data->callback,
|
|
||||||
+ data->user_data,
|
|
||||||
+ G_IO_ERROR,
|
|
||||||
+ G_IO_ERROR_FAILED,
|
|
||||||
+ "Timeout waiting for mount to appear");
|
|
||||||
+ g_simple_async_result_complete (simple);
|
|
||||||
+ g_object_unref (simple);
|
|
||||||
+
|
|
||||||
+ g_signal_handler_disconnect (data->volume, data->wait_for_mount_changed_signal_handler_id);
|
|
||||||
+ g_source_remove (data->wait_for_mount_timeout_id);
|
|
||||||
+
|
|
||||||
+ mount_point_op_free (data);
|
|
||||||
+
|
|
||||||
+ return FALSE;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+mount_point_op_cb (GPid pid, gint status, gpointer user_data)
|
|
||||||
+{
|
|
||||||
+ MountPointOp *data = user_data;
|
|
||||||
+ GSimpleAsyncResult *simple;
|
|
||||||
+
|
|
||||||
+ g_spawn_close_pid (pid);
|
|
||||||
+
|
|
||||||
+ if (WEXITSTATUS (status) != 0)
|
|
||||||
+ {
|
|
||||||
+ GError *error;
|
|
||||||
+ error = g_error_new_literal (G_IO_ERROR,
|
|
||||||
+ G_IO_ERROR_FAILED,
|
|
||||||
+ data->error_string->str);
|
|
||||||
+ simple = g_simple_async_result_new_from_error (G_OBJECT (data->volume),
|
|
||||||
+ data->callback,
|
|
||||||
+ data->user_data,
|
|
||||||
+ error);
|
|
||||||
+ g_error_free (error);
|
|
||||||
+ g_simple_async_result_complete (simple);
|
|
||||||
+ g_object_unref (simple);
|
|
||||||
+ mount_point_op_free (data);
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ /* wait for the GMount to appear - this is to honor this requirement
|
|
||||||
+ *
|
|
||||||
+ * "If the mount operation succeeded, g_volume_get_mount() on
|
|
||||||
+ * volume is guaranteed to return the mount right after calling
|
|
||||||
+ * this function; there's no need to listen for the
|
|
||||||
+ * 'mount-added' signal on GVolumeMonitor."
|
|
||||||
+ *
|
|
||||||
+ * So we set up a signal handler waiting for it to appear. We also set up
|
|
||||||
+ * a timer for handling the case when it never appears.
|
|
||||||
+ */
|
|
||||||
+ if (data->volume->mount == NULL)
|
|
||||||
+ {
|
|
||||||
+ /* no need to ref, GSimpleAsyncResult has a ref on data->volume */
|
|
||||||
+ data->wait_for_mount_timeout_id = g_timeout_add (5 * 1000,
|
|
||||||
+ mount_point_op_never_appeared_cb,
|
|
||||||
+ data);
|
|
||||||
+ data->wait_for_mount_changed_signal_handler_id = g_signal_connect (data->volume,
|
|
||||||
+ "changed",
|
|
||||||
+ G_CALLBACK (mount_point_op_changed_cb),
|
|
||||||
+ data);
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ /* have the mount already, finish up */
|
|
||||||
+ simple = g_simple_async_result_new (G_OBJECT (data->volume),
|
|
||||||
+ data->callback,
|
|
||||||
+ data->user_data,
|
|
||||||
+ NULL);
|
|
||||||
+ g_simple_async_result_complete (simple);
|
|
||||||
+ g_object_unref (simple);
|
|
||||||
+ mount_point_op_free (data);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static gboolean
|
|
||||||
+mount_point_op_read_error (GIOChannel *channel,
|
|
||||||
+ GIOCondition condition,
|
|
||||||
+ gpointer user_data)
|
|
||||||
+{
|
|
||||||
+ MountPointOp *data = user_data;
|
|
||||||
+ gchar buf[BUFSIZ];
|
|
||||||
+ gsize bytes_read;
|
|
||||||
+ GError *error;
|
|
||||||
+ GIOStatus status;
|
|
||||||
+
|
|
||||||
+ error = NULL;
|
|
||||||
+read:
|
|
||||||
+ status = g_io_channel_read_chars (channel, buf, sizeof (buf), &bytes_read, &error);
|
|
||||||
+ if (status == G_IO_STATUS_NORMAL)
|
|
||||||
+ {
|
|
||||||
+ g_string_append_len (data->error_string, buf, bytes_read);
|
|
||||||
+ if (bytes_read == sizeof (buf))
|
|
||||||
+ goto read;
|
|
||||||
+ }
|
|
||||||
+ else if (status == G_IO_STATUS_EOF)
|
|
||||||
+ {
|
|
||||||
+ g_string_append_len (data->error_string, buf, bytes_read);
|
|
||||||
+ }
|
|
||||||
+ else if (status == G_IO_STATUS_ERROR)
|
|
||||||
+ {
|
|
||||||
+ if (data->error_string->len > 0)
|
|
||||||
+ g_string_append (data->error_string, "\n");
|
|
||||||
+
|
|
||||||
+ g_string_append (data->error_string, error->message);
|
|
||||||
+ g_error_free (error);
|
|
||||||
+ return FALSE;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return TRUE;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+g_gdu_volume_mount_unix_mount_point (GGduVolume *volume,
|
|
||||||
+ GMountMountFlags flags,
|
|
||||||
+ GMountOperation *mount_operation,
|
|
||||||
+ GCancellable *cancellable,
|
|
||||||
+ GAsyncReadyCallback callback,
|
|
||||||
+ gpointer user_data)
|
|
||||||
+{
|
|
||||||
+ MountPointOp *data;
|
|
||||||
+ GPid child_pid;
|
|
||||||
+ GError *error;
|
|
||||||
+ const gchar *argv[] = {"mount", NULL, NULL};
|
|
||||||
+
|
|
||||||
+ argv[1] = g_unix_mount_point_get_mount_path (volume->unix_mount_point);
|
|
||||||
+
|
|
||||||
+ data = g_new0 (MountPointOp, 1);
|
|
||||||
+ data->volume = volume;
|
|
||||||
+ data->callback = callback;
|
|
||||||
+ data->user_data = user_data;
|
|
||||||
+ data->cancellable = cancellable;
|
|
||||||
+
|
|
||||||
+ error = NULL;
|
|
||||||
+ if (!g_spawn_async_with_pipes (NULL, /* working dir */
|
|
||||||
+ (gchar **) argv,
|
|
||||||
+ NULL, /* envp */
|
|
||||||
+ G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH,
|
|
||||||
+ NULL, /* child_setup */
|
|
||||||
+ NULL, /* user_data for child_setup */
|
|
||||||
+ &child_pid,
|
|
||||||
+ NULL, /* standard_input */
|
|
||||||
+ NULL, /* standard_output */
|
|
||||||
+ &(data->error_fd),
|
|
||||||
+ &error))
|
|
||||||
+ {
|
|
||||||
+ g_assert (error != NULL);
|
|
||||||
+ goto handle_error;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ data->error_string = g_string_new ("");
|
|
||||||
+
|
|
||||||
+ data->error_channel = g_io_channel_unix_new (data->error_fd);
|
|
||||||
+ g_io_channel_set_flags (data->error_channel, G_IO_FLAG_NONBLOCK, &error);
|
|
||||||
+ if (error != NULL)
|
|
||||||
+ goto handle_error;
|
|
||||||
+
|
|
||||||
+ data->error_channel_source_id = g_io_add_watch (data->error_channel, G_IO_IN, mount_point_op_read_error, data);
|
|
||||||
+ g_child_watch_add (child_pid, mount_point_op_cb, data);
|
|
||||||
+
|
|
||||||
+handle_error:
|
|
||||||
+ if (error != NULL)
|
|
||||||
+ {
|
|
||||||
+ GSimpleAsyncResult *simple;
|
|
||||||
+ simple = g_simple_async_result_new_from_error (G_OBJECT (data->volume),
|
|
||||||
+ data->callback,
|
|
||||||
+ data->user_data,
|
|
||||||
+ error);
|
|
||||||
+ g_simple_async_result_complete (simple);
|
|
||||||
+ g_object_unref (simple);
|
|
||||||
+
|
|
||||||
+ mount_point_op_free (data);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/* ---------------------------------------------------------------------------------------------------- */
|
|
||||||
+
|
|
||||||
+typedef struct {
|
|
||||||
GObject *object;
|
|
||||||
GAsyncReadyCallback callback;
|
|
||||||
gpointer user_data;
|
|
||||||
@@ -1300,19 +1615,22 @@ g_gdu_volume_get_identifier (GVolume *_volume,
|
|
||||||
|
|
||||||
id = NULL;
|
|
||||||
|
|
||||||
- device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume));
|
|
||||||
+ if (volume->gdu_volume != NULL)
|
|
||||||
+ {
|
|
||||||
+ device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume));
|
|
||||||
|
|
||||||
- label = gdu_device_id_get_label (device);
|
|
||||||
- uuid = gdu_device_id_get_uuid (device);
|
|
||||||
+ label = gdu_device_id_get_label (device);
|
|
||||||
+ uuid = gdu_device_id_get_uuid (device);
|
|
||||||
|
|
||||||
- g_object_unref (device);
|
|
||||||
+ g_object_unref (device);
|
|
||||||
|
|
||||||
- if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE) == 0)
|
|
||||||
- id = g_strdup (volume->device_file);
|
|
||||||
- else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_LABEL) == 0)
|
|
||||||
- id = strlen (label) > 0 ? g_strdup (label) : NULL;
|
|
||||||
- else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UUID) == 0)
|
|
||||||
- id = strlen (uuid) > 0 ? g_strdup (uuid) : NULL;
|
|
||||||
+ if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE) == 0)
|
|
||||||
+ id = g_strdup (volume->device_file);
|
|
||||||
+ else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_LABEL) == 0)
|
|
||||||
+ id = strlen (label) > 0 ? g_strdup (label) : NULL;
|
|
||||||
+ else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UUID) == 0)
|
|
||||||
+ id = strlen (uuid) > 0 ? g_strdup (uuid) : NULL;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
@@ -1326,19 +1644,21 @@ g_gdu_volume_enumerate_identifiers (GVolume *_volume)
|
|
||||||
const gchar *label;
|
|
||||||
const gchar *uuid;
|
|
||||||
|
|
||||||
- device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume));
|
|
||||||
-
|
|
||||||
- label = gdu_device_id_get_label (device);
|
|
||||||
- uuid = gdu_device_id_get_uuid (device);
|
|
||||||
-
|
|
||||||
- g_object_unref (device);
|
|
||||||
-
|
|
||||||
p = g_ptr_array_new ();
|
|
||||||
- g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE));
|
|
||||||
- if (strlen (label) > 0)
|
|
||||||
- g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_LABEL));
|
|
||||||
- if (strlen (uuid) > 0)
|
|
||||||
- g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UUID));
|
|
||||||
+
|
|
||||||
+ if (volume->gdu_volume != NULL)
|
|
||||||
+ {
|
|
||||||
+ device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume));
|
|
||||||
+ label = gdu_device_id_get_label (device);
|
|
||||||
+ uuid = gdu_device_id_get_uuid (device);
|
|
||||||
+ g_object_unref (device);
|
|
||||||
+
|
|
||||||
+ g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE));
|
|
||||||
+ if (strlen (label) > 0)
|
|
||||||
+ g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_LABEL));
|
|
||||||
+ if (strlen (uuid) > 0)
|
|
||||||
+ g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UUID));
|
|
||||||
+ }
|
|
||||||
|
|
||||||
g_ptr_array_add (p, NULL);
|
|
||||||
|
|
||||||
@@ -1452,3 +1772,9 @@ g_gdu_volume_get_presentable_with_cleartext (GGduVolume *volume)
|
|
||||||
|
|
||||||
return GDU_PRESENTABLE (ret);
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+GUnixMountPoint *
|
|
||||||
+g_gdu_volume_get_unix_mount_point (GGduVolume *volume)
|
|
||||||
+{
|
|
||||||
+ return volume->unix_mount_point;
|
|
||||||
+}
|
|
||||||
diff --git a/monitor/gdu/ggduvolume.h b/monitor/gdu/ggduvolume.h
|
|
||||||
index 8fd7358..a230d28 100644
|
|
||||||
--- a/monitor/gdu/ggduvolume.h
|
|
||||||
+++ b/monitor/gdu/ggduvolume.h
|
|
||||||
@@ -50,6 +50,9 @@ GGduVolume *g_gdu_volume_new (GVolumeMonitor *volume_monitor,
|
|
||||||
GGduDrive *drive,
|
|
||||||
GFile *activation_root);
|
|
||||||
|
|
||||||
+GGduVolume *g_gdu_volume_new_for_unix_mount_point (GVolumeMonitor *volume_monitor,
|
|
||||||
+ GUnixMountPoint *unix_mount_point);
|
|
||||||
+
|
|
||||||
void g_gdu_volume_set_mount (GGduVolume *volume,
|
|
||||||
GGduMount *mount);
|
|
||||||
void g_gdu_volume_unset_mount (GGduVolume *volume,
|
|
||||||
@@ -69,10 +72,12 @@ gboolean g_gdu_volume_has_uuid (GGduVolume *volume,
|
|
||||||
gboolean g_gdu_volume_has_device_file (GGduVolume *volume,
|
|
||||||
const gchar *device_file);
|
|
||||||
|
|
||||||
-GduPresentable *g_gdu_volume_get_presentable (GGduVolume *volume);
|
|
||||||
+GduPresentable *g_gdu_volume_get_presentable (GGduVolume *volume);
|
|
||||||
|
|
||||||
GduPresentable *g_gdu_volume_get_presentable_with_cleartext (GGduVolume *volume);
|
|
||||||
|
|
||||||
+GUnixMountPoint *g_gdu_volume_get_unix_mount_point (GGduVolume *volume);
|
|
||||||
+
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __G_GDU_VOLUME_H__ */
|
|
||||||
diff --git a/monitor/gdu/ggduvolumemonitor.c b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
index caa25a0..67e2ec0 100644
|
|
||||||
--- a/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
+++ b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
@@ -51,6 +51,7 @@ struct _GGduVolumeMonitor {
|
|
||||||
|
|
||||||
GList *drives;
|
|
||||||
GList *volumes;
|
|
||||||
+ GList *fstab_volumes;
|
|
||||||
GList *mounts;
|
|
||||||
|
|
||||||
/* we keep volumes/mounts for blank and audio discs separate to handle e.g. mixed discs properly */
|
|
||||||
@@ -80,6 +81,9 @@ static void update_drives (GGduVolumeMonitor *monitor,
|
|
||||||
static void update_volumes (GGduVolumeMonitor *monitor,
|
|
||||||
GList **added_volumes,
|
|
||||||
GList **removed_volumes);
|
|
||||||
+static void update_fstab_volumes (GGduVolumeMonitor *monitor,
|
|
||||||
+ GList **added_volumes,
|
|
||||||
+ GList **removed_volumes);
|
|
||||||
static void update_mounts (GGduVolumeMonitor *monitor,
|
|
||||||
GList **added_mounts,
|
|
||||||
GList **removed_mounts);
|
|
||||||
@@ -135,6 +139,7 @@ g_gdu_volume_monitor_finalize (GObject *object)
|
|
||||||
g_list_free (monitor->last_mounts);
|
|
||||||
|
|
||||||
list_free (monitor->drives);
|
|
||||||
+ list_free (monitor->fstab_volumes);
|
|
||||||
list_free (monitor->volumes);
|
|
||||||
list_free (monitor->mounts);
|
|
||||||
|
|
||||||
@@ -171,6 +176,8 @@ get_volumes (GVolumeMonitor *volume_monitor)
|
|
||||||
monitor = G_GDU_VOLUME_MONITOR (volume_monitor);
|
|
||||||
|
|
||||||
l = g_list_copy (monitor->volumes);
|
|
||||||
+ ll = g_list_copy (monitor->fstab_volumes);
|
|
||||||
+ l = g_list_concat (l, ll);
|
|
||||||
ll = g_list_copy (monitor->disc_volumes);
|
|
||||||
l = g_list_concat (l, ll);
|
|
||||||
|
|
||||||
@@ -211,6 +218,13 @@ get_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid)
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ for (l = monitor->fstab_volumes; l != NULL; l = l->next)
|
|
||||||
+ {
|
|
||||||
+ volume = l->data;
|
|
||||||
+ if (g_gdu_volume_has_uuid (volume, uuid))
|
|
||||||
+ goto found;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
for (l = monitor->disc_volumes; l != NULL; l = l->next)
|
|
||||||
{
|
|
||||||
volume = l->data;
|
|
||||||
@@ -549,14 +563,49 @@ find_volume_for_mount_path (GGduVolumeMonitor *monitor,
|
|
||||||
for (l = monitor->volumes; l != NULL; l = l->next)
|
|
||||||
{
|
|
||||||
GGduVolume *volume = l->data;
|
|
||||||
+ if (g_gdu_volume_has_mount_path (volume, mount_path))
|
|
||||||
+ {
|
|
||||||
+ found = volume;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
|
|
||||||
+ for (l = monitor->fstab_volumes; l != NULL; l = l->next)
|
|
||||||
+ {
|
|
||||||
+ GGduVolume *volume = l->data;
|
|
||||||
if (g_gdu_volume_has_mount_path (volume, mount_path))
|
|
||||||
{
|
|
||||||
found = volume;
|
|
||||||
- break;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ out:
|
|
||||||
+ return found;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static GGduVolume *
|
|
||||||
+find_volume_for_unix_mount_point (GGduVolumeMonitor *monitor,
|
|
||||||
+ GUnixMountPoint *unix_mount_point)
|
|
||||||
+{
|
|
||||||
+ GList *l;
|
|
||||||
+ GGduVolume *found;
|
|
||||||
+
|
|
||||||
+ found = NULL;
|
|
||||||
+ for (l = monitor->fstab_volumes; l != NULL; l = l->next)
|
|
||||||
+ {
|
|
||||||
+ GGduVolume *volume = l->data;
|
|
||||||
+ GUnixMountPoint *volume_mount_point;
|
|
||||||
+
|
|
||||||
+ volume_mount_point = g_gdu_volume_get_unix_mount_point (volume);
|
|
||||||
+ if (g_unix_mount_point_compare (unix_mount_point, volume_mount_point) == 0)
|
|
||||||
+ {
|
|
||||||
+ found = volume;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ out:
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -859,6 +908,7 @@ update_all (GGduVolumeMonitor *monitor,
|
|
||||||
|
|
||||||
update_drives (monitor, &added_drives, &removed_drives);
|
|
||||||
update_volumes (monitor, &added_volumes, &removed_volumes);
|
|
||||||
+ update_fstab_volumes (monitor, &added_volumes, &removed_volumes);
|
|
||||||
update_mounts (monitor, &added_mounts, &removed_mounts);
|
|
||||||
update_discs (monitor,
|
|
||||||
&added_volumes, &removed_volumes,
|
|
||||||
@@ -935,16 +985,34 @@ find_volume_for_device_file (GGduVolumeMonitor *monitor,
|
|
||||||
const gchar *device_file)
|
|
||||||
{
|
|
||||||
GList *l;
|
|
||||||
+ GGduVolume *ret;
|
|
||||||
|
|
||||||
+ ret = NULL;
|
|
||||||
for (l = monitor->volumes; l != NULL; l = l->next)
|
|
||||||
{
|
|
||||||
GGduVolume *volume = G_GDU_VOLUME (l->data);
|
|
||||||
|
|
||||||
if (g_gdu_volume_has_device_file (volume, device_file))
|
|
||||||
- return volume;
|
|
||||||
+ {
|
|
||||||
+ ret = volume;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
- return NULL;
|
|
||||||
+ ret = NULL;
|
|
||||||
+ for (l = monitor->fstab_volumes; l != NULL; l = l->next)
|
|
||||||
+ {
|
|
||||||
+ GGduVolume *volume = G_GDU_VOLUME (l->data);
|
|
||||||
+
|
|
||||||
+ if (g_gdu_volume_has_device_file (volume, device_file))
|
|
||||||
+ {
|
|
||||||
+ ret = volume;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ out:
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GGduDrive *
|
|
||||||
@@ -1189,6 +1257,106 @@ update_volumes (GGduVolumeMonitor *monitor,
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
+update_fstab_volumes (GGduVolumeMonitor *monitor,
|
|
||||||
+ GList **added_volumes,
|
|
||||||
+ GList **removed_volumes)
|
|
||||||
+{
|
|
||||||
+ GList *fstab_mount_points;
|
|
||||||
+ GList *cur_fstab_mount_points;
|
|
||||||
+ GList *new_fstab_mount_points;
|
|
||||||
+ GList *removed, *added;
|
|
||||||
+ GList *l;
|
|
||||||
+ GGduVolume *volume;
|
|
||||||
+
|
|
||||||
+ fstab_mount_points = g_unix_mount_points_get (NULL);
|
|
||||||
+
|
|
||||||
+ cur_fstab_mount_points = NULL;
|
|
||||||
+ for (l = monitor->fstab_volumes; l != NULL; l = l->next)
|
|
||||||
+ cur_fstab_mount_points = g_list_prepend (cur_fstab_mount_points, g_gdu_volume_get_unix_mount_point (G_GDU_VOLUME (l->data)));
|
|
||||||
+
|
|
||||||
+ new_fstab_mount_points = NULL;
|
|
||||||
+ for (l = fstab_mount_points; l != NULL; l = l->next)
|
|
||||||
+ {
|
|
||||||
+ GUnixMountPoint *mount_point = l->data;
|
|
||||||
+ const gchar *device_file;
|
|
||||||
+
|
|
||||||
+ /* only show user mountable mount points */
|
|
||||||
+ if (!g_unix_mount_point_is_user_mountable (mount_point))
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ /* only show stuff that can be mounted in user-visible locations */
|
|
||||||
+ if (!_g_unix_mount_point_guess_should_display (mount_point))
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ /* ignore mount point if the device doesn't exist or is handled by DeviceKit-disks */
|
|
||||||
+ device_file = g_unix_mount_point_get_device_path (mount_point);
|
|
||||||
+ if (g_str_has_prefix (device_file, "/dev/"))
|
|
||||||
+ {
|
|
||||||
+ gchar resolved_path[PATH_MAX];
|
|
||||||
+ GduDevice *device;
|
|
||||||
+
|
|
||||||
+ /* doesn't exist */
|
|
||||||
+ if (realpath (device_file, resolved_path) != 0)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ /* is handled by DKD */
|
|
||||||
+ device = gdu_pool_get_by_device_file (monitor->pool, resolved_path);
|
|
||||||
+ if (device != NULL)
|
|
||||||
+ {
|
|
||||||
+ g_object_unref (device);
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ new_fstab_mount_points = g_list_prepend (new_fstab_mount_points, mount_point);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ diff_sorted_lists (cur_fstab_mount_points,
|
|
||||||
+ new_fstab_mount_points, (GCompareFunc) g_unix_mount_point_compare,
|
|
||||||
+ &added, &removed);
|
|
||||||
+
|
|
||||||
+ for (l = removed; l != NULL; l = l->next)
|
|
||||||
+ {
|
|
||||||
+ GUnixMountPoint *mount_point = l->data;
|
|
||||||
+ volume = find_volume_for_unix_mount_point (monitor, mount_point);
|
|
||||||
+ if (volume != NULL)
|
|
||||||
+ {
|
|
||||||
+ g_gdu_volume_removed (volume);
|
|
||||||
+ monitor->fstab_volumes = g_list_remove (monitor->fstab_volumes, volume);
|
|
||||||
+ *removed_volumes = g_list_prepend (*removed_volumes, volume);
|
|
||||||
+ /*g_debug ("removed volume for /etc/fstab mount point %s", g_unix_mount_point_get_mount_path (mount_point));*/
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for (l = added; l != NULL; l = l->next)
|
|
||||||
+ {
|
|
||||||
+ GUnixMountPoint *mount_point = l->data;
|
|
||||||
+
|
|
||||||
+ volume = g_gdu_volume_new_for_unix_mount_point (G_VOLUME_MONITOR (monitor), mount_point);
|
|
||||||
+ if (volume != NULL)
|
|
||||||
+ {
|
|
||||||
+ /* steal mount_point since g_gdu_volume_new_for_unix_mount_point() takes ownership of it */
|
|
||||||
+ fstab_mount_points = g_list_remove (fstab_mount_points, mount_point);
|
|
||||||
+ monitor->fstab_volumes = g_list_prepend (monitor->fstab_volumes, volume);
|
|
||||||
+ *added_volumes = g_list_prepend (*added_volumes, g_object_ref (volume));
|
|
||||||
+ /*g_debug ("added volume for /etc/fstab mount point %s", g_unix_mount_point_get_mount_path (mount_point));*/
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ g_unix_mount_point_free (mount_point);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ g_list_free (added);
|
|
||||||
+ g_list_free (removed);
|
|
||||||
+
|
|
||||||
+ g_list_free (cur_fstab_mount_points);
|
|
||||||
+
|
|
||||||
+ g_list_foreach (fstab_mount_points, (GFunc) g_unix_mount_point_free, NULL);
|
|
||||||
+ g_list_free (fstab_mount_points);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
update_mounts (GGduVolumeMonitor *monitor,
|
|
||||||
GList **added_mounts,
|
|
||||||
GList **removed_mounts)
|
|
||||||
--
|
|
||||||
1.6.2.2
|
|
||||||
|
|
@ -1,326 +0,0 @@
|
|||||||
From 8d9fc8a777fb1b00ae371e276a14416a0987f4af Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Zeuthen <davidz@redhat.com>
|
|
||||||
Date: Mon, 13 Apr 2009 14:20:15 -0400
|
|
||||||
Subject: [PATCH 11/13] =?utf-8?q?Bug=20576083=20=E2=80=93=20pre-unmount=20signals=20not=20being=20triggered?=
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=utf-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Basically emit GVolumeMonitor::mount-pre-unmount on the volume monitor
|
|
||||||
and retry unmount operation a couple of times.
|
|
||||||
---
|
|
||||||
monitor/gdu/ggdumount.c | 177 +++++++++++++++++++++++++++++++++++++---------
|
|
||||||
1 files changed, 142 insertions(+), 35 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/monitor/gdu/ggdumount.c b/monitor/gdu/ggdumount.c
|
|
||||||
index e074a20..78088d5 100644
|
|
||||||
--- a/monitor/gdu/ggdumount.c
|
|
||||||
+++ b/monitor/gdu/ggdumount.c
|
|
||||||
@@ -38,6 +38,9 @@
|
|
||||||
#include "ggdumount.h"
|
|
||||||
#include "ggduvolume.h"
|
|
||||||
|
|
||||||
+#define BUSY_UNMOUNT_NUM_ATTEMPTS 5
|
|
||||||
+#define BUSY_UNMOUNT_MS_DELAY_BETWEEN_ATTEMPTS 500
|
|
||||||
+
|
|
||||||
struct _GGduMount
|
|
||||||
{
|
|
||||||
GObject parent;
|
|
||||||
@@ -451,26 +454,52 @@ g_gdu_mount_can_eject (GMount *_mount)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
GMount *mount;
|
|
||||||
+
|
|
||||||
+ gchar **argv;
|
|
||||||
+ guint num_attempts_left;
|
|
||||||
+
|
|
||||||
GAsyncReadyCallback callback;
|
|
||||||
gpointer user_data;
|
|
||||||
GCancellable *cancellable;
|
|
||||||
+
|
|
||||||
int error_fd;
|
|
||||||
GIOChannel *error_channel;
|
|
||||||
guint error_channel_source_id;
|
|
||||||
GString *error_string;
|
|
||||||
-} UnmountEjectOp;
|
|
||||||
+
|
|
||||||
+} UnmountOp;
|
|
||||||
+
|
|
||||||
+static gboolean unmount_attempt (UnmountOp *data);
|
|
||||||
|
|
||||||
static void
|
|
||||||
-eject_unmount_cb (GPid pid, gint status, gpointer user_data)
|
|
||||||
+unmount_cb (GPid pid, gint status, gpointer user_data)
|
|
||||||
{
|
|
||||||
- UnmountEjectOp *data = user_data;
|
|
||||||
+ UnmountOp *data = user_data;
|
|
||||||
GSimpleAsyncResult *simple;
|
|
||||||
|
|
||||||
+ g_spawn_close_pid (pid);
|
|
||||||
+
|
|
||||||
if (WEXITSTATUS (status) != 0)
|
|
||||||
{
|
|
||||||
GError *error;
|
|
||||||
+ gint error_code;
|
|
||||||
+
|
|
||||||
+ error_code = G_IO_ERROR_FAILED;
|
|
||||||
+ /* we may want to add more strstr() checks here depending on what unmount helper is being used etc... */
|
|
||||||
+ if (data->error_string->str != NULL && strstr (data->error_string->str, "is busy") != NULL)
|
|
||||||
+ error_code = G_IO_ERROR_BUSY;
|
|
||||||
+
|
|
||||||
+ if (error_code == G_IO_ERROR_BUSY && data->num_attempts_left > 0)
|
|
||||||
+ {
|
|
||||||
+ g_timeout_add (BUSY_UNMOUNT_MS_DELAY_BETWEEN_ATTEMPTS,
|
|
||||||
+ (GSourceFunc) unmount_attempt,
|
|
||||||
+ data);
|
|
||||||
+ data->num_attempts_left -= 1;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
error = g_error_new_literal (G_IO_ERROR,
|
|
||||||
- G_IO_ERROR_FAILED,
|
|
||||||
+ error_code,
|
|
||||||
data->error_string->str);
|
|
||||||
simple = g_simple_async_result_new_from_error (G_OBJECT (data->mount),
|
|
||||||
data->callback,
|
|
||||||
@@ -493,16 +522,19 @@ eject_unmount_cb (GPid pid, gint status, gpointer user_data)
|
|
||||||
g_io_channel_unref (data->error_channel);
|
|
||||||
g_string_free (data->error_string, TRUE);
|
|
||||||
close (data->error_fd);
|
|
||||||
- g_spawn_close_pid (pid);
|
|
||||||
+ g_strfreev (data->argv);
|
|
||||||
g_free (data);
|
|
||||||
+
|
|
||||||
+ out:
|
|
||||||
+ ;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
-eject_unmount_read_error (GIOChannel *channel,
|
|
||||||
- GIOCondition condition,
|
|
||||||
- gpointer user_data)
|
|
||||||
+unmount_read_error (GIOChannel *channel,
|
|
||||||
+ GIOCondition condition,
|
|
||||||
+ gpointer user_data)
|
|
||||||
{
|
|
||||||
- UnmountEjectOp *data = user_data;
|
|
||||||
+ UnmountOp *data = user_data;
|
|
||||||
gchar buf[BUFSIZ];
|
|
||||||
gsize bytes_read;
|
|
||||||
GError *error;
|
|
||||||
@@ -532,26 +564,15 @@ read:
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void
|
|
||||||
-eject_unmount_do (GMount *mount,
|
|
||||||
- GCancellable *cancellable,
|
|
||||||
- GAsyncReadyCallback callback,
|
|
||||||
- gpointer user_data,
|
|
||||||
- char **argv)
|
|
||||||
+static gboolean
|
|
||||||
+unmount_attempt (UnmountOp *data)
|
|
||||||
{
|
|
||||||
- UnmountEjectOp *data;
|
|
||||||
GPid child_pid;
|
|
||||||
GError *error;
|
|
||||||
|
|
||||||
- data = g_new0 (UnmountEjectOp, 1);
|
|
||||||
- data->mount = mount;
|
|
||||||
- data->callback = callback;
|
|
||||||
- data->user_data = user_data;
|
|
||||||
- data->cancellable = cancellable;
|
|
||||||
-
|
|
||||||
error = NULL;
|
|
||||||
if (!g_spawn_async_with_pipes (NULL, /* working dir */
|
|
||||||
- argv,
|
|
||||||
+ data->argv,
|
|
||||||
NULL, /* envp */
|
|
||||||
G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH,
|
|
||||||
NULL, /* child_setup */
|
|
||||||
@@ -572,8 +593,8 @@ eject_unmount_do (GMount *mount,
|
|
||||||
if (error != NULL)
|
|
||||||
goto handle_error;
|
|
||||||
|
|
||||||
- data->error_channel_source_id = g_io_add_watch (data->error_channel, G_IO_IN, eject_unmount_read_error, data);
|
|
||||||
- g_child_watch_add (child_pid, eject_unmount_cb, data);
|
|
||||||
+ data->error_channel_source_id = g_io_add_watch (data->error_channel, G_IO_IN, unmount_read_error, data);
|
|
||||||
+ g_child_watch_add (child_pid, unmount_cb, data);
|
|
||||||
|
|
||||||
handle_error:
|
|
||||||
|
|
||||||
@@ -596,6 +617,28 @@ handle_error:
|
|
||||||
g_error_free (error);
|
|
||||||
g_free (data);
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ return FALSE;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+unmount_do (GMount *mount,
|
|
||||||
+ GCancellable *cancellable,
|
|
||||||
+ GAsyncReadyCallback callback,
|
|
||||||
+ gpointer user_data,
|
|
||||||
+ char **argv)
|
|
||||||
+{
|
|
||||||
+ UnmountOp *data;
|
|
||||||
+
|
|
||||||
+ data = g_new0 (UnmountOp, 1);
|
|
||||||
+ data->mount = mount;
|
|
||||||
+ data->callback = callback;
|
|
||||||
+ data->user_data = user_data;
|
|
||||||
+ data->cancellable = cancellable;
|
|
||||||
+ data->num_attempts_left = BUSY_UNMOUNT_NUM_ATTEMPTS;
|
|
||||||
+ data->argv = g_strdupv (argv);
|
|
||||||
+
|
|
||||||
+ unmount_attempt (data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
|
||||||
@@ -619,19 +662,54 @@ luks_lock_cb (GduDevice *device,
|
|
||||||
g_object_unref (simple);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static gboolean gdu_unmount_attempt (GSimpleAsyncResult *simple);
|
|
||||||
+
|
|
||||||
static void
|
|
||||||
-unmount_cb (GduDevice *device,
|
|
||||||
- GError *error,
|
|
||||||
- gpointer user_data)
|
|
||||||
+gdu_unmount_cb (GduDevice *device,
|
|
||||||
+ GError *error,
|
|
||||||
+ gpointer user_data)
|
|
||||||
{
|
|
||||||
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
|
|
||||||
|
|
||||||
if (error != NULL)
|
|
||||||
{
|
|
||||||
+ gint error_code;
|
|
||||||
+
|
|
||||||
+ /*g_debug ("domain=%s error_code=%d '%s'", g_quark_to_string (error->domain), error->code, error->message);*/
|
|
||||||
+
|
|
||||||
+ error_code = G_IO_ERROR_FAILED;
|
|
||||||
+ if (error->domain == GDU_ERROR && error->code == GDU_ERROR_BUSY)
|
|
||||||
+ error_code = G_IO_ERROR_BUSY;
|
|
||||||
+
|
|
||||||
/* We could handle PolicyKit integration here but this action is allowed by default
|
|
||||||
* and this won't be needed when porting to PolicyKit 1.0 anyway
|
|
||||||
*/
|
|
||||||
- g_simple_async_result_set_from_error (simple, error);
|
|
||||||
+
|
|
||||||
+ if (error_code == G_IO_ERROR_BUSY)
|
|
||||||
+ {
|
|
||||||
+ guint num_attempts_left;
|
|
||||||
+
|
|
||||||
+ num_attempts_left = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (simple), "num-attempts-left"));
|
|
||||||
+
|
|
||||||
+ if (num_attempts_left > 0)
|
|
||||||
+ {
|
|
||||||
+ num_attempts_left -= 1;
|
|
||||||
+ g_object_set_data (G_OBJECT (simple),
|
|
||||||
+ "num-attempts-left",
|
|
||||||
+ GUINT_TO_POINTER (num_attempts_left));
|
|
||||||
+
|
|
||||||
+ g_timeout_add (BUSY_UNMOUNT_MS_DELAY_BETWEEN_ATTEMPTS,
|
|
||||||
+ (GSourceFunc) gdu_unmount_attempt,
|
|
||||||
+ simple);
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ g_simple_async_result_set_error (simple,
|
|
||||||
+ G_IO_ERROR,
|
|
||||||
+ error_code,
|
|
||||||
+ "%s",
|
|
||||||
+ error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
g_simple_async_result_complete (simple);
|
|
||||||
g_object_unref (simple);
|
|
||||||
@@ -687,6 +765,17 @@ unmount_cb (GduDevice *device,
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static gboolean
|
|
||||||
+gdu_unmount_attempt (GSimpleAsyncResult *simple)
|
|
||||||
+{
|
|
||||||
+ GduDevice *device;
|
|
||||||
+
|
|
||||||
+ /* TODO: honor flags */
|
|
||||||
+ device = g_object_get_data (G_OBJECT (simple), "gdu-device");
|
|
||||||
+ gdu_device_op_filesystem_unmount (device, gdu_unmount_cb, simple);
|
|
||||||
+ return FALSE;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void
|
|
||||||
g_gdu_mount_unmount (GMount *_mount,
|
|
||||||
GMountUnmountFlags flags,
|
|
||||||
@@ -698,6 +787,21 @@ g_gdu_mount_unmount (GMount *_mount,
|
|
||||||
GSimpleAsyncResult *simple;
|
|
||||||
GduPresentable *gdu_volume;
|
|
||||||
|
|
||||||
+ /* emit the ::mount-pre-unmount signal */
|
|
||||||
+ g_signal_emit_by_name (mount->volume_monitor, "mount-pre-unmount", mount);
|
|
||||||
+
|
|
||||||
+ /* If we end up with G_IO_ERROR_BUSY, try again BUSY_UNMOUNT_NUM_ATTEMPTS times
|
|
||||||
+ * waiting BUSY_UNMOUNT_MS_DELAY_BETWEEN_ATTEMPTS milliseconds between each
|
|
||||||
+ * attempt.
|
|
||||||
+ *
|
|
||||||
+ * This is to give other processes recieving the ::mount-pre-unmount signal some
|
|
||||||
+ * time to close file descriptors.
|
|
||||||
+ *
|
|
||||||
+ * TODO: Unfortunately this code is a bit messy because we take two different
|
|
||||||
+ * codepaths depending on whether we use GDU or the native unmount command.
|
|
||||||
+ * It would be good to clean this up.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
gdu_volume = NULL;
|
|
||||||
if (mount->volume != NULL)
|
|
||||||
gdu_volume = g_gdu_volume_get_presentable_with_cleartext (mount->volume);
|
|
||||||
@@ -713,7 +817,7 @@ g_gdu_mount_unmount (GMount *_mount,
|
|
||||||
else
|
|
||||||
argv[1] = mount->device_file;
|
|
||||||
|
|
||||||
- eject_unmount_do (_mount, cancellable, callback, user_data, argv);
|
|
||||||
+ unmount_do (_mount, cancellable, callback, user_data, argv);
|
|
||||||
}
|
|
||||||
else if (gdu_volume != NULL)
|
|
||||||
{
|
|
||||||
@@ -722,6 +826,10 @@ g_gdu_mount_unmount (GMount *_mount,
|
|
||||||
user_data,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
+ g_object_set_data (G_OBJECT (simple),
|
|
||||||
+ "num-attempts-left",
|
|
||||||
+ GUINT_TO_POINTER (BUSY_UNMOUNT_NUM_ATTEMPTS));
|
|
||||||
+
|
|
||||||
if (mount->is_burn_mount)
|
|
||||||
{
|
|
||||||
/* burn mounts are really never mounted... */
|
|
||||||
@@ -731,12 +839,9 @@ g_gdu_mount_unmount (GMount *_mount,
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GduDevice *device;
|
|
||||||
-
|
|
||||||
- /* TODO: honor flags */
|
|
||||||
-
|
|
||||||
device = gdu_presentable_get_device (gdu_volume);
|
|
||||||
- gdu_device_op_filesystem_unmount (device, unmount_cb, simple);
|
|
||||||
- g_object_unref (device);
|
|
||||||
+ g_object_set_data_full (G_OBJECT (simple), "gdu-device", device, g_object_unref);
|
|
||||||
+ gdu_unmount_attempt (simple);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
@@ -760,6 +865,8 @@ g_gdu_mount_unmount_finish (GMount *mount,
|
|
||||||
return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
|
|
||||||
}
|
|
||||||
|
|
||||||
+/* ---------------------------------------------------------------------------------------------------- */
|
|
||||||
+
|
|
||||||
typedef struct {
|
|
||||||
GObject *object;
|
|
||||||
GAsyncReadyCallback callback;
|
|
||||||
--
|
|
||||||
1.6.2.2
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
|||||||
From 2bce9f36bd365be284c10af6a1f74c6120adc3e8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Zeuthen <davidz@redhat.com>
|
|
||||||
Date: Wed, 15 Apr 2009 11:33:36 -0400
|
|
||||||
Subject: [PATCH 12/13] use new gnome-disk-utility API to hide unwanted devices
|
|
||||||
|
|
||||||
This is to resolve bugs like
|
|
||||||
|
|
||||||
https://bugzilla.redhat.com/show_bug.cgi?id=495170
|
|
||||||
---
|
|
||||||
monitor/gdu/ggduvolumemonitor.c | 12 ++++++++++++
|
|
||||||
1 files changed, 12 insertions(+), 0 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/monitor/gdu/ggduvolumemonitor.c b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
index 67e2ec0..2c1f727 100644
|
|
||||||
--- a/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
+++ b/monitor/gdu/ggduvolumemonitor.c
|
|
||||||
@@ -720,6 +720,12 @@ should_mount_be_ignored (GduPool *pool, GduDevice *d)
|
|
||||||
|
|
||||||
ret = FALSE;
|
|
||||||
|
|
||||||
+ if (gdu_device_get_presentation_hide (d))
|
|
||||||
+ {
|
|
||||||
+ ret = TRUE;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
mount_path = gdu_device_get_mount_path (d);
|
|
||||||
if (mount_path == NULL || strlen (mount_path) == 0)
|
|
||||||
goto out;
|
|
||||||
@@ -751,6 +757,9 @@ should_volume_be_ignored (GduPool *pool, GduVolume *volume, GList *fstab_mount_p
|
|
||||||
|
|
||||||
device = gdu_presentable_get_device (GDU_PRESENTABLE (volume));
|
|
||||||
|
|
||||||
+ if (gdu_device_get_presentation_hide (device))
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
usage = gdu_device_id_get_usage (device);
|
|
||||||
type = gdu_device_id_get_type (device);
|
|
||||||
|
|
||||||
@@ -824,6 +833,9 @@ should_drive_be_ignored (GduPool *pool, GduDrive *d, GList *fstab_mount_points)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (gdu_device_get_presentation_hide (device))
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
has_volumes = FALSE;
|
|
||||||
all_volumes_are_ignored = TRUE;
|
|
||||||
|
|
||||||
--
|
|
||||||
1.6.2.2
|
|
||||||
|
|
@ -1,99 +0,0 @@
|
|||||||
From 7fd9061afbd0ec4664adb17aed706e12fd5f3eee Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Zeuthen <davidz@redhat.com>
|
|
||||||
Date: Wed, 15 Apr 2009 14:41:27 -0400
|
|
||||||
Subject: [PATCH 13/13] pass the 'flush' mount option for vfat
|
|
||||||
|
|
||||||
This mount option makes the vfat filesystem driver flush data more
|
|
||||||
often. As a consequence
|
|
||||||
|
|
||||||
1. users never get to see the gnome-disk-utility notification daemon
|
|
||||||
dialog just added
|
|
||||||
|
|
||||||
http://people.freedesktop.org/~david/gdu-unmount-busy-1.png
|
|
||||||
|
|
||||||
but that's useful for other filesystems as well.
|
|
||||||
|
|
||||||
2. The Nautilus copy dialog stays up until things are on the disk
|
|
||||||
|
|
||||||
We do this in gvfs rather than DeviceKit-disks because in some
|
|
||||||
scenarios 'flush' may be unwanted and there is currently no way to
|
|
||||||
turn it off (e.g. no 'noflush' or 'flush=0' option).
|
|
||||||
|
|
||||||
Ideally the kernel would get this kind of thing right by itself.
|
|
||||||
---
|
|
||||||
monitor/gdu/ggduvolume.c | 36 +++++++++++++++++++++++++++++++++---
|
|
||||||
1 files changed, 33 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/monitor/gdu/ggduvolume.c b/monitor/gdu/ggduvolume.c
|
|
||||||
index 49494a1..871a1c5 100644
|
|
||||||
--- a/monitor/gdu/ggduvolume.c
|
|
||||||
+++ b/monitor/gdu/ggduvolume.c
|
|
||||||
@@ -648,6 +648,27 @@ g_gdu_volume_get_mount (GVolume *volume)
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
+static gchar **
|
|
||||||
+get_mount_options (GduDevice *device)
|
|
||||||
+{
|
|
||||||
+ gchar **ret;
|
|
||||||
+
|
|
||||||
+ /* one day we might read this from user settings */
|
|
||||||
+ if (g_strcmp0 (gdu_device_id_get_usage (device), "filesystem") == 0 &&
|
|
||||||
+ g_strcmp0 (gdu_device_id_get_type (device), "vfat") == 0)
|
|
||||||
+ {
|
|
||||||
+ ret = g_new0 (gchar *, 2);
|
|
||||||
+ ret[0] = g_strdup ("flush");
|
|
||||||
+ ret[1] = NULL;
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ ret = NULL;
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/* ---------------------------------------------------------------------------------------------------- */
|
|
||||||
+
|
|
||||||
struct MountOpData
|
|
||||||
{
|
|
||||||
GGduVolume *volume;
|
|
||||||
@@ -735,8 +756,11 @@ mount_obtain_authz_cb (GObject *source_object,
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
+ gchar **mount_options;
|
|
||||||
/* got the authz, now try again */
|
|
||||||
- gdu_device_op_filesystem_mount (data->device_to_mount, mount_cb, data);
|
|
||||||
+ mount_options = get_mount_options (data->device_to_mount);
|
|
||||||
+ gdu_device_op_filesystem_mount (data->device_to_mount, mount_options, mount_cb, data);
|
|
||||||
+ g_strfreev (mount_options);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -842,7 +866,10 @@ mount_cleartext_device (MountOpData *data,
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
- gdu_device_op_filesystem_mount (data->device_to_mount, mount_cb, data);
|
|
||||||
+ gchar **mount_options;
|
|
||||||
+ mount_options = get_mount_options (data->device_to_mount);
|
|
||||||
+ gdu_device_op_filesystem_mount (data->device_to_mount, mount_options, mount_cb, data);
|
|
||||||
+ g_strfreev (mount_options);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref (pool);
|
|
||||||
@@ -1260,8 +1287,11 @@ g_gdu_volume_mount (GVolume *_volume,
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
+ gchar **mount_options;
|
|
||||||
data->device_to_mount = g_object_ref (device);
|
|
||||||
- gdu_device_op_filesystem_mount (data->device_to_mount, mount_cb, data);
|
|
||||||
+ mount_options = get_mount_options (data->device_to_mount);
|
|
||||||
+ gdu_device_op_filesystem_mount (data->device_to_mount, mount_options, mount_cb, data);
|
|
||||||
+ g_strfreev (mount_options);
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
--
|
|
||||||
1.6.2.2
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
|||||||
From 5073d2736d6a83de04e749ae5952071da3d1ccbc Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tomas Bzatek <tbzatek@redhat.com>
|
|
||||||
Date: Tue, 12 May 2009 15:17:06 +0200
|
|
||||||
Subject: [PATCH 4/4] CDDA: allow query well-formed filenames only
|
|
||||||
|
|
||||||
This will check for ".wav" suffix as long as sscanf()
|
|
||||||
doesn't care of the rest of the formatting string after
|
|
||||||
last placeholder. Querying filenames like
|
|
||||||
"Track 10.nonsense" will now throw an error.
|
|
||||||
|
|
||||||
Partially fixes https://bugzilla.redhat.com/show_bug.cgi?id=499266
|
|
||||||
---
|
|
||||||
daemon/gvfsbackendcdda.c | 3 ++-
|
|
||||||
1 files changed, 2 insertions(+), 1 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/daemon/gvfsbackendcdda.c b/daemon/gvfsbackendcdda.c
|
|
||||||
index c97aa44..9b30753 100644
|
|
||||||
--- a/daemon/gvfsbackendcdda.c
|
|
||||||
+++ b/daemon/gvfsbackendcdda.c
|
|
||||||
@@ -460,7 +460,8 @@ get_track_num_from_name (GVfsBackendCdda *cdda_backend, const char *filename)
|
|
||||||
char *basename;
|
|
||||||
|
|
||||||
basename = g_path_get_basename (filename);
|
|
||||||
- if (sscanf (basename, "Track %d.wav", &n) == 1)
|
|
||||||
+ if (sscanf (basename, "Track %d.wav", &n) == 1 &&
|
|
||||||
+ g_str_has_suffix (basename, ".wav"))
|
|
||||||
{
|
|
||||||
g_free (basename);
|
|
||||||
return n;
|
|
||||||
--
|
|
||||||
1.6.2.2
|
|
||||||
|
|
33
gvfs.spec
33
gvfs.spec
@ -1,14 +1,14 @@
|
|||||||
Summary: Backends for the gio framework in GLib
|
Summary: Backends for the gio framework in GLib
|
||||||
Name: gvfs
|
Name: gvfs
|
||||||
Version: 1.3.1
|
Version: 1.3.1
|
||||||
Release: 1%{?dist}
|
Release: 2%{?dist}
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
Group: System Environment/Libraries
|
Group: System Environment/Libraries
|
||||||
URL: http://www.gtk.org
|
URL: http://www.gtk.org
|
||||||
Source: http://download.gnome.org/sources/gvfs/1.3/gvfs-%{version}.tar.bz2
|
Source: http://download.gnome.org/sources/gvfs/1.3/gvfs-%{version}.tar.bz2
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||||
BuildRequires: pkgconfig
|
BuildRequires: pkgconfig
|
||||||
BuildRequires: glib2-devel >= 2.19.2
|
BuildRequires: glib2-devel >= 2.21.2
|
||||||
BuildRequires: dbus-glib-devel
|
BuildRequires: dbus-glib-devel
|
||||||
BuildRequires: /usr/bin/ssh
|
BuildRequires: /usr/bin/ssh
|
||||||
BuildRequires: libcdio-devel >= 0.78.2
|
BuildRequires: libcdio-devel >= 0.78.2
|
||||||
@ -19,10 +19,10 @@ BuildRequires: gnome-keyring-devel
|
|||||||
BuildRequires: intltool
|
BuildRequires: intltool
|
||||||
BuildRequires: gettext-devel
|
BuildRequires: gettext-devel
|
||||||
BuildRequires: GConf2-devel
|
BuildRequires: GConf2-devel
|
||||||
BuildRequires: gnome-disk-utility-devel >= 0.3
|
BuildRequires: gnome-disk-utility-devel >= 0.4
|
||||||
# This is a hack until the xfce4-notifyd dependency issue is fixed
|
# This is a hack until the xfce4-notifyd dependency issue is fixed
|
||||||
# https://fedorahosted.org/rel-eng/ticket/1788
|
# https://fedorahosted.org/rel-eng/ticket/1788
|
||||||
BuildRequires: notification-daemon
|
#BuildRequires: notification-daemon
|
||||||
|
|
||||||
|
|
||||||
Requires(post): desktop-file-utils
|
Requires(post): desktop-file-utils
|
||||||
@ -40,6 +40,18 @@ Patch8: gvfs-1.2.2-dnssd-deadlock.patch
|
|||||||
# https://bugzilla.redhat.com/show_bug.cgi?id=504339
|
# https://bugzilla.redhat.com/show_bug.cgi?id=504339
|
||||||
Patch9: gvfs-1.2.3-sftp-40sec-timeout.patch
|
Patch9: gvfs-1.2.3-sftp-40sec-timeout.patch
|
||||||
|
|
||||||
|
|
||||||
|
# Backports from trunk
|
||||||
|
Patch100: 0001-FTP-prepare-the-code-for-active-FTP-support.patch
|
||||||
|
Patch101: 0002-FTP-Bug-516704-Be-able-to-connect-to-an-Active-FTP-S.patch
|
||||||
|
Patch102: 0004-FTP-add-the-error-code-for-EPRT-s-522-error.patch
|
||||||
|
Patch103: 0005-FTP-add-EPRT-support.patch
|
||||||
|
Patch104: 0006-Bug-582772-gvfsd-computer-crashes-with-SEGSEV-in-rec.patch
|
||||||
|
Patch105: 0007-Better-handling-of-PC-floppy-drives.patch
|
||||||
|
Patch106: 0008-FTP-use-the-EPRT-feature-response-for-EPRT-support-n.patch
|
||||||
|
Patch107: 0009-FTP-remove-EPSV-as-default-feature.patch
|
||||||
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
The gvfs package provides backend implementations for the gio
|
The gvfs package provides backend implementations for the gio
|
||||||
framework in GLib. It includes ftp, sftp, cifs.
|
framework in GLib. It includes ftp, sftp, cifs.
|
||||||
@ -126,6 +138,15 @@ media players (Media Transfer Protocol) to applications using gvfs.
|
|||||||
%patch8 -p1 -b .dnssd-deadlock
|
%patch8 -p1 -b .dnssd-deadlock
|
||||||
%patch9 -p1 -b .sftp-timeout
|
%patch9 -p1 -b .sftp-timeout
|
||||||
|
|
||||||
|
%patch100 -p1
|
||||||
|
%patch101 -p1
|
||||||
|
%patch102 -p1
|
||||||
|
%patch103 -p1
|
||||||
|
%patch104 -p1
|
||||||
|
%patch105 -p1
|
||||||
|
%patch106 -p1
|
||||||
|
%patch107 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
|
|
||||||
# Needed for gvfs-0.2.1-archive-integration.patch
|
# Needed for gvfs-0.2.1-archive-integration.patch
|
||||||
@ -268,6 +289,10 @@ update-desktop-database &> /dev/null ||:
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Jun 22 2009 Tomas Bzatek <tbzatek@redhat.com> - 1.3.1-2
|
||||||
|
- Bump version requirements
|
||||||
|
- Backport FTP and Computer backend patches from master
|
||||||
|
|
||||||
* Mon Jun 15 2009 Matthias Clasen <mclasen@redhat.com> - 1.3.1-1
|
* Mon Jun 15 2009 Matthias Clasen <mclasen@redhat.com> - 1.3.1-1
|
||||||
- Update to 1.3.1
|
- Update to 1.3.1
|
||||||
- Drop obsolete patches
|
- Drop obsolete patches
|
||||||
|
Loading…
Reference in New Issue
Block a user