Commit 515ece56 authored by ibuler's avatar ibuler

[Update] 修改sftp

parent 93783dad
...@@ -103,6 +103,13 @@ class StubSFTPServer(SFTPServerInterface): ...@@ -103,6 +103,13 @@ class StubSFTPServer(SFTPServerInterface):
rpath = '/' + '/'.join(rpath) rpath = '/' + '/'.join(rpath)
return host, rpath return host, rpath
def get_sftp_rpath(self, path):
host, rpath = self.parse_path(path)
sftp = None
if host:
sftp = self.get_host_sftp(host)
return sftp, rpath
@staticmethod @staticmethod
def stat_host_dir(): def stat_host_dir():
tmp = tempfile.TemporaryDirectory() tmp = tempfile.TemporaryDirectory()
...@@ -115,16 +122,15 @@ class StubSFTPServer(SFTPServerInterface): ...@@ -115,16 +122,15 @@ class StubSFTPServer(SFTPServerInterface):
def list_folder(self, path): def list_folder(self, path):
print("Call list folder: {}".format(path)) print("Call list folder: {}".format(path))
host, rpath = self.parse_path(path)
output = [] output = []
if host == '': if path == "/":
for filename in self.hosts: for filename in self.hosts:
attr = self.stat_host_dir() attr = self.stat_host_dir()
attr.filename = filename attr.filename = filename
output.append(attr) output.append(attr)
else: else:
sftp = self.get_host_sftp(host) sftp, rpath = self.get_sftp_rpath(path)
file_list = sftp.listdir(rpath) file_list = sftp.listdir(rpath)
for filename in file_list: for filename in file_list:
attr = sftp.stat(os.path.join(rpath, filename)) attr = sftp.stat(os.path.join(rpath, filename))
...@@ -133,10 +139,9 @@ class StubSFTPServer(SFTPServerInterface): ...@@ -133,10 +139,9 @@ class StubSFTPServer(SFTPServerInterface):
return output return output
def stat(self, path): def stat(self, path):
host, *rpath = path.lstrip('/').split('/') host, rpath = self.parse_path(path)
rpath = '/' + '/'.join(rpath)
if host == '': if host and not rpath:
attr = self.stat_host_dir() attr = self.stat_host_dir()
attr.filename = host attr.filename = host
return attr return attr
...@@ -146,8 +151,7 @@ class StubSFTPServer(SFTPServerInterface): ...@@ -146,8 +151,7 @@ class StubSFTPServer(SFTPServerInterface):
def lstat(self, path): def lstat(self, path):
print("Call lstat: {}".format(path)) print("Call lstat: {}".format(path))
host, *rpath = path.lstrip('/').split('/') host, rpath = self.parse_path(path)
rpath = '/' + '/'.join(rpath)
if host == '': if host == '':
attr = self.stat_host_dir() attr = self.stat_host_dir()
...@@ -160,8 +164,7 @@ class StubSFTPServer(SFTPServerInterface): ...@@ -160,8 +164,7 @@ class StubSFTPServer(SFTPServerInterface):
def open(self, path, flags, attr): def open(self, path, flags, attr):
print("Call {}: {}**{}**{}".format("Open", path, flags, attr)) print("Call {}: {}**{}**{}".format("Open", path, flags, attr))
host, *rpath = path.lstrip('/').split('/') host, rpath = self.parse_path(path)
rpath = '/' + '/'.join(rpath)
binary_flag = getattr(os, 'O_BINARY', 0) binary_flag = getattr(os, 'O_BINARY', 0)
flags |= binary_flag flags |= binary_flag
...@@ -193,90 +196,50 @@ class StubSFTPServer(SFTPServerInterface): ...@@ -193,90 +196,50 @@ class StubSFTPServer(SFTPServerInterface):
def remove(self, path): def remove(self, path):
print("Call {}".format("Remove")) print("Call {}".format("Remove"))
path = self._realpath(path) sftp, rpath = self.get_sftp_rpath(path)
try:
os.remove(path) if sftp is not None:
except OSError as e: sftp.remove(rpath)
return SFTPServer.convert_errno(e.errno)
return SFTP_OK return SFTP_OK
def rename(self, oldpath, newpath): def rename(self, src, dest):
print("Call {}".format("Rename")) print("Call {}".format("Rename"))
oldpath = self._realpath(oldpath) host1, rsrc = self.parse_path(src)
newpath = self._realpath(newpath) host2, rdest = self.parse_path(dest)
try:
os.rename(oldpath, newpath) if host1 == host2 and host1:
except OSError as e: sftp = self.get_host_sftp(host2)
return SFTPServer.convert_errno(e.errno) sftp.rename(rsrc, rdest)
return SFTP_OK return SFTP_OK
def mkdir(self, path, attr): def mkdir(self, path, attr):
print("Call {}".format("Mkdir")) print("Call {}".format("Mkdir"))
path = self._realpath(path) sftp, rpath = self.get_sftp_rpath(path)
try: if sftp is not None:
os.mkdir(path) sftp.mkdir(rpath)
if attr is not None:
SFTPServer.set_file_attr(path, attr)
except OSError as e:
return SFTPServer.convert_errno(e.errno)
return SFTP_OK return SFTP_OK
def rmdir(self, path): def rmdir(self, path):
print("Call {}".format("Rmdir")) print("Call {}".format("Rmdir"))
path = self._realpath(path) sftp, rpath = self.get_sftp_rpath(path)
try: if sftp is not None:
os.rmdir(path) sftp.rmdir(rpath)
except OSError as e:
return SFTPServer.convert_errno(e.errno)
return SFTP_OK return SFTP_OK
def chattr(self, path, attr): def chattr(self, path, attr):
print("Call {}".format("Chattr")) print("Call {}".format("Chattr"))
path = self._realpath(path) sftp, rpath = self.get_sftp_rpath(path)
try: if sftp is not None:
SFTPServer.set_file_attr(path, attr) if attr._flags & attr.FLAG_PERMISSIONS:
except OSError as e: sftp.chmod(rpath, attr.st_mode)
return SFTPServer.convert_errno(e.errno) if attr._flags & attr.FLAG_UIDGID:
sftp.chown(rpath, attr.st_uid, attr.st_gid)
if attr._flags & attr.FLAG_AMTIME:
sftp.utime(rpath, (attr.st_atime, attr.st_mtime))
if attr._flags & attr.FLAG_SIZE:
sftp.truncate(rpath, attr.st_size)
return SFTP_OK return SFTP_OK
def symlink(self, target_path, path):
print("Call {}".format("Symlink"))
path = self._realpath(path)
if (len(target_path) > 0) and (target_path[0] == '/'):
# absolute symlink
target_path = os.path.join(self.ROOT, target_path[1:])
if target_path[:2] == '//':
# bug in os.path.join
target_path = target_path[1:]
else:
# compute relative to path
abspath = os.path.join(os.path.dirname(path), target_path)
if abspath[:len(self.ROOT)] != self.ROOT:
# this symlink isn't going to work anyway -- just break it immediately
target_path = '<error>'
try:
os.symlink(target_path, path)
except OSError as e:
return SFTPServer.convert_errno(e.errno)
return SFTP_OK
def readlink(self, path):
print("Call {}".format("Read link"))
path = self._realpath(path)
try:
symlink = os.readlink(path)
except OSError as e:
return SFTPServer.convert_errno(e.errno)
# if it's absolute, remove the root
if os.path.isabs(symlink):
if symlink[:len(self.ROOT)] == self.ROOT:
symlink = symlink[len(self.ROOT):]
if (len(symlink) == 0) or (symlink[0] != '/'):
symlink = '/' + symlink
else:
symlink = '<error>'
return symlink
HOST, PORT = 'localhost', 3373 HOST, PORT = 'localhost', 3373
BACKLOG = 10 BACKLOG = 10
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment