summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Zach C2008-08-06 21:04:09 -0700
committerGravatar Matt Colyer2008-08-06 21:04:09 -0700
commitbef655966045af34e1f20a7211f0cab2e7e79001 (patch)
tree590b41891fab48af0c3f35431f7476bbc2b4b0a2 /src
parentd81a3c5c412cca9b8327d6d27625bc52650e9651 (diff)
downloadlibimobiledevice-bef655966045af34e1f20a7211f0cab2e7e79001.tar.gz
libimobiledevice-bef655966045af34e1f20a7211f0cab2e7e79001.tar.bz2
Adds locking and fixes a minor bug in mux_recv
Signed-off-by: Matt Colyer <matt@colyer.name>
Diffstat (limited to 'src')
-rw-r--r--src/AFC.c54
-rw-r--r--src/AFC.h1
-rw-r--r--src/ifuse.c2
-rw-r--r--src/iphone.c2
-rw-r--r--src/usbmux.c9
5 files changed, 58 insertions, 10 deletions
diff --git a/src/AFC.c b/src/AFC.c
index 5c9f68c..d7a4dda 100644
--- a/src/AFC.c
+++ b/src/AFC.c
@@ -26,6 +26,21 @@ const int MAXIMUM_PACKET_SIZE = (2 << 15) - 32;
26 26
27extern int debug; 27extern int debug;
28 28
29
30/* Locking, for thread-safety (well... kind of, hehe) */
31void afc_lock(AFClient *client) {
32 while (client->lock) {
33 sleep(200);
34 }
35 client->lock = 1;
36}
37
38void afc_unlock(AFClient *client) { // just to be pretty
39 client->lock = 0;
40}
41
42/* main AFC functions */
43
29AFClient *afc_connect(iPhone *phone, int s_port, int d_port) { 44AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {
30 if (!phone) return NULL; 45 if (!phone) return NULL;
31 AFClient *client = (AFClient*)malloc(sizeof(AFClient)); 46 AFClient *client = (AFClient*)malloc(sizeof(AFClient));
@@ -39,6 +54,7 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {
39 client->afc_packet->header1 = 0x36414643; 54 client->afc_packet->header1 = 0x36414643;
40 client->afc_packet->header2 = 0x4141504C; 55 client->afc_packet->header2 = 0x4141504C;
41 client->file_handle = 0; 56 client->file_handle = 0;
57 client->lock = 0;
42 return client; 58 return client;
43 } else { 59 } else {
44 mux_close_connection(client->connection); 60 mux_close_connection(client->connection);
@@ -184,6 +200,7 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
184 final_buffer = (char*)malloc(sizeof(char) * recv_len); 200 final_buffer = (char*)malloc(sizeof(char) * recv_len);
185 while(current_count < recv_len){ 201 while(current_count < recv_len){
186 bytes = mux_recv(client->connection, buffer, recv_len-current_count); 202 bytes = mux_recv(client->connection, buffer, recv_len-current_count);
203 if (debug) printf("receive_AFC_data: still collecting packets\n");
187 if (bytes < 0) 204 if (bytes < 0)
188 { 205 {
189 if(debug) printf("receive_AFC_data: mux_recv failed: %d\n", bytes); 206 if(debug) printf("receive_AFC_data: mux_recv failed: %d\n", bytes);
@@ -194,6 +211,12 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
194 if(debug) printf("receive_AFC_data: mux_recv delivered too much data\n"); 211 if(debug) printf("receive_AFC_data: mux_recv delivered too much data\n");
195 break; 212 break;
196 } 213 }
214 if (strstr(buffer, "CFA6LPAA")) {
215 if (debug) printf("receive_AFC_data: WARNING: there is AFC data in this packet at %i\n", strstr(buffer, "CFA6LPAA") - buffer);
216 if (debug) printf("receive_AFC_data: the total packet length is %i\n", bytes);
217 //continue; // but we do need to continue because packets/headers != data
218 }
219
197 memcpy(final_buffer+current_count, buffer, bytes); 220 memcpy(final_buffer+current_count, buffer, bytes);
198 current_count += bytes; 221 current_count += bytes;
199 } 222 }
@@ -211,18 +234,20 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
211} 234}
212 235
213char **afc_get_dir_list(AFClient *client, const char *dir) { 236char **afc_get_dir_list(AFClient *client, const char *dir) {
237 afc_lock(client);
214 client->afc_packet->operation = AFC_LIST_DIR; 238 client->afc_packet->operation = AFC_LIST_DIR;
215 int bytes = 0; 239 int bytes = 0;
216 char *blah = NULL, **list = NULL; 240 char *blah = NULL, **list = NULL;
217 client->afc_packet->entire_length = client->afc_packet->this_length = 0; 241 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
218 bytes = dispatch_AFC_packet(client, dir, strlen(dir)); 242 bytes = dispatch_AFC_packet(client, dir, strlen(dir));
219 if (!bytes) return NULL; 243 if (!bytes) { afc_unlock(client); return NULL; }
220 244
221 bytes = receive_AFC_data(client, &blah); 245 bytes = receive_AFC_data(client, &blah);
222 if (!bytes && !blah) return NULL; 246 if (!bytes && !blah) { afc_unlock(client); return NULL; }
223 247
224 list = make_strings_list(blah, bytes); 248 list = make_strings_list(blah, bytes);
225 free(blah); 249 free(blah);
250 afc_unlock(client);
226 return list; 251 return list;
227} 252}
228 253
@@ -243,23 +268,24 @@ char **make_strings_list(char *tokens, int true_length) {
243 268
244int afc_delete_file(AFClient *client, const char *path) { 269int afc_delete_file(AFClient *client, const char *path) {
245 if (!client || !path || !client->afc_packet || !client->connection) return 0; 270 if (!client || !path || !client->afc_packet || !client->connection) return 0;
246 271 afc_lock(client);
247 char *receive = NULL; 272 char *receive = NULL;
248 client->afc_packet->this_length = client->afc_packet->entire_length = 0; 273 client->afc_packet->this_length = client->afc_packet->entire_length = 0;
249 client->afc_packet->operation = AFC_DELETE; 274 client->afc_packet->operation = AFC_DELETE;
250 int bytes; 275 int bytes;
251 bytes = dispatch_AFC_packet(client, path, strlen(path)); 276 bytes = dispatch_AFC_packet(client, path, strlen(path));
252 if (bytes <= 0) return 0; 277 if (bytes <= 0) { afc_unlock(client); return 0; }
253 278
254 bytes = receive_AFC_data(client, &receive); 279 bytes = receive_AFC_data(client, &receive);
255 free(receive); 280 free(receive);
256 if (bytes <= 0) return 0; 281 afc_unlock(client);
282 if (bytes <= 0) { return 0; }
257 else return 1; 283 else return 1;
258} 284}
259 285
260int afc_rename_file(AFClient *client, const char *from, const char *to) { 286int afc_rename_file(AFClient *client, const char *from, const char *to) {
261 if (!client || !from || !to || !client->afc_packet || !client->connection) return 0; 287 if (!client || !from || !to || !client->afc_packet || !client->connection) return 0;
262 288 afc_lock(client);
263 char *receive = NULL; 289 char *receive = NULL;
264 char *send = (char*)malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32))); 290 char *send = (char*)malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32)));
265 int bytes = 0; 291 int bytes = 0;
@@ -271,10 +297,11 @@ int afc_rename_file(AFClient *client, const char *from, const char *to) {
271 client->afc_packet->entire_length = client->afc_packet->this_length = 0; 297 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
272 client->afc_packet->operation = AFC_RENAME; 298 client->afc_packet->operation = AFC_RENAME;
273 bytes = dispatch_AFC_packet(client, send, strlen(to) + strlen(from) + 2); 299 bytes = dispatch_AFC_packet(client, send, strlen(to) + strlen(from) + 2);
274 if (bytes <= 0) return 0; 300 if (bytes <= 0) { afc_unlock(client); return 0; }
275 301
276 bytes = receive_AFC_data(client, &receive); 302 bytes = receive_AFC_data(client, &receive);
277 free(receive); 303 free(receive);
304 afc_unlock(client);
278 if (bytes <= 0) return 0; 305 if (bytes <= 0) return 0;
279 else return 1; 306 else return 1;
280} 307}
@@ -284,6 +311,7 @@ int afc_rename_file(AFClient *client, const char *from, const char *to) {
284AFCFile *afc_get_file_info(AFClient *client, const char *path) { 311AFCFile *afc_get_file_info(AFClient *client, const char *path) {
285 client->afc_packet->operation = AFC_GET_INFO; 312 client->afc_packet->operation = AFC_GET_INFO;
286 client->afc_packet->entire_length = client->afc_packet->this_length = 0; 313 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
314 afc_lock(client);
287 dispatch_AFC_packet(client, path, strlen(path)); 315 dispatch_AFC_packet(client, path, strlen(path));
288 316
289 char *received, **list; 317 char *received, **list;
@@ -293,6 +321,7 @@ AFCFile *afc_get_file_info(AFClient *client, const char *path) {
293 length = receive_AFC_data(client, &received); 321 length = receive_AFC_data(client, &received);
294 list = make_strings_list(received, length); 322 list = make_strings_list(received, length);
295 free(received); 323 free(received);
324 afc_unlock(client); // the rest is just interpretation anyway
296 if (list) { 325 if (list) {
297 my_file = (AFCFile *)malloc(sizeof(AFCFile)); 326 my_file = (AFCFile *)malloc(sizeof(AFCFile));
298 for (i = 0; strcmp(list[i], ""); i++) { 327 for (i = 0; strcmp(list[i], ""); i++) {
@@ -323,6 +352,7 @@ AFCFile *afc_get_file_info(AFClient *client, const char *path) {
323AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode) { 352AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode) {
324 if (file_mode != AFC_FILE_READ && file_mode != AFC_FILE_WRITE) return NULL; 353 if (file_mode != AFC_FILE_READ && file_mode != AFC_FILE_WRITE) return NULL;
325 if (!client ||!client->connection || !client->afc_packet) return NULL; 354 if (!client ||!client->connection || !client->afc_packet) return NULL;
355 afc_lock(client);
326 char *further_data = (char*)malloc(sizeof(char) * (8 + strlen(filename) + 1)); 356 char *further_data = (char*)malloc(sizeof(char) * (8 + strlen(filename) + 1));
327 AFCFile *file_infos = NULL; 357 AFCFile *file_infos = NULL;
328 memcpy(further_data, &file_mode, 4); 358 memcpy(further_data, &file_mode, 4);
@@ -338,10 +368,12 @@ AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode)
338 free(further_data); 368 free(further_data);
339 if (bytes <= 0) { 369 if (bytes <= 0) {
340 if (debug) printf("didn't read enough\n"); 370 if (debug) printf("didn't read enough\n");
371 afc_unlock(client);
341 return NULL; 372 return NULL;
342 } else { 373 } else {
343 length_thing = receive_AFC_data(client, &further_data); 374 length_thing = receive_AFC_data(client, &further_data);
344 if (length_thing && further_data) { 375 if (length_thing && further_data) {
376 afc_unlock(client); // don't want to hang on the next call... and besides, it'll re-lock, do its thing, and unlock again anyway.
345 file_infos = afc_get_file_info(client, filename); 377 file_infos = afc_get_file_info(client, filename);
346 memcpy(&file_infos->filehandle, further_data, 4); 378 memcpy(&file_infos->filehandle, further_data, 4);
347 return file_infos; 379 return file_infos;
@@ -357,6 +389,8 @@ AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode)
357int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) { 389int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {
358 if (!client || !client->afc_packet || !client->connection || !file) return -1; 390 if (!client || !client->afc_packet || !client->connection || !file) return -1;
359 AFCFilePacket *packet = (AFCFilePacket*)malloc(sizeof(AFCFilePacket)); 391 AFCFilePacket *packet = (AFCFilePacket*)malloc(sizeof(AFCFilePacket));
392 if (debug) printf("afc_read_file called for length %i\n");
393 afc_lock(client);
360 char *input = NULL; 394 char *input = NULL;
361 packet->unknown1 = packet->unknown2 = 0; 395 packet->unknown1 = packet->unknown2 = 0;
362 packet->filehandle = file->filehandle; 396 packet->filehandle = file->filehandle;
@@ -369,6 +403,7 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {
369 403
370 if (bytes > 0) { 404 if (bytes > 0) {
371 bytes = receive_AFC_data(client, &input); 405 bytes = receive_AFC_data(client, &input);
406 afc_unlock(client);
372 if (bytes < 0) { 407 if (bytes < 0) {
373 if (input) free(input); 408 if (input) free(input);
374 return -1; 409 return -1;
@@ -382,6 +417,7 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {
382 return (bytes > length) ? length : bytes; 417 return (bytes > length) ? length : bytes;
383 } 418 }
384 } else { 419 } else {
420 afc_unlock(client);
385 return -1; 421 return -1;
386 } 422 }
387 return 0; 423 return 0;
@@ -390,6 +426,7 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {
390int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length) { 426int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length) {
391 char *acknowledgement = NULL; 427 char *acknowledgement = NULL;
392 if (!client ||!client->afc_packet || !client->connection || !file) return -1; 428 if (!client ||!client->afc_packet || !client->connection || !file) return -1;
429 afc_lock(client);
393 client->afc_packet->this_length = sizeof(AFCPacket) + 8; 430 client->afc_packet->this_length = sizeof(AFCPacket) + 8;
394 client->afc_packet->entire_length = client->afc_packet->this_length + length; 431 client->afc_packet->entire_length = client->afc_packet->this_length + length;
395 client->afc_packet->operation = AFC_WRITE; 432 client->afc_packet->operation = AFC_WRITE;
@@ -407,6 +444,7 @@ int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length
407 444
408 zero = bytes; 445 zero = bytes;
409 bytes = receive_AFC_data(client, &acknowledgement); 446 bytes = receive_AFC_data(client, &acknowledgement);
447 afc_unlock(client);
410 if (bytes <= 0) { 448 if (bytes <= 0) {
411 if (debug) printf("afc_write_file: uh oh?\n"); 449 if (debug) printf("afc_write_file: uh oh?\n");
412 } 450 }
@@ -418,6 +456,7 @@ void afc_close_file(AFClient *client, AFCFile *file) {
418 char *buffer = malloc(sizeof(char) * 8); 456 char *buffer = malloc(sizeof(char) * 8);
419 uint32 zero = 0; 457 uint32 zero = 0;
420 if (debug) printf("File handle %i\n", file->filehandle); 458 if (debug) printf("File handle %i\n", file->filehandle);
459 afc_lock(client);
421 memcpy(buffer, &file->filehandle, sizeof(uint32)); 460 memcpy(buffer, &file->filehandle, sizeof(uint32));
422 memcpy(buffer+sizeof(uint32), &zero, sizeof(zero)); 461 memcpy(buffer+sizeof(uint32), &zero, sizeof(zero));
423 client->afc_packet->operation = AFC_FILE_CLOSE; 462 client->afc_packet->operation = AFC_FILE_CLOSE;
@@ -430,6 +469,7 @@ void afc_close_file(AFClient *client, AFCFile *file) {
430 if (!bytes) return; 469 if (!bytes) return;
431 470
432 bytes = receive_AFC_data(client, &buffer); 471 bytes = receive_AFC_data(client, &buffer);
472 afc_unlock(client);
433 return; 473 return;
434 if (buffer) free(buffer); // we're *SUPPOSED* to get an "error" here. 474 if (buffer) free(buffer); // we're *SUPPOSED* to get an "error" here.
435} 475}
diff --git a/src/AFC.h b/src/AFC.h
index 2827030..32defbe 100644
--- a/src/AFC.h
+++ b/src/AFC.h
@@ -38,6 +38,7 @@ typedef struct {
38 usbmux_connection *connection; 38 usbmux_connection *connection;
39 AFCPacket *afc_packet; 39 AFCPacket *afc_packet;
40 int file_handle; 40 int file_handle;
41 int lock;
41} AFClient; 42} AFClient;
42 43
43typedef struct { 44typedef struct {
diff --git a/src/ifuse.c b/src/ifuse.c
index f33eaaa..7d6f72a 100644
--- a/src/ifuse.c
+++ b/src/ifuse.c
@@ -41,7 +41,7 @@
41GHashTable *file_handles; 41GHashTable *file_handles;
42int fh_index = 0; 42int fh_index = 0;
43 43
44int debug = 0; 44int debug = 1;
45 45
46static int ifuse_getattr(const char *path, struct stat *stbuf) { 46static int ifuse_getattr(const char *path, struct stat *stbuf) {
47 int res = 0; 47 int res = 0;
diff --git a/src/iphone.c b/src/iphone.c
index 6000a19..426b629 100644
--- a/src/iphone.c
+++ b/src/iphone.c
@@ -163,7 +163,7 @@ int send_to_phone(iPhone *phone, char *data, int datalen) {
163 * @param data Where to put data read 163 * @param data Where to put data read
164 * @param datalen How much data to read in 164 * @param datalen How much data to read in
165 * 165 *
166 * @returns How many bytes were read in, or -1 on error. 166 * @return How many bytes were read in, or -1 on error.
167 */ 167 */
168int recv_from_phone(iPhone *phone, char *data, int datalen) { 168int recv_from_phone(iPhone *phone, char *data, int datalen) {
169 if (!phone) return -1; 169 if (!phone) return -1;
diff --git a/src/usbmux.c b/src/usbmux.c
index 235a1f2..d79ee47 100644
--- a/src/usbmux.c
+++ b/src/usbmux.c
@@ -301,8 +301,15 @@ int mux_recv(usbmux_connection *connection, char *data, uint32 datalen) {
301 for (i = 0; i < connections; i++) { 301 for (i = 0; i < connections; i++) {
302 if (connlist[i]->header->sport == header->dport && connlist[i]->header->dport == header->sport) { 302 if (connlist[i]->header->sport == header->dport && connlist[i]->header->dport == header->sport) {
303 // we have a winner. 303 // we have a winner.
304 char *nfb = (char*)malloc(sizeof(char) * (connlist[i]->r_len + (bytes - 28)));
305 if (connlist[i]->recv_buffer && connlist[i]->r_len) {
306 memcpy(nfb, connlist[i]->recv_buffer, connlist[i]->r_len);
307 free(connlist[i]->recv_buffer);
308 }
304 connlist[i]->r_len += bytes - 28; 309 connlist[i]->r_len += bytes - 28;
305 connlist[i]->recv_buffer = (char*)realloc(connlist[i]->recv_buffer, sizeof(char) * connection->r_len); // grow their buffer 310 //connlist[i]->recv_buffer = (char*)realloc(connlist[i]->recv_buffer, sizeof(char) * connection->r_len); // grow their buffer
311 connlist[i]->recv_buffer = nfb;
312 nfb = NULL; // A cookie for you if you can guess what "nfb" means.
306 complex = connlist[i]->r_len - (bytes - 28); 313 complex = connlist[i]->r_len - (bytes - 28);
307 memcpy(connlist[i]->recv_buffer+complex, buffer+28, bytes-28); // paste into their buffer 314 memcpy(connlist[i]->recv_buffer+complex, buffer+28, bytes-28); // paste into their buffer
308 connlist[i]->header->ocnt += bytes-28; 315 connlist[i]->header->ocnt += bytes-28;