1
# -*- encoding: utf-8 -*-
2
##############################################################################
4
# OpenERP, Open Source Management Solution
5
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
8
# This program is free software: you can redistribute it and/or modify
9
# it under the terms of the GNU General Public License as published by
10
# the Free Software Foundation, either version 3 of the License, or
11
# (at your option) any later version.
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU General Public License for more details.
18
# You should have received a copy of the GNU General Public License
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
21
##############################################################################
24
class SFTPHandle (paramiko.SFTPHandle):
25
def __init__(self, flags=0):
27
Create a new file handle representing a local file being served over
28
SFTP. If C{flags} is passed in, it's used to determine if the file
29
is open in append mode.
31
@param flags: optional flags as passed to L{SFTPServerInterface.open}
36
# only for handles to folders:
42
When a client closes a file, this method is called on the handle.
43
Normally you would use this method to close the underlying OS level
46
The default implementation checks for attributes on C{self} named
47
C{readfile} and/or C{writefile}, and if either or both are present,
48
their C{close()} methods are called. This means that if you are
49
using the default implementations of L{read} and L{write}, this
50
method's default implementation should be fine also.
52
readfile = getattr(self, 'readfile', None)
53
if readfile is not None:
55
writefile = getattr(self, 'writefile', None)
56
if writefile is not None:
59
def read(self, offset, length):
61
Read up to C{length} bytes from this file, starting at position
62
C{offset}. The offset may be a python long, since SFTP allows it
65
If the end of the file has been reached, this method may return an
66
empty string to signify EOF, or it may also return L{SFTP_EOF}.
68
The default implementation checks for an attribute on C{self} named
69
C{readfile}, and if present, performs the read operation on the python
70
file-like object found there. (This is meant as a time saver for the
71
common case where you are wrapping a python file object.)
73
@param offset: position in the file to start reading from.
74
@type offset: int or long
75
@param length: number of bytes to attempt to read.
77
@return: data read from the file, or an SFTP error code.
80
readfile = getattr(self, 'readfile', None)
82
return SFTP_OP_UNSUPPORTED
84
if self.__tell is None:
85
self.__tell = readfile.tell()
86
if offset != self.__tell:
89
data = readfile.read(length)
92
return SFTPServer.convert_errno(e.errno)
93
self.__tell += len(data)
96
def write(self, offset, data):
98
Write C{data} into this file at position C{offset}. Extending the
99
file past its original end is expected. Unlike python's normal
100
C{write()} methods, this method cannot do a partial write: it must
101
write all of C{data} or else return an error.
103
The default implementation checks for an attribute on C{self} named
104
C{writefile}, and if present, performs the write operation on the
105
python file-like object found there. The attribute is named
106
differently from C{readfile} to make it easy to implement read-only
107
(or write-only) files, but if both attributes are present, they should
108
refer to the same file.
110
@param offset: position in the file to start reading from.
111
@type offset: int or long
112
@param data: data to write into the file.
114
@return: an SFTP error code like L{SFTP_OK}.
116
writefile = getattr(self, 'writefile', None)
117
if writefile is None:
118
return SFTP_OP_UNSUPPORTED
120
# in append mode, don't care about seeking
121
if (self.__flags & os.O_APPEND) == 0:
122
if self.__tell is None:
123
self.__tell = writefile.tell()
124
if offset != self.__tell:
125
writefile.seek(offset)
127
writefile.write(data)
131
return SFTPServer.convert_errno(e.errno)
132
if self.__tell is not None:
133
self.__tell += len(data)
136
def chattr(self, attr):
138
Change the attributes of this file. The C{attr} object will contain
139
only those fields provided by the client in its request, so you should
140
check for the presence of fields before using them.
142
@param attr: the attributes to change on this file.
143
@type attr: L{SFTPAttributes}
144
@return: an error code like L{SFTP_OK}.
147
return SFTP_OP_UNSUPPORTED
153
def _set_files(self, files):
155
Used by the SFTP server code to cache a directory listing. (In
156
the SFTP protocol, listing a directory is a multi-stage process
157
requiring a temporary handle.)
161
def _get_next_files(self):
163
Used by the SFTP server code to retreive a cached directory
166
fnlist = self.__files[:16]
167
self.__files = self.__files[16:]
173
def _set_name(self, name):