summaryrefslogtreecommitdiffstats
path: root/src/AFC.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/AFC.c')
-rw-r--r--src/AFC.c350
1 files changed, 239 insertions, 111 deletions
diff --git a/src/AFC.c b/src/AFC.c
index b24c331..e5fe526 100644
--- a/src/AFC.c
+++ b/src/AFC.c
@@ -20,12 +20,13 @@
20 */ 20 */
21 21
22#include <stdio.h> 22#include <stdio.h>
23#include <errno.h>
23#include "AFC.h" 24#include "AFC.h"
24 25#include "utils.h"
25 26
26 27
27// This is the maximum size an AFC data packet can be 28// This is the maximum size an AFC data packet can be
28const int MAXIMUM_PACKET_SIZE = (2 << 15) - 32; 29const int MAXIMUM_PACKET_SIZE = (2 << 15);
29 30
30/** Locks an AFC client, done for thread safety stuff 31/** Locks an AFC client, done for thread safety stuff
31 * 32 *
@@ -88,14 +89,9 @@ iphone_error_t iphone_afc_new_client(iphone_device_t device, int src_port, int d
88 } 89 }
89 90
90 client_loc->afc_packet->packet_num = 0; 91 client_loc->afc_packet->packet_num = 0;
91 client_loc->afc_packet->unknown1 = 0;
92 client_loc->afc_packet->unknown2 = 0;
93 client_loc->afc_packet->unknown3 = 0;
94 client_loc->afc_packet->unknown4 = 0;
95 client_loc->afc_packet->entire_length = 0; 92 client_loc->afc_packet->entire_length = 0;
96 client_loc->afc_packet->this_length = 0; 93 client_loc->afc_packet->this_length = 0;
97 client_loc->afc_packet->header1 = 0x36414643; 94 memcpy(client_loc->afc_packet->magic, AFC_MAGIC, AFC_MAGIC_LEN);
98 client_loc->afc_packet->header2 = 0x4141504C;
99 client_loc->file_handle = 0; 95 client_loc->file_handle = 0;
100 client_loc->lock = 0; 96 client_loc->lock = 0;
101 client_loc->mutex = g_mutex_new(); 97 client_loc->mutex = g_mutex_new();
@@ -115,10 +111,93 @@ iphone_error_t iphone_afc_free_client(iphone_afc_client_t client)
115 111
116 iphone_mux_free_client(client->connection); 112 iphone_mux_free_client(client->connection);
117 free(client->afc_packet); 113 free(client->afc_packet);
114 if (client->mutex) {
115 g_mutex_free(client->mutex);
116 }
118 free(client); 117 free(client);
119 return IPHONE_E_SUCCESS; 118 return IPHONE_E_SUCCESS;
120} 119}
121 120
121/**
122 * Returns the AFC error code that has been sent by the device if
123 * an error occured (set inside receive_AFC_data)
124 *
125 * @param client AFC client for that the error value is to be retrieved.
126 *
127 * @return AFC error code or -1 on error.
128 */
129int iphone_afc_get_afcerror(iphone_afc_client_t client)
130{
131 int res = -1;
132 if (client) {
133 afc_lock(client);
134 res = client->afcerror;
135 afc_unlock(client);
136 }
137 return res;
138}
139
140/**
141 * Tries to convert the AFC error value into a meaningful errno value.
142 * Internally used by iphone_afc_get_errno.
143 *
144 * @param afcerror AFC error value to convert
145 *
146 * @return errno value or -1 if the errno could not be determined.
147 *
148 * @see iphone_afc_get_errno
149 */
150static int afcerror_to_errno(int afcerror)
151{
152 int res = -1;
153 switch (afcerror) {
154 case 0: // ERROR_SUCCESS, this means no error.
155 res = 0;
156 break;
157 case 4: // occurs if you try to open a file as directory
158 res = ENOTDIR;
159 break;
160 case 7: // occurs e.g. if you try to close a file handle that
161 // does not belong to an open file
162 res = EINVAL;
163 break;
164 case 8: // occurs if you try to open a non-existent file
165 res = ENOENT;
166 break;
167 case 9: // occurs if you try to open a directory as file
168 res = EISDIR;
169 break;
170 case 10: // occurs if you try to open a file without permission
171 res = EPERM;
172 break;
173 default: // we'll assume it's an errno value, but report it
174 log_debug_msg("WARNING: unknown AFC error %d, perhaps it's '%s'?\n", afcerror, strerror(afcerror));
175 res = afcerror;
176 break;
177 }
178
179 log_debug_msg("Mapped AFC error %d to errno %d: %s\n", afcerror, res, strerror(res));
180
181 return res;
182}
183
184/**
185 * Returns the client's AFC error code converted to an errno value.
186 *
187 * @param client AFC client for that the errno value is to be retrieved.
188 *
189 * @return errno value or -1 on error.
190 */
191int iphone_afc_get_errno(iphone_afc_client_t client)
192{
193 int res = -1;
194 if (client) {
195 afc_lock(client);
196 res = afcerror_to_errno(client->afcerror);
197 afc_unlock(client);
198 }
199 return res;
200}
122 201
123/** Dispatches an AFC packet over a client. 202/** Dispatches an AFC packet over a client.
124 * 203 *
@@ -169,7 +248,7 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, int
169 return -1; 248 return -1;
170 } 249 }
171 memcpy(buffer + sizeof(AFCPacket), data, offset); 250 memcpy(buffer + sizeof(AFCPacket), data, offset);
172 iphone_mux_send(client->connection, buffer, client->afc_packet->this_length, &bytes); 251 iphone_mux_send(client->connection, buffer, client->afc_packet->this_length, (uint32_t*)&bytes);
173 free(buffer); 252 free(buffer);
174 if (bytes <= 0) { 253 if (bytes <= 0) {
175 return bytes; 254 return bytes;
@@ -180,11 +259,11 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, int
180 log_debug_msg("Buffer: \n"); 259 log_debug_msg("Buffer: \n");
181 log_debug_buffer(data + offset, length - offset); 260 log_debug_buffer(data + offset, length - offset);
182 261
183 iphone_mux_send(client->connection, data + offset, length - offset, &bytes); 262 iphone_mux_send(client->connection, data + offset, length - offset, (uint32_t*)&bytes);
184 return bytes; 263 return bytes;
185 } else { 264 } else {
186 log_debug_msg("dispatch_AFC_packet doin things the old way\n"); 265 log_debug_msg("dispatch_AFC_packet doin things the old way\n");
187 char *buffer = (char *) malloc(sizeof(char) * client->afc_packet->this_length); 266 buffer = (char *) malloc(sizeof(char) * client->afc_packet->this_length);
188 log_debug_msg("dispatch_AFC_packet packet length = %i\n", client->afc_packet->this_length); 267 log_debug_msg("dispatch_AFC_packet packet length = %i\n", client->afc_packet->this_length);
189 memcpy(buffer, (char *) client->afc_packet, sizeof(AFCPacket)); 268 memcpy(buffer, (char *) client->afc_packet, sizeof(AFCPacket));
190 log_debug_msg("dispatch_AFC_packet packet data follows\n"); 269 log_debug_msg("dispatch_AFC_packet packet data follows\n");
@@ -194,7 +273,7 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, int
194 } 273 }
195 log_debug_buffer(buffer, client->afc_packet->this_length); 274 log_debug_buffer(buffer, client->afc_packet->this_length);
196 log_debug_msg("\n"); 275 log_debug_msg("\n");
197 iphone_mux_send(client->connection, buffer, client->afc_packet->this_length, &bytes); 276 iphone_mux_send(client->connection, buffer, client->afc_packet->this_length, (uint32_t*)&bytes);
198 277
199 if (buffer) { 278 if (buffer) {
200 free(buffer); 279 free(buffer);
@@ -215,91 +294,136 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, int
215 * received raised a non-trivial error condition (i.e. non-zero with 294 * received raised a non-trivial error condition (i.e. non-zero with
216 * AFC_ERROR operation) 295 * AFC_ERROR operation)
217 */ 296 */
218
219static int receive_AFC_data(iphone_afc_client_t client, char **dump_here) 297static int receive_AFC_data(iphone_afc_client_t client, char **dump_here)
220{ 298{
221 AFCPacket *r_packet; 299 AFCPacket header;
222 char *buffer = (char *) malloc(sizeof(AFCPacket) * 4); 300 int bytes = 0;
223 char *final_buffer = NULL; 301 uint32_t entire_len = 0;
224 int bytes = 0, recv_len = 0, current_count = 0; 302 uint32_t this_len = 0;
225 int retval = 0; 303 uint32_t current_count = 0;
304 uint64_t param1 = -1;
305
306 // reset internal afc error value
307 client->afcerror = 0;
226 308
227 iphone_mux_recv(client->connection, buffer, sizeof(AFCPacket) * 4, &bytes); 309 // first, read the AFC header
310 iphone_mux_recv(client->connection, (char*)&header, sizeof(AFCPacket), (uint32_t*)&bytes);
228 if (bytes <= 0) { 311 if (bytes <= 0) {
229 free(buffer); 312 log_debug_msg("%s: Just didn't get enough.\n", __func__);
230 log_debug_msg("Just didn't get enough.\n"); 313 *dump_here = NULL;
314 return -1;
315 } else if ((uint32_t)bytes < sizeof(AFCPacket)) {
316 log_debug_msg("%s: Did not even get the AFCPacket header\n", __func__);
231 *dump_here = NULL; 317 *dump_here = NULL;
232 return -1; 318 return -1;
233 } 319 }
234 320
235 r_packet = (AFCPacket *) malloc(sizeof(AFCPacket)); 321 // check if it's a valid AFC header
236 memcpy(r_packet, buffer, sizeof(AFCPacket)); 322 if (strncmp(header.magic, AFC_MAGIC, AFC_MAGIC_LEN)) {
237 323 log_debug_msg("%s: Invalid AFC packet received (magic != " AFC_MAGIC ")!\n", __func__);
238 if (r_packet->entire_length == r_packet->this_length
239 && r_packet->entire_length > sizeof(AFCPacket) && r_packet->operation != AFC_ERROR) {
240 *dump_here = (char *) malloc(sizeof(char) * (r_packet->entire_length - sizeof(AFCPacket)));
241 memcpy(*dump_here, buffer + sizeof(AFCPacket), r_packet->entire_length - sizeof(AFCPacket));
242 retval = r_packet->entire_length - sizeof(AFCPacket);
243 free(buffer);
244 free(r_packet);
245 return retval;
246 } 324 }
247 325
248 uint32_t param1 = buffer[sizeof(AFCPacket)]; 326 // check if it has the correct packet number
249 free(buffer); 327 if (header.packet_num != client->afc_packet->packet_num) {
328 // otherwise print a warning but do not abort
329 log_debug_msg("%s: ERROR: Unexpected packet number (%lld != %lld) aborting.\n", __func__, header.packet_num, client->afc_packet->packet_num);
330 *dump_here = NULL;
331 return -1;
332 }
250 333
251 if (r_packet->operation == AFC_ERROR && !(client->afc_packet->operation == AFC_DELETE && param1 == 7)) { 334 // then, read the attached packet
252 log_debug_msg("Oops? Bad operation code received: 0x%X, operation=0x%X, param1=%d\n", 335 if (header.this_length < sizeof(AFCPacket)) {
253 r_packet->operation, client->afc_packet->operation, param1); 336 log_debug_msg("%s: Invalid AFCPacket header received!\n", __func__);
254 recv_len = r_packet->entire_length - r_packet->this_length; 337 *dump_here = NULL;
255 free(r_packet); 338 return -1;
256 log_debug_msg("recv_len=%d\n", recv_len); 339 } else if ((header.this_length == header.entire_length)
257 if (param1 == 0) { 340 && header.entire_length == sizeof(AFCPacket)) {
258 log_debug_msg("... false alarm, but still\n"); 341 log_debug_msg("%s: Empty AFCPacket received!\n", __func__);
259 *dump_here = NULL; 342 *dump_here = NULL;
343 if (header.operation == AFC_SUCCESS_RESPONSE) {
260 return 0; 344 return 0;
261 } else { 345 } else {
262 log_debug_msg("Errno %i\n", param1); 346 client->afcerror = EIO;
347 return -1;
263 } 348 }
264 *dump_here = NULL;
265 return -1;
266 } else {
267 log_debug_msg("Operation code %x\nFull length %i and this length %i\n",
268 r_packet->operation, r_packet->entire_length, r_packet->this_length);
269 } 349 }
270 350
271 recv_len = r_packet->entire_length - r_packet->this_length; 351 log_debug_msg("%s: received AFC packet, full len=%lld, this len=%lld, operation=%lld\n", __func__, header.entire_length, header.this_length, header.operation);
272 free(r_packet); 352
273 if (!recv_len && r_packet->operation == AFC_SUCCESS_RESPONSE) { 353 entire_len = (uint32_t)header.entire_length - sizeof(AFCPacket);
354 this_len = (uint32_t)header.this_length - sizeof(AFCPacket);
355
356 // this is here as a check (perhaps a different upper limit is good?)
357 if (entire_len > (uint32_t)MAXIMUM_PACKET_SIZE) {
358 fprintf(stderr, "%s: entire_len is larger than MAXIMUM_PACKET_SIZE, (%d > %d)!\n", __func__, entire_len, MAXIMUM_PACKET_SIZE);
359 }
360
361 *dump_here = (char*)malloc(entire_len);
362 iphone_mux_recv(client->connection, *dump_here, this_len, (uint32_t*)&bytes);
363 if (bytes <= 0) {
364 free(*dump_here);
274 *dump_here = NULL; 365 *dump_here = NULL;
275 return 0; 366 log_debug_msg("%s: Did not get packet contents!\n", __func__);
367 return -1;
368 } else if ((uint32_t)bytes < this_len) {
369 free(*dump_here);
370 *dump_here = NULL;
371 log_debug_msg("%s: Could not receive this_len=%d bytes\n", __func__, this_len);
372 return -1;
276 } 373 }
277 // Keep collecting packets until we have received the entire file. 374
278 buffer = (char *) malloc(sizeof(char) * (recv_len < MAXIMUM_PACKET_SIZE) ? recv_len : MAXIMUM_PACKET_SIZE); 375 current_count = this_len;
279 final_buffer = (char *) malloc(sizeof(char) * recv_len); 376
280 while (current_count < recv_len) { 377 if (entire_len > this_len) {
281 iphone_mux_recv(client->connection, buffer, recv_len - current_count, &bytes); 378 while (current_count < entire_len) {
282 log_debug_msg("receive_AFC_data: still collecting packets\n"); 379 iphone_mux_recv(client->connection, (*dump_here)+current_count, entire_len - current_count, (uint32_t*)&bytes);
283 if (bytes < 0) { 380 if (bytes <= 0) {
284 log_debug_msg("receive_AFC_data: mux_recv failed: %d\n", bytes); 381 log_debug_msg("%s: Error receiving data (recv returned %d)\n", __func__, bytes);
285 break; 382 break;
286 } 383 }
287 if (bytes > recv_len - current_count) { 384 current_count += bytes;
288 log_debug_msg("receive_AFC_data: mux_recv delivered too much data\n");
289 break;
290 } 385 }
291 if (bytes > 7 && strstr(buffer, "CFA6LPAA")) { 386 if (current_count < entire_len) {
292 log_debug_msg("receive_AFC_data: WARNING: there is AFC data in this packet at %ti\n", 387 log_debug_msg("%s: WARNING: could not receive full packet (read %s, size %d)\n", __func__, current_count, entire_len);
293 strstr(buffer, "CFA6LPAA") - buffer);
294 log_debug_msg("receive_AFC_data: the total packet length is %i\n", bytes);
295 } 388 }
389 }
296 390
297 memcpy(final_buffer + current_count, buffer, bytes); 391 if (current_count >= sizeof(uint64_t)) {
298 current_count += bytes; 392 param1 = *(uint64_t*)(*dump_here);
299 } 393 }
300 free(buffer);
301 394
302 *dump_here = final_buffer; 395 // check for errors
396 if (header.operation == AFC_SUCCESS_RESPONSE) {
397 // we got a positive response!
398 log_debug_msg("%s: got a success response\n", __func__);
399 } else if (header.operation == AFC_FILE_HANDLE) {
400 // we got a file handle response
401 log_debug_msg("%s: got a file handle response, handle=%lld\n", __func__, param1);
402 } else if (header.operation == AFC_ERROR) {
403 // error message received
404 if (param1 == 0) {
405 // ERROR_SUCCESS, this is not an error!
406 log_debug_msg("%s: ERROR_SUCCESS\n", __func__);
407 } else {
408 // but this is an error!
409 log_debug_msg("%s: ERROR %lld\n", __func__, param1);
410 free(*dump_here);
411 *dump_here = NULL;
412 // store error value
413 client->afcerror = (int)param1;
414 afcerror_to_errno(client->afcerror);
415 return -1;
416 }
417 } else {
418 // unknown operation code received!
419 free(*dump_here);
420 *dump_here = NULL;
421
422 log_debug_msg("%s: WARNING: Unknown operation code received 0x%llx param1=%lld\n", __func__, header.operation, param1);
423 fprintf(stderr, "%s: WARNING: Unknown operation code received 0x%llx param1=%lld\n", __func__, header.operation, param1);
424
425 return -1;
426 }
303 return current_count; 427 return current_count;
304} 428}
305 429
@@ -364,9 +488,9 @@ iphone_error_t iphone_afc_get_dir_list(iphone_afc_client_t client, const char *d
364 } 488 }
365 // Receive the data 489 // Receive the data
366 bytes = receive_AFC_data(client, &data); 490 bytes = receive_AFC_data(client, &data);
367 if (bytes < 0 && !data) { 491 if (bytes < 0) {
368 afc_unlock(client); 492 afc_unlock(client);
369 return IPHONE_E_NOT_ENOUGH_DATA; 493 return IPHONE_E_AFC_ERROR;
370 } 494 }
371 // Parse the data 495 // Parse the data
372 list_loc = make_strings_list(data, bytes); 496 list_loc = make_strings_list(data, bytes);
@@ -408,9 +532,9 @@ iphone_error_t iphone_afc_get_devinfo(iphone_afc_client_t client, char ***infos)
408 } 532 }
409 // Receive the data 533 // Receive the data
410 bytes = receive_AFC_data(client, &data); 534 bytes = receive_AFC_data(client, &data);
411 if (bytes < 0 && !data) { 535 if (bytes < 0) {
412 afc_unlock(client); 536 afc_unlock(client);
413 return IPHONE_E_NOT_ENOUGH_DATA; 537 return IPHONE_E_AFC_ERROR;
414 } 538 }
415 // Parse the data 539 // Parse the data
416 list = make_strings_list(data, bytes); 540 list = make_strings_list(data, bytes);
@@ -456,10 +580,9 @@ iphone_error_t iphone_afc_delete_file(iphone_afc_client_t client, const char *pa
456 afc_unlock(client); 580 afc_unlock(client);
457 581
458 if (bytes < 0) { 582 if (bytes < 0) {
459 return IPHONE_E_NOT_ENOUGH_DATA; 583 return IPHONE_E_AFC_ERROR;
460 } else {
461 return IPHONE_E_SUCCESS;
462 } 584 }
585 return IPHONE_E_SUCCESS;
463} 586}
464 587
465/** Renames a file on the phone. 588/** Renames a file on the phone.
@@ -501,10 +624,9 @@ iphone_error_t iphone_afc_rename_file(iphone_afc_client_t client, const char *fr
501 afc_unlock(client); 624 afc_unlock(client);
502 625
503 if (bytes < 0) { 626 if (bytes < 0) {
504 return IPHONE_E_NOT_ENOUGH_DATA; 627 return IPHONE_E_AFC_ERROR;
505 } else {
506 return IPHONE_E_SUCCESS;
507 } 628 }
629 return IPHONE_E_SUCCESS;
508} 630}
509 631
510/** Creates a directory on the phone. 632/** Creates a directory on the phone.
@@ -542,10 +664,9 @@ iphone_error_t iphone_afc_mkdir(iphone_afc_client_t client, const char *dir)
542 afc_unlock(client); 664 afc_unlock(client);
543 665
544 if (bytes < 0) { 666 if (bytes < 0) {
545 return IPHONE_E_NOT_ENOUGH_DATA; 667 return IPHONE_E_AFC_ERROR;
546 } else {
547 return IPHONE_E_SUCCESS;
548 } 668 }
669 return IPHONE_E_SUCCESS;
549} 670}
550 671
551/** Gets information about a specific file. 672/** Gets information about a specific file.
@@ -586,7 +707,7 @@ static iphone_afc_file_t afc_get_file_info(iphone_afc_client_t client, const cha
586 my_file = (iphone_afc_file_t) malloc(sizeof(struct iphone_afc_file_int)); 707 my_file = (iphone_afc_file_t) malloc(sizeof(struct iphone_afc_file_int));
587 for (i = 0; list[i]; i++) { 708 for (i = 0; list[i]; i++) {
588 if (!strcmp(list[i], "st_size")) { 709 if (!strcmp(list[i], "st_size")) {
589 my_file->size = atoi(list[i + 1]); 710 my_file->size = atoll(list[i + 1]);
590 } 711 }
591 712
592 if (!strcmp(list[i], "st_blocks")) { 713 if (!strcmp(list[i], "st_blocks")) {
@@ -595,11 +716,17 @@ static iphone_afc_file_t afc_get_file_info(iphone_afc_client_t client, const cha
595 716
596 if (!strcmp(list[i], "st_ifmt")) { 717 if (!strcmp(list[i], "st_ifmt")) {
597 if (!strcmp(list[i + 1], "S_IFREG")) { 718 if (!strcmp(list[i + 1], "S_IFREG")) {
598 my_file->type = S_IFREG; 719 my_file->mode = S_IFREG;
599 } else if (!strcmp(list[i + 1], "S_IFDIR")) { 720 } else if (!strcmp(list[i + 1], "S_IFDIR")) {
600 my_file->type = S_IFDIR; 721 my_file->mode = S_IFDIR;
722 } else if (!strcmp(list[i + 1], "S_IFLNK")) {
723 my_file->mode = S_IFLNK;
601 } 724 }
602 } 725 }
726
727 if (!strcmp(list[i], "st_nlink")) {
728 my_file->nlink = atoi(list[i + 1]);
729 }
603 } 730 }
604 g_strfreev(list); 731 g_strfreev(list);
605 return my_file; 732 return my_file;
@@ -627,13 +754,14 @@ iphone_error_t iphone_afc_get_file_attr(iphone_afc_client_t client, const char *
627 memset(stbuf, 0, sizeof(struct stat)); 754 memset(stbuf, 0, sizeof(struct stat));
628 iphone_afc_file_t file = afc_get_file_info(client, filename); 755 iphone_afc_file_t file = afc_get_file_info(client, filename);
629 if (!file) { 756 if (!file) {
630 ret = IPHONE_E_NO_SUCH_FILE; 757 ret = IPHONE_E_AFC_ERROR;
631 } else { 758 } else {
632 stbuf->st_mode = file->type | (S_ISDIR(file->type) ? 0755 : 0644); 759 stbuf->st_mode = file->mode | (S_ISDIR(file->mode) ? 0755 : (S_ISLNK(file->mode) ? 0777 : 0644));
633 stbuf->st_size = file->size; 760 stbuf->st_size = file->size;
634 stbuf->st_blksize = 2048; // FIXME: Is this the actual block 761 stbuf->st_blksize = 2048; // FIXME: Is this the actual block
635 // size used on the iPhone? 762 // size used on the iPhone?
636 stbuf->st_blocks = file->blocks; 763 stbuf->st_blocks = file->blocks;
764 stbuf->st_nlink = file->nlink;
637 stbuf->st_uid = getuid(); 765 stbuf->st_uid = getuid();
638 stbuf->st_gid = getgid(); 766 stbuf->st_gid = getgid();
639 767
@@ -699,7 +827,7 @@ iphone_afc_open_file(iphone_afc_client_t client, const char *filename,
699 } else { 827 } else {
700 log_debug_msg("afc_open_file: Didn't get any further data\n"); 828 log_debug_msg("afc_open_file: Didn't get any further data\n");
701 afc_unlock(client); 829 afc_unlock(client);
702 return IPHONE_E_NOT_ENOUGH_DATA; 830 return IPHONE_E_AFC_ERROR;
703 } 831 }
704 832
705 afc_unlock(client); 833 afc_unlock(client);
@@ -736,7 +864,6 @@ iphone_afc_read_file(iphone_afc_client_t client, iphone_afc_file_t file, char *d
736 864
737 // Send the read command 865 // Send the read command
738 AFCFilePacket *packet = (AFCFilePacket *) malloc(sizeof(AFCFilePacket)); 866 AFCFilePacket *packet = (AFCFilePacket *) malloc(sizeof(AFCFilePacket));
739 packet->unknown1 = packet->unknown2 = 0;
740 packet->filehandle = file->filehandle; 867 packet->filehandle = file->filehandle;
741 packet->size = ((length - current_count) < MAXIMUM_READ_SIZE) ? (length - current_count) : MAXIMUM_READ_SIZE; 868 packet->size = ((length - current_count) < MAXIMUM_READ_SIZE) ? (length - current_count) : MAXIMUM_READ_SIZE;
742 client->afc_packet->operation = AFC_READ; 869 client->afc_packet->operation = AFC_READ;
@@ -752,10 +879,8 @@ iphone_afc_read_file(iphone_afc_client_t client, iphone_afc_file_t file, char *d
752 bytes_loc = receive_AFC_data(client, &input); 879 bytes_loc = receive_AFC_data(client, &input);
753 log_debug_msg("afc_read_file: bytes returned: %i\n", bytes_loc); 880 log_debug_msg("afc_read_file: bytes returned: %i\n", bytes_loc);
754 if (bytes_loc < 0) { 881 if (bytes_loc < 0) {
755 if (input)
756 free(input);
757 afc_unlock(client); 882 afc_unlock(client);
758 return IPHONE_E_NOT_ENOUGH_DATA; 883 return IPHONE_E_AFC_ERROR;
759 } else if (bytes_loc == 0) { 884 } else if (bytes_loc == 0) {
760 if (input) 885 if (input)
761 free(input); 886 free(input);
@@ -830,7 +955,9 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file,
830 bytes_loc = receive_AFC_data(client, &acknowledgement); 955 bytes_loc = receive_AFC_data(client, &acknowledgement);
831 if (bytes_loc < 0) { 956 if (bytes_loc < 0) {
832 afc_unlock(client); 957 afc_unlock(client);
833 return IPHONE_E_NOT_ENOUGH_DATA; 958 return IPHONE_E_AFC_ERROR;
959 } else {
960 free(acknowledgement);
834 } 961 }
835 } 962 }
836 963
@@ -838,7 +965,7 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file,
838 // didn't get sent in the for loop 965 // didn't get sent in the for loop
839 // this length is fine because it's always sizeof(AFCPacket) + 8, but 966 // this length is fine because it's always sizeof(AFCPacket) + 8, but
840 // to be sure we do it again 967 // to be sure we do it again
841 if (current_count == length) { 968 if (current_count == (uint32_t)length) {
842 afc_unlock(client); 969 afc_unlock(client);
843 *bytes = current_count; 970 *bytes = current_count;
844 return IPHONE_E_SUCCESS; 971 return IPHONE_E_SUCCESS;
@@ -868,6 +995,8 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file,
868 afc_unlock(client); 995 afc_unlock(client);
869 if (bytes_loc < 0) { 996 if (bytes_loc < 0) {
870 log_debug_msg("afc_write_file: uh oh?\n"); 997 log_debug_msg("afc_write_file: uh oh?\n");
998 } else {
999 free(acknowledgement);
871 } 1000 }
872 *bytes = current_count; 1001 *bytes = current_count;
873 return IPHONE_E_SUCCESS; 1002 return IPHONE_E_SUCCESS;
@@ -965,12 +1094,14 @@ iphone_error_t iphone_afc_lock_file(iphone_afc_client_t client, iphone_afc_file_
965 } 1094 }
966 // Receive the response 1095 // Receive the response
967 bytes = receive_AFC_data(client, &buffer); 1096 bytes = receive_AFC_data(client, &buffer);
968 log_debug_msg("%s: receiving response (%d bytes)\n", __func__, bytes);
969 if (buffer) { 1097 if (buffer) {
970 log_debug_buffer(buffer, bytes); 1098 log_debug_buffer(buffer, bytes);
971 free(buffer); 1099 free(buffer);
972 } 1100 }
973 afc_unlock(client); 1101 afc_unlock(client);
1102 if (bytes < 0) {
1103 return IPHONE_E_AFC_ERROR;
1104 }
974 return IPHONE_E_SUCCESS; 1105 return IPHONE_E_SUCCESS;
975} 1106}
976 1107
@@ -1019,11 +1150,10 @@ iphone_error_t iphone_afc_seek_file(iphone_afc_client_t client, iphone_afc_file_
1019 1150
1020 afc_unlock(client); 1151 afc_unlock(client);
1021 1152
1022 if (bytes >= 0) { 1153 if (bytes < 0) {
1023 return IPHONE_E_SUCCESS; 1154 return IPHONE_E_AFC_ERROR;
1024 } else {
1025 return IPHONE_E_NOT_ENOUGH_DATA;
1026 } 1155 }
1156 return IPHONE_E_SUCCESS;
1027} 1157}
1028 1158
1029/** Sets the size of a file on the phone. 1159/** Sets the size of a file on the phone.
@@ -1067,11 +1197,10 @@ iphone_error_t iphone_afc_truncate_file(iphone_afc_client_t client, iphone_afc_f
1067 1197
1068 afc_unlock(client); 1198 afc_unlock(client);
1069 1199
1070 if (bytes >= 0) { 1200 if (bytes < 0) {
1071 return IPHONE_E_SUCCESS; 1201 return IPHONE_E_AFC_ERROR;
1072 } else {
1073 return IPHONE_E_NOT_ENOUGH_DATA;
1074 } 1202 }
1203 return IPHONE_E_SUCCESS;
1075} 1204}
1076 1205
1077/** Sets the size of a file on the phone without prior opening it. 1206/** Sets the size of a file on the phone without prior opening it.
@@ -1114,10 +1243,9 @@ iphone_error_t iphone_afc_truncate(iphone_afc_client_t client, const char *path,
1114 afc_unlock(client); 1243 afc_unlock(client);
1115 1244
1116 if (bytes < 0) { 1245 if (bytes < 0) {
1117 return IPHONE_E_NOT_ENOUGH_DATA; 1246 return IPHONE_E_AFC_ERROR;
1118 } else {
1119 return IPHONE_E_SUCCESS;
1120 } 1247 }
1248 return IPHONE_E_SUCCESS;
1121} 1249}
1122 1250
1123 1251