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