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