From 8d118e28f17d7b7f2aa18ba8e0bd55b7383fc92f Mon Sep 17 00:00:00 2001
From: david-sarah <david-sarah@jacaranda.org>
Date: Mon, 17 May 2010 17:42:05 -0700
Subject: [PATCH] SFTP: change error code returned for ExistingChildError to
 FX_FAILURE (fixes gvfs with some picky programs such as gedit).

---
 src/allmydata/frontends/sftpd.py | 12 ++++++++++--
 src/allmydata/test/test_sftp.py  |  2 +-
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/src/allmydata/frontends/sftpd.py b/src/allmydata/frontends/sftpd.py
index e978c508..eb172c95 100644
--- a/src/allmydata/frontends/sftpd.py
+++ b/src/allmydata/frontends/sftpd.py
@@ -107,10 +107,18 @@ def _raise_error(err):
     if err.check(NoSuchChildError):
         childname = err.value.args[0].encode('utf-8')
         raise SFTPError(FX_NO_SUCH_FILE, childname)
-    if err.check(ExistingChildError) or err.check(NotWriteableError):
-        # later versions of SFTP define FX_FILE_ALREADY_EXISTS, but version 3 doesn't
+    if err.check(NotWriteableError):
         msg = err.value.args[0].encode('utf-8')
         raise SFTPError(FX_PERMISSION_DENIED, msg)
+    if err.check(ExistingChildError):
+        # Versions of SFTP after v3 (which is what twisted.conch implements)
+        # define a specific error code for this case: FX_FILE_ALREADY_EXISTS.
+        # However v3 doesn't; instead, other servers such as sshd return
+        # FX_FAILURE. The gvfs SFTP backend, for example, depends on this
+        # to translate the error to the equivalent of POSIX EEXIST, which is
+        # necessary for some picky programs (such as gedit).
+        msg = err.value.args[0].encode('utf-8')
+        raise SFTPError(FX_FAILURE, msg)
     if err.check(NotImplementedError):
         raise SFTPError(FX_OP_UNSUPPORTED, str(err.value))
     if err.check(EOFError):
diff --git a/src/allmydata/test/test_sftp.py b/src/allmydata/test/test_sftp.py
index 51a9f962..c6b1fa06 100644
--- a/src/allmydata/test/test_sftp.py
+++ b/src/allmydata/test/test_sftp.py
@@ -234,7 +234,7 @@ class Handler(GridTestMixin, ShouldFailMixin, unittest.TestCase):
             self.shouldFailWithSFTPError(sftp.FX_NO_SUCH_FILE, "_raise_error NoSuchChildError",
                                          sftpd._raise_error, Failure(NoSuchChildError("foo"))))
         d.addCallback(lambda ign:
-            self.shouldFailWithSFTPError(sftp.FX_PERMISSION_DENIED, "_raise_error ExistingChildError",
+            self.shouldFailWithSFTPError(sftp.FX_FAILURE, "_raise_error ExistingChildError",
                                          sftpd._raise_error, Failure(ExistingChildError("foo"))))
         d.addCallback(lambda ign:
             self.shouldFailWithSFTPError(sftp.FX_PERMISSION_DENIED, "_raise_error NotWriteableError",
-- 
2.45.2