From 59f16a14692f7d84c5871394b8928d94b4dc34ce Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Tue, 19 May 2020 05:43:38 +0200 Subject: afc: Reduce packet segmentation and unnecessary malloc/free --- src/afc.c | 284 +++++++++++++++++++++++++++++++++++++++++--------------------- src/afc.h | 1 + 2 files changed, 188 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 client_loc->free_parent = 0; /* allocate a packet */ - client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket)); + client_loc->packet_extra = 1024; + client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket) + client_loc->packet_extra); if (!client_loc->afc_packet) { free(client_loc); return AFC_E_NO_MEM; } - client_loc->afc_packet->packet_num = 0; client_loc->afc_packet->entire_length = 0; client_loc->afc_packet->this_length = 0; @@ -148,7 +148,7 @@ LIBIMOBILEDEVICE_API afc_error_t afc_client_free(afc_client_t client) * * @return AFC_E_SUCCESS on success or an AFC_E_* error value. */ -static 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) +static 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) { uint32_t sent = 0; @@ -157,8 +157,6 @@ static afc_error_t afc_dispatch_packet(afc_client_t client, uint64_t operation, *bytes_sent = 0; - if (!data || !data_length) - data_length = 0; if (!payload || !payload_length) payload_length = 0; @@ -169,34 +167,26 @@ static afc_error_t afc_dispatch_packet(afc_client_t client, uint64_t operation, debug_info("packet length = %i", client->afc_packet->this_length); - debug_buffer((char*)client->afc_packet, sizeof(AFCPacket)); - - /* send AFC packet header */ + /* send AFC packet header and data */ AFCPacket_to_LE(client->afc_packet); + debug_buffer((char*)client->afc_packet, sizeof(AFCPacket) + data_length); sent = 0; - service_send(client->parent, (void*)client->afc_packet, sizeof(AFCPacket), &sent); + service_send(client->parent, (void*)client->afc_packet, sizeof(AFCPacket) + data_length, &sent); AFCPacket_from_LE(client->afc_packet); *bytes_sent += sent; - if (sent < sizeof(AFCPacket)) { - return AFC_E_SUCCESS; - } - - /* send AFC packet data (if there's data to send) */ - sent = 0; - if (data_length > 0) { - debug_info("packet data follows"); - debug_buffer(data, data_length); - service_send(client->parent, data, data_length, &sent); - } - *bytes_sent += sent; - if (sent < data_length) { + if (sent < sizeof(AFCPacket) + data_length) { return AFC_E_SUCCESS; } sent = 0; if (payload_length > 0) { - debug_info("packet payload follows"); - debug_buffer(payload, payload_length); + if (payload_length > 256) { + debug_info("packet payload follows (256/%u)", payload_length); + debug_buffer(payload, 256); + } else { + debug_info("packet payload follows"); + debug_buffer(payload, payload_length); + } service_send(client->parent, payload, payload_length, &sent); } *bytes_sent += sent; @@ -310,8 +300,13 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t } debug_info("packet data size = %i", current_count); - debug_info("packet data follows"); - debug_buffer(dump_here, current_count); + if (current_count > 256) { + debug_info("packet data follows (256/%u)", current_count); + debug_buffer(dump_here, 256); + } else { + debug_info("packet data follows"); + debug_buffer(dump_here, current_count); + } /* check operation types */ if (header.operation == AFC_OP_STATUS) { @@ -400,6 +395,21 @@ static char **make_strings_list(char *tokens, uint32_t length) return list; } +static int _afc_check_packet_buffer(afc_client_t client, uint32_t data_len) +{ + if (data_len > client->packet_extra) { + client->packet_extra = (data_len & ~8) + 8; + AFCPacket* newpkt = (AFCPacket*)realloc(client->afc_packet, sizeof(AFCPacket) + client->packet_extra); + if (!newpkt) { + return -1; + } + client->afc_packet = newpkt; + } + return 0; +} + +#define AFC_PACKET_DATA_PTR ((char*)client->afc_packet + sizeof(AFCPacket)) + LIBIMOBILEDEVICE_API afc_error_t afc_read_directory(afc_client_t client, const char *path, char ***directory_information) { uint32_t bytes = 0; @@ -411,8 +421,16 @@ LIBIMOBILEDEVICE_API afc_error_t afc_read_directory(afc_client_t client, const c afc_lock(client); + uint32_t data_len = (uint32_t)strlen(path)+1; + if (_afc_check_packet_buffer(client, data_len) < 0) { + afc_unlock(client); + debug_info("Failed to realloc packet buffer"); + return AFC_E_NO_MEM; + } + /* Send the command */ - ret = afc_dispatch_packet(client, AFC_OP_READ_DIR, path, strlen(path)+1, NULL, 0, &bytes); + memcpy(AFC_PACKET_DATA_PTR, path, data_len); + ret = afc_dispatch_packet(client, AFC_OP_READ_DIR, data_len, NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { afc_unlock(client); return AFC_E_NOT_ENOUGH_DATA; @@ -448,7 +466,7 @@ LIBIMOBILEDEVICE_API afc_error_t afc_get_device_info(afc_client_t client, char * afc_lock(client); /* Send the command */ - ret = afc_dispatch_packet(client, AFC_OP_GET_DEVINFO, NULL, 0, NULL, 0, &bytes); + ret = afc_dispatch_packet(client, AFC_OP_GET_DEVINFO, 0, NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { afc_unlock(client); return AFC_E_NOT_ENOUGH_DATA; @@ -510,8 +528,16 @@ LIBIMOBILEDEVICE_API afc_error_t afc_remove_path(afc_client_t client, const char afc_lock(client); + uint32_t data_len = (uint32_t)strlen(path)+1; + if (_afc_check_packet_buffer(client, data_len) < 0) { + afc_unlock(client); + debug_info("Failed to realloc packet buffer"); + return AFC_E_NO_MEM; + } + /* Send command */ - ret = afc_dispatch_packet(client, AFC_OP_REMOVE_PATH, path, strlen(path)+1, NULL, 0, &bytes); + memcpy(AFC_PACKET_DATA_PTR, path, data_len); + ret = afc_dispatch_packet(client, AFC_OP_REMOVE_PATH, data_len, NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { afc_unlock(client); return AFC_E_NOT_ENOUGH_DATA; @@ -533,18 +559,25 @@ LIBIMOBILEDEVICE_API afc_error_t afc_rename_path(afc_client_t client, const char if (!client || !from || !to || !client->afc_packet || !client->parent) return AFC_E_INVALID_ARG; - char *buffer = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32_t))); uint32_t bytes = 0; afc_error_t ret = AFC_E_UNKNOWN_ERROR; + size_t from_len = strlen(from); + size_t to_len = strlen(to); + afc_lock(client); - /* Send command */ - memcpy(buffer, from, strlen(from) + 1); - memcpy(buffer + strlen(from) + 1, to, strlen(to) + 1); - ret = afc_dispatch_packet(client, AFC_OP_RENAME_PATH, buffer, strlen(to)+1 + strlen(from)+1, NULL, 0, &bytes); - free(buffer); + uint32_t data_len = (uint32_t)(from_len+1 + to_len+1); + if (_afc_check_packet_buffer(client, data_len) < 0) { + afc_unlock(client); + debug_info("Failed to realloc packet buffer"); + return AFC_E_NO_MEM; + } + /* Send command */ + memcpy(AFC_PACKET_DATA_PTR, from, from_len+1); + memcpy(AFC_PACKET_DATA_PTR + from_len+1, to, to_len+1); + ret = afc_dispatch_packet(client, AFC_OP_RENAME_PATH, data_len, NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { afc_unlock(client); return AFC_E_NOT_ENOUGH_DATA; @@ -567,8 +600,16 @@ LIBIMOBILEDEVICE_API afc_error_t afc_make_directory(afc_client_t client, const c afc_lock(client); + uint32_t data_len = (uint32_t)strlen(path)+1; + if (_afc_check_packet_buffer(client, data_len) < 0) { + afc_unlock(client); + debug_info("Failed to realloc packet buffer"); + return AFC_E_NO_MEM; + } + /* Send command */ - ret = afc_dispatch_packet(client, AFC_OP_MAKE_DIR, path, strlen(path)+1, NULL, 0, &bytes); + memcpy(AFC_PACKET_DATA_PTR, path, data_len); + ret = afc_dispatch_packet(client, AFC_OP_MAKE_DIR, data_len, NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { afc_unlock(client); 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 afc_lock(client); + uint32_t data_len = (uint32_t)strlen(path)+1; + if (_afc_check_packet_buffer(client, data_len) < 0) { + afc_unlock(client); + debug_info("Failed to realloc packet buffer"); + return AFC_E_NO_MEM; + } + + debug_info("We got %p and %p", client->afc_packet, AFC_PACKET_DATA_PTR); + /* Send command */ - ret = afc_dispatch_packet(client, AFC_OP_GET_FILE_INFO, path, strlen(path)+1, NULL, 0, &bytes); + memcpy(AFC_PACKET_DATA_PTR, path, data_len); + ret = afc_dispatch_packet(client, AFC_OP_GET_FILE_INFO, data_len, NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { afc_unlock(client); return AFC_E_NOT_ENOUGH_DATA; @@ -616,9 +667,8 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_open(afc_client_t client, const char * if (!client || !client->parent || !client->afc_packet) return AFC_E_INVALID_ARG; - uint64_t file_mode_loc = htole64(file_mode); + //uint64_t file_mode_loc = htole64(file_mode); uint32_t bytes = 0; - char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1)); afc_error_t ret = AFC_E_UNKNOWN_ERROR; /* 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 * afc_lock(client); - /* Send command */ - memcpy(data, &file_mode_loc, 8); - memcpy(data + 8, filename, strlen(filename)); - data[8 + strlen(filename)] = '\0'; - ret = afc_dispatch_packet(client, AFC_OP_FILE_OPEN, data, 8 + strlen(filename) + 1, NULL, 0, &bytes); - free(data); + uint32_t data_len = (uint32_t)(strlen(filename)+1 + 8); + if (_afc_check_packet_buffer(client, data_len) < 0) { + afc_unlock(client); + debug_info("Failed to realloc packet buffer"); + return AFC_E_NO_MEM; + } + /* Send command */ + //memcpy(AFC_PACKET_DATA_PTR, &file_mode_loc, 8); + *(uint64_t*)(AFC_PACKET_DATA_PTR) = htole64(file_mode); + memcpy(AFC_PACKET_DATA_PTR + 8, filename, data_len-8); + ret = afc_dispatch_packet(client, AFC_OP_FILE_OPEN, data_len, NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { debug_info("Didn't receive a response to the command"); afc_unlock(client); return AFC_E_NOT_ENOUGH_DATA; } /* Receive the data */ - data = NULL; + char* data = NULL; ret = afc_receive_data(client, &data, &bytes); if ((ret == AFC_E_SUCCESS) && (bytes > 0) && data) { afc_unlock(client); @@ -663,23 +718,25 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_read(afc_client_t client, uint64_t han { char *input = NULL; uint32_t current_count = 0, bytes_loc = 0; + struct readinfo { + uint64_t handle; + uint64_t size; + }; afc_error_t ret = AFC_E_SUCCESS; if (!client || !client->afc_packet || !client->parent || handle == 0) return AFC_E_INVALID_ARG; debug_info("called for length %i", length); + //uint32_t data_len = 8 + 8; + afc_lock(client); /* Send the read command */ - struct { - uint64_t handle; - uint64_t size; - } readinfo; - readinfo.handle = handle; - readinfo.size = htole64(length); - ret = afc_dispatch_packet(client, AFC_OP_FILE_READ, (const char*)&readinfo, sizeof(readinfo), NULL, 0, &bytes_loc); - + struct readinfo* readinfo = (struct readinfo*)(AFC_PACKET_DATA_PTR); + readinfo->handle = handle; + readinfo->size = htole64(length); + ret = afc_dispatch_packet(client, AFC_OP_FILE_READ, sizeof(struct readinfo), NULL, 0, &bytes_loc); if (ret != AFC_E_SUCCESS) { afc_unlock(client); 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 if (!client || !client->afc_packet || !client->parent || !bytes_written || (handle == 0)) return AFC_E_INVALID_ARG; + uint32_t data_len = 8; + afc_lock(client); debug_info("Write length: %i", length); - ret = afc_dispatch_packet(client, AFC_OP_FILE_WRITE, (const char*)&handle, 8, data, length, &bytes_loc); + *(uint64_t*)(AFC_PACKET_DATA_PTR) = handle; + ret = afc_dispatch_packet(client, AFC_OP_FILE_WRITE, data_len, data, length, &bytes_loc); current_count += bytes_loc - (sizeof(AFCPacket) + 8); @@ -752,12 +812,15 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_close(afc_client_t client, uint64_t ha if (!client || (handle == 0)) return AFC_E_INVALID_ARG; + uint32_t data_len = 8; + afc_lock(client); debug_info("File handle %i", handle); /* Send command */ - ret = afc_dispatch_packet(client, AFC_OP_FILE_CLOSE, (const char*)&handle, 8, NULL, 0, &bytes); + *(uint64_t*)(AFC_PACKET_DATA_PTR) = handle; + ret = afc_dispatch_packet(client, AFC_OP_FILE_CLOSE, data_len, NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { afc_unlock(client); @@ -775,10 +838,10 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_close(afc_client_t client, uint64_t ha LIBIMOBILEDEVICE_API afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation) { uint32_t bytes = 0; - struct { + struct lockinfo { uint64_t handle; uint64_t op; - } lockinfo; + }; afc_error_t ret = AFC_E_UNKNOWN_ERROR; if (!client || (handle == 0)) @@ -789,10 +852,10 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_lock(afc_client_t client, uint64_t han debug_info("file handle %i", handle); /* Send command */ - lockinfo.handle = handle; - lockinfo.op = htole64(operation); - ret = afc_dispatch_packet(client, AFC_OP_FILE_LOCK, (const char*)&lockinfo, sizeof(lockinfo), NULL, 0, &bytes); - + struct lockinfo* lockinfo = (struct lockinfo*)(AFC_PACKET_DATA_PTR); + lockinfo->handle = handle; + lockinfo->op = htole64(operation); + ret = afc_dispatch_packet(client, AFC_OP_FILE_LOCK, sizeof(struct lockinfo), NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { afc_unlock(client); 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 LIBIMOBILEDEVICE_API afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence) { uint32_t bytes = 0; - struct { + struct seekinfo { uint64_t handle; uint64_t whence; int64_t offset; - } seekinfo; + }; afc_error_t ret = AFC_E_UNKNOWN_ERROR; if (!client || (handle == 0)) @@ -822,10 +885,11 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_seek(afc_client_t client, uint64_t han afc_lock(client); /* Send the command */ - seekinfo.handle = handle; - seekinfo.whence = htole64(whence); - seekinfo.offset = (int64_t)htole64(offset); - ret = afc_dispatch_packet(client, AFC_OP_FILE_SEEK, (const char*)&seekinfo, sizeof(seekinfo), NULL, 0, &bytes); + struct seekinfo* seekinfo = (struct seekinfo*)(AFC_PACKET_DATA_PTR); + seekinfo->handle = handle; + seekinfo->whence = htole64(whence); + seekinfo->offset = (int64_t)htole64(offset); + ret = afc_dispatch_packet(client, AFC_OP_FILE_SEEK, sizeof(struct seekinfo), NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { afc_unlock(client); @@ -848,11 +912,13 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_tell(afc_client_t client, uint64_t han if (!client || (handle == 0)) return AFC_E_INVALID_ARG; + uint32_t data_len = 8; + afc_lock(client); /* Send the command */ - ret = afc_dispatch_packet(client, AFC_OP_FILE_TELL, (const char*)&handle, 8, NULL, 0, &bytes); - + *(uint64_t*)(AFC_PACKET_DATA_PTR) = handle; + ret = afc_dispatch_packet(client, AFC_OP_FILE_TELL, data_len, NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { afc_unlock(client); 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 LIBIMOBILEDEVICE_API afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize) { uint32_t bytes = 0; - struct { + struct truncinfo { uint64_t handle; uint64_t newsize; - } truncinfo; + }; afc_error_t ret = AFC_E_UNKNOWN_ERROR; if (!client || (handle == 0)) @@ -887,9 +953,10 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_truncate(afc_client_t client, uint64_t afc_lock(client); /* Send command */ - truncinfo.handle = handle; - truncinfo.newsize = htole64(newsize); - ret = afc_dispatch_packet(client, AFC_OP_FILE_SET_SIZE, (const char*)&truncinfo, sizeof(truncinfo), NULL, 0, &bytes); + struct truncinfo* truncinfo = (struct truncinfo*)(AFC_PACKET_DATA_PTR); + truncinfo->handle = handle; + truncinfo->newsize = htole64(newsize); + ret = afc_dispatch_packet(client, AFC_OP_FILE_SET_SIZE, sizeof(struct truncinfo), NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { afc_unlock(client); @@ -908,19 +975,22 @@ LIBIMOBILEDEVICE_API afc_error_t afc_truncate(afc_client_t client, const char *p if (!client || !path || !client->afc_packet || !client->parent) return AFC_E_INVALID_ARG; - char *buffer = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8)); uint32_t bytes = 0; - uint64_t size_requested = htole64(newsize); afc_error_t ret = AFC_E_UNKNOWN_ERROR; afc_lock(client); - /* Send command */ - memcpy(buffer, &size_requested, 8); - memcpy(buffer + 8, path, strlen(path) + 1); - ret = afc_dispatch_packet(client, AFC_OP_TRUNCATE, buffer, 8 + strlen(path) + 1, NULL, 0, &bytes); - free(buffer); + uint32_t data_len = 8 + (uint32_t)(strlen(path)+1); + if (_afc_check_packet_buffer(client, data_len) < 0) { + afc_unlock(client); + debug_info("Failed to realloc packet buffer"); + return AFC_E_NO_MEM; + } + /* Send command */ + *(uint64_t*)(AFC_PACKET_DATA_PTR) = htole64(newsize); + memcpy(AFC_PACKET_DATA_PTR + 8, path, data_len-8); + ret = afc_dispatch_packet(client, AFC_OP_TRUNCATE, data_len, NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { afc_unlock(client); 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 if (!client || !target || !linkname || !client->afc_packet || !client->parent) return AFC_E_INVALID_ARG; - char *buffer = (char *) malloc(sizeof(char) * (strlen(target)+1 + strlen(linkname)+1 + 8)); uint32_t bytes = 0; uint64_t type = htole64(linktype); afc_error_t ret = AFC_E_UNKNOWN_ERROR; + size_t target_len = strlen(target); + size_t link_len = strlen(linkname); + afc_lock(client); + uint32_t data_len = 8 + target_len + 1 + link_len + 1; + if (_afc_check_packet_buffer(client, data_len) < 0) { + afc_unlock(client); + debug_info("Failed to realloc packet buffer"); + return AFC_E_NO_MEM; + } + debug_info("link type: %lld", type); - debug_info("target: %s, length:%d", target, strlen(target)); - debug_info("linkname: %s, length:%d", linkname, strlen(linkname)); + debug_info("target: %s, length:%d", target, target_len); + debug_info("linkname: %s, length:%d", linkname, link_len); /* Send command */ - memcpy(buffer, &type, 8); - memcpy(buffer + 8, target, strlen(target) + 1); - memcpy(buffer + 8 + strlen(target) + 1, linkname, strlen(linkname) + 1); - ret = afc_dispatch_packet(client, AFC_OP_MAKE_LINK, buffer, 8 + strlen(linkname) + 1 + strlen(target) + 1, NULL, 0, &bytes); - free(buffer); + *(uint64_t*)(AFC_PACKET_DATA_PTR) = htole64(linktype); + memcpy(AFC_PACKET_DATA_PTR + 8, target, target_len + 1); + memcpy(AFC_PACKET_DATA_PTR + 8 + target_len + 1, linkname, link_len + 1); + ret = afc_dispatch_packet(client, AFC_OP_MAKE_LINK, data_len, NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { afc_unlock(client); 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 if (!client || !path || !client->afc_packet || !client->parent) return AFC_E_INVALID_ARG; - char *buffer = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8)); uint32_t bytes = 0; - uint64_t mtime_loc = htole64(mtime); afc_error_t ret = AFC_E_UNKNOWN_ERROR; afc_lock(client); + uint32_t data_len = 8 + strlen(path) + 1; + if (_afc_check_packet_buffer(client, data_len) < 0) { + afc_unlock(client); + debug_info("Failed to realloc packet buffer"); + return AFC_E_NO_MEM; + } + /* Send command */ - memcpy(buffer, &mtime_loc, 8); - memcpy(buffer + 8, path, strlen(path) + 1); - ret = afc_dispatch_packet(client, AFC_OP_SET_FILE_MOD_TIME, buffer, 8 + strlen(path) + 1, NULL, 0, &bytes); - free(buffer); + *(uint64_t*)(AFC_PACKET_DATA_PTR) = htole64(mtime); + memcpy(AFC_PACKET_DATA_PTR + 8, path, data_len-8); + ret = afc_dispatch_packet(client, AFC_OP_SET_FILE_MOD_TIME, data_len, NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { afc_unlock(client); return AFC_E_NOT_ENOUGH_DATA; @@ -1006,8 +1088,16 @@ LIBIMOBILEDEVICE_API afc_error_t afc_remove_path_and_contents(afc_client_t clien afc_lock(client); + uint32_t data_len = strlen(path) + 1; + if (_afc_check_packet_buffer(client, data_len) < 0) { + afc_unlock(client); + debug_info("Failed to realloc packet buffer"); + return AFC_E_NO_MEM; + } + /* Send command */ - ret = afc_dispatch_packet(client, AFC_OP_REMOVE_PATH_AND_CONTENTS, path, strlen(path)+1, NULL, 0, &bytes); + memcpy(AFC_PACKET_DATA_PTR, path, data_len); + ret = afc_dispatch_packet(client, AFC_OP_REMOVE_PATH_AND_CONTENTS, data_len, NULL, 0, &bytes); if (ret != AFC_E_SUCCESS) { afc_unlock(client); return AFC_E_NOT_ENOUGH_DATA; diff --git a/src/afc.h b/src/afc.h index 4ff8037..3e4ef67 100644 --- a/src/afc.h +++ b/src/afc.h @@ -53,6 +53,7 @@ typedef struct { struct afc_client_private { service_client_t parent; AFCPacket *afc_packet; + uint32_t packet_extra; mutex_t mutex; int free_parent; }; -- cgit v1.1-32-gdbae