gvfs r2349 - in trunk: . daemon
- From: alexl svn gnome org
- To: svn-commits-list gnome org
- Subject: gvfs r2349 - in trunk: . daemon
- Date: Tue, 24 Mar 2009 11:01:06 +0000 (UTC)
Author: alexl
Date: Tue Mar 24 11:01:06 2009
New Revision: 2349
URL: http://svn.gnome.org/viewvc/gvfs?rev=2349&view=rev
Log:
2009-03-24 Alexander Larsson <alexl redhat com>
* daemon/gvfsbackendsftp.c:
Fix reporting of "not found" or "not directory" errors when
sftp returns NOT_FOUND, since that can mean either of these.
Modified:
trunk/ChangeLog
trunk/daemon/gvfsbackendsftp.c
Modified: trunk/daemon/gvfsbackendsftp.c
==============================================================================
--- trunk/daemon/gvfsbackendsftp.c (original)
+++ trunk/daemon/gvfsbackendsftp.c Tue Mar 24 11:01:06 2009
@@ -1730,6 +1730,11 @@
return res;
}
+static guint32
+read_status_code (GDataInputStream *status_reply)
+{
+ return g_data_input_stream_read_uint32 (status_reply, NULL, NULL);
+}
static gboolean
error_from_status (GVfsJob *job,
@@ -1740,7 +1745,7 @@
{
guint32 code;
- code = g_data_input_stream_read_uint32 (reply, NULL, NULL);
+ code = read_status_code (reply);
return error_from_status_code (job, code,
failure_error, allowed_sftp_error,
@@ -1816,7 +1821,7 @@
stat_error = 0;
info = NULL;
if (reply_type == SSH_FXP_STATUS)
- stat_error = g_data_input_stream_read_uint32 (reply, NULL, NULL);
+ stat_error = read_status_code (reply);
else if (reply_type == SSH_FXP_ATTRS)
{
info = g_file_info_new ();
@@ -1846,7 +1851,7 @@
static void
error_from_lstat (GVfsBackendSftp *backend,
GVfsJob *job,
- GDataInputStream *original_reply,
+ guint32 original_error,
const char *path,
ErrorFromStatCallback callback,
gpointer user_data)
@@ -1859,7 +1864,7 @@
put_string (command, path);
data = g_slice_new (ErrorFromStatData);
- data->original_error = g_data_input_stream_read_uint32 (original_reply, NULL, NULL);
+ data->original_error = original_error;
data->callback = callback;
data->user_data = user_data;
queue_command_stream_and_free (op_backend, command, error_from_lstat_reply,
@@ -2731,6 +2736,71 @@
return TRUE;
}
+static void not_dir_or_not_exist_error (GVfsBackendSftp *backend,
+ GVfsJob *job,
+ char *filename);
+
+static void
+not_dir_or_not_exist_error_cb (GVfsBackendSftp *backend,
+ GVfsJob *job,
+ gint original_error,
+ gint stat_error,
+ GFileInfo *info,
+ gpointer user_data)
+{
+ char *path;
+
+ path = user_data;
+ if (info != NULL)
+ {
+ if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
+ /* Parent is a directory, so must not have found child */
+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+ _("No such file or directory"));
+ else /* Some path element was not a directory */
+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY,
+ _("Not a directory"));
+ }
+ else if (stat_error == SSH_FX_NO_SUCH_FILE)
+ {
+ not_dir_or_not_exist_error (backend, job, path);
+ }
+ else
+ {
+ /* Some other weird error, lets say "not found" */
+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+ _("No such file or directory"));
+ }
+
+ g_free (path);
+}
+
+static void
+not_dir_or_not_exist_error (GVfsBackendSftp *backend,
+ GVfsJob *job,
+ char *filename)
+{
+ char *parent;
+
+ parent = g_path_get_dirname (filename);
+ if (strcmp (parent, ".") == 0)
+ {
+ g_free (parent);
+ /* Root not found? Weird, but at least not
+ NOT_DIRECTORY, so lets report not found */
+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+ _("No such file or directory"));
+ return;
+ }
+
+ error_from_lstat (backend,
+ job,
+ SSH_FX_NO_SUCH_FILE,
+ filename,
+ not_dir_or_not_exist_error_cb,
+ parent);
+}
+
static void
create_reply (GVfsBackendSftp *backend,
int reply_type,
@@ -2740,10 +2810,22 @@
gpointer user_data)
{
SftpHandle *handle;
+ guint32 code;
if (reply_type == SSH_FXP_STATUS)
{
- result_from_status (job, reply, G_IO_ERROR_EXISTS, -1);
+ code = read_status_code (reply);
+
+ if (code == SSH_FX_NO_SUCH_FILE)
+ {
+ /* openssh sftp returns NO_SUCH_FILE for both ENOTDIR and ENOENT,
+ we need to stat-walk the hierarchy to see what the error was */
+ not_dir_or_not_exist_error (backend, job,
+ G_VFS_JOB_OPEN_FOR_WRITE (job)->filename);
+ return;
+ }
+
+ result_from_status_code (job, code, G_IO_ERROR_EXISTS, -1);
return;
}
@@ -2798,6 +2880,14 @@
return;
}
+ if (original_error == SSH_FX_NO_SUCH_FILE)
+ {
+ not_dir_or_not_exist_error (backend, job,
+ G_VFS_JOB_OPEN_FOR_WRITE (job)->filename);
+ return;
+ }
+
+
result_from_status_code (job, original_error, -1, -1);
}
@@ -2813,7 +2903,7 @@
if (reply_type == SSH_FXP_STATUS)
{
- error_from_lstat (backend, job, reply,
+ error_from_lstat (backend, job, read_status_code (reply),
G_VFS_JOB_OPEN_FOR_WRITE (job)->filename,
append_to_error,
NULL);
@@ -3193,6 +3283,13 @@
/* Open should not return OK */
g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_FAILED,
_("Invalid reply received"));
+ else if (error->code == G_IO_ERROR_NOT_FOUND)
+ {
+ g_error_free (error);
+ /* openssh sftp returns NO_SUCH_FILE for ENOTDIR */
+ not_dir_or_not_exist_error (backend, job,
+ G_VFS_JOB_OPEN_FOR_WRITE (job)->filename);
+ }
else if (error->code == G_IO_ERROR_EXISTS)
{
/* It was *probably* the EXCL flag failing. I wish we had
@@ -3616,7 +3713,7 @@
if (reply_type == SSH_FXP_STATUS)
{
- error_from_lstat (backend, job, reply,
+ error_from_lstat (backend, job, read_status_code (reply),
G_VFS_JOB_ENUMERATE (job)->filename,
open_dir_error,
NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]