summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2014-03-21 22:54:08 +0100
committerGravatar Nikias Bassen2014-03-21 22:54:08 +0100
commit7320497d00fde338f795e8caa8ebdb24cff2ee7d (patch)
tree1b8a43405a304c263bcd4f6cbe2d6ff4f091c65e /src
parent6274a11918e5c327f46d02756869de9701b6c598 (diff)
downloadlibimobiledevice-7320497d00fde338f795e8caa8ebdb24cff2ee7d.tar.gz
libimobiledevice-7320497d00fde338f795e8caa8ebdb24cff2ee7d.tar.bz2
afc: Remove segmentation code from afc_file_read()
Diffstat (limited to 'src')
-rw-r--r--src/afc.c85
1 files changed, 34 insertions, 51 deletions
diff --git a/src/afc.c b/src/afc.c
index 41a4e62..5b61ba7 100644
--- a/src/afc.c
+++ b/src/afc.c
@@ -32,9 +32,6 @@
32#include "common/debug.h" 32#include "common/debug.h"
33#include "endianness.h" 33#include "endianness.h"
34 34
35/** The maximum size an AFC data packet can be */
36static const int MAXIMUM_PACKET_SIZE = (2 << 15);
37
38/** 35/**
39 * Locks an AFC client, done for thread safety stuff 36 * Locks an AFC client, done for thread safety stuff
40 * 37 *
@@ -309,11 +306,6 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t
309 entire_len = (uint32_t)header.entire_length - sizeof(AFCPacket); 306 entire_len = (uint32_t)header.entire_length - sizeof(AFCPacket);
310 this_len = (uint32_t)header.this_length - sizeof(AFCPacket); 307 this_len = (uint32_t)header.this_length - sizeof(AFCPacket);
311 308
312 /* this is here as a check (perhaps a different upper limit is good?) */
313 if (entire_len > (uint32_t)MAXIMUM_PACKET_SIZE) {
314 fprintf(stderr, "%s: entire_len is larger than MAXIMUM_PACKET_SIZE, (%d > %d)!", __func__, entire_len, MAXIMUM_PACKET_SIZE);
315 }
316
317 dump_here = (char*)malloc(entire_len); 309 dump_here = (char*)malloc(entire_len);
318 if (this_len > 0) { 310 if (this_len > 0) {
319 service_receive(client->parent, dump_here, this_len, bytes_recv); 311 service_receive(client->parent, dump_here, this_len, bytes_recv);
@@ -795,7 +787,6 @@ afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length,
795{ 787{
796 char *input = NULL; 788 char *input = NULL;
797 uint32_t current_count = 0, bytes_loc = 0; 789 uint32_t current_count = 0, bytes_loc = 0;
798 const uint32_t MAXIMUM_READ_SIZE = 1 << 16;
799 afc_error_t ret = AFC_E_SUCCESS; 790 afc_error_t ret = AFC_E_SUCCESS;
800 791
801 if (!client || !client->afc_packet || !client->parent || handle == 0) 792 if (!client || !client->afc_packet || !client->parent || handle == 0)
@@ -804,50 +795,42 @@ afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length,
804 795
805 afc_lock(client); 796 afc_lock(client);
806 797
807 /* Looping here to get around the maximum amount of data that 798 /* Send the read command */
808 afc_receive_data can handle */ 799 struct {
809 while (current_count < length) { 800 uint64_t handle;
810 debug_info("current count is %i but length is %i", current_count, length); 801 uint64_t size;
811 802 } readinfo;
812 /* Send the read command */ 803 readinfo.handle = handle;
813 struct { 804 readinfo.size = htole64(length);
814 uint64_t handle; 805 ret = afc_dispatch_packet(client, AFC_OP_READ, (const char*)&readinfo, sizeof(readinfo), NULL, 0, &bytes_loc);
815 uint64_t size; 806
816 } readinfo; 807 if (ret != AFC_E_SUCCESS) {
817 readinfo.handle = handle; 808 afc_unlock(client);
818 readinfo.size = htole64(((length - current_count) < MAXIMUM_READ_SIZE) ? (length - current_count) : MAXIMUM_READ_SIZE); 809 return AFC_E_NOT_ENOUGH_DATA;
819 ret = afc_dispatch_packet(client, AFC_OP_READ, (const char*)&readinfo, sizeof(readinfo), NULL, 0, &bytes_loc); 810 }
820 811 /* Receive the data */
821 if (ret != AFC_E_SUCCESS) { 812 ret = afc_receive_data(client, &input, &bytes_loc);
822 afc_unlock(client); 813 debug_info("afc_receive_data returned error: %d", ret);
823 return AFC_E_NOT_ENOUGH_DATA; 814 debug_info("bytes returned: %i", bytes_loc);
824 } 815 if (ret != AFC_E_SUCCESS) {
825 /* Receive the data */ 816 afc_unlock(client);
826 ret = afc_receive_data(client, &input, &bytes_loc); 817 return ret;
827 debug_info("afc_receive_data returned error: %d", ret); 818 } else if (bytes_loc == 0) {
828 debug_info("bytes returned: %i", bytes_loc); 819 if (input)
829 if (ret != AFC_E_SUCCESS) { 820 free(input);
830 afc_unlock(client); 821 afc_unlock(client);
831 return ret; 822 *bytes_read = current_count;
832 } else if (bytes_loc == 0) { 823 /* FIXME: check that's actually a success */
833 if (input) 824 return ret;
834 free(input); 825 } else {
835 afc_unlock(client); 826 if (input) {
836 *bytes_read = current_count; 827 debug_info("%d", bytes_loc);
837 /* FIXME: check that's actually a success */ 828 memcpy(data + current_count, input, (bytes_loc > length) ? length : bytes_loc);
838 return ret; 829 free(input);
839 } else { 830 input = NULL;
840 if (input) { 831 current_count += (bytes_loc > length) ? length : bytes_loc;
841 debug_info("%d", bytes_loc);
842 memcpy(data + current_count, input, (bytes_loc > length) ? length : bytes_loc);
843 free(input);
844 input = NULL;
845 current_count += (bytes_loc > length) ? length : bytes_loc;
846 }
847 } 832 }
848 } 833 }
849 debug_info("returning current_count as %i", current_count);
850
851 afc_unlock(client); 834 afc_unlock(client);
852 *bytes_read = current_count; 835 *bytes_read = current_count;
853 return ret; 836 return ret;