1414# License along with this library; if not, write to the Free Software
1515# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130
1616
17+ from libc.stdlib cimport malloc, free
18+
1719from session cimport Session
1820from sftp_handles cimport SFTPFile, SFTPDir
19- from utils cimport handle_ssh_error_codes
21+ from sftp_attributes cimport SFTPAttributes
22+ from sftp_statvfs cimport SFTPStatVFS
23+ from utils cimport handle_ssh_error_codes, to_bytes
2024
2125cimport c_sftp
22-
23-
24- cdef class SFTPStatVFS:
25-
26- def __dealloc__ (self ):
27- if self ._stats is not NULL :
28- c_sftp.sftp_statvfs_free(self ._stats)
29- self ._stats = NULL
30-
31-
32- cdef class SFTPAttributes:
33-
34- def __dealloc__ (self ):
35- if self ._attrs is not NULL :
36- c_sftp.sftp_attributes_free(self ._attrs)
37- self ._attrs = NULL
26+ from c_ssh cimport ssh_get_error_code, timeval
3827
3928
4029cdef class SFTP:
@@ -47,16 +36,18 @@ cdef class SFTP:
4736
4837 def __cinit__ (self , Session session ):
4938 self .session = session
50- cdef int rc
51- with nogil:
52- rc = c_sftp.sftp_init(self ._sftp)
53- handle_ssh_error_codes(rc, self .session._session)
5439
5540 def __dealloc__ (self ):
5641 if self ._sftp is not NULL :
5742 c_sftp.sftp_free(self ._sftp)
5843 self ._sftp = NULL
5944
45+ def init (self ):
46+ cdef int rc
47+ with nogil:
48+ rc = c_sftp.sftp_init(self ._sftp)
49+ return handle_ssh_error_codes(rc, self .session._session)
50+
6051 def get_error (self ):
6152 cdef int rc
6253 with nogil:
@@ -70,62 +61,219 @@ cdef class SFTP:
7061 return rc
7162
7263 def extensions_get_name (self , unsigned int indexn ):
73- pass
64+ cdef const char * _name
65+ cdef bytes name = None
66+ with nogil:
67+ _name = c_sftp.sftp_extensions_get_name(self ._sftp, indexn)
68+ if _name is not NULL :
69+ name = _name
70+ return name
7471
7572 def extensions_get_data (self , unsigned int indexn ):
76- pass
73+ cdef const char * _name
74+ cdef bytes name = None
75+ with nogil:
76+ _name = c_sftp.sftp_extensions_get_data(self ._sftp, indexn)
77+ if _name is not NULL :
78+ name = _name
79+ return name
7780
7881 def extension_supported (self , name not None , data not None ):
79- pass
82+ cdef bint rc
83+ cdef bytes b_name = to_bytes(name)
84+ cdef const char * c_name = b_name
85+ cdef bytes b_data = to_bytes(data)
86+ cdef const char * c_data = b_data
87+ with nogil:
88+ rc = c_sftp.sftp_extension_supported(
89+ self ._sftp, c_name, c_data)
90+ return bool (rc)
8091
8192 def opendir (self , path not None ):
82- pass
93+ cdef SFTPDir _dir
94+ cdef c_sftp.sftp_dir c_dir
95+ cdef bytes b_path = to_bytes(path)
96+ cdef const char * c_path = b_path
97+ with nogil:
98+ c_dir = c_sftp.sftp_opendir(self ._sftp, c_path)
99+ if c_dir is NULL :
100+ return handle_ssh_error_codes(
101+ ssh_get_error_code(self .session._session),
102+ self .session._session)
103+ _dir = SFTPDir.from_ptr(c_dir, self )
104+ return _dir
83105
84106 def stat (self , path not None ):
85- pass
107+ cdef SFTPAttributes _attrs
108+ cdef c_sftp.sftp_attributes c_attrs
109+ cdef bytes b_path = to_bytes(path)
110+ cdef const char * c_path = b_path
111+ with nogil:
112+ c_attrs = c_sftp.sftp_stat(self ._sftp, c_path)
113+ if c_attrs is NULL :
114+ return handle_ssh_error_codes(
115+ ssh_get_error_code(self .session._session),
116+ self .session._session)
117+ _attrs = SFTPAttributes.from_ptr(c_attrs, self )
118+ return _attrs
86119
87120 def lstat (self , path not None ):
88- pass
121+ cdef SFTPAttributes _attrs
122+ cdef c_sftp.sftp_attributes c_attrs
123+ cdef bytes b_path = to_bytes(path)
124+ cdef const char * c_path = b_path
125+ with nogil:
126+ c_attrs = c_sftp.sftp_lstat(self ._sftp, c_path)
127+ if c_attrs is NULL :
128+ return handle_ssh_error_codes(
129+ ssh_get_error_code(self .session._session),
130+ self .session._session)
131+ _attrs = SFTPAttributes.from_ptr(c_attrs, self )
132+ return _attrs
89133
90134 def open (self , path not None , int accesstype , c_sftp.mode_t mode ):
91- pass
135+ cdef bytes b_path = to_bytes(path)
136+ cdef const char * c_path = b_path
137+ cdef SFTPFile _file
138+ cdef c_sftp.sftp_file c_file
139+ with nogil:
140+ c_file = c_sftp.sftp_open(self ._sftp, c_path, accesstype, mode)
141+ if c_file is NULL :
142+ return handle_ssh_error_codes(
143+ ssh_get_error_code(self .session._session),
144+ self .session._session)
145+ _file = SFTPFile.from_ptr(c_file, self )
146+ return _file
92147
93148 def unlink (self , path not None ):
94- pass
149+ cdef bytes b_path = to_bytes(path)
150+ cdef const char * c_path = b_path
151+ cdef int rc
152+ with nogil:
153+ rc = c_sftp.sftp_unlink(self ._sftp, c_path)
154+ return handle_ssh_error_codes(rc, self .session._session)
95155
96156 def rmdir (self , path not None ):
97- pass
157+ cdef bytes b_path = to_bytes(path)
158+ cdef const char * c_path = b_path
159+ cdef int rc
160+ with nogil:
161+ rc = c_sftp.sftp_rmdir(self ._sftp, c_path)
162+ return handle_ssh_error_codes(rc, self .session._session)
98163
99164 def mkdir (self , path not None , c_sftp.mode_t mode ):
100- pass
165+ cdef bytes b_path = to_bytes(path)
166+ cdef const char * c_path = b_path
167+ cdef int rc
168+ with nogil:
169+ rc = c_sftp.sftp_mkdir(self ._sftp, c_path, mode)
170+ return handle_ssh_error_codes(rc, self .session._session)
101171
102172 def rename (self , original not None , newname not None ):
103- pass
173+ cdef bytes b_orig = to_bytes(original)
174+ cdef const char * c_orig = b_orig
175+ cdef bytes b_newname = to_bytes(newname)
176+ cdef const char * c_newname = b_newname
177+ cdef int rc
178+ with nogil:
179+ rc = c_sftp.sftp_rename(self ._sftp, c_orig, c_newname)
180+ return handle_ssh_error_codes(rc, self .session._session)
104181
105182 def setstat (self , path not None , SFTPAttributes attr ):
106- pass
183+ cdef bytes b_path = to_bytes(path)
184+ cdef const char * c_path = b_path
185+ cdef int rc
186+ with nogil:
187+ rc = c_sftp.sftp_setstat(self ._sftp, c_path, attr._attrs)
188+ return handle_ssh_error_codes(rc, self .session._session)
107189
108190 def chown (self , path not None ,
109191 c_sftp.uid_t owner , c_sftp.gid_t group ):
110- pass
192+ cdef bytes b_path = to_bytes(path)
193+ cdef const char * c_path = b_path
194+ cdef int rc
195+ with nogil:
196+ rc = c_sftp.sftp_chown(self ._sftp, c_path, owner, group)
197+ return handle_ssh_error_codes(rc, self .session._session)
111198
112199 def chmod (self , path not None , c_sftp.mode_t mode ):
113- pass
200+ cdef bytes b_path = to_bytes(path)
201+ cdef const char * c_path = b_path
202+ cdef int rc
203+ with nogil:
204+ rc = c_sftp.sftp_chmod(self ._sftp, c_path, mode)
205+ return handle_ssh_error_codes(rc, self .session._session)
114206
115- def utimes (self , path not None , times ):
116- pass
207+ def utimes (self , path not None , long seconds , long microseconds ):
208+ cdef bytes b_path = to_bytes(path)
209+ cdef const char * c_path = b_path
210+ cdef int rc
211+ cdef timeval * _val
212+ with nogil:
213+ _val = < timeval * > malloc(sizeof(timeval))
214+ if _val is NULL :
215+ with gil:
216+ raise MemoryError
217+ _val.tv_sec = seconds
218+ _val.tv_usec = microseconds
219+ rc = c_sftp.sftp_utimes(self ._sftp, c_path, _val)
220+ free(_val)
221+ return handle_ssh_error_codes(rc, self .session._session)
117222
118223 def symlink (self , source not None , dest not None ):
119- pass
224+ cdef bytes b_source = to_bytes(source)
225+ cdef const char * c_source = b_source
226+ cdef bytes b_dest = to_bytes(dest)
227+ cdef const char * c_dest = b_dest
228+ cdef int rc
229+ with nogil:
230+ rc = c_sftp.sftp_symlink(self ._sftp, c_source, c_dest)
231+ return handle_ssh_error_codes(rc, self .session._session)
120232
121233 def readlink (self , path not None ):
122- pass
234+ cdef bytes b_path = to_bytes(path)
235+ cdef const char * c_path = b_path
236+ cdef char * _link
237+ cdef bytes b_link
238+ with nogil:
239+ _link = c_sftp.sftp_readlink(self ._sftp, c_path)
240+ if _link is NULL :
241+ return handle_ssh_error_codes(
242+ ssh_get_error_code(self .session._session),
243+ self .session._session)
244+ b_link = _link
245+ return b_link
123246
124247 def statvfs (self , path not None ):
125- pass
248+ cdef bytes b_path = to_bytes(path)
249+ cdef const char * c_path = b_path
250+ cdef SFTPStatVFS vfs
251+ cdef c_sftp.sftp_statvfs_t c_vfs
252+ with nogil:
253+ c_vfs = c_sftp.sftp_statvfs(self ._sftp, c_path)
254+ if c_vfs is NULL :
255+ return handle_ssh_error_codes(
256+ ssh_get_error_code(self .session._session),
257+ self .session._session)
258+ vfs = SFTPStatVFS.from_ptr(c_vfs, self )
259+ return vfs
126260
127261 def canonicalize_path (self , path not None ):
128- pass
262+ cdef bytes b_path = to_bytes(path)
263+ cdef const char * c_path = b_path
264+ cdef char * _rpath
265+ cdef bytes b_rpath
266+ with nogil:
267+ _rpath = c_sftp.sftp_canonicalize_path(self ._sftp, c_path)
268+ if _rpath is NULL :
269+ return handle_ssh_error_codes(
270+ ssh_get_error_code(self .session._session),
271+ self .session._session)
272+ b_rpath = _rpath
273+ return b_rpath
129274
130275 def server_version (self ):
131- pass
276+ cdef int rc
277+ with nogil:
278+ rc = c_sftp.sftp_server_version(self ._sftp)
279+ return rc
0 commit comments