1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19  """ 
 20  Abstraction of an SFTP file handle (for server mode). 
 21  """ 
 22   
 23  import os 
 24   
 25  from paramiko.common import * 
 26  from paramiko.sftp import * 
 27   
 28   
 30      """ 
 31      Abstract object representing a handle to an open file (or folder) in an 
 32      SFTP server implementation.  Each handle has a string representation used 
 33      by the client to refer to the underlying file. 
 34       
 35      Server implementations can (and should) subclass SFTPHandle to implement 
 36      features of a file handle, like L{stat} or L{chattr}. 
 37      """ 
 39          """ 
 40          Create a new file handle representing a local file being served over 
 41          SFTP.  If C{flags} is passed in, it's used to determine if the file 
 42          is open in append mode. 
 43           
 44          @param flags: optional flags as passed to L{SFTPServerInterface.open} 
 45          @type flags: int 
 46          """ 
 47          self.__flags = flags 
 48          self.__name = None 
 49           
 50          self.__files = { } 
 51          self.__tell = None 
  52   
 54          """ 
 55          When a client closes a file, this method is called on the handle. 
 56          Normally you would use this method to close the underlying OS level 
 57          file object(s). 
 58           
 59          The default implementation checks for attributes on C{self} named 
 60          C{readfile} and/or C{writefile}, and if either or both are present, 
 61          their C{close()} methods are called.  This means that if you are 
 62          using the default implementations of L{read} and L{write}, this 
 63          method's default implementation should be fine also. 
 64          """ 
 65          readfile = getattr(self, 'readfile', None) 
 66          if readfile is not None: 
 67              readfile.close() 
 68          writefile = getattr(self, 'writefile', None) 
 69          if writefile is not None: 
 70              writefile.close() 
  71   
 72 -    def read(self, offset, length): 
  73          """ 
 74          Read up to C{length} bytes from this file, starting at position 
 75          C{offset}.  The offset may be a python long, since SFTP allows it 
 76          to be 64 bits. 
 77   
 78          If the end of the file has been reached, this method may return an 
 79          empty string to signify EOF, or it may also return L{SFTP_EOF}. 
 80   
 81          The default implementation checks for an attribute on C{self} named 
 82          C{readfile}, and if present, performs the read operation on the python 
 83          file-like object found there.  (This is meant as a time saver for the 
 84          common case where you are wrapping a python file object.) 
 85   
 86          @param offset: position in the file to start reading from. 
 87          @type offset: int or long 
 88          @param length: number of bytes to attempt to read. 
 89          @type length: int 
 90          @return: data read from the file, or an SFTP error code. 
 91          @rtype: str 
 92          """ 
 93          readfile = getattr(self, 'readfile', None) 
 94          if readfile is None: 
 95              return SFTP_OP_UNSUPPORTED 
 96          try: 
 97              if self.__tell is None: 
 98                  self.__tell = readfile.tell() 
 99              if offset != self.__tell: 
100                  readfile.seek(offset) 
101                  self.__tell = offset 
102              data = readfile.read(length) 
103          except IOError, e: 
104              self.__tell = None 
105              return SFTPServer.convert_errno(e.errno) 
106          self.__tell += len(data) 
107          return data 
 108   
109 -    def write(self, offset, data): 
 110          """ 
111          Write C{data} into this file at position C{offset}.  Extending the 
112          file past its original end is expected.  Unlike python's normal 
113          C{write()} methods, this method cannot do a partial write: it must 
114          write all of C{data} or else return an error. 
115   
116          The default implementation checks for an attribute on C{self} named 
117          C{writefile}, and if present, performs the write operation on the 
118          python file-like object found there.  The attribute is named 
119          differently from C{readfile} to make it easy to implement read-only 
120          (or write-only) files, but if both attributes are present, they should 
121          refer to the same file. 
122           
123          @param offset: position in the file to start reading from. 
124          @type offset: int or long 
125          @param data: data to write into the file. 
126          @type data: str 
127          @return: an SFTP error code like L{SFTP_OK}. 
128          """ 
129          writefile = getattr(self, 'writefile', None) 
130          if writefile is None: 
131              return SFTP_OP_UNSUPPORTED 
132          try: 
133               
134              if (self.__flags & os.O_APPEND) == 0: 
135                  if self.__tell is None: 
136                      self.__tell = writefile.tell() 
137                  if offset != self.__tell: 
138                      writefile.seek(offset) 
139                      self.__tell = offset 
140              writefile.write(data) 
141              writefile.flush() 
142          except IOError, e: 
143              self.__tell = None 
144              return SFTPServer.convert_errno(e.errno) 
145          if self.__tell is not None: 
146              self.__tell += len(data) 
147          return SFTP_OK 
 148   
150          """ 
151          Return an L{SFTPAttributes} object referring to this open file, or an 
152          error code.  This is equivalent to L{SFTPServerInterface.stat}, except 
153          it's called on an open file instead of a path. 
154   
155          @return: an attributes object for the given file, or an SFTP error 
156              code (like L{SFTP_PERMISSION_DENIED}). 
157          @rtype: L{SFTPAttributes} I{or error code} 
158          """ 
159          return SFTP_OP_UNSUPPORTED 
 160   
162          """ 
163          Change the attributes of this file.  The C{attr} object will contain 
164          only those fields provided by the client in its request, so you should 
165          check for the presence of fields before using them. 
166   
167          @param attr: the attributes to change on this file. 
168          @type attr: L{SFTPAttributes} 
169          @return: an error code like L{SFTP_OK}. 
170          @rtype: int 
171          """ 
172          return SFTP_OP_UNSUPPORTED 
 173   
174   
175       
176   
177       
179          """ 
180          Used by the SFTP server code to cache a directory listing.  (In 
181          the SFTP protocol, listing a directory is a multi-stage process 
182          requiring a temporary handle.) 
183          """ 
184          self.__files = files 
 185   
187          """ 
188          Used by the SFTP server code to retreive a cached directory 
189          listing. 
190          """ 
191          fnlist = self.__files[:16] 
192          self.__files = self.__files[16:] 
193          return fnlist 
 194   
197   
 200   
201   
202  from paramiko.sftp_server import SFTPServer 
203