-import tempfile
+from types import NoneType
+
from zope.interface import implements
from twisted.application import service, strports
from twisted.internet import defer
from allmydata.interfaces import IDirectoryNode, ExistingChildError, \
NoSuchChildError
from allmydata.immutable.upload import FileHandle
+from allmydata.util.fileutil import EncryptedTemporaryFile
+from allmydata.util.assertutil import precondition
class ReadFile:
implements(ftp.IReadFile)
raise NotImplementedError("Non-streaming producer not supported.")
# we write the data to a temporary file, since Tahoe can't do
# streaming upload yet.
- self.f = tempfile.TemporaryFile()
+ self.f = EncryptedTemporaryFile()
return None
def unregisterProducer(self):
if isdir:
value = 0
else:
- value = childnode.get_size()
+ value = childnode.get_size() or 0
elif key == "directory":
value = isdir
elif key == "permissions":
elif key == "hardlinks":
value = 1
elif key == "modified":
- value = metadata.get("mtime", 0)
+ # follow sftpd convention (i.e. linkmotime in preference to mtime)
+ if "linkmotime" in metadata.get("tahoe", {}):
+ value = metadata["tahoe"]["linkmotime"]
+ else:
+ value = metadata.get("mtime", 0)
elif key == "owner":
value = self.username
elif key == "group":
d.addCallback(_got_parent)
return d
-from auth import AccountURLChecker, AccountFileChecker, NeedRootcapLookupScheme
+from allmydata.frontends.auth import AccountURLChecker, AccountFileChecker, NeedRootcapLookupScheme
class Dispatcher:
class FTPServer(service.MultiService):
def __init__(self, client, accountfile, accounturl, ftp_portstr):
+ precondition(isinstance(accountfile, (unicode, NoneType)), accountfile)
service.MultiService.__init__(self)
- # make sure we're using a patched Twisted that uses IWriteFile.close:
- # see docs/frontends/FTP-and-SFTP.txt and
- # http://twistedmatrix.com/trac/ticket/3462 for details.
- if "close" not in ftp.IWriteFile.names():
- raise AssertionError("your twisted is lacking a vital patch, see docs/frontends/FTP-and-SFTP.txt")
-
r = Dispatcher(client)
p = portal.Portal(r)