summaryrefslogtreecommitdiffstats
path: root/src
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
parent33a9279d2d256086362e4404724e076fbbf86cc0 (diff)
downloadlibimobiledevice-59f16a14692f7d84c5871394b8928d94b4dc34ce.tar.gz
libimobiledevice-59f16a14692f7d84c5871394b8928d94b4dc34ce.tar.bz2
afc: Reduce packet segmentation and unnecessary malloc/free
Diffstat (limited to 'src')
-rw-r--r--src/afc.c284
-rw-r--r--src/afc.h1
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;
};