diff options
author | Robey Pointer <robey@lag.net> | 2004-09-11 20:56:01 +0000 |
---|---|---|
committer | Robey Pointer <robey@lag.net> | 2004-09-11 20:56:01 +0000 |
commit | 4cac30252a9aebccc87c76f5671a16d5b0b9b57a (patch) | |
tree | cc0b0ecb2686b6ca8b747a8f444acb49d57217db /paramiko/sftp.py | |
parent | 3a4ca74e0a16d07296fc51391d466819b2ca3dad (diff) | |
download | paramiko-4cac30252a9aebccc87c76f5671a16d5b0b9b57a.tar.gz |
[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-85]
move SFTPFile and SFTPAttributes into their own files
move SFTPFile and SFTPAttributes into their own files.
Diffstat (limited to 'paramiko/sftp.py')
-rw-r--r-- | paramiko/sftp.py | 264 |
1 files changed, 1 insertions, 263 deletions
diff --git a/paramiko/sftp.py b/paramiko/sftp.py index f7ed3762..e9d23b25 100644 --- a/paramiko/sftp.py +++ b/paramiko/sftp.py @@ -18,12 +18,11 @@ # along with Paramiko; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -import struct, socket, stat, time +import struct, socket from common import * import util from channel import Channel from message import Message -from file import BufferedFile CMD_INIT, CMD_VERSION, CMD_OPEN, CMD_CLOSE, CMD_READ, CMD_WRITE, CMD_LSTAT, CMD_FSTAT, \ CMD_SETSTAT, CMD_FSETSTAT, CMD_OPENDIR, CMD_READDIR, CMD_REMOVE, CMD_MKDIR, \ @@ -56,271 +55,10 @@ FXF_EXCL = 0x20 _VERSION = 3 -class SFTPAttributes (object): - """ - Representation of the attributes of a file (or proxied file) for SFTP in - client or server mode. It attemps to mirror the object returned by - C{os.stat} as closely as possible, so it may have the following fields: - - st_size - - st_uid - - st_gid - - st_mode - - st_atime - - st_mtime - - Because SFTP allows flags to have other arbitrary named attributes, these - are stored in a dict named C{attr}. - """ - - FLAG_SIZE = 1 - FLAG_UIDGID = 2 - FLAG_PERMISSIONS = 4 - FLAG_AMTIME = 8 - FLAG_EXTENDED = 0x80000000L - - def __init__(self): - """ - Create a new (empty) SFTPAttributes object. All fields will be empty. - """ - self._flags = 0 - self.attr = {} - - def from_stat(cls, obj): - """ - Create an SFTPAttributes object from an existing C{stat} object (an - object returned by C{os.stat}). - - @param obj: an object returned by C{os.stat} (or equivalent). - @type obj: object - @return: new L{SFTPAttributes} object with the same attribute fields. - @rtype: L{SFTPAttributes} - """ - attr = cls() - attr.st_size = obj.st_size - attr.st_uid = obj.st_uid - attr.st_gid = obj.st_gid - attr.st_mode = obj.st_mode - attr.st_atime = obj.st_atime - attr.st_mtime = obj.st_mtime - return attr - from_stat = classmethod(from_stat) - - - ### internals... - - - def _from_msg(cls, msg): - attr = cls() - attr._unpack(msg) - return attr - _from_msg = classmethod(_from_msg) - - def _unpack(self, msg): - self._flags = msg.get_int() - if self._flags & self.FLAG_SIZE: - self.st_size = msg.get_int64() - if self._flags & self.FLAG_UIDGID: - self.st_uid = msg.get_int() - self.st_gid = msg.get_int() - if self._flags & self.FLAG_PERMISSIONS: - self.st_mode = msg.get_int() - if self._flags & self.FLAG_AMTIME: - self.st_atime = msg.get_int() - self.st_mtime = msg.get_int() - if self._flags & self.FLAG_EXTENDED: - count = msg.get_int() - for i in range(count): - self.attr[msg.get_string()] = msg.get_string() - return msg.get_remainder() - - def _pack(self, msg): - self._flags = 0 - if hasattr(self, 'st_size'): - self._flags |= self.FLAG_SIZE - if hasattr(self, 'st_uid') or hasattr(self, 'st_gid'): - self._flags |= self.FLAG_UIDGID - if hasattr(self, 'st_mode'): - self._flags |= self.FLAG_PERMISSIONS - if hasattr(self, 'st_atime') or hasattr(self, 'st_mtime'): - self._flags |= self.FLAG_AMTIME - if len(self.attr) > 0: - self._flags |= self.FLAG_EXTENDED - msg.add_int(self._flags) - if self._flags & self.FLAG_SIZE: - msg.add_int64(self.st_size) - if self._flags & self.FLAG_UIDGID: - msg.add_int(getattr(self, 'st_uid', 0)) - msg.add_int(getattr(self, 'st_gid', 0)) - if self._flags & self.FLAG_PERMISSIONS: - msg.add_int(self.st_mode) - if self._flags & self.FLAG_AMTIME: - msg.add_int(getattr(self, 'st_atime', 0)) - msg.add_int(getattr(self, 'st_mtime', 0)) - if self._flags & self.FLAG_EXTENDED: - msg.add_int(len(self.attr)) - for key, val in self.attr.iteritems(): - msg.add_string(key) - msg.add_string(val) - return - - def _rwx(n, suid, sticky=False): - if suid: - suid = 2 - out = '-r'[n >> 2] + '-w'[(n >> 1) & 1] - if sticky: - out += '-xTt'[suid + (n & 1)] - else: - out += '-xSs'[suid + (n & 1)] - return out - _rwx = staticmethod(_rwx) - - def __str__(self): - "create a unix-style long description of the file (like ls -l)" - if hasattr(self, 'permissions'): - kind = self.permissions & stat.S_IFMT - if kind == stat.S_IFIFO: - ks = 'p' - elif kind == stat.S_IFCHR: - ks = 'c' - elif kind == stat.S_IFDIR: - ks = 'd' - elif kind == stat.S_IFBLK: - ks = 'b' - elif kind == stat.S_IFREG: - ks = '-' - elif kind == stat.S_IFLNK: - ks = 'l' - elif kind == stat.S_IFSOCK: - ks = 's' - else: - ks = '?' - ks += _rwx((self.permissions & 0700) >> 6, self.permissions & stat.S_ISUID) - ks += _rwx((self.permissions & 070) >> 3, self.permissions & stat.S_ISGID) - ks += _rwx(self.permissions & 7, self.permissions & stat.S_ISVTX, True) - else: - ks = '?---------' - uid = getattr(self, 'uid', -1) - gid = getattr(self, 'gid', -1) - size = getattr(self, 'size', -1) - mtime = getattr(self, 'mtime', 0) - # compute display date - if abs(time.time() - mtime) > 15552000: - # (15552000 = 6 months) - datestr = time.strftime('%d %b %Y', time.localtime(mtime)) - else: - datestr = time.strftime('%d %b %H:%M', time.localtime(mtime)) - return '%s 1 %-8d %-8d %8d %-12s' % (ks, uid, gid, size, datestr) - - - class SFTPError (Exception): pass -class SFTPFile (BufferedFile): - - """ - Some sftp servers will choke if you send read/write requests larger than - this size. - """ - MAX_REQUEST_SIZE = 32768 - - def __init__(self, sftp, handle, mode='r', bufsize=-1): - BufferedFile.__init__(self) - self.sftp = sftp - self.handle = handle - BufferedFile._set_mode(self, mode, bufsize) - - def _get_size(self): - t, msg = self.sftp._request(CMD_FSTAT, self.handle) - if t != CMD_ATTRS: - raise SFTPError('Expected attrs') - attr = SFTPAttributes._from_msg(msg) - try: - return attr.st_size - except: - return 0 - - def close(self): - BufferedFile.close(self) - self.sftp._request(CMD_CLOSE, self.handle) - - def _read(self, size): - size = min(size, self.MAX_REQUEST_SIZE) - t, msg = self.sftp._request(CMD_READ, self.handle, long(self._realpos), int(size)) - if t != CMD_DATA: - raise SFTPError('Expected data') - return msg.get_string() - - def _write(self, data): - offset = 0 - while offset < len(data): - chunk = min(len(data) - offset, self.MAX_REQUEST_SIZE) - t, msg = self.sftp._request(CMD_WRITE, self.handle, long(self._realpos + offset), - str(data[offset : offset + chunk])) - offset += chunk - return len(data) - - def settimeout(self, timeout): - """ - Set a timeout on read/write operations on the underlying socket or - ssh L{Channel}. - - @see: L{Channel.settimeout} - @param timeout: seconds to wait for a pending read/write operation - before raising C{socket.timeout}, or C{None} for no timeout - @type timeout: float - """ - self.sock.settimeout(timeout) - - def gettimeout(self): - """ - Returns the timeout in seconds (as a float) associated with the socket - or ssh L{Channel} used for this file. - - @see: L{Channel.gettimeout} - @rtype: float - """ - return self.sock.gettimeout() - - def setblocking(self, blocking): - """ - Set blocking or non-blocking mode on the underiying socket or ssh - L{Channel}. - - @see: L{Channel.setblocking} - @param blocking: 0 to set non-blocking mode; non-0 to set blocking - mode. - @type blocking: int - """ - self.sock.setblocking(blocking) - - def seek(self, offset, whence=0): - self.flush() - if whence == self.SEEK_SET: - self._realpos = self._pos = offset - elif whence == self.SEEK_CUR: - self._realpos += offset - self._pos += offset - else: - self._realpos = self._pos = self._get_size() + offset - self._rbuffer = '' - - def stat(self): - """ - Retrieve information about this file from the remote system. This is - exactly like L{SFTP.stat}, except that it operates on an already-open - file. - - @return: an object containing attributes about this file. - @rtype: SFTPAttributes - """ - t, msg = self.sftp._request(CMD_FSTAT, self.handle) - if t != CMD_ATTRS: - raise SFTPError('Expected attributes') - return SFTPAttributes._from_msg(msg) - - class BaseSFTP (object): def __init__(self): self.logger = logging.getLogger('paramiko.sftp') |