summaryrefslogtreecommitdiffstats
path: root/cython/afc.pxi
diff options
context:
space:
mode:
Diffstat (limited to 'cython/afc.pxi')
-rw-r--r--cython/afc.pxi337
1 files changed, 337 insertions, 0 deletions
diff --git a/cython/afc.pxi b/cython/afc.pxi
new file mode 100644
index 0000000..6bd8182
--- /dev/null
+++ b/cython/afc.pxi
@@ -0,0 +1,337 @@
1cdef extern from "libimobiledevice/afc.h":
2 cdef struct afc_client_private:
3 pass
4 ctypedef afc_client_private *afc_client_t
5 ctypedef enum afc_error_t:
6 AFC_E_SUCCESS = 0
7 AFC_E_UNKNOWN_ERROR = 1
8 AFC_E_OP_HEADER_INVALID = 2
9 AFC_E_NO_RESOURCES = 3
10 AFC_E_READ_ERROR = 4
11 AFC_E_WRITE_ERROR = 5
12 AFC_E_UNKNOWN_PACKET_TYPE = 6
13 AFC_E_INVALID_ARG = 7
14 AFC_E_OBJECT_NOT_FOUND = 8
15 AFC_E_OBJECT_IS_DIR = 9
16 AFC_E_PERM_DENIED = 10
17 AFC_E_SERVICE_NOT_CONNECTED = 11
18 AFC_E_OP_TIMEOUT = 12
19 AFC_E_TOO_MUCH_DATA = 13
20 AFC_E_END_OF_DATA = 14
21 AFC_E_OP_NOT_SUPPORTED = 15
22 AFC_E_OBJECT_EXISTS = 16
23 AFC_E_OBJECT_BUSY = 17
24 AFC_E_NO_SPACE_LEFT = 18
25 AFC_E_OP_WOULD_BLOCK = 19
26 AFC_E_IO_ERROR = 20
27 AFC_E_OP_INTERRUPTED = 21
28 AFC_E_OP_IN_PROGRESS = 22
29 AFC_E_INTERNAL_ERROR = 23
30 AFC_E_MUX_ERROR = 30
31 AFC_E_NO_MEM = 31
32 AFC_E_NOT_ENOUGH_DATA = 32
33 AFC_E_DIR_NOT_EMPTY = 33
34 ctypedef enum afc_file_mode_t:
35 AFC_FOPEN_RDONLY = 0x00000001
36 AFC_FOPEN_RW = 0x00000002
37 AFC_FOPEN_WRONLY = 0x00000003
38 AFC_FOPEN_WR = 0x00000004
39 AFC_FOPEN_APPEND = 0x00000005
40 AFC_FOPEN_RDAPPEND = 0x00000006
41 ctypedef enum afc_link_type_t:
42 AFC_HARDLINK = 1
43 AFC_SYMLINK = 2
44 ctypedef enum afc_lock_op_t:
45 AFC_LOCK_SH = 1 | 4
46 AFC_LOCK_EX = 2 | 4
47 AFC_LOCK_UN = 8 | 4
48
49 afc_error_t afc_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, afc_client_t *client)
50 afc_error_t afc_client_free(afc_client_t client)
51 afc_error_t afc_get_device_info(afc_client_t client, char ***infos)
52 afc_error_t afc_read_directory(afc_client_t client, char *dir, char ***list)
53 afc_error_t afc_get_file_info(afc_client_t client, char *filename, char ***infolist)
54 afc_error_t afc_remove_path(afc_client_t client, char *path)
55 afc_error_t afc_remove_path_and_contents(afc_client_t client, char *path)
56 afc_error_t afc_rename_path(afc_client_t client, char *f, char *to)
57 afc_error_t afc_make_directory(afc_client_t client, char *dir)
58 afc_error_t afc_truncate(afc_client_t client, char *path, uint64_t newsize)
59 afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, char *target, char *linkname)
60 afc_error_t afc_set_file_time(afc_client_t client, char *path, uint64_t mtime)
61
62 afc_error_t afc_file_open(afc_client_t client, char *filename, afc_file_mode_t file_mode, uint64_t *handle)
63 afc_error_t afc_file_close(afc_client_t client, uint64_t handle)
64 afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation)
65 afc_error_t afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length, uint32_t *bytes_read)
66 afc_error_t afc_file_write(afc_client_t client, uint64_t handle, char *data, uint32_t length, uint32_t *bytes_written)
67 afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence)
68 afc_error_t afc_file_tell(afc_client_t client, uint64_t handle, uint64_t *position)
69 afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize)
70
71LOCK_SH = AFC_LOCK_SH
72LOCK_EX = AFC_LOCK_EX
73LOCK_UN = AFC_LOCK_UN
74
75cdef class AfcError(BaseError):
76 def __init__(self, *args, **kwargs):
77 self._lookup_table = {
78 AFC_E_SUCCESS: "Success",
79 AFC_E_UNKNOWN_ERROR: "Unknown error",
80 AFC_E_OP_HEADER_INVALID: "OP header invalid",
81 AFC_E_NO_RESOURCES: "No resources",
82 AFC_E_READ_ERROR: "Read error",
83 AFC_E_WRITE_ERROR: "Write error",
84 AFC_E_UNKNOWN_PACKET_TYPE: "Unknown packet type",
85 AFC_E_INVALID_ARG: "Invalid argument",
86 AFC_E_OBJECT_NOT_FOUND: "Object not found",
87 AFC_E_OBJECT_IS_DIR: "Object is directory",
88 AFC_E_PERM_DENIED: "Permission denied",
89 AFC_E_SERVICE_NOT_CONNECTED: "Service not connected",
90 AFC_E_OP_TIMEOUT: "OP timeout",
91 AFC_E_TOO_MUCH_DATA: "Too much data",
92 AFC_E_END_OF_DATA: "End of data",
93 AFC_E_OP_NOT_SUPPORTED: "OP not supported",
94 AFC_E_OBJECT_EXISTS: "Object exists",
95 AFC_E_OBJECT_BUSY: "Object busy",
96 AFC_E_NO_SPACE_LEFT: "No space left",
97 AFC_E_OP_WOULD_BLOCK: "OP would block",
98 AFC_E_IO_ERROR: "IO error",
99 AFC_E_OP_INTERRUPTED: "OP interrupted",
100 AFC_E_OP_IN_PROGRESS: "OP in progress",
101 AFC_E_INTERNAL_ERROR: "Internal error",
102 AFC_E_MUX_ERROR: "MUX error",
103 AFC_E_NO_MEM: "No memory",
104 AFC_E_NOT_ENOUGH_DATA: "Not enough data",
105 AFC_E_DIR_NOT_EMPTY: "Directory not empty"
106 }
107 BaseError.__init__(self, *args, **kwargs)
108
109# forward declaration of AfcClient
110cdef class AfcClient(BaseService)
111
112cdef class AfcFile(Base):
113 cdef uint64_t _c_handle
114 cdef AfcClient _client
115 cdef bytes _filename
116
117 def __init__(self, *args, **kwargs):
118 raise TypeError("AfcFile cannot be instantiated")
119
120 def __enter__(self):
121 return self
122
123 def __exit__(self, type, value, traceback):
124 self.close()
125
126 cpdef close(self):
127 self.handle_error(afc_file_close(self._client._c_client, self._c_handle))
128
129 cpdef lock(self, int operation):
130 self.handle_error(afc_file_lock(self._client._c_client, self._c_handle, <afc_lock_op_t>operation))
131
132 cpdef seek(self, int64_t offset, int whence):
133 self.handle_error(afc_file_seek(self._client._c_client, self._c_handle, offset, whence))
134
135 cpdef uint64_t tell(self):
136 cdef uint64_t position
137 self.handle_error(afc_file_tell(self._client._c_client, self._c_handle, &position))
138 return position
139
140 cpdef truncate(self, uint64_t newsize):
141 self.handle_error(afc_file_truncate(self._client._c_client, self._c_handle, newsize))
142
143 cpdef bytes read(self, uint32_t size):
144 cdef:
145 uint32_t bytes_read
146 char* c_data = <char *>malloc(size)
147 bytes result
148 try:
149 self.handle_error(afc_file_read(self._client._c_client, self._c_handle, c_data, size, &bytes_read))
150 result = c_data[:bytes_read]
151 return result
152 except BaseError, e:
153 raise
154 finally:
155 free(c_data)
156
157 cpdef uint32_t write(self, bytes data):
158 cdef:
159 uint32_t bytes_written
160 char* c_data = data
161 try:
162 self.handle_error(afc_file_write(self._client._c_client, self._c_handle, c_data, len(data), &bytes_written))
163 except BaseError, e:
164 raise
165
166 return bytes_written
167
168 cdef inline BaseError _error(self, int16_t ret):
169 return AfcError(ret)
170
171cdef class AfcClient(BaseService):
172 __service_name__ = "com.apple.afc"
173 cdef afc_client_t _c_client
174
175 def __cinit__(self, iDevice device = None, LockdownServiceDescriptor descriptor = None, *args, **kwargs):
176 if (device is not None and descriptor is not None):
177 self.handle_error(afc_client_new(device._c_dev, descriptor._c_service_descriptor, &(self._c_client)))
178
179 def __dealloc__(self):
180 cdef afc_error_t err
181 if self._c_client is not NULL:
182 err = afc_client_free(self._c_client)
183 self.handle_error(err)
184
185 cdef BaseError _error(self, int16_t ret):
186 return AfcError(ret)
187
188 cpdef list get_device_info(self):
189 cdef:
190 afc_error_t err
191 char** infos = NULL
192 bytes info
193 int i = 0
194 list result = []
195 err = afc_get_device_info(self._c_client, &infos)
196 try:
197 self.handle_error(err)
198 except BaseError, e:
199 raise
200 finally:
201 if infos != NULL:
202 while infos[i]:
203 info = infos[i]
204 result.append(info)
205 free(infos[i])
206 i = i + 1
207 free(infos)
208
209 return result
210
211 cpdef list read_directory(self, bytes directory):
212 cdef:
213 afc_error_t err
214 char** dir_list = NULL
215 bytes f
216 int i = 0
217 list result = []
218 err = afc_read_directory(self._c_client, directory, &dir_list)
219 try:
220 self.handle_error(err)
221 except BaseError, e:
222 raise
223 finally:
224 if dir_list != NULL:
225 while dir_list[i]:
226 f = dir_list[i]
227 result.append(f)
228 free(dir_list[i])
229 i = i + 1
230 free(dir_list)
231
232 return result
233
234 cpdef AfcFile open(self, bytes filename, bytes mode=b'r'):
235 cdef:
236 afc_file_mode_t c_mode
237 uint64_t handle
238 AfcFile f
239 if mode == b'r':
240 c_mode = AFC_FOPEN_RDONLY
241 elif mode == b'r+':
242 c_mode = AFC_FOPEN_RW
243 elif mode == b'w':
244 c_mode = AFC_FOPEN_WRONLY
245 elif mode == b'w+':
246 c_mode = AFC_FOPEN_WR
247 elif mode == b'a':
248 c_mode = AFC_FOPEN_APPEND
249 elif mode == b'a+':
250 c_mode = AFC_FOPEN_RDAPPEND
251 else:
252 raise ValueError("mode string must be 'r', 'r+', 'w', 'w+', 'a', or 'a+'")
253
254 self.handle_error(afc_file_open(self._c_client, filename, c_mode, &handle))
255 f = AfcFile.__new__(AfcFile)
256 f._c_handle = handle
257 f._client = self
258 f._filename = filename
259
260 return f
261
262 cpdef list get_file_info(self, bytes path):
263 cdef:
264 list result = []
265 char** c_result = NULL
266 int i = 0
267 bytes info
268 try:
269 self.handle_error(afc_get_file_info(self._c_client, path, &c_result))
270 except BaseError, e:
271 raise
272 finally:
273 if c_result != NULL:
274 while c_result[i]:
275 info = c_result[i]
276 result.append(info)
277 free(c_result[i])
278 i = i + 1
279 free(c_result)
280
281 return result
282
283 cpdef remove_path(self, bytes path):
284 self.handle_error(afc_remove_path(self._c_client, path))
285
286 cpdef remove_path_and_contents(self, bytes path):
287 self.handle_error(afc_remove_path_and_contents(self._c_client, path))
288
289 cpdef rename_path(self, bytes f, bytes t):
290 self.handle_error(afc_rename_path(self._c_client, f, t))
291
292 cpdef make_directory(self, bytes d):
293 self.handle_error(afc_make_directory(self._c_client, d))
294
295 cpdef truncate(self, bytes path, uint64_t newsize):
296 self.handle_error(afc_truncate(self._c_client, path, newsize))
297
298 cpdef link(self, bytes source, bytes link_name):
299 self.handle_error(afc_make_link(self._c_client, AFC_HARDLINK, source, link_name))
300
301 cpdef symlink(self, bytes source, bytes link_name):
302 self.handle_error(afc_make_link(self._c_client, AFC_SYMLINK, source, link_name))
303
304 cpdef set_file_time(self, bytes path, uint64_t mtime):
305 self.handle_error(afc_set_file_time(self._c_client, path, mtime))
306
307cdef class Afc2Client(AfcClient):
308 __service_name__ = "com.apple.afc2"
309
310 cpdef AfcFile open(self, bytes filename, bytes mode=b'r'):
311 cdef:
312 afc_file_mode_t c_mode
313 uint64_t handle
314 AfcFile f
315 if mode == b'r':
316 c_mode = AFC_FOPEN_RDONLY
317 elif mode == b'r+':
318 c_mode = AFC_FOPEN_RW
319 elif mode == b'w':
320 c_mode = AFC_FOPEN_WRONLY
321 elif mode == b'w+':
322 c_mode = AFC_FOPEN_WR
323 elif mode == b'a':
324 c_mode = AFC_FOPEN_APPEND
325 elif mode == b'a+':
326 c_mode = AFC_FOPEN_RDAPPEND
327 else:
328 raise ValueError("mode string must be 'r', 'r+', 'w', 'w+', 'a', or 'a+'")
329
330 self.handle_error(afc_file_open(self._c_client, filename, c_mode, &handle))
331 f = AfcFile.__new__(AfcFile)
332 f._c_handle = handle
333 f._client = <AfcClient>self
334 f._filename = filename
335
336 return f
337