Package paramiko :: Module sftp_attr
[frames] | no frames]

Source Code for Module paramiko.sftp_attr

  1  # Copyright (C) 2003-2006 Robey Pointer <robey@lag.net> 
  2  # 
  3  # This file is part of paramiko. 
  4  # 
  5  # Paramiko is free software; you can redistribute it and/or modify it under the 
  6  # terms of the GNU Lesser General Public License as published by the Free 
  7  # Software Foundation; either version 2.1 of the License, or (at your option) 
  8  # any later version. 
  9  # 
 10  # Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY 
 11  # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 
 12  # A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
 13  # details. 
 14  # 
 15  # You should have received a copy of the GNU Lesser General Public License 
 16  # along with Paramiko; if not, write to the Free Software Foundation, Inc., 
 17  # 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. 
 18   
 19  import stat 
 20  import time 
 21  from paramiko.common import * 
 22  from paramiko.sftp import * 
 23   
 24   
25 -class SFTPAttributes (object):
26 """ 27 Representation of the attributes of a file (or proxied file) for SFTP in 28 client or server mode. It attemps to mirror the object returned by 29 C{os.stat} as closely as possible, so it may have the following fields, 30 with the same meanings as those returned by an C{os.stat} object: 31 - st_size 32 - st_uid 33 - st_gid 34 - st_mode 35 - st_atime 36 - st_mtime 37 38 Because SFTP allows flags to have other arbitrary named attributes, these 39 are stored in a dict named C{attr}. Occasionally, the filename is also 40 stored, in C{filename}. 41 """ 42 43 FLAG_SIZE = 1 44 FLAG_UIDGID = 2 45 FLAG_PERMISSIONS = 4 46 FLAG_AMTIME = 8 47 FLAG_EXTENDED = 0x80000000L 48
49 - def __init__(self):
50 """ 51 Create a new (empty) SFTPAttributes object. All fields will be empty. 52 """ 53 self._flags = 0 54 self.st_size = None 55 self.st_uid = None 56 self.st_gid = None 57 self.st_mode = None 58 self.st_atime = None 59 self.st_mtime = None 60 self.attr = {}
61
62 - def from_stat(cls, obj, filename=None):
63 """ 64 Create an SFTPAttributes object from an existing C{stat} object (an 65 object returned by C{os.stat}). 66 67 @param obj: an object returned by C{os.stat} (or equivalent). 68 @type obj: object 69 @param filename: the filename associated with this file. 70 @type filename: str 71 @return: new L{SFTPAttributes} object with the same attribute fields. 72 @rtype: L{SFTPAttributes} 73 """ 74 attr = cls() 75 attr.st_size = obj.st_size 76 attr.st_uid = obj.st_uid 77 attr.st_gid = obj.st_gid 78 attr.st_mode = obj.st_mode 79 attr.st_atime = obj.st_atime 80 attr.st_mtime = obj.st_mtime 81 if filename is not None: 82 attr.filename = filename 83 return attr
84 from_stat = classmethod(from_stat) 85
86 - def __repr__(self):
87 return '<SFTPAttributes: %s>' % self._debug_str()
88 89 90 ### internals... 91 92
93 - def _from_msg(cls, msg, filename=None, longname=None):
94 attr = cls() 95 attr._unpack(msg) 96 if filename is not None: 97 attr.filename = filename 98 if longname is not None: 99 attr.longname = longname 100 return attr
101 _from_msg = classmethod(_from_msg) 102
103 - def _unpack(self, msg):
104 self._flags = msg.get_int() 105 if self._flags & self.FLAG_SIZE: 106 self.st_size = msg.get_int64() 107 if self._flags & self.FLAG_UIDGID: 108 self.st_uid = msg.get_int() 109 self.st_gid = msg.get_int() 110 if self._flags & self.FLAG_PERMISSIONS: 111 self.st_mode = msg.get_int() 112 if self._flags & self.FLAG_AMTIME: 113 self.st_atime = msg.get_int() 114 self.st_mtime = msg.get_int() 115 if self._flags & self.FLAG_EXTENDED: 116 count = msg.get_int() 117 for i in range(count): 118 self.attr[msg.get_string()] = msg.get_string()
119
120 - def _pack(self, msg):
121 self._flags = 0 122 if self.st_size is not None: 123 self._flags |= self.FLAG_SIZE 124 if (self.st_uid is not None) and (self.st_gid is not None): 125 self._flags |= self.FLAG_UIDGID 126 if self.st_mode is not None: 127 self._flags |= self.FLAG_PERMISSIONS 128 if (self.st_atime is not None) and (self.st_mtime is not None): 129 self._flags |= self.FLAG_AMTIME 130 if len(self.attr) > 0: 131 self._flags |= self.FLAG_EXTENDED 132 msg.add_int(self._flags) 133 if self._flags & self.FLAG_SIZE: 134 msg.add_int64(self.st_size) 135 if self._flags & self.FLAG_UIDGID: 136 msg.add_int(self.st_uid) 137 msg.add_int(self.st_gid) 138 if self._flags & self.FLAG_PERMISSIONS: 139 msg.add_int(self.st_mode) 140 if self._flags & self.FLAG_AMTIME: 141 # throw away any fractional seconds 142 msg.add_int(long(self.st_atime)) 143 msg.add_int(long(self.st_mtime)) 144 if self._flags & self.FLAG_EXTENDED: 145 msg.add_int(len(self.attr)) 146 for key, val in self.attr.iteritems(): 147 msg.add_string(key) 148 msg.add_string(val) 149 return
150
151 - def _debug_str(self):
152 out = '[ ' 153 if self.st_size is not None: 154 out += 'size=%d ' % self.st_size 155 if (self.st_uid is not None) and (self.st_gid is not None): 156 out += 'uid=%d gid=%d ' % (self.st_uid, self.st_gid) 157 if self.st_mode is not None: 158 out += 'mode=' + oct(self.st_mode) + ' ' 159 if (self.st_atime is not None) and (self.st_mtime is not None): 160 out += 'atime=%d mtime=%d ' % (self.st_atime, self.st_mtime) 161 for k, v in self.attr.iteritems(): 162 out += '"%s"=%r ' % (str(k), v) 163 out += ']' 164 return out
165
166 - def _rwx(n, suid, sticky=False):
167 if suid: 168 suid = 2 169 out = '-r'[n >> 2] + '-w'[(n >> 1) & 1] 170 if sticky: 171 out += '-xTt'[suid + (n & 1)] 172 else: 173 out += '-xSs'[suid + (n & 1)] 174 return out
175 _rwx = staticmethod(_rwx) 176
177 - def __str__(self):
178 "create a unix-style long description of the file (like ls -l)" 179 if self.st_mode is not None: 180 kind = stat.S_IFMT(self.st_mode) 181 if kind == stat.S_IFIFO: 182 ks = 'p' 183 elif kind == stat.S_IFCHR: 184 ks = 'c' 185 elif kind == stat.S_IFDIR: 186 ks = 'd' 187 elif kind == stat.S_IFBLK: 188 ks = 'b' 189 elif kind == stat.S_IFREG: 190 ks = '-' 191 elif kind == stat.S_IFLNK: 192 ks = 'l' 193 elif kind == stat.S_IFSOCK: 194 ks = 's' 195 else: 196 ks = '?' 197 ks += self._rwx((self.st_mode & 0700) >> 6, self.st_mode & stat.S_ISUID) 198 ks += self._rwx((self.st_mode & 070) >> 3, self.st_mode & stat.S_ISGID) 199 ks += self._rwx(self.st_mode & 7, self.st_mode & stat.S_ISVTX, True) 200 else: 201 ks = '?---------' 202 # compute display date 203 if (self.st_mtime is None) or (self.st_mtime == 0xffffffff): 204 # shouldn't really happen 205 datestr = '(unknown date)' 206 else: 207 if abs(time.time() - self.st_mtime) > 15552000: 208 # (15552000 = 6 months) 209 datestr = time.strftime('%d %b %Y', time.localtime(self.st_mtime)) 210 else: 211 datestr = time.strftime('%d %b %H:%M', time.localtime(self.st_mtime)) 212 filename = getattr(self, 'filename', '?') 213 214 # not all servers support uid/gid 215 uid = self.st_uid 216 gid = self.st_gid 217 if uid is None: 218 uid = 0 219 if gid is None: 220 gid = 0 221 222 return '%s 1 %-8d %-8d %8d %-12s %s' % (ks, uid, gid, self.st_size, datestr, filename)
223