summaryrefslogtreecommitdiffstats
path: root/src/afc.c
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2020-05-19 05:43:38 +0200
committerGravatar Nikias Bassen2020-05-19 05:43:38 +0200
commit59f16a14692f7d84c5871394b8928d94b4dc34ce (patch)
tree16e35f19b0860f8eaacfdd04f0102996871b9cf0 /src/afc.c
parent33a9279d2d256086362e4404724e076fbbf86cc0 (diff)
downloadlibimobiledevice-59f16a14692f7d84c5871394b8928d94b4dc34ce.tar.gz
libimobiledevice-59f16a14692f7d84c5871394b8928d94b4dc34ce.tar.bz2
afc: Reduce packet segmentation and unnecessary malloc/free
Diffstat (limited to 'src/afc.c')
-rw-r--r--src/afc.c284
1 files changed, 187 insertions, 97 deletions
diff --git a/src/afc.c b/src/afc.c
index 9ef800b..4b8436e 100644
--- a/src/afc.c
+++ b/src/afc.c
@@ -78,12 +78,12 @@ LIBIMOBILEDEVICE_API afc_error_t afc_client_new_with_service_client(service_clie
78 client_loc->free_parent = 0; 78 client_loc->free_parent = 0;
79 79
80 /* allocate a packet */ 80 /* allocate a packet */
81 client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket)); 81 client_loc->packet_extra = 1024;
82 client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket) + client_loc->packet_extra);
82 if (!client_loc->afc_packet) { 83 if (!client_loc->afc_packet) {
83 free(client_loc); 84 free(client_loc);
84 return AFC_E_NO_MEM; 85 return AFC_E_NO_MEM;
85 } 86 }
86
87 client_loc->afc_packet->packet_num = 0; 87 client_loc->afc_packet->packet_num = 0;
88 client_loc->afc_packet->entire_length = 0; 88 client_loc->afc_packet->entire_length = 0;
89 client_loc->afc_packet->this_length = 0; 89 client_loc->afc_packet->this_length = 0;
@@ -148,7 +148,7 @@ LIBIMOBILEDEVICE_API afc_error_t afc_client_free(afc_client_t client)
148 * 148 *
149 * @return AFC_E_SUCCESS on success or an AFC_E_* error value. 149 * @return AFC_E_SUCCESS on success or an AFC_E_* error value.
150 */ 150 */
151static afc_error_t afc_dispatch_packet(afc_client_t client, uint64_t operation, const char *data, uint32_t data_length, const char* payload, uint32_t payload_length, uint32_t *bytes_sent) 151static afc_error_t afc_dispatch_packet(afc_client_t client, uint64_t operation, uint32_t data_length, const char* payload, uint32_t payload_length, uint32_t *bytes_sent)
152{ 152{
153 uint32_t sent = 0; 153 uint32_t sent = 0;
154 154
@@ -157,8 +157,6 @@ static afc_error_t afc_dispatch_packet(afc_client_t client, uint64_t operation,
157 157
158 *bytes_sent = 0; 158 *bytes_sent = 0;
159 159
160 if (!data || !data_length)
161 data_length = 0;
162 if (!payload || !payload_length) 160 if (!payload || !payload_length)
163 payload_length = 0; 161 payload_length = 0;
164 162
@@ -169,34 +167,26 @@ static afc_error_t afc_dispatch_packet(afc_client_t client, uint64_t operation,
169 167
170 debug_info("packet length = %i", client->afc_packet->this_length); 168 debug_info("packet length = %i", client->afc_packet->this_length);
171 169
172 debug_buffer((char*)client->afc_packet, sizeof(AFCPacket)); 170 /* send AFC packet header and data */
173
174 /* send AFC packet header */
175 AFCPacket_to_LE(client->afc_packet); 171 AFCPacket_to_LE(client->afc_packet);
172 debug_buffer((char*)client->afc_packet, sizeof(AFCPacket) + data_length);
176 sent = 0; 173 sent = 0;
177 service_send(client->parent, (void*)client->afc_packet, sizeof(AFCPacket), &sent); 174 service_send(client->parent, (void*)client->afc_packet, sizeof(AFCPacket) + data_length, &sent);
178 AFCPacket_from_LE(client->afc_packet); 175 AFCPacket_from_LE(client->afc_packet);
179 *bytes_sent += sent; 176 *bytes_sent += sent;
180 if (sent < sizeof(AFCPacket)) { 177 if (sent < sizeof(AFCPacket) + data_length) {
181 return AFC_E_SUCCESS;
182 }
183
184 /* send AFC packet data (if there's data to send) */
185 sent = 0;
186 if (data_length > 0) {
187 debug_info("packet data follows");
188 debug_buffer(data, data_length);
189 service_send(client->parent, data, data_length, &sent);
190 }
191 *bytes_sent += sent;
192 if (sent < data_length) {
193 return AFC_E_SUCCESS; 178 return AFC_E_SUCCESS;
194 } 179 }
195 180
196 sent = 0; 181 sent = 0;
197 if (payload_length > 0) { 182 if (payload_length > 0) {
198 debug_info("packet payload follows"); 183 if (payload_length > 256) {
199 debug_buffer(payload, payload_length); 184 debug_info("packet payload follows (256/%u)", payload_length);
185 debug_buffer(payload, 256);
186 } else {
187 debug_info("packet payload follows");
188 debug_buffer(payload, payload_length);
189 }
200 service_send(client->parent, payload, payload_length, &sent); 190 service_send(client->parent, payload, payload_length, &sent);
201 } 191 }
202 *bytes_sent += sent; 192 *bytes_sent += sent;
@@ -310,8 +300,13 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t
310 } 300 }
311 301
312 debug_info("packet data size = %i", current_count); 302 debug_info("packet data size = %i", current_count);
313 debug_info("packet data follows"); 303 if (current_count > 256) {
314 debug_buffer(dump_here, current_count); 304 debug_info("packet data follows (256/%u)", current_count);
305 debug_buffer(dump_here, 256);
306 } else {
307 debug_info("packet data follows");
308 debug_buffer(dump_here, current_count);
309 }
315 310
316 /* check operation types */ 311 /* check operation types */
317 if (header.operation == AFC_OP_STATUS) { 312 if (header.operation == AFC_OP_STATUS) {
@@ -400,6 +395,21 @@ static char **make_strings_list(char *tokens, uint32_t length)
400 return list; 395 return list;
401} 396}
402 397
398static int _afc_check_packet_buffer(afc_client_t client, uint32_t data_len)
399{
400 if (data_len > client->packet_extra) {
401 client->packet_extra = (data_len & ~8) + 8;
402 AFCPacket* newpkt = (AFCPacket*)realloc(client->afc_packet, sizeof(AFCPacket) + client->packet_extra);
403 if (!newpkt) {
404 return -1;
405 }
406 client->afc_packet = newpkt;
407 }
408 return 0;
409}
410
411#define AFC_PACKET_DATA_PTR ((char*)client->afc_packet + sizeof(AFCPacket))
412
403LIBIMOBILEDEVICE_API afc_error_t afc_read_directory(afc_client_t client, const char *path, char ***directory_information) 413LIBIMOBILEDEVICE_API afc_error_t afc_read_directory(afc_client_t client, const char *path, char ***directory_information)
404{ 414{
405 uint32_t bytes = 0; 415 uint32_t bytes = 0;
@@ -411,8 +421,16 @@ LIBIMOBILEDEVICE_API afc_error_t afc_read_directory(afc_client_t client, const c
411 421
412 afc_lock(client); 422 afc_lock(client);
413 423
424 uint32_t data_len = (uint32_t)strlen(path)+1;
425 if (_afc_check_packet_buffer(client, data_len) < 0) {
426 afc_unlock(client);
427 debug_info("Failed to realloc packet buffer");
428 return AFC_E_NO_MEM;
429 }
430
414 /* Send the command */ 431 /* Send the command */
415 ret = afc_dispatch_packet(client, AFC_OP_READ_DIR, path, strlen(path)+1, NULL, 0, &bytes); 432 memcpy(AFC_PACKET_DATA_PTR, path, data_len);
433 ret = afc_dispatch_packet(client, AFC_OP_READ_DIR, data_len, NULL, 0, &bytes);
416 if (ret != AFC_E_SUCCESS) { 434 if (ret != AFC_E_SUCCESS) {
417 afc_unlock(client); 435 afc_unlock(client);
418 return AFC_E_NOT_ENOUGH_DATA; 436 return AFC_E_NOT_ENOUGH_DATA;
@@ -448,7 +466,7 @@ LIBIMOBILEDEVICE_API afc_error_t afc_get_device_info(afc_client_t client, char *
448 afc_lock(client); 466 afc_lock(client);
449 467
450 /* Send the command */ 468 /* Send the command */
451 ret = afc_dispatch_packet(client, AFC_OP_GET_DEVINFO, NULL, 0, NULL, 0, &bytes); 469 ret = afc_dispatch_packet(client, AFC_OP_GET_DEVINFO, 0, NULL, 0, &bytes);
452 if (ret != AFC_E_SUCCESS) { 470 if (ret != AFC_E_SUCCESS) {
453 afc_unlock(client); 471 afc_unlock(client);
454 return AFC_E_NOT_ENOUGH_DATA; 472 return AFC_E_NOT_ENOUGH_DATA;
@@ -510,8 +528,16 @@ LIBIMOBILEDEVICE_API afc_error_t afc_remove_path(afc_client_t client, const char
510 528
511 afc_lock(client); 529 afc_lock(client);
512 530
531 uint32_t data_len = (uint32_t)strlen(path)+1;
532 if (_afc_check_packet_buffer(client, data_len) < 0) {
533 afc_unlock(client);
534 debug_info("Failed to realloc packet buffer");
535 return AFC_E_NO_MEM;
536 }
537
513 /* Send command */ 538 /* Send command */
514 ret = afc_dispatch_packet(client, AFC_OP_REMOVE_PATH, path, strlen(path)+1, NULL, 0, &bytes); 539 memcpy(AFC_PACKET_DATA_PTR, path, data_len);
540 ret = afc_dispatch_packet(client, AFC_OP_REMOVE_PATH, data_len, NULL, 0, &bytes);
515 if (ret != AFC_E_SUCCESS) { 541 if (ret != AFC_E_SUCCESS) {
516 afc_unlock(client); 542 afc_unlock(client);
517 return AFC_E_NOT_ENOUGH_DATA; 543 return AFC_E_NOT_ENOUGH_DATA;
@@ -533,18 +559,25 @@ LIBIMOBILEDEVICE_API afc_error_t afc_rename_path(afc_client_t client, const char
533 if (!client || !from || !to || !client->afc_packet || !client->parent) 559 if (!client || !from || !to || !client->afc_packet || !client->parent)
534 return AFC_E_INVALID_ARG; 560 return AFC_E_INVALID_ARG;
535 561
536 char *buffer = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32_t)));
537 uint32_t bytes = 0; 562 uint32_t bytes = 0;
538 afc_error_t ret = AFC_E_UNKNOWN_ERROR; 563 afc_error_t ret = AFC_E_UNKNOWN_ERROR;
539 564
565 size_t from_len = strlen(from);
566 size_t to_len = strlen(to);
567
540 afc_lock(client); 568 afc_lock(client);
541 569
542 /* Send command */ 570 uint32_t data_len = (uint32_t)(from_len+1 + to_len+1);
543 memcpy(buffer, from, strlen(from) + 1); 571 if (_afc_check_packet_buffer(client, data_len) < 0) {
544 memcpy(buffer + strlen(from) + 1, to, strlen(to) + 1); 572 afc_unlock(client);
545 ret = afc_dispatch_packet(client, AFC_OP_RENAME_PATH, buffer, strlen(to)+1 + strlen(from)+1, NULL, 0, &bytes); 573 debug_info("Failed to realloc packet buffer");
546 free(buffer); 574 return AFC_E_NO_MEM;
575 }
547 576
577 /* Send command */
578 memcpy(AFC_PACKET_DATA_PTR, from, from_len+1);
579 memcpy(AFC_PACKET_DATA_PTR + from_len+1, to, to_len+1);
580 ret = afc_dispatch_packet(client, AFC_OP_RENAME_PATH, data_len, NULL, 0, &bytes);
548 if (ret != AFC_E_SUCCESS) { 581 if (ret != AFC_E_SUCCESS) {
549 afc_unlock(client); 582 afc_unlock(client);
550 return AFC_E_NOT_ENOUGH_DATA; 583 return AFC_E_NOT_ENOUGH_DATA;
@@ -567,8 +600,16 @@ LIBIMOBILEDEVICE_API afc_error_t afc_make_directory(afc_client_t client, const c
567 600
568 afc_lock(client); 601 afc_lock(client);
569 602
603 uint32_t data_len = (uint32_t)strlen(path)+1;
604 if (_afc_check_packet_buffer(client, data_len) < 0) {
605 afc_unlock(client);
606 debug_info("Failed to realloc packet buffer");
607 return AFC_E_NO_MEM;
608 }
609
570 /* Send command */ 610 /* Send command */
571 ret = afc_dispatch_packet(client, AFC_OP_MAKE_DIR, path, strlen(path)+1, NULL, 0, &bytes); 611 memcpy(AFC_PACKET_DATA_PTR, path, data_len);
612 ret = afc_dispatch_packet(client, AFC_OP_MAKE_DIR, data_len, NULL, 0, &bytes);
572 if (ret != AFC_E_SUCCESS) { 613 if (ret != AFC_E_SUCCESS) {
573 afc_unlock(client); 614 afc_unlock(client);
574 return AFC_E_NOT_ENOUGH_DATA; 615 return AFC_E_NOT_ENOUGH_DATA;
@@ -592,8 +633,18 @@ LIBIMOBILEDEVICE_API afc_error_t afc_get_file_info(afc_client_t client, const ch
592 633
593 afc_lock(client); 634 afc_lock(client);
594 635
636 uint32_t data_len = (uint32_t)strlen(path)+1;
637 if (_afc_check_packet_buffer(client, data_len) < 0) {
638 afc_unlock(client);
639 debug_info("Failed to realloc packet buffer");
640 return AFC_E_NO_MEM;
641 }
642
643 debug_info("We got %p and %p", client->afc_packet, AFC_PACKET_DATA_PTR);
644
595 /* Send command */ 645 /* Send command */
596 ret = afc_dispatch_packet(client, AFC_OP_GET_FILE_INFO, path, strlen(path)+1, NULL, 0, &bytes); 646 memcpy(AFC_PACKET_DATA_PTR, path, data_len);
647 ret = afc_dispatch_packet(client, AFC_OP_GET_FILE_INFO, data_len, NULL, 0, &bytes);
597 if (ret != AFC_E_SUCCESS) { 648 if (ret != AFC_E_SUCCESS) {
598 afc_unlock(client); 649 afc_unlock(client);
599 return AFC_E_NOT_ENOUGH_DATA; 650 return AFC_E_NOT_ENOUGH_DATA;
@@ -616,9 +667,8 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_open(afc_client_t client, const char *
616 if (!client || !client->parent || !client->afc_packet) 667 if (!client || !client->parent || !client->afc_packet)
617 return AFC_E_INVALID_ARG; 668 return AFC_E_INVALID_ARG;
618 669
619 uint64_t file_mode_loc = htole64(file_mode); 670 //uint64_t file_mode_loc = htole64(file_mode);
620 uint32_t bytes = 0; 671 uint32_t bytes = 0;
621 char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1));
622 afc_error_t ret = AFC_E_UNKNOWN_ERROR; 672 afc_error_t ret = AFC_E_UNKNOWN_ERROR;
623 673
624 /* set handle to 0 so in case an error occurs, the handle is invalid */ 674 /* set handle to 0 so in case an error occurs, the handle is invalid */
@@ -626,20 +676,25 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_open(afc_client_t client, const char *
626 676
627 afc_lock(client); 677 afc_lock(client);
628 678
629 /* Send command */ 679 uint32_t data_len = (uint32_t)(strlen(filename)+1 + 8);
630 memcpy(data, &file_mode_loc, 8); 680 if (_afc_check_packet_buffer(client, data_len) < 0) {
631 memcpy(data + 8, filename, strlen(filename)); 681 afc_unlock(client);
632 data[8 + strlen(filename)] = '\0'; 682 debug_info("Failed to realloc packet buffer");
633 ret = afc_dispatch_packet(client, AFC_OP_FILE_OPEN, data, 8 + strlen(filename) + 1, NULL, 0, &bytes); 683 return AFC_E_NO_MEM;
634 free(data); 684 }
635 685
686 /* Send command */
687 //memcpy(AFC_PACKET_DATA_PTR, &file_mode_loc, 8);
688 *(uint64_t*)(AFC_PACKET_DATA_PTR) = htole64(file_mode);
689 memcpy(AFC_PACKET_DATA_PTR + 8, filename, data_len-8);
690 ret = afc_dispatch_packet(client, AFC_OP_FILE_OPEN, data_len, NULL, 0, &bytes);
636 if (ret != AFC_E_SUCCESS) { 691 if (ret != AFC_E_SUCCESS) {
637 debug_info("Didn't receive a response to the command"); 692 debug_info("Didn't receive a response to the command");
638 afc_unlock(client); 693 afc_unlock(client);
639 return AFC_E_NOT_ENOUGH_DATA; 694 return AFC_E_NOT_ENOUGH_DATA;
640 } 695 }
641 /* Receive the data */ 696 /* Receive the data */
642 data = NULL; 697 char* data = NULL;
643 ret = afc_receive_data(client, &data, &bytes); 698 ret = afc_receive_data(client, &data, &bytes);
644 if ((ret == AFC_E_SUCCESS) && (bytes > 0) && data) { 699 if ((ret == AFC_E_SUCCESS) && (bytes > 0) && data) {
645 afc_unlock(client); 700 afc_unlock(client);
@@ -663,23 +718,25 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_read(afc_client_t client, uint64_t han
663{ 718{
664 char *input = NULL; 719 char *input = NULL;
665 uint32_t current_count = 0, bytes_loc = 0; 720 uint32_t current_count = 0, bytes_loc = 0;
721 struct readinfo {
722 uint64_t handle;
723 uint64_t size;
724 };
666 afc_error_t ret = AFC_E_SUCCESS; 725 afc_error_t ret = AFC_E_SUCCESS;
667 726
668 if (!client || !client->afc_packet || !client->parent || handle == 0) 727 if (!client || !client->afc_packet || !client->parent || handle == 0)
669 return AFC_E_INVALID_ARG; 728 return AFC_E_INVALID_ARG;
670 debug_info("called for length %i", length); 729 debug_info("called for length %i", length);
671 730
731 //uint32_t data_len = 8 + 8;
732
672 afc_lock(client); 733 afc_lock(client);
673 734
674 /* Send the read command */ 735 /* Send the read command */
675 struct { 736 struct readinfo* readinfo = (struct readinfo*)(AFC_PACKET_DATA_PTR);
676 uint64_t handle; 737 readinfo->handle = handle;
677 uint64_t size; 738 readinfo->size = htole64(length);
678 } readinfo; 739 ret = afc_dispatch_packet(client, AFC_OP_FILE_READ, sizeof(struct readinfo), NULL, 0, &bytes_loc);
679 readinfo.handle = handle;
680 readinfo.size = htole64(length);
681 ret = afc_dispatch_packet(client, AFC_OP_FILE_READ, (const char*)&readinfo, sizeof(readinfo), NULL, 0, &bytes_loc);
682
683 if (ret != AFC_E_SUCCESS) { 740 if (ret != AFC_E_SUCCESS) {
684 afc_unlock(client); 741 afc_unlock(client);
685 return AFC_E_NOT_ENOUGH_DATA; 742 return AFC_E_NOT_ENOUGH_DATA;
@@ -721,11 +778,14 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_write(afc_client_t client, uint64_t ha
721 if (!client || !client->afc_packet || !client->parent || !bytes_written || (handle == 0)) 778 if (!client || !client->afc_packet || !client->parent || !bytes_written || (handle == 0))
722 return AFC_E_INVALID_ARG; 779 return AFC_E_INVALID_ARG;
723 780
781 uint32_t data_len = 8;
782
724 afc_lock(client); 783 afc_lock(client);
725 784
726 debug_info("Write length: %i", length); 785 debug_info("Write length: %i", length);
727 786
728 ret = afc_dispatch_packet(client, AFC_OP_FILE_WRITE, (const char*)&handle, 8, data, length, &bytes_loc); 787 *(uint64_t*)(AFC_PACKET_DATA_PTR) = handle;
788 ret = afc_dispatch_packet(client, AFC_OP_FILE_WRITE, data_len, data, length, &bytes_loc);
729 789
730 current_count += bytes_loc - (sizeof(AFCPacket) + 8); 790 current_count += bytes_loc - (sizeof(AFCPacket) + 8);
731 791
@@ -752,12 +812,15 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_close(afc_client_t client, uint64_t ha
752 if (!client || (handle == 0)) 812 if (!client || (handle == 0))
753 return AFC_E_INVALID_ARG; 813 return AFC_E_INVALID_ARG;
754 814
815 uint32_t data_len = 8;
816
755 afc_lock(client); 817 afc_lock(client);
756 818
757 debug_info("File handle %i", handle); 819 debug_info("File handle %i", handle);
758 820
759 /* Send command */ 821 /* Send command */
760 ret = afc_dispatch_packet(client, AFC_OP_FILE_CLOSE, (const char*)&handle, 8, NULL, 0, &bytes); 822 *(uint64_t*)(AFC_PACKET_DATA_PTR) = handle;
823 ret = afc_dispatch_packet(client, AFC_OP_FILE_CLOSE, data_len, NULL, 0, &bytes);
761 824
762 if (ret != AFC_E_SUCCESS) { 825 if (ret != AFC_E_SUCCESS) {
763 afc_unlock(client); 826 afc_unlock(client);
@@ -775,10 +838,10 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_close(afc_client_t client, uint64_t ha
775LIBIMOBILEDEVICE_API afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation) 838LIBIMOBILEDEVICE_API afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation)
776{ 839{
777 uint32_t bytes = 0; 840 uint32_t bytes = 0;
778 struct { 841 struct lockinfo {
779 uint64_t handle; 842 uint64_t handle;
780 uint64_t op; 843 uint64_t op;
781 } lockinfo; 844 };
782 afc_error_t ret = AFC_E_UNKNOWN_ERROR; 845 afc_error_t ret = AFC_E_UNKNOWN_ERROR;
783 846
784 if (!client || (handle == 0)) 847 if (!client || (handle == 0))
@@ -789,10 +852,10 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_lock(afc_client_t client, uint64_t han
789 debug_info("file handle %i", handle); 852 debug_info("file handle %i", handle);
790 853
791 /* Send command */ 854 /* Send command */
792 lockinfo.handle = handle; 855 struct lockinfo* lockinfo = (struct lockinfo*)(AFC_PACKET_DATA_PTR);
793 lockinfo.op = htole64(operation); 856 lockinfo->handle = handle;
794 ret = afc_dispatch_packet(client, AFC_OP_FILE_LOCK, (const char*)&lockinfo, sizeof(lockinfo), NULL, 0, &bytes); 857 lockinfo->op = htole64(operation);
795 858 ret = afc_dispatch_packet(client, AFC_OP_FILE_LOCK, sizeof(struct lockinfo), NULL, 0, &bytes);
796 if (ret != AFC_E_SUCCESS) { 859 if (ret != AFC_E_SUCCESS) {
797 afc_unlock(client); 860 afc_unlock(client);
798 debug_info("could not send lock command"); 861 debug_info("could not send lock command");
@@ -809,11 +872,11 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_lock(afc_client_t client, uint64_t han
809LIBIMOBILEDEVICE_API afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence) 872LIBIMOBILEDEVICE_API afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence)
810{ 873{
811 uint32_t bytes = 0; 874 uint32_t bytes = 0;
812 struct { 875 struct seekinfo {
813 uint64_t handle; 876 uint64_t handle;
814 uint64_t whence; 877 uint64_t whence;
815 int64_t offset; 878 int64_t offset;
816 } seekinfo; 879 };
817 afc_error_t ret = AFC_E_UNKNOWN_ERROR; 880 afc_error_t ret = AFC_E_UNKNOWN_ERROR;
818 881
819 if (!client || (handle == 0)) 882 if (!client || (handle == 0))
@@ -822,10 +885,11 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_seek(afc_client_t client, uint64_t han
822 afc_lock(client); 885 afc_lock(client);
823 886
824 /* Send the command */ 887 /* Send the command */
825 seekinfo.handle = handle; 888 struct seekinfo* seekinfo = (struct seekinfo*)(AFC_PACKET_DATA_PTR);
826 seekinfo.whence = htole64(whence); 889 seekinfo->handle = handle;
827 seekinfo.offset = (int64_t)htole64(offset); 890 seekinfo->whence = htole64(whence);
828 ret = afc_dispatch_packet(client, AFC_OP_FILE_SEEK, (const char*)&seekinfo, sizeof(seekinfo), NULL, 0, &bytes); 891 seekinfo->offset = (int64_t)htole64(offset);
892 ret = afc_dispatch_packet(client, AFC_OP_FILE_SEEK, sizeof(struct seekinfo), NULL, 0, &bytes);
829 893
830 if (ret != AFC_E_SUCCESS) { 894 if (ret != AFC_E_SUCCESS) {
831 afc_unlock(client); 895 afc_unlock(client);
@@ -848,11 +912,13 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_tell(afc_client_t client, uint64_t han
848 if (!client || (handle == 0)) 912 if (!client || (handle == 0))
849 return AFC_E_INVALID_ARG; 913 return AFC_E_INVALID_ARG;
850 914
915 uint32_t data_len = 8;
916
851 afc_lock(client); 917 afc_lock(client);
852 918
853 /* Send the command */ 919 /* Send the command */
854 ret = afc_dispatch_packet(client, AFC_OP_FILE_TELL, (const char*)&handle, 8, NULL, 0, &bytes); 920 *(uint64_t*)(AFC_PACKET_DATA_PTR) = handle;
855 921 ret = afc_dispatch_packet(client, AFC_OP_FILE_TELL, data_len, NULL, 0, &bytes);
856 if (ret != AFC_E_SUCCESS) { 922 if (ret != AFC_E_SUCCESS) {
857 afc_unlock(client); 923 afc_unlock(client);
858 return AFC_E_NOT_ENOUGH_DATA; 924 return AFC_E_NOT_ENOUGH_DATA;
@@ -875,10 +941,10 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_tell(afc_client_t client, uint64_t han
875LIBIMOBILEDEVICE_API afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize) 941LIBIMOBILEDEVICE_API afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize)
876{ 942{
877 uint32_t bytes = 0; 943 uint32_t bytes = 0;
878 struct { 944 struct truncinfo {
879 uint64_t handle; 945 uint64_t handle;
880 uint64_t newsize; 946 uint64_t newsize;
881 } truncinfo; 947 };
882 afc_error_t ret = AFC_E_UNKNOWN_ERROR; 948 afc_error_t ret = AFC_E_UNKNOWN_ERROR;
883 949
884 if (!client || (handle == 0)) 950 if (!client || (handle == 0))
@@ -887,9 +953,10 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_truncate(afc_client_t client, uint64_t
887 afc_lock(client); 953 afc_lock(client);
888 954
889 /* Send command */ 955 /* Send command */
890 truncinfo.handle = handle; 956 struct truncinfo* truncinfo = (struct truncinfo*)(AFC_PACKET_DATA_PTR);
891 truncinfo.newsize = htole64(newsize); 957 truncinfo->handle = handle;
892 ret = afc_dispatch_packet(client, AFC_OP_FILE_SET_SIZE, (const char*)&truncinfo, sizeof(truncinfo), NULL, 0, &bytes); 958 truncinfo->newsize = htole64(newsize);
959 ret = afc_dispatch_packet(client, AFC_OP_FILE_SET_SIZE, sizeof(struct truncinfo), NULL, 0, &bytes);
893 960
894 if (ret != AFC_E_SUCCESS) { 961 if (ret != AFC_E_SUCCESS) {
895 afc_unlock(client); 962 afc_unlock(client);
@@ -908,19 +975,22 @@ LIBIMOBILEDEVICE_API afc_error_t afc_truncate(afc_client_t client, const char *p
908 if (!client || !path || !client->afc_packet || !client->parent) 975 if (!client || !path || !client->afc_packet || !client->parent)
909 return AFC_E_INVALID_ARG; 976 return AFC_E_INVALID_ARG;
910 977
911 char *buffer = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8));
912 uint32_t bytes = 0; 978 uint32_t bytes = 0;
913 uint64_t size_requested = htole64(newsize);
914 afc_error_t ret = AFC_E_UNKNOWN_ERROR; 979 afc_error_t ret = AFC_E_UNKNOWN_ERROR;
915 980
916 afc_lock(client); 981 afc_lock(client);
917 982
918 /* Send command */ 983 uint32_t data_len = 8 + (uint32_t)(strlen(path)+1);
919 memcpy(buffer, &size_requested, 8); 984 if (_afc_check_packet_buffer(client, data_len) < 0) {
920 memcpy(buffer + 8, path, strlen(path) + 1); 985 afc_unlock(client);
921 ret = afc_dispatch_packet(client, AFC_OP_TRUNCATE, buffer, 8 + strlen(path) + 1, NULL, 0, &bytes); 986 debug_info("Failed to realloc packet buffer");
922 free(buffer); 987 return AFC_E_NO_MEM;
988 }
923 989
990 /* Send command */
991 *(uint64_t*)(AFC_PACKET_DATA_PTR) = htole64(newsize);
992 memcpy(AFC_PACKET_DATA_PTR + 8, path, data_len-8);
993 ret = afc_dispatch_packet(client, AFC_OP_TRUNCATE, data_len, NULL, 0, &bytes);
924 if (ret != AFC_E_SUCCESS) { 994 if (ret != AFC_E_SUCCESS) {
925 afc_unlock(client); 995 afc_unlock(client);
926 return AFC_E_NOT_ENOUGH_DATA; 996 return AFC_E_NOT_ENOUGH_DATA;
@@ -938,23 +1008,31 @@ LIBIMOBILEDEVICE_API afc_error_t afc_make_link(afc_client_t client, afc_link_typ
938 if (!client || !target || !linkname || !client->afc_packet || !client->parent) 1008 if (!client || !target || !linkname || !client->afc_packet || !client->parent)
939 return AFC_E_INVALID_ARG; 1009 return AFC_E_INVALID_ARG;
940 1010
941 char *buffer = (char *) malloc(sizeof(char) * (strlen(target)+1 + strlen(linkname)+1 + 8));
942 uint32_t bytes = 0; 1011 uint32_t bytes = 0;
943 uint64_t type = htole64(linktype); 1012 uint64_t type = htole64(linktype);
944 afc_error_t ret = AFC_E_UNKNOWN_ERROR; 1013 afc_error_t ret = AFC_E_UNKNOWN_ERROR;
945 1014
1015 size_t target_len = strlen(target);
1016 size_t link_len = strlen(linkname);
1017
946 afc_lock(client); 1018 afc_lock(client);
947 1019
1020 uint32_t data_len = 8 + target_len + 1 + link_len + 1;
1021 if (_afc_check_packet_buffer(client, data_len) < 0) {
1022 afc_unlock(client);
1023 debug_info("Failed to realloc packet buffer");
1024 return AFC_E_NO_MEM;
1025 }
1026
948 debug_info("link type: %lld", type); 1027 debug_info("link type: %lld", type);
949 debug_info("target: %s, length:%d", target, strlen(target)); 1028 debug_info("target: %s, length:%d", target, target_len);
950 debug_info("linkname: %s, length:%d", linkname, strlen(linkname)); 1029 debug_info("linkname: %s, length:%d", linkname, link_len);
951 1030
952 /* Send command */ 1031 /* Send command */
953 memcpy(buffer, &type, 8); 1032 *(uint64_t*)(AFC_PACKET_DATA_PTR) = htole64(linktype);
954 memcpy(buffer + 8, target, strlen(target) + 1); 1033 memcpy(AFC_PACKET_DATA_PTR + 8, target, target_len + 1);
955 memcpy(buffer + 8 + strlen(target) + 1, linkname, strlen(linkname) + 1); 1034 memcpy(AFC_PACKET_DATA_PTR + 8 + target_len + 1, linkname, link_len + 1);
956 ret = afc_dispatch_packet(client, AFC_OP_MAKE_LINK, buffer, 8 + strlen(linkname) + 1 + strlen(target) + 1, NULL, 0, &bytes); 1035 ret = afc_dispatch_packet(client, AFC_OP_MAKE_LINK, data_len, NULL, 0, &bytes);
957 free(buffer);
958 if (ret != AFC_E_SUCCESS) { 1036 if (ret != AFC_E_SUCCESS) {
959 afc_unlock(client); 1037 afc_unlock(client);
960 return AFC_E_NOT_ENOUGH_DATA; 1038 return AFC_E_NOT_ENOUGH_DATA;
@@ -972,18 +1050,22 @@ LIBIMOBILEDEVICE_API afc_error_t afc_set_file_time(afc_client_t client, const ch
972 if (!client || !path || !client->afc_packet || !client->parent) 1050 if (!client || !path || !client->afc_packet || !client->parent)
973 return AFC_E_INVALID_ARG; 1051 return AFC_E_INVALID_ARG;
974 1052
975 char *buffer = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8));
976 uint32_t bytes = 0; 1053 uint32_t bytes = 0;
977 uint64_t mtime_loc = htole64(mtime);
978 afc_error_t ret = AFC_E_UNKNOWN_ERROR; 1054 afc_error_t ret = AFC_E_UNKNOWN_ERROR;
979 1055
980 afc_lock(client); 1056 afc_lock(client);
981 1057
1058 uint32_t data_len = 8 + strlen(path) + 1;
1059 if (_afc_check_packet_buffer(client, data_len) < 0) {
1060 afc_unlock(client);
1061 debug_info("Failed to realloc packet buffer");
1062 return AFC_E_NO_MEM;
1063 }
1064
982 /* Send command */ 1065 /* Send command */
983 memcpy(buffer, &mtime_loc, 8); 1066 *(uint64_t*)(AFC_PACKET_DATA_PTR) = htole64(mtime);
984 memcpy(buffer + 8, path, strlen(path) + 1); 1067 memcpy(AFC_PACKET_DATA_PTR + 8, path, data_len-8);
985 ret = afc_dispatch_packet(client, AFC_OP_SET_FILE_MOD_TIME, buffer, 8 + strlen(path) + 1, NULL, 0, &bytes); 1068 ret = afc_dispatch_packet(client, AFC_OP_SET_FILE_MOD_TIME, data_len, NULL, 0, &bytes);
986 free(buffer);
987 if (ret != AFC_E_SUCCESS) { 1069 if (ret != AFC_E_SUCCESS) {
988 afc_unlock(client); 1070 afc_unlock(client);
989 return AFC_E_NOT_ENOUGH_DATA; 1071 return AFC_E_NOT_ENOUGH_DATA;
@@ -1006,8 +1088,16 @@ LIBIMOBILEDEVICE_API afc_error_t afc_remove_path_and_contents(afc_client_t clien
1006 1088
1007 afc_lock(client); 1089 afc_lock(client);
1008 1090
1091 uint32_t data_len = strlen(path) + 1;
1092 if (_afc_check_packet_buffer(client, data_len) < 0) {
1093 afc_unlock(client);
1094 debug_info("Failed to realloc packet buffer");
1095 return AFC_E_NO_MEM;
1096 }
1097
1009 /* Send command */ 1098 /* Send command */
1010 ret = afc_dispatch_packet(client, AFC_OP_REMOVE_PATH_AND_CONTENTS, path, strlen(path)+1, NULL, 0, &bytes); 1099 memcpy(AFC_PACKET_DATA_PTR, path, data_len);
1100 ret = afc_dispatch_packet(client, AFC_OP_REMOVE_PATH_AND_CONTENTS, data_len, NULL, 0, &bytes);
1011 if (ret != AFC_E_SUCCESS) { 1101 if (ret != AFC_E_SUCCESS) {
1012 afc_unlock(client); 1102 afc_unlock(client);
1013 return AFC_E_NOT_ENOUGH_DATA; 1103 return AFC_E_NOT_ENOUGH_DATA;