summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AFC.c208
-rw-r--r--src/AFC.h36
2 files changed, 131 insertions, 113 deletions
diff --git a/src/AFC.c b/src/AFC.c
index 3985551..7b6608f 100644
--- a/src/AFC.c
+++ b/src/AFC.c
@@ -23,6 +23,7 @@
23#include "AFC.h" 23#include "AFC.h"
24#include "plist.h" 24#include "plist.h"
25 25
26
26// This is the maximum size an AFC data packet can be 27// This is the maximum size an AFC data packet can be
27const int MAXIMUM_PACKET_SIZE = (2 << 15) - 32; 28const int MAXIMUM_PACKET_SIZE = (2 << 15) - 32;
28 29
@@ -32,7 +33,7 @@ extern int debug;
32 * 33 *
33 * @param client The AFC client connection to lock 34 * @param client The AFC client connection to lock
34 */ 35 */
35static void afc_lock(AFClient *client) { 36static void afc_lock(iphone_afc_client_t client) {
36 if (debug) fprintf(stderr, "Locked\n"); 37 if (debug) fprintf(stderr, "Locked\n");
37 while (client->lock) { 38 while (client->lock) {
38 usleep(500); // they say it's obsolete, but whatever 39 usleep(500); // they say it's obsolete, but whatever
@@ -44,7 +45,7 @@ static void afc_lock(AFClient *client) {
44 * 45 *
45 * @param client The AFC 46 * @param client The AFC
46 */ 47 */
47static void afc_unlock(AFClient *client) { // just to be pretty 48static void afc_unlock(iphone_afc_client_t client) { // just to be pretty
48 if (debug) fprintf(stderr, "Unlocked\n"); 49 if (debug) fprintf(stderr, "Unlocked\n");
49 client->lock = 0; 50 client->lock = 0;
50} 51}
@@ -57,50 +58,52 @@ static void afc_unlock(AFClient *client) { // just to be pretty
57 * 58 *
58 * @return A handle to the newly-connected client or NULL upon error. 59 * @return A handle to the newly-connected client or NULL upon error.
59 */ 60 */
60AFClient *afc_connect(iPhone *phone, int s_port, int d_port) { 61int iphone_afc_new_client ( iphone_device_t device, int src_port, int dst_port, iphone_afc_client_t *client ) {
61 AFClient *client = (AFClient*)malloc(sizeof(AFClient)); 62 int ret = IPHONE_E_SUCCESS;
63 iphone_afc_client_t client_loc = (iphone_afc_client_t)malloc(sizeof(struct iphone_afc_client_int));
62 64
63 if (!phone) return NULL; 65 if (!device) return IPHONE_E_INVALID_ARG;
64 66
65 // Attempt connection 67 // Attempt connection
66 client->connection = mux_connect(phone, s_port, d_port); 68 client_loc->connection = NULL;
67 if (!client->connection) { 69 ret = iphone_mux_new_client(device, src_port, dst_port,&client_loc->connection);
68 free(client); 70 if (IPHONE_E_SUCCESS != ret || !client_loc->connection) {
69 return NULL; 71 free(client_loc);
72 return ret;
70 } 73 }
71 74
72 // Allocate a packet 75 // Allocate a packet
73 client->afc_packet = (AFCPacket*)malloc(sizeof(AFCPacket)); 76 client_loc->afc_packet = (AFCPacket*)malloc(sizeof(AFCPacket));
74 if (!client->afc_packet) { 77 if (!client_loc->afc_packet) {
75 mux_close_connection(client->connection); 78 mux_close_connection(client_loc->connection);
76 free(client); 79 free(client_loc);
77 return NULL; 80 return IPHONE_E_UNKNOWN_ERROR;
78 } 81 }
79 82
80 client->afc_packet->packet_num = 0; 83 client_loc->afc_packet->packet_num = 0;
81 client->afc_packet->unknown1 = 0; 84 client_loc->afc_packet->unknown1 = 0;
82 client->afc_packet->unknown2 = 0; 85 client_loc->afc_packet->unknown2 = 0;
83 client->afc_packet->unknown3 = 0; 86 client_loc->afc_packet->unknown3 = 0;
84 client->afc_packet->unknown4 = 0; 87 client_loc->afc_packet->unknown4 = 0;
85 client->afc_packet->entire_length = 0; 88 client_loc->afc_packet->entire_length = 0;
86 client->afc_packet->this_length = 0; 89 client_loc->afc_packet->this_length = 0;
87 client->afc_packet->header1 = 0x36414643; 90 client_loc->afc_packet->header1 = 0x36414643;
88 client->afc_packet->header2 = 0x4141504C; 91 client_loc->afc_packet->header2 = 0x4141504C;
89 client->file_handle = 0; 92 client_loc->file_handle = 0;
90 client->lock = 0; 93 client_loc->lock = 0;
91 94
92 return client; 95 *client = client_loc;
96 return IPHONE_E_SUCCESS;
93} 97}
94 98
95/** Disconnects an AFC client from the phone. 99/** Disconnects an AFC client from the phone.
96 * 100 *
97 * @param client The client to disconnect. 101 * @param client The client to disconnect.
98 */ 102 */
99 103void iphone_afc_free_client ( iphone_afc_client_t client ) {
100void afc_disconnect(AFClient *client) {
101 if (!client || !client->connection || !client->afc_packet) return; 104 if (!client || !client->connection || !client->afc_packet) return;
102 105
103 mux_close_connection(client->connection); 106 iphone_mux_free_client(client->connection);
104 free(client->afc_packet); 107 free(client->afc_packet);
105 free(client); 108 free(client);
106} 109}
@@ -119,7 +122,7 @@ void afc_disconnect(AFClient *client) {
119 * reason is that if you set them to different values, it indicates 122 * reason is that if you set them to different values, it indicates
120 * you want to send the data as two packets. 123 * you want to send the data as two packets.
121 */ 124 */
122static int dispatch_AFC_packet(AFClient *client, const char *data, int length) { 125static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, int length) {
123 int bytes = 0, offset = 0; 126 int bytes = 0, offset = 0;
124 char *buffer; 127 char *buffer;
125 128
@@ -200,7 +203,7 @@ static int dispatch_AFC_packet(AFClient *client, const char *data, int length) {
200 * AFC_ERROR operation) 203 * AFC_ERROR operation)
201 */ 204 */
202 205
203static int receive_AFC_data(AFClient *client, char **dump_here) { 206static int receive_AFC_data(iphone_afc_client_t client, char **dump_here) {
204 AFCPacket *r_packet; 207 AFCPacket *r_packet;
205 char *buffer = (char*)malloc(sizeof(AFCPacket) * 4); 208 char *buffer = (char*)malloc(sizeof(AFCPacket) * 4);
206 char *final_buffer = NULL; 209 char *final_buffer = NULL;
@@ -321,7 +324,7 @@ static char **make_strings_list(char *tokens, int true_length) {
321 * @return A char ** list of files in that directory, terminated by an empty 324 * @return A char ** list of files in that directory, terminated by an empty
322 * string for now or NULL if there was an error. 325 * string for now or NULL if there was an error.
323 */ 326 */
324char **afc_get_dir_list(AFClient *client, const char *dir) { 327char **iphone_afc_get_dir_list ( iphone_afc_client_t client, const char *dir) {
325 int bytes = 0; 328 int bytes = 0;
326 char *data = NULL, **list = NULL; 329 char *data = NULL, **list = NULL;
327 330
@@ -362,7 +365,7 @@ char **afc_get_dir_list(AFClient *client, const char *dir) {
362 * @return A char ** list of parameters as given by AFC or NULL if there was an 365 * @return A char ** list of parameters as given by AFC or NULL if there was an
363 * error. 366 * error.
364 */ 367 */
365char **afc_get_devinfo(AFClient *client) { 368char **iphone_afc_get_devinfo ( iphone_afc_client_t client ) {
366 int bytes = 0; 369 int bytes = 0;
367 char *data = NULL, **list = NULL; 370 char *data = NULL, **list = NULL;
368 371
@@ -400,13 +403,14 @@ char **afc_get_devinfo(AFClient *client) {
400 * @param client The client to have delete the file. 403 * @param client The client to have delete the file.
401 * @param path The file to delete. (must be a fully-qualified path) 404 * @param path The file to delete. (must be a fully-qualified path)
402 * 405 *
403 * @return 1 on success, 0 on failure. 406 * @return IPHONE_E_SUCCESS if everythong went well, IPHONE_E_INVALID_ARG
407 * if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise.
404 */ 408 */
405int afc_delete_file(AFClient *client, const char *path) { 409int iphone_afc_delete_file ( iphone_afc_client_t client, const char *path) {
406 char *response = NULL; 410 char *response = NULL;
407 int bytes; 411 int bytes;
408 412
409 if (!client || !path || !client->afc_packet || !client->connection) return 0; 413 if (!client || !path || !client->afc_packet || !client->connection) return IPHONE_E_INVALID_ARG;
410 414
411 afc_lock(client); 415 afc_lock(client);
412 416
@@ -416,7 +420,7 @@ int afc_delete_file(AFClient *client, const char *path) {
416 bytes = dispatch_AFC_packet(client, path, strlen(path)); 420 bytes = dispatch_AFC_packet(client, path, strlen(path));
417 if (bytes <= 0) { 421 if (bytes <= 0) {
418 afc_unlock(client); 422 afc_unlock(client);
419 return 0; 423 return IPHONE_E_NOT_ENOUGH_DATA;
420 } 424 }
421 425
422 // Receive response 426 // Receive response
@@ -426,9 +430,9 @@ int afc_delete_file(AFClient *client, const char *path) {
426 afc_unlock(client); 430 afc_unlock(client);
427 431
428 if (bytes < 0) { 432 if (bytes < 0) {
429 return 0; 433 return IPHONE_E_NOT_ENOUGH_DATA;
430 } else { 434 } else {
431 return 1; 435 return IPHONE_E_SUCCESS;
432 } 436 }
433} 437}
434 438
@@ -438,14 +442,15 @@ int afc_delete_file(AFClient *client, const char *path) {
438 * @param from The file to rename. (must be a fully-qualified path) 442 * @param from The file to rename. (must be a fully-qualified path)
439 * @param to The new name of the file. (must also be a fully-qualified path) 443 * @param to The new name of the file. (must also be a fully-qualified path)
440 * 444 *
441 * @return 1 on success, 0 on failure. 445 * @return IPHONE_E_SUCCESS if everythong went well, IPHONE_E_INVALID_ARG
446 * if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise.
442 */ 447 */
443int afc_rename_file(AFClient *client, const char *from, const char *to) { 448int iphone_afc_rename_file ( iphone_afc_client_t client, const char *from, const char *to) {
444 char *response = NULL; 449 char *response = NULL;
445 char *send = (char*)malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32))); 450 char *send = (char*)malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32)));
446 int bytes = 0; 451 int bytes = 0;
447 452
448 if (!client || !from || !to || !client->afc_packet || !client->connection) return 0; 453 if (!client || !from || !to || !client->afc_packet || !client->connection) return IPHONE_E_INVALID_ARG;
449 454
450 afc_lock(client); 455 afc_lock(client);
451 456
@@ -458,7 +463,7 @@ int afc_rename_file(AFClient *client, const char *from, const char *to) {
458 free(send); 463 free(send);
459 if (bytes <= 0) { 464 if (bytes <= 0) {
460 afc_unlock(client); 465 afc_unlock(client);
461 return 0; 466 return IPHONE_E_NOT_ENOUGH_DATA;
462 } 467 }
463 468
464 // Receive response 469 // Receive response
@@ -468,9 +473,9 @@ int afc_rename_file(AFClient *client, const char *from, const char *to) {
468 afc_unlock(client); 473 afc_unlock(client);
469 474
470 if (bytes < 0) { 475 if (bytes < 0) {
471 return 0; 476 return IPHONE_E_NOT_ENOUGH_DATA;
472 } else { 477 } else {
473 return 1; 478 return IPHONE_E_SUCCESS;
474 } 479 }
475} 480}
476 481
@@ -479,15 +484,15 @@ int afc_rename_file(AFClient *client, const char *from, const char *to) {
479 * @param client The client to use to make a directory. 484 * @param client The client to use to make a directory.
480 * @param dir The directory's path. (must be a fully-qualified path, I assume 485 * @param dir The directory's path. (must be a fully-qualified path, I assume
481 * all other mkdir restrictions apply as well) 486 * all other mkdir restrictions apply as well)
482 * 487 *
483 * @return 1 on success, 0 on failure. 488 * @return IPHONE_E_SUCCESS if everythong went well, IPHONE_E_INVALID_ARG
489 * if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise.
484 */ 490 */
485 491int iphone_afc_mkdir ( iphone_afc_client_t client, const char *dir) {
486int afc_mkdir(AFClient *client, const char *dir) {
487 int bytes = 0; 492 int bytes = 0;
488 char *response = NULL; 493 char *response = NULL;
489 494
490 if (!client) return 0; 495 if (!client) return IPHONE_E_INVALID_ARG;
491 496
492 afc_lock(client); 497 afc_lock(client);
493 498
@@ -497,7 +502,7 @@ int afc_mkdir(AFClient *client, const char *dir) {
497 bytes = dispatch_AFC_packet(client, dir, strlen(dir)); 502 bytes = dispatch_AFC_packet(client, dir, strlen(dir));
498 if (bytes <= 0) { 503 if (bytes <= 0) {
499 afc_unlock(client); 504 afc_unlock(client);
500 return 0; 505 return IPHONE_E_NOT_ENOUGH_DATA;
501 } 506 }
502 507
503 // Receive response 508 // Receive response
@@ -506,10 +511,10 @@ int afc_mkdir(AFClient *client, const char *dir) {
506 511
507 afc_unlock(client); 512 afc_unlock(client);
508 513
509 if (bytes == 0) { 514 if (bytes < 0) {
510 return 1; 515 return IPHONE_E_NOT_ENOUGH_DATA;
511 } else { 516 } else {
512 return 0; 517 return IPHONE_E_SUCCESS;
513 } 518 }
514} 519}
515 520
@@ -521,9 +526,9 @@ int afc_mkdir(AFClient *client, const char *dir) {
521 * @return A pointer to an AFCFile struct containing the information received, 526 * @return A pointer to an AFCFile struct containing the information received,
522 * or NULL on failure. 527 * or NULL on failure.
523 */ 528 */
524AFCFile *afc_get_file_info(AFClient *client, const char *path) { 529iphone_afc_file_t afc_get_file_info(iphone_afc_client_t client, const char *path) {
525 char *received, **list; 530 char *received, **list;
526 AFCFile *my_file; 531 iphone_afc_file_t my_file;
527 int length, i = 0; 532 int length, i = 0;
528 533
529 afc_lock(client); 534 afc_lock(client);
@@ -547,7 +552,7 @@ AFCFile *afc_get_file_info(AFClient *client, const char *path) {
547 552
548 // Parse the data 553 // Parse the data
549 if (list) { 554 if (list) {
550 my_file = (AFCFile *)malloc(sizeof(AFCFile)); 555 my_file = (iphone_afc_file_t)malloc(sizeof(struct iphone_afc_file_int));
551 for (i = 0; list[i]; i++) { 556 for (i = 0; list[i]; i++) {
552 if (!strcmp(list[i], "st_size")) { 557 if (!strcmp(list[i], "st_size")) {
553 my_file->size = atoi(list[i+1]); 558 my_file->size = atoi(list[i+1]);
@@ -572,6 +577,36 @@ AFCFile *afc_get_file_info(AFClient *client, const char *path) {
572 } 577 }
573} 578}
574 579
580/** Gets information about a specific file.
581 *
582 * @param client The client to use to get the information of the file.
583 * @param path The fully-qualified path to the file
584 * @param stbuf output buffer where file information will be stored
585 *
586 * @return A pointer to an AFCFile struct containing the information received,
587 * or NULL on failure.
588 */
589int iphone_afc_get_file_attr ( iphone_afc_client_t client, const char *filename, struct stat *stbuf ) {
590
591 int ret = IPHONE_E_SUCCESS;
592 if (!client ||!client->connection || !client->afc_packet || !stbuf) return IPHONE_E_INVALID_ARG;
593
594 memset(stbuf, 0, sizeof(struct stat));
595 iphone_afc_file_t file = afc_get_file_info(client, filename);
596 if (!file){
597 ret = IPHONE_E_NO_SUCH_FILE;
598 } else {
599 stbuf->st_mode = file->type | 0644; // but we don't want anything on the iPhone executable, like, ever
600 stbuf->st_size = file->size;
601 stbuf->st_blksize = 2048; // FIXME: Is this the actual block size used on the iPhone?
602 stbuf->st_blocks = file->blocks;
603 stbuf->st_uid = getuid();
604 stbuf->st_gid = getgid();
605
606 afc_close_file(client,file);
607 }
608}
609
575/** Opens a file on the phone. 610/** Opens a file on the phone.
576 * 611 *
577 * @param client The client to use to open the file. 612 * @param client The client to use to open the file.
@@ -585,13 +620,13 @@ AFCFile *afc_get_file_info(AFClient *client, const char *path) {
585 * received by afc_get_file_info) as well as the handle to the file or 620 * received by afc_get_file_info) as well as the handle to the file or
586 * NULL in the case of failure. 621 * NULL in the case of failure.
587 */ 622 */
588AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode) { 623int iphone_afc_open_file ( iphone_afc_client_t client, const char *filename, uint32_t file_mode, iphone_afc_file_t *file ) {
589 AFCFile *file_infos = NULL; 624 iphone_afc_file_t file_loc = NULL;
590 uint32 ag = 0; 625 uint32 ag = 0;
591 int bytes = 0, length = 0; 626 int bytes = 0, length = 0;
592 char *data = (char*)malloc(sizeof(char) * (8 + strlen(filename) + 1)); 627 char *data = (char*)malloc(sizeof(char) * (8 + strlen(filename) + 1));
593 628
594 if (!client ||!client->connection || !client->afc_packet) return NULL; 629 if (!client ||!client->connection || !client->afc_packet) return IPHONE_E_INVALID_ARG;
595 630
596 afc_lock(client); 631 afc_lock(client);
597 632
@@ -608,7 +643,7 @@ AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode)
608 if (bytes <= 0) { 643 if (bytes <= 0) {
609 if (debug) fprintf(stderr, "afc_open_file: Didn't receive a response to the command\n"); 644 if (debug) fprintf(stderr, "afc_open_file: Didn't receive a response to the command\n");
610 afc_unlock(client); 645 afc_unlock(client);
611 return NULL; 646 return IPHONE_E_NOT_ENOUGH_DATA;
612 } 647 }
613 648
614 // Receive the data 649 // Receive the data
@@ -617,19 +652,20 @@ AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode)
617 afc_unlock(client); 652 afc_unlock(client);
618 653
619 // Get the file info and return it 654 // Get the file info and return it
620 file_infos = afc_get_file_info(client, filename); 655 file_loc = afc_get_file_info(client, filename);
621 memcpy(&file_infos->filehandle, data, 4); 656 memcpy(&file_loc->filehandle, data, 4);
622 free(data); 657 free(data);
623 return file_infos; 658 *file = file_loc;
659 return IPHONE_E_SUCCESS;
624 } else { 660 } else {
625 if (debug) fprintf(stderr, "afc_open_file: Didn't get any further data\n"); 661 if (debug) fprintf(stderr, "afc_open_file: Didn't get any further data\n");
626 afc_unlock(client); 662 afc_unlock(client);
627 return NULL; 663 return IPHONE_E_NOT_ENOUGH_DATA;
628 } 664 }
629 665
630 afc_unlock(client); 666 afc_unlock(client);
631 667
632 return NULL; 668 return IPHONE_E_UNKNOWN_ERROR;
633} 669}
634 670
635/** Attempts to the read the given number of bytes from the given file. 671/** Attempts to the read the given number of bytes from the given file.
@@ -641,7 +677,7 @@ AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode)
641 * 677 *
642 * @return The number of bytes read if successful. If there was an error -1. 678 * @return The number of bytes read if successful. If there was an error -1.
643 */ 679 */
644int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) { 680int iphone_afc_read_file ( iphone_afc_client_t client, iphone_afc_file_t file, char *data, int length) {
645 char *input = NULL; 681 char *input = NULL;
646 int current_count = 0, bytes = 0; 682 int current_count = 0, bytes = 0;
647 const int MAXIMUM_READ_SIZE = 1 << 16; 683 const int MAXIMUM_READ_SIZE = 1 << 16;
@@ -708,8 +744,7 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {
708 * @return The number of bytes written to the file, or a value less than 0 if 744 * @return The number of bytes written to the file, or a value less than 0 if
709 * none were written... 745 * none were written...
710 */ 746 */
711 747int iphone_afc_write_file ( iphone_afc_client_t client, iphone_afc_file_t file, const char *data, int length) {
712int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length) {
713 char *acknowledgement = NULL; 748 char *acknowledgement = NULL;
714 const int MAXIMUM_WRITE_SIZE = 1 << 16; 749 const int MAXIMUM_WRITE_SIZE = 1 << 16;
715 uint32 zero = 0, bytes = 0, segments = (length / MAXIMUM_WRITE_SIZE), current_count = 0, i = 0; 750 uint32 zero = 0, bytes = 0, segments = (length / MAXIMUM_WRITE_SIZE), current_count = 0, i = 0;
@@ -737,8 +772,8 @@ int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length
737 return bytes; 772 return bytes;
738 } 773 }
739 free(out_buffer); 774 free(out_buffer);
740 out_buffer = NULL; 775 out_buffer = NULL;
741 776
742 current_count += bytes; 777 current_count += bytes;
743 bytes = receive_AFC_data(client, &acknowledgement); 778 bytes = receive_AFC_data(client, &acknowledgement);
744 if (bytes < 0) { 779 if (bytes < 0) {
@@ -763,7 +798,7 @@ int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length
763 memcpy(out_buffer+8, data+current_count, (length - current_count)); 798 memcpy(out_buffer+8, data+current_count, (length - current_count));
764 bytes = dispatch_AFC_packet(client, out_buffer, (length - current_count) + 8); 799 bytes = dispatch_AFC_packet(client, out_buffer, (length - current_count) + 8);
765 free(out_buffer); 800 free(out_buffer);
766 out_buffer = NULL; 801 out_buffer = NULL;
767 802
768 current_count += bytes; 803 current_count += bytes;
769 804
@@ -788,7 +823,7 @@ int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length
788 * @param file A pointer to an AFCFile struct containing the file handle of the 823 * @param file A pointer to an AFCFile struct containing the file handle of the
789 * file to close. 824 * file to close.
790 */ 825 */
791void afc_close_file(AFClient *client, AFCFile *file) { 826void iphone_afc_close_file ( iphone_afc_client_t client, iphone_afc_file_t file) {
792 char *buffer = malloc(sizeof(char) * 8); 827 char *buffer = malloc(sizeof(char) * 8);
793 uint32 zero = 0; 828 uint32 zero = 0;
794 int bytes = 0; 829 int bytes = 0;
@@ -817,7 +852,7 @@ void afc_close_file(AFClient *client, AFCFile *file) {
817 // Receive the response 852 // Receive the response
818 bytes = receive_AFC_data(client, &buffer); 853 bytes = receive_AFC_data(client, &buffer);
819 if (buffer) free(buffer); 854 if (buffer) free(buffer);
820 855 free(file);
821 afc_unlock(client); 856 afc_unlock(client);
822} 857}
823 858
@@ -828,10 +863,9 @@ void afc_close_file(AFClient *client, AFCFile *file) {
828 * @param seekpos Where to seek to. If passed a negative value, this will seek 863 * @param seekpos Where to seek to. If passed a negative value, this will seek
829 * from the end of the file. 864 * from the end of the file.
830 * 865 *
831 * @return 0 on success, -1 on failure. 866 * @return IPHONE_E_SUCCESS on success, IPHONE_E_NOT_ENOUGH_DATA on failure.
832 */ 867 */
833 868int iphone_afc_seek_file ( iphone_afc_client_t client, iphone_afc_file_t file, int seekpos) {
834int afc_seek_file(AFClient *client, AFCFile *file, int seekpos) {
835 char *buffer = (char*)malloc(sizeof(char) * 24); 869 char *buffer = (char*)malloc(sizeof(char) * 24);
836 uint32 seekto = 0, bytes = 0, zero = 0; 870 uint32 seekto = 0, bytes = 0, zero = 0;
837 871
@@ -855,7 +889,7 @@ int afc_seek_file(AFClient *client, AFCFile *file, int seekpos) {
855 889
856 if (bytes <= 0) { 890 if (bytes <= 0) {
857 afc_unlock(client); 891 afc_unlock(client);
858 return -1; 892 return IPHONE_E_NOT_ENOUGH_DATA;
859 } 893 }
860 894
861 // Receive response 895 // Receive response
@@ -865,9 +899,9 @@ int afc_seek_file(AFClient *client, AFCFile *file, int seekpos) {
865 afc_unlock(client); 899 afc_unlock(client);
866 900
867 if (bytes >= 0) { 901 if (bytes >= 0) {
868 return 0; 902 return IPHONE_E_SUCCESS;
869 } else { 903 } else {
870 return -1; 904 return IPHONE_E_NOT_ENOUGH_DATA;
871 } 905 }
872} 906}
873 907
@@ -882,7 +916,7 @@ int afc_seek_file(AFClient *client, AFCFile *file, int seekpos) {
882 * @note This function is more akin to ftruncate than truncate, and truncate 916 * @note This function is more akin to ftruncate than truncate, and truncate
883 * calls would have to open the file before calling this, sadly. 917 * calls would have to open the file before calling this, sadly.
884 */ 918 */
885int afc_truncate_file(AFClient *client, AFCFile *file, uint32 newsize) { 919int iphone_afc_truncate_file ( iphone_afc_client_t client, iphone_afc_file_t file, uint32_t newsize) {
886 char *buffer = (char*)malloc(sizeof(char) * 16); 920 char *buffer = (char*)malloc(sizeof(char) * 16);
887 uint32 bytes = 0, zero = 0; 921 uint32 bytes = 0, zero = 0;
888 922
@@ -901,7 +935,7 @@ int afc_truncate_file(AFClient *client, AFCFile *file, uint32 newsize) {
901 935
902 if (bytes <= 0) { 936 if (bytes <= 0) {
903 afc_unlock(client); 937 afc_unlock(client);
904 return -1; 938 return IPHONE_E_NOT_ENOUGH_DATA;
905 } 939 }
906 940
907 // Receive response 941 // Receive response
@@ -911,8 +945,8 @@ int afc_truncate_file(AFClient *client, AFCFile *file, uint32 newsize) {
911 afc_unlock(client); 945 afc_unlock(client);
912 946
913 if (bytes >= 0) { 947 if (bytes >= 0) {
914 return 0; 948 return IPHONE_E_SUCCESS;
915 } else { 949 } else {
916 return -1; 950 return IPHONE_E_NOT_ENOUGH_DATA;
917 } 951 }
918} 952}
diff --git a/src/AFC.h b/src/AFC.h
index e04ce63..60cb22a 100644
--- a/src/AFC.h
+++ b/src/AFC.h
@@ -33,25 +33,24 @@ typedef struct {
33} AFCPacket; 33} AFCPacket;
34 34
35typedef struct { 35typedef struct {
36 usbmux_connection *connection;
37 AFCPacket *afc_packet;
38 int file_handle;
39 int lock;
40} AFClient;
41
42typedef struct {
43 uint32 filehandle, unknown1, size, unknown2; 36 uint32 filehandle, unknown1, size, unknown2;
44} AFCFilePacket; 37} AFCFilePacket;
45 38
46typedef struct {
47 uint32 filehandle, blocks, size, type;
48} AFCFile;
49
50typedef struct __AFCToken { 39typedef struct __AFCToken {
51 struct __AFCToken *last, *next; 40 struct __AFCToken *last, *next;
52 char *token; 41 char *token;
53} AFCToken; 42} AFCToken;
54 43
44struct iphone_afc_client_int {
45 iphone_umux_client_t connection;
46 AFCPacket *afc_packet;
47 int file_handle;
48 int lock;
49};
50
51struct iphone_afc_file_int {
52 uint32 filehandle, blocks, size, type;
53};
55 54
56enum { 55enum {
57 AFC_FILE_READ = 0x00000002, // seems to be able to read and write files 56 AFC_FILE_READ = 0x00000002, // seems to be able to read and write files
@@ -82,18 +81,3 @@ enum {
82 AFC_WRITE = 0x00000010 81 AFC_WRITE = 0x00000010
83}; 82};
84 83
85AFClient *afc_connect(iPhone *phone, int s_port, int d_port);
86void afc_disconnect(AFClient *client);
87
88char **afc_get_devinfo(AFClient *client);
89char **afc_get_dir_list(AFClient *client, const char *dir);
90AFCFile *afc_get_file_info(AFClient *client, const char *path);
91AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode);
92void afc_close_file(AFClient *client, AFCFile *file);
93int afc_read_file(AFClient *client, AFCFile *file, char *data, int length);
94int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length);
95int afc_seek_file(AFClient *client, AFCFile *file, int seekpos);
96int afc_truncate_file(AFClient *client, AFCFile *file, uint32 newsize);
97int afc_delete_file(AFClient *client, const char *path);
98int afc_rename_file(AFClient *client, const char *from, const char *to);
99int afc_mkdir(AFClient *client, const char *dir);