summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2009-07-03 22:11:01 +0200
committerGravatar Matt Colyer2009-07-07 08:31:25 -0700
commit9990d53ba2ff4e92b1844beb001dcc9c47d30f3e (patch)
tree1ac137519294fc2be6eed870811a8047bf8ed1e4
parent52d1beb6e43cc12ff57e648f1e5bdfadc4d36929 (diff)
downloadlibimobiledevice-9990d53ba2ff4e92b1844beb001dcc9c47d30f3e.tar.gz
libimobiledevice-9990d53ba2ff4e92b1844beb001dcc9c47d30f3e.tar.bz2
AFC cleanup: remove iphone_afc_file_* and use handles instead. Removed afc_get_file_attr because this function has to go into the program (like ifuse); afc_get_file_info has to be used instead. Modified dispatch_AFC_Packet so that the real buffer size has to be specified (instead of length-1).
-rw-r--r--dev/afccheck.c4
-rw-r--r--dev/main.c27
-rw-r--r--include/libiphone/libiphone.h19
-rw-r--r--src/AFC.c218
-rw-r--r--src/AFC.h11
5 files changed, 94 insertions, 185 deletions
diff --git a/dev/afccheck.c b/dev/afccheck.c
index 2f7d92c..965981b 100644
--- a/dev/afccheck.c
+++ b/dev/afccheck.c
@@ -50,13 +50,13 @@ void check_afc(gpointer data)
50 } 50 }
51 51
52 //now writes buffer on iphone 52 //now writes buffer on iphone
53 iphone_afc_file_t file = NULL; 53 uint64_t file = 0;
54 char path[50]; 54 char path[50];
55 sprintf(path, "/Buf%i", ((param *) data)->id); 55 sprintf(path, "/Buf%i", ((param *) data)->id);
56 iphone_afc_open_file(((param *) data)->afc, path, AFC_FOPEN_RW, &file); 56 iphone_afc_open_file(((param *) data)->afc, path, AFC_FOPEN_RW, &file);
57 iphone_afc_write_file(((param *) data)->afc, file, (char *) buf, buffersize, &bytes); 57 iphone_afc_write_file(((param *) data)->afc, file, (char *) buf, buffersize, &bytes);
58 iphone_afc_close_file(((param *) data)->afc, file); 58 iphone_afc_close_file(((param *) data)->afc, file);
59 file = NULL; 59 file = 0;
60 if (bytes != buffersize) 60 if (bytes != buffersize)
61 printf("Write operation failed\n"); 61 printf("Write operation failed\n");
62 62
diff --git a/dev/main.c b/dev/main.c
index 5c9a5a7..c8c9dfa 100644
--- a/dev/main.c
+++ b/dev/main.c
@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
59 int npp; 59 int npp;
60 iphone_lckd_client_t control = NULL; 60 iphone_lckd_client_t control = NULL;
61 iphone_device_t phone = NULL; 61 iphone_device_t phone = NULL;
62 iphone_afc_file_t lockfile = NULL; 62 uint64_t lockfile = 0;
63 iphone_np_client_t gnp = NULL; 63 iphone_np_client_t gnp = NULL;
64 64
65 if (argc > 1 && !strcasecmp(argv[1], "--debug")) { 65 if (argc > 1 && !strcasecmp(argv[1], "--debug")) {
@@ -148,14 +148,23 @@ int main(int argc, char *argv[])
148 } 148 }
149 g_strfreev(dirs); 149 g_strfreev(dirs);
150 150
151 iphone_afc_file_t my_file = NULL; 151 uint64_t my_file = 0;
152 struct stat stbuf; 152 char **info = NULL;
153 iphone_afc_get_file_attr(afc, "/iTunesOnTheGoPlaylist.plist", &stbuf); 153 uint64_t fsize = 0;
154 if (IPHONE_E_SUCCESS == iphone_afc_get_file_info(afc, "/readme.libiphone.fx", &info) && info) {
155 for (i = 0; info[i]; i += 2) {
156 printf("%s: %s\n", info[i], info[i+1]);
157 if (!strcmp(info[i], "st_size")) {
158 fsize = atoll(info[i+1]);
159 }
160 }
161 }
162
154 if (IPHONE_E_SUCCESS == 163 if (IPHONE_E_SUCCESS ==
155 iphone_afc_open_file(afc, "/iTunesOnTheGoPlaylist.plist", AFC_FOPEN_RDONLY, &my_file) && my_file) { 164 iphone_afc_open_file(afc, "/readme.libiphone.fx", AFC_FOPEN_RDONLY, &my_file) && my_file) {
156 printf("A file size: %i\n", (int) stbuf.st_size); 165 printf("A file size: %i\n", fsize);
157 char *file_data = (char *) malloc(sizeof(char) * stbuf.st_size); 166 char *file_data = (char *) malloc(sizeof(char) * fsize);
158 iphone_afc_read_file(afc, my_file, file_data, stbuf.st_size, &bytes); 167 iphone_afc_read_file(afc, my_file, file_data, fsize, &bytes);
159 if (bytes >= 0) { 168 if (bytes >= 0) {
160 printf("The file's data:\n"); 169 printf("The file's data:\n");
161 fwrite(file_data, 1, bytes, stdout); 170 fwrite(file_data, 1, bytes, stdout);
@@ -193,7 +202,7 @@ int main(int argc, char *argv[])
193 202
194 printf("Seek & read\n"); 203 printf("Seek & read\n");
195 iphone_afc_open_file(afc, "/readme.libiphone.fx", AFC_FOPEN_RDONLY, &my_file); 204 iphone_afc_open_file(afc, "/readme.libiphone.fx", AFC_FOPEN_RDONLY, &my_file);
196 if (IPHONE_E_SUCCESS != iphone_afc_seek_file(afc, my_file, 5)) 205 if (IPHONE_E_SUCCESS != iphone_afc_seek_file(afc, my_file, 5, SEEK_CUR))
197 printf("WARN: SEEK DID NOT WORK\n"); 206 printf("WARN: SEEK DID NOT WORK\n");
198 char *threeletterword = (char *) malloc(sizeof(char) * 5); 207 char *threeletterword = (char *) malloc(sizeof(char) * 5);
199 iphone_afc_read_file(afc, my_file, threeletterword, 3, &bytes); 208 iphone_afc_read_file(afc, my_file, threeletterword, 3, &bytes);
diff --git a/include/libiphone/libiphone.h b/include/libiphone/libiphone.h
index bd8d9fb..fc24d35 100644
--- a/include/libiphone/libiphone.h
+++ b/include/libiphone/libiphone.h
@@ -72,9 +72,6 @@ typedef struct iphone_lckd_client_int *iphone_lckd_client_t;
72struct iphone_afc_client_int; 72struct iphone_afc_client_int;
73typedef struct iphone_afc_client_int *iphone_afc_client_t; 73typedef struct iphone_afc_client_int *iphone_afc_client_t;
74 74
75struct iphone_afc_file_int;
76typedef struct iphone_afc_file_int *iphone_afc_file_t;
77
78struct iphone_msync_client_int; 75struct iphone_msync_client_int;
79typedef struct iphone_msync_client_int *iphone_msync_client_t; 76typedef struct iphone_msync_client_int *iphone_msync_client_t;
80 77
@@ -118,14 +115,14 @@ int iphone_afc_get_errno ( iphone_afc_client_t client );
118iphone_error_t iphone_afc_get_devinfo ( iphone_afc_client_t client, char ***infos ); 115iphone_error_t iphone_afc_get_devinfo ( iphone_afc_client_t client, char ***infos );
119iphone_error_t iphone_afc_get_dir_list ( iphone_afc_client_t client, const char *dir, char ***list); 116iphone_error_t iphone_afc_get_dir_list ( iphone_afc_client_t client, const char *dir, char ***list);
120 117
121iphone_error_t iphone_afc_get_file_attr ( iphone_afc_client_t client, const char *filename, struct stat *stbuf ); 118iphone_error_t iphone_afc_get_file_info ( iphone_afc_client_t client, const char *filename, char ***infolist );
122iphone_error_t iphone_afc_open_file ( iphone_afc_client_t client, const char *filename, iphone_afc_file_mode_t file_mode, iphone_afc_file_t *file ); 119iphone_error_t iphone_afc_open_file ( iphone_afc_client_t client, const char *filename, iphone_afc_file_mode_t file_mode, uint64_t *handle );
123iphone_error_t iphone_afc_close_file ( iphone_afc_client_t client, iphone_afc_file_t file); 120iphone_error_t iphone_afc_close_file ( iphone_afc_client_t client, uint64_t handle);
124iphone_error_t iphone_afc_lock_file ( iphone_afc_client_t client, iphone_afc_file_t file, int operation); 121iphone_error_t iphone_afc_lock_file ( iphone_afc_client_t client, uint64_t handle, int operation);
125iphone_error_t iphone_afc_read_file ( iphone_afc_client_t client, iphone_afc_file_t file, char *data, int length, uint32_t *bytes); 122iphone_error_t iphone_afc_read_file ( iphone_afc_client_t client, uint64_t handle, char *data, int length, uint32_t *bytes);
126iphone_error_t iphone_afc_write_file ( iphone_afc_client_t client, iphone_afc_file_t file, const char *data, int length, uint32_t *bytes); 123iphone_error_t iphone_afc_write_file ( iphone_afc_client_t client, uint64_t handle, const char *data, int length, uint32_t *bytes);
127iphone_error_t iphone_afc_seek_file ( iphone_afc_client_t client, iphone_afc_file_t file, int seekpos); 124iphone_error_t iphone_afc_seek_file ( iphone_afc_client_t client, uint64_t handle, int64_t offset, int whence);
128iphone_error_t iphone_afc_truncate_file ( iphone_afc_client_t client, iphone_afc_file_t file, uint32_t newsize); 125iphone_error_t iphone_afc_truncate_file ( iphone_afc_client_t client, uint64_t handle, uint64_t newsize);
129iphone_error_t iphone_afc_delete_file ( iphone_afc_client_t client, const char *path); 126iphone_error_t iphone_afc_delete_file ( iphone_afc_client_t client, const char *path);
130iphone_error_t iphone_afc_rename_file ( iphone_afc_client_t client, const char *from, const char *to); 127iphone_error_t iphone_afc_rename_file ( iphone_afc_client_t client, const char *from, const char *to);
131iphone_error_t iphone_afc_mkdir ( iphone_afc_client_t client, const char *dir); 128iphone_error_t iphone_afc_mkdir ( iphone_afc_client_t client, const char *dir);
diff --git a/src/AFC.c b/src/AFC.c
index abaeb3f..af9efa5 100644
--- a/src/AFC.c
+++ b/src/AFC.c
@@ -225,7 +225,7 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, uin
225 225
226 client->afc_packet->packet_num++; 226 client->afc_packet->packet_num++;
227 if (!client->afc_packet->entire_length) { 227 if (!client->afc_packet->entire_length) {
228 client->afc_packet->entire_length = (length) ? sizeof(AFCPacket) + length + 1 : sizeof(AFCPacket); 228 client->afc_packet->entire_length = (length) ? sizeof(AFCPacket) + length : sizeof(AFCPacket);
229 client->afc_packet->this_length = client->afc_packet->entire_length; 229 client->afc_packet->this_length = client->afc_packet->entire_length;
230 } 230 }
231 if (!client->afc_packet->this_length) { 231 if (!client->afc_packet->this_length) {
@@ -270,7 +270,6 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, uin
270 log_debug_msg("dispatch_AFC_packet packet data follows\n"); 270 log_debug_msg("dispatch_AFC_packet packet data follows\n");
271 if (length > 0) { 271 if (length > 0) {
272 memcpy(buffer + sizeof(AFCPacket), data, length); 272 memcpy(buffer + sizeof(AFCPacket), data, length);
273 buffer[sizeof(AFCPacket) + length] = '\0';
274 } 273 }
275 log_debug_buffer(buffer, client->afc_packet->this_length); 274 log_debug_buffer(buffer, client->afc_packet->this_length);
276 log_debug_msg("\n"); 275 log_debug_msg("\n");
@@ -484,7 +483,7 @@ iphone_error_t iphone_afc_get_dir_list(iphone_afc_client_t client, const char *d
484 client->afc_packet->operation = AFC_LIST_DIR; 483 client->afc_packet->operation = AFC_LIST_DIR;
485 client->afc_packet->entire_length = 0; 484 client->afc_packet->entire_length = 0;
486 client->afc_packet->this_length = 0; 485 client->afc_packet->this_length = 0;
487 bytes = dispatch_AFC_packet(client, dir, strlen(dir)); 486 bytes = dispatch_AFC_packet(client, dir, strlen(dir)+1);
488 if (bytes <= 0) { 487 if (bytes <= 0) {
489 afc_unlock(client); 488 afc_unlock(client);
490 return IPHONE_E_NOT_ENOUGH_DATA; 489 return IPHONE_E_NOT_ENOUGH_DATA;
@@ -570,7 +569,7 @@ iphone_error_t iphone_afc_delete_file(iphone_afc_client_t client, const char *pa
570 // Send command 569 // Send command
571 client->afc_packet->this_length = client->afc_packet->entire_length = 0; 570 client->afc_packet->this_length = client->afc_packet->entire_length = 0;
572 client->afc_packet->operation = AFC_DELETE; 571 client->afc_packet->operation = AFC_DELETE;
573 bytes = dispatch_AFC_packet(client, path, strlen(path)); 572 bytes = dispatch_AFC_packet(client, path, strlen(path)+1);
574 if (bytes <= 0) { 573 if (bytes <= 0) {
575 afc_unlock(client); 574 afc_unlock(client);
576 return IPHONE_E_NOT_ENOUGH_DATA; 575 return IPHONE_E_NOT_ENOUGH_DATA;
@@ -613,7 +612,7 @@ iphone_error_t iphone_afc_rename_file(iphone_afc_client_t client, const char *fr
613 memcpy(send + strlen(from) + 1, to, strlen(to) + 1); 612 memcpy(send + strlen(from) + 1, to, strlen(to) + 1);
614 client->afc_packet->entire_length = client->afc_packet->this_length = 0; 613 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
615 client->afc_packet->operation = AFC_RENAME; 614 client->afc_packet->operation = AFC_RENAME;
616 bytes = dispatch_AFC_packet(client, send, strlen(to) + strlen(from) + 2); 615 bytes = dispatch_AFC_packet(client, send, strlen(to)+1 + strlen(from)+1);
617 free(send); 616 free(send);
618 if (bytes <= 0) { 617 if (bytes <= 0) {
619 afc_unlock(client); 618 afc_unlock(client);
@@ -654,7 +653,7 @@ iphone_error_t iphone_afc_mkdir(iphone_afc_client_t client, const char *dir)
654 // Send command 653 // Send command
655 client->afc_packet->operation = AFC_MAKE_DIR; 654 client->afc_packet->operation = AFC_MAKE_DIR;
656 client->afc_packet->this_length = client->afc_packet->entire_length = 0; 655 client->afc_packet->this_length = client->afc_packet->entire_length = 0;
657 bytes = dispatch_AFC_packet(client, dir, strlen(dir)); 656 bytes = dispatch_AFC_packet(client, dir, strlen(dir)+1);
658 if (bytes <= 0) { 657 if (bytes <= 0) {
659 afc_unlock(client); 658 afc_unlock(client);
660 return IPHONE_E_NOT_ENOUGH_DATA; 659 return IPHONE_E_NOT_ENOUGH_DATA;
@@ -676,102 +675,42 @@ iphone_error_t iphone_afc_mkdir(iphone_afc_client_t client, const char *dir)
676 * 675 *
677 * @param client The client to use to get the information of the file. 676 * @param client The client to use to get the information of the file.
678 * @param path The fully-qualified path to the file. 677 * @param path The fully-qualified path to the file.
678 * @param infolist Pointer to a buffer that will be filled with a NULL-terminated
679 * list of strings with the file information.
680 * Set to NULL before calling this function.
679 * 681 *
680 * @return A pointer to an AFCFile struct containing the information received, 682 * @return IPHONE_E_SUCCESS on success or an IPHONE_E_* error value
681 * or NULL on failure. 683 * when something went wrong.
682 */ 684 */
683static iphone_afc_file_t afc_get_file_info(iphone_afc_client_t client, const char *path) 685iphone_error_t iphone_afc_get_file_info(iphone_afc_client_t client, const char *path, char ***infolist)
684{ 686{
685 char *received, **list; 687 char *received = NULL;
686 iphone_afc_file_t my_file; 688 int length;
687 int length, i = 0; 689
690 if (!client || !path || !infolist) {
691 return IPHONE_E_INVALID_ARG;
692 }
688 693
689 afc_lock(client); 694 afc_lock(client);
690 695
691 // Send command 696 // Send command
692 client->afc_packet->operation = AFC_GET_INFO; 697 client->afc_packet->operation = AFC_GET_INFO;
693 client->afc_packet->entire_length = client->afc_packet->this_length = 0; 698 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
694 dispatch_AFC_packet(client, path, strlen(path)); 699 dispatch_AFC_packet(client, path, strlen(path)+1);
695 700
696 // Receive data 701 // Receive data
697 length = receive_AFC_data(client, &received); 702 length = receive_AFC_data(client, &received);
698 if (received) { 703 if (received) {
699 list = make_strings_list(received, length); 704 *infolist = make_strings_list(received, length);
700 free(received); 705 free(received);
701 } else { 706 } else {
702 afc_unlock(client); 707 afc_unlock(client);
703 return NULL; 708 return IPHONE_E_AFC_ERROR;
704 } 709 }
705 710
706 afc_unlock(client); 711 afc_unlock(client);
707 712
708 // Parse the data 713 return IPHONE_E_SUCCESS;
709 if (list) {
710 my_file = (iphone_afc_file_t) malloc(sizeof(struct iphone_afc_file_int));
711 for (i = 0; list[i]; i++) {
712 if (!strcmp(list[i], "st_size")) {
713 my_file->size = atoll(list[i + 1]);
714 }
715
716 if (!strcmp(list[i], "st_blocks")) {
717 my_file->blocks = atoi(list[i + 1]);
718 }
719
720 if (!strcmp(list[i], "st_ifmt")) {
721 if (!strcmp(list[i + 1], "S_IFREG")) {
722 my_file->mode = S_IFREG;
723 } else if (!strcmp(list[i + 1], "S_IFDIR")) {
724 my_file->mode = S_IFDIR;
725 } else if (!strcmp(list[i + 1], "S_IFLNK")) {
726 my_file->mode = S_IFLNK;
727 }
728 }
729
730 if (!strcmp(list[i], "st_nlink")) {
731 my_file->nlink = atoi(list[i + 1]);
732 }
733 }
734 g_strfreev(list);
735 return my_file;
736 } else {
737 return NULL;
738 }
739}
740
741/** Gets information about a specific file.
742 *
743 * @param client The client to use to get the information of the file.
744 * @param path The fully-qualified path to the file
745 * @param stbuf output buffer where file information will be stored
746 *
747 * @return A pointer to an AFCFile struct containing the information received,
748 * or NULL on failure.
749 */
750iphone_error_t iphone_afc_get_file_attr(iphone_afc_client_t client, const char *filename, struct stat * stbuf)
751{
752
753 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
754 if (!client || client->sfd < 0 || !client->afc_packet || !stbuf)
755 return IPHONE_E_INVALID_ARG;
756
757 memset(stbuf, 0, sizeof(struct stat));
758 iphone_afc_file_t file = afc_get_file_info(client, filename);
759 if (!file) {
760 ret = IPHONE_E_AFC_ERROR;
761 } else {
762 stbuf->st_mode = file->mode | (S_ISDIR(file->mode) ? 0755 : (S_ISLNK(file->mode) ? 0777 : 0644));
763 stbuf->st_size = file->size;
764 stbuf->st_blksize = 2048; // FIXME: Is this the actual block
765 // size used on the iPhone?
766 stbuf->st_blocks = file->blocks;
767 stbuf->st_nlink = file->nlink;
768 stbuf->st_uid = getuid();
769 stbuf->st_gid = getgid();
770
771 free(file);
772 ret = IPHONE_E_SUCCESS;
773 }
774 return ret;
775} 714}
776 715
777/** Opens a file on the phone. 716/** Opens a file on the phone.
@@ -782,20 +721,21 @@ iphone_error_t iphone_afc_get_file_attr(iphone_afc_client_t client, const char *
782 * AFC_FILE_WRITE; the former lets you read and write, 721 * AFC_FILE_WRITE; the former lets you read and write,
783 * however, and the second one will *create* the file, 722 * however, and the second one will *create* the file,
784 * destroying anything previously there. 723 * destroying anything previously there.
724 * @param handle Pointer to a uint64_t that will hold the handle of the file
785 * 725 *
786 * @return A pointer to an AFCFile struct containing the file information (as 726 * @return IPHONE_E_SUCCESS on success or an IPHONE_E_* error on failure.
787 * received by afc_get_file_info) as well as the handle to the file or
788 * NULL in the case of failure.
789 */ 727 */
790iphone_error_t 728iphone_error_t
791iphone_afc_open_file(iphone_afc_client_t client, const char *filename, 729iphone_afc_open_file(iphone_afc_client_t client, const char *filename,
792 iphone_afc_file_mode_t file_mode, iphone_afc_file_t * file) 730 iphone_afc_file_mode_t file_mode, uint64_t *handle)
793{ 731{
794 iphone_afc_file_t file_loc = NULL;
795 uint32_t ag = 0; 732 uint32_t ag = 0;
796 int bytes = 0, length = 0; 733 int bytes = 0, length = 0;
797 char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1)); 734 char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1));
798 735
736 // set handle to 0 so in case an error occurs, the handle is invalid
737 *handle = 0;
738
799 if (!client || client->sfd < 0|| !client->afc_packet) 739 if (!client || client->sfd < 0|| !client->afc_packet)
800 return IPHONE_E_INVALID_ARG; 740 return IPHONE_E_INVALID_ARG;
801 741
@@ -808,7 +748,7 @@ iphone_afc_open_file(iphone_afc_client_t client, const char *filename,
808 data[8 + strlen(filename)] = '\0'; 748 data[8 + strlen(filename)] = '\0';
809 client->afc_packet->operation = AFC_FILE_OPEN; 749 client->afc_packet->operation = AFC_FILE_OPEN;
810 client->afc_packet->entire_length = client->afc_packet->this_length = 0; 750 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
811 bytes = dispatch_AFC_packet(client, data, 8 + strlen(filename)); 751 bytes = dispatch_AFC_packet(client, data, 8 + strlen(filename) + 1);
812 free(data); 752 free(data);
813 753
814 if (bytes <= 0) { 754 if (bytes <= 0) {
@@ -821,11 +761,9 @@ iphone_afc_open_file(iphone_afc_client_t client, const char *filename,
821 if (length > 0 && data) { 761 if (length > 0 && data) {
822 afc_unlock(client); 762 afc_unlock(client);
823 763
824 // Get the file info and return it 764 // Get the file handle
825 file_loc = afc_get_file_info(client, filename); 765 memcpy(handle, data, sizeof(uint64_t));
826 memcpy(&file_loc->filehandle, data, 4);
827 free(data); 766 free(data);
828 *file = file_loc;
829 return IPHONE_E_SUCCESS; 767 return IPHONE_E_SUCCESS;
830 } else { 768 } else {
831 log_debug_msg("afc_open_file: Didn't get any further data\n"); 769 log_debug_msg("afc_open_file: Didn't get any further data\n");
@@ -841,20 +779,20 @@ iphone_afc_open_file(iphone_afc_client_t client, const char *filename,
841/** Attempts to the read the given number of bytes from the given file. 779/** Attempts to the read the given number of bytes from the given file.
842 * 780 *
843 * @param client The relevant AFC client 781 * @param client The relevant AFC client
844 * @param file The AFCFile to read from 782 * @param handle File handle of a previously opened file
845 * @param data The pointer to the memory region to store the read data 783 * @param data The pointer to the memory region to store the read data
846 * @param length The number of bytes to read 784 * @param length The number of bytes to read
847 * 785 *
848 * @return The number of bytes read if successful. If there was an error -1. 786 * @return The number of bytes read if successful. If there was an error -1.
849 */ 787 */
850iphone_error_t 788iphone_error_t
851iphone_afc_read_file(iphone_afc_client_t client, iphone_afc_file_t file, char *data, int length, uint32_t * bytes) 789iphone_afc_read_file(iphone_afc_client_t client, uint64_t handle, char *data, int length, uint32_t * bytes)
852{ 790{
853 char *input = NULL; 791 char *input = NULL;
854 int current_count = 0, bytes_loc = 0; 792 int current_count = 0, bytes_loc = 0;
855 const int MAXIMUM_READ_SIZE = 1 << 16; 793 const int MAXIMUM_READ_SIZE = 1 << 16;
856 794
857 if (!client || !client->afc_packet || client->sfd < 0 || !file) 795 if (!client || !client->afc_packet || client->sfd < 0 || handle == 0)
858 return IPHONE_E_INVALID_ARG; 796 return IPHONE_E_INVALID_ARG;
859 log_debug_msg("afc_read_file called for length %i\n", length); 797 log_debug_msg("afc_read_file called for length %i\n", length);
860 798
@@ -867,7 +805,7 @@ iphone_afc_read_file(iphone_afc_client_t client, iphone_afc_file_t file, char *d
867 805
868 // Send the read command 806 // Send the read command
869 AFCFilePacket *packet = (AFCFilePacket *) malloc(sizeof(AFCFilePacket)); 807 AFCFilePacket *packet = (AFCFilePacket *) malloc(sizeof(AFCFilePacket));
870 packet->filehandle = file->filehandle; 808 packet->filehandle = handle;
871 packet->size = ((length - current_count) < MAXIMUM_READ_SIZE) ? (length - current_count) : MAXIMUM_READ_SIZE; 809 packet->size = ((length - current_count) < MAXIMUM_READ_SIZE) ? (length - current_count) : MAXIMUM_READ_SIZE;
872 client->afc_packet->operation = AFC_READ; 810 client->afc_packet->operation = AFC_READ;
873 client->afc_packet->entire_length = client->afc_packet->this_length = 0; 811 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
@@ -911,7 +849,7 @@ iphone_afc_read_file(iphone_afc_client_t client, iphone_afc_file_t file, char *d
911/** Writes a given number of bytes to a file. 849/** Writes a given number of bytes to a file.
912 * 850 *
913 * @param client The client to use to write to the file. 851 * @param client The client to use to write to the file.
914 * @param file A pointer to an AFCFile struct; serves as the file handle. 852 * @param handle File handle of previously opened file.
915 * @param data The data to write to the file. 853 * @param data The data to write to the file.
916 * @param length How much data to write. 854 * @param length How much data to write.
917 * 855 *
@@ -919,7 +857,7 @@ iphone_afc_read_file(iphone_afc_client_t client, iphone_afc_file_t file, char *d
919 * none were written... 857 * none were written...
920 */ 858 */
921iphone_error_t 859iphone_error_t
922iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file, 860iphone_afc_write_file(iphone_afc_client_t client, uint64_t handle,
923 const char *data, int length, uint32_t * bytes) 861 const char *data, int length, uint32_t * bytes)
924{ 862{
925 char *acknowledgement = NULL; 863 char *acknowledgement = NULL;
@@ -929,7 +867,7 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file,
929 int bytes_loc = 0; 867 int bytes_loc = 0;
930 char *out_buffer = NULL; 868 char *out_buffer = NULL;
931 869
932 if (!client || !client->afc_packet || client->sfd < 0 || !file || !bytes) 870 if (!client || !client->afc_packet || client->sfd < 0 || !bytes || (handle == 0))
933 return IPHONE_E_INVALID_ARG; 871 return IPHONE_E_INVALID_ARG;
934 872
935 afc_lock(client); 873 afc_lock(client);
@@ -943,8 +881,7 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file,
943 client->afc_packet->entire_length = client->afc_packet->this_length + MAXIMUM_WRITE_SIZE; 881 client->afc_packet->entire_length = client->afc_packet->this_length + MAXIMUM_WRITE_SIZE;
944 client->afc_packet->operation = AFC_WRITE; 882 client->afc_packet->operation = AFC_WRITE;
945 out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); 883 out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket));
946 memcpy(out_buffer, (char *) &file->filehandle, sizeof(uint32_t)); 884 memcpy(out_buffer, (char *)&handle, sizeof(uint64_t));
947 memcpy(out_buffer + 4, (char *) &zero, sizeof(uint32_t));
948 memcpy(out_buffer + 8, data + current_count, MAXIMUM_WRITE_SIZE); 885 memcpy(out_buffer + 8, data + current_count, MAXIMUM_WRITE_SIZE);
949 bytes_loc = dispatch_AFC_packet(client, out_buffer, MAXIMUM_WRITE_SIZE + 8); 886 bytes_loc = dispatch_AFC_packet(client, out_buffer, MAXIMUM_WRITE_SIZE + 8);
950 if (bytes_loc < 0) { 887 if (bytes_loc < 0) {
@@ -978,8 +915,7 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file,
978 client->afc_packet->entire_length = client->afc_packet->this_length + (length - current_count); 915 client->afc_packet->entire_length = client->afc_packet->this_length + (length - current_count);
979 client->afc_packet->operation = AFC_WRITE; 916 client->afc_packet->operation = AFC_WRITE;
980 out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); 917 out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket));
981 memcpy(out_buffer, (char *) &file->filehandle, sizeof(uint32_t)); 918 memcpy(out_buffer, (char *) &handle, sizeof(uint64_t));
982 memcpy(out_buffer + 4, (char *) &zero, sizeof(uint32_t));
983 memcpy(out_buffer + 8, data + current_count, (length - current_count)); 919 memcpy(out_buffer + 8, data + current_count, (length - current_count));
984 bytes_loc = dispatch_AFC_packet(client, out_buffer, (length - current_count) + 8); 920 bytes_loc = dispatch_AFC_packet(client, out_buffer, (length - current_count) + 8);
985 free(out_buffer); 921 free(out_buffer);
@@ -1008,27 +944,24 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file,
1008/** Closes a file on the phone. 944/** Closes a file on the phone.
1009 * 945 *
1010 * @param client The client to close the file with. 946 * @param client The client to close the file with.
1011 * @param file A pointer to an AFCFile struct containing the file handle of the 947 * @param handle File handle of a previously opened file.
1012 * file to close.
1013 */ 948 */
1014iphone_error_t iphone_afc_close_file(iphone_afc_client_t client, iphone_afc_file_t file) 949iphone_error_t iphone_afc_close_file(iphone_afc_client_t client, uint64_t handle)
1015{ 950{
1016 if (!client || !file) 951 if (!client || (handle == 0))
1017 return IPHONE_E_INVALID_ARG; 952 return IPHONE_E_INVALID_ARG;
1018 char *buffer = malloc(sizeof(char) * 8); 953 char *buffer = malloc(sizeof(char) * 8);
1019 uint32_t zero = 0;
1020 int bytes = 0; 954 int bytes = 0;
1021 955
1022 afc_lock(client); 956 afc_lock(client);
1023 957
1024 log_debug_msg("afc_close_file: File handle %i\n", file->filehandle); 958 log_debug_msg("afc_close_file: File handle %i\n", handle);
1025 959
1026 // Send command 960 // Send command
1027 memcpy(buffer, &file->filehandle, sizeof(uint32_t)); 961 memcpy(buffer, &handle, sizeof(uint64_t));
1028 memcpy(buffer + sizeof(uint32_t), &zero, sizeof(zero));
1029 client->afc_packet->operation = AFC_FILE_CLOSE; 962 client->afc_packet->operation = AFC_FILE_CLOSE;
1030 client->afc_packet->entire_length = client->afc_packet->this_length = 0; 963 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
1031 bytes = dispatch_AFC_packet(client, buffer, sizeof(char) * 8); 964 bytes = dispatch_AFC_packet(client, buffer, 8);
1032 free(buffer); 965 free(buffer);
1033 buffer = NULL; 966 buffer = NULL;
1034 967
@@ -1044,7 +977,6 @@ iphone_error_t iphone_afc_close_file(iphone_afc_client_t client, iphone_afc_file
1044 bytes = receive_AFC_data(client, &buffer); 977 bytes = receive_AFC_data(client, &buffer);
1045 if (buffer) 978 if (buffer)
1046 free(buffer); 979 free(buffer);
1047 free(file);
1048 afc_unlock(client); 980 afc_unlock(client);
1049 return IPHONE_E_SUCCESS; 981 return IPHONE_E_SUCCESS;
1050} 982}
@@ -1062,31 +994,28 @@ iphone_error_t iphone_afc_close_file(iphone_afc_client_t client, iphone_afc_file
1062 * LOCK_UN 8 // unlock 994 * LOCK_UN 8 // unlock
1063 * 995 *
1064 * @param client The client to close the file with. 996 * @param client The client to close the file with.
1065 * @param file A pointer to an AFCFile struct containing the file handle of the 997 * @param handle File handle of a previously opened file.
1066 * file to close.
1067 * @operation the lock or unlock operation to perform. 998 * @operation the lock or unlock operation to perform.
1068 */ 999 */
1069iphone_error_t iphone_afc_lock_file(iphone_afc_client_t client, iphone_afc_file_t file, int operation) 1000iphone_error_t iphone_afc_lock_file(iphone_afc_client_t client, uint64_t handle, int operation)
1070{ 1001{
1071 if (!client || !file) 1002 if (!client || (handle == 0))
1072 return IPHONE_E_INVALID_ARG; 1003 return IPHONE_E_INVALID_ARG;
1073 char *buffer = malloc(16); 1004 char *buffer = malloc(16);
1074 uint32_t zero = 0;
1075 int bytes = 0; 1005 int bytes = 0;
1076 uint64_t op = operation; 1006 uint64_t op = operation;
1077 1007
1078 afc_lock(client); 1008 afc_lock(client);
1079 1009
1080 log_debug_msg("afc_lock_file: File handle %i\n", file->filehandle); 1010 log_debug_msg("afc_lock_file: File handle %i\n", handle);
1081 1011
1082 // Send command 1012 // Send command
1083 memcpy(buffer, &file->filehandle, sizeof(uint32_t)); 1013 memcpy(buffer, &handle, sizeof(uint64_t));
1084 memcpy(buffer + sizeof(uint32_t), &zero, sizeof(zero));
1085 memcpy(buffer + 8, &op, 8); 1014 memcpy(buffer + 8, &op, 8);
1086 1015
1087 client->afc_packet->operation = AFC_FILE_LOCK; 1016 client->afc_packet->operation = AFC_FILE_LOCK;
1088 client->afc_packet->entire_length = client->afc_packet->this_length = 0; 1017 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
1089 bytes = dispatch_AFC_packet(client, buffer, 15); 1018 bytes = dispatch_AFC_packet(client, buffer, 16);
1090 free(buffer); 1019 free(buffer);
1091 buffer = NULL; 1020 buffer = NULL;
1092 1021
@@ -1111,34 +1040,28 @@ iphone_error_t iphone_afc_lock_file(iphone_afc_client_t client, iphone_afc_file_
1111/** Seeks to a given position of a pre-opened file on the phone. 1040/** Seeks to a given position of a pre-opened file on the phone.
1112 * 1041 *
1113 * @param client The client to use to seek to the position. 1042 * @param client The client to use to seek to the position.
1114 * @param file The file to seek to a position on. 1043 * @param handle File handle of a previously opened.
1115 * @param seekpos Where to seek to. If passed a negative value, this will seek 1044 * @param offset Seek offset.
1116 * from the end of the file. 1045 * @param whence Seeking direction, one of SEEK_SET, SEEK_CUR, or SEEK_END.
1117 * 1046 *
1118 * @return IPHONE_E_SUCCESS on success, IPHONE_E_NOT_ENOUGH_DATA on failure. 1047 * @return IPHONE_E_SUCCESS on success, IPHONE_E_NOT_ENOUGH_DATA on failure.
1119 */ 1048 */
1120iphone_error_t iphone_afc_seek_file(iphone_afc_client_t client, iphone_afc_file_t file, int seekpos) 1049iphone_error_t iphone_afc_seek_file(iphone_afc_client_t client, uint64_t handle, int64_t offset, int whence)
1121{ 1050{
1122 char *buffer = (char *) malloc(sizeof(char) * 24); 1051 char *buffer = (char *) malloc(sizeof(char) * 24);
1123 uint32_t seekto = 0, zero = 0; 1052 uint32_t zero = 0;
1124 int bytes = 0; 1053 int bytes = 0;
1125 1054
1126 if (seekpos < 0)
1127 seekpos = file->size - abs(seekpos);
1128
1129 afc_lock(client); 1055 afc_lock(client);
1130 1056
1131 // Send the command 1057 // Send the command
1132 seekto = seekpos; 1058 memcpy(buffer, &handle, sizeof(uint64_t)); // handle
1133 memcpy(buffer, &file->filehandle, sizeof(uint32_t)); // handle 1059 memcpy(buffer + 8, &whence, sizeof(int32_t)); // fromwhere
1134 memcpy(buffer + 4, &zero, sizeof(uint32_t)); // pad
1135 memcpy(buffer + 8, &zero, sizeof(uint32_t)); // fromwhere
1136 memcpy(buffer + 12, &zero, sizeof(uint32_t)); // pad 1060 memcpy(buffer + 12, &zero, sizeof(uint32_t)); // pad
1137 memcpy(buffer + 16, &seekto, sizeof(uint32_t)); // offset 1061 memcpy(buffer + 16, &offset, sizeof(uint64_t)); // offset
1138 memcpy(buffer + 20, &zero, sizeof(uint32_t)); // pad
1139 client->afc_packet->operation = AFC_FILE_SEEK; 1062 client->afc_packet->operation = AFC_FILE_SEEK;
1140 client->afc_packet->this_length = client->afc_packet->entire_length = 0; 1063 client->afc_packet->this_length = client->afc_packet->entire_length = 0;
1141 bytes = dispatch_AFC_packet(client, buffer, 23); 1064 bytes = dispatch_AFC_packet(client, buffer, 24);
1142 free(buffer); 1065 free(buffer);
1143 buffer = NULL; 1066 buffer = NULL;
1144 1067
@@ -1162,7 +1085,7 @@ iphone_error_t iphone_afc_seek_file(iphone_afc_client_t client, iphone_afc_file_
1162/** Sets the size of a file on the phone. 1085/** Sets the size of a file on the phone.
1163 * 1086 *
1164 * @param client The client to use to set the file size. 1087 * @param client The client to use to set the file size.
1165 * @param file The (pre-opened) file to set the size on. 1088 * @param handle File handle of a previously opened file.
1166 * @param newsize The size to set the file to. 1089 * @param newsize The size to set the file to.
1167 * 1090 *
1168 * @return 0 on success, -1 on failure. 1091 * @return 0 on success, -1 on failure.
@@ -1170,22 +1093,19 @@ iphone_error_t iphone_afc_seek_file(iphone_afc_client_t client, iphone_afc_file_
1170 * @note This function is more akin to ftruncate than truncate, and truncate 1093 * @note This function is more akin to ftruncate than truncate, and truncate
1171 * calls would have to open the file before calling this, sadly. 1094 * calls would have to open the file before calling this, sadly.
1172 */ 1095 */
1173iphone_error_t iphone_afc_truncate_file(iphone_afc_client_t client, iphone_afc_file_t file, uint32_t newsize) 1096iphone_error_t iphone_afc_truncate_file(iphone_afc_client_t client, uint64_t handle, uint64_t newsize)
1174{ 1097{
1175 char *buffer = (char *) malloc(sizeof(char) * 16); 1098 char *buffer = (char *) malloc(sizeof(char) * 16);
1176 int bytes = 0; 1099 int bytes = 0;
1177 uint32_t zero = 0;
1178 1100
1179 afc_lock(client); 1101 afc_lock(client);
1180 1102
1181 // Send command 1103 // Send command
1182 memcpy(buffer, &file->filehandle, sizeof(uint32_t)); // handle 1104 memcpy(buffer, &handle, sizeof(uint64_t)); // handle
1183 memcpy(buffer + 4, &zero, sizeof(uint32_t)); // pad 1105 memcpy(buffer + 8, &newsize, sizeof(uint64_t)); // newsize
1184 memcpy(buffer + 8, &newsize, sizeof(uint32_t)); // newsize
1185 memcpy(buffer + 12, &zero, 3); // pad
1186 client->afc_packet->operation = AFC_FILE_TRUNCATE; 1106 client->afc_packet->operation = AFC_FILE_TRUNCATE;
1187 client->afc_packet->this_length = client->afc_packet->entire_length = 0; 1107 client->afc_packet->this_length = client->afc_packet->entire_length = 0;
1188 bytes = dispatch_AFC_packet(client, buffer, 15); 1108 bytes = dispatch_AFC_packet(client, buffer, 16);
1189 free(buffer); 1109 free(buffer);
1190 buffer = NULL; 1110 buffer = NULL;
1191 1111
@@ -1232,7 +1152,7 @@ iphone_error_t iphone_afc_truncate(iphone_afc_client_t client, const char *path,
1232 memcpy(send + 8, path, strlen(path) + 1); 1152 memcpy(send + 8, path, strlen(path) + 1);
1233 client->afc_packet->entire_length = client->afc_packet->this_length = 0; 1153 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
1234 client->afc_packet->operation = AFC_TRUNCATE; 1154 client->afc_packet->operation = AFC_TRUNCATE;
1235 bytes = dispatch_AFC_packet(client, send, 8 + strlen(path)); 1155 bytes = dispatch_AFC_packet(client, send, 8 + strlen(path) + 1);
1236 free(send); 1156 free(send);
1237 if (bytes <= 0) { 1157 if (bytes <= 0) {
1238 afc_unlock(client); 1158 afc_unlock(client);
@@ -1250,9 +1170,3 @@ iphone_error_t iphone_afc_truncate(iphone_afc_client_t client, const char *path,
1250 } 1170 }
1251 return IPHONE_E_SUCCESS; 1171 return IPHONE_E_SUCCESS;
1252} 1172}
1253
1254
1255uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file)
1256{
1257 return file->filehandle;
1258}
diff --git a/src/AFC.h b/src/AFC.h
index 5827518..a9c33c3 100644
--- a/src/AFC.h
+++ b/src/AFC.h
@@ -55,16 +55,6 @@ struct iphone_afc_client_int {
55 GMutex *mutex; 55 GMutex *mutex;
56}; 56};
57 57
58struct iphone_afc_file_int {
59 uint32_t filehandle;
60 uint32_t blocks;
61 off_t size;
62 uint32_t mode;
63 uint32_t nlink;
64};
65
66
67
68enum { 58enum {
69 AFC_ERROR = 0x00000001, 59 AFC_ERROR = 0x00000001,
70 AFC_SUCCESS_RESPONSE = 0x00000002, 60 AFC_SUCCESS_RESPONSE = 0x00000002,
@@ -96,5 +86,4 @@ enum {
96 AFC_MAKE_LINK = 0x0000001C // MakeLink 86 AFC_MAKE_LINK = 0x0000001C // MakeLink
97}; 87};
98 88
99uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file);
100static int afcerror_to_errno(int afcerror); 89static int afcerror_to_errno(int afcerror);