diff options
| -rw-r--r-- | src/AFC.c | 82 | ||||
| -rw-r--r-- | src/ifuse.c | 3 |
2 files changed, 55 insertions, 30 deletions
| @@ -141,7 +141,7 @@ int receive_AFC_data(AFClient *client, char **dump_here) { | |||
| 141 | char *buffer = (char*)malloc(sizeof(AFCPacket) * 4); | 141 | char *buffer = (char*)malloc(sizeof(AFCPacket) * 4); |
| 142 | char *final_buffer = NULL; | 142 | char *final_buffer = NULL; |
| 143 | int bytes = 0, recv_len = 0, current_count=0; | 143 | int bytes = 0, recv_len = 0, current_count=0; |
| 144 | int retval = 0; | 144 | int retval = 0; |
| 145 | 145 | ||
| 146 | bytes = mux_recv(client->connection, buffer, sizeof(AFCPacket) * 4); | 146 | bytes = mux_recv(client->connection, buffer, sizeof(AFCPacket) * 4); |
| 147 | if (bytes <= 0) { | 147 | if (bytes <= 0) { |
| @@ -386,41 +386,63 @@ AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode) | |||
| 386 | return NULL; | 386 | return NULL; |
| 387 | } | 387 | } |
| 388 | 388 | ||
| 389 | /** Attempts to the read the given number of bytes from the given file. | ||
| 390 | * | ||
| 391 | * @param client The relevant AFC client | ||
| 392 | * @param file The AFCFile to read from | ||
| 393 | * @param data The pointer to the memory region to store the read data | ||
| 394 | * @param length The number of bytes to read | ||
| 395 | * | ||
| 396 | * @return The number of bytes read if successful. If there was an error | ||
| 397 | */ | ||
| 389 | int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) { | 398 | int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) { |
| 390 | if (!client || !client->afc_packet || !client->connection || !file) return -1; | 399 | if (!client || !client->afc_packet || !client->connection || !file) return -1; |
| 391 | AFCFilePacket *packet = (AFCFilePacket*)malloc(sizeof(AFCFilePacket)); | 400 | if (debug) printf("afc_read_file called for length %i\n", length); |
| 392 | if (debug) printf("afc_read_file called for length %i\n"); | 401 | |
| 393 | afc_lock(client); | ||
| 394 | char *input = NULL; | 402 | char *input = NULL; |
| 395 | packet->unknown1 = packet->unknown2 = 0; | 403 | int current_count = 0, bytes = 0; |
| 396 | packet->filehandle = file->filehandle; | 404 | const int MAXIMUM_READ_SIZE = 1 << 16; |
| 397 | packet->size = length; | 405 | |
| 398 | int bytes = 0; | 406 | afc_lock(client); |
| 399 | 407 | ||
| 400 | client->afc_packet->operation = AFC_READ; | 408 | |
| 401 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | 409 | // Looping here to get around the maximum amount of data that recieve_AFC_data can handle |
| 402 | bytes = dispatch_AFC_packet(client, (char*)packet, sizeof(AFCFilePacket)); | 410 | while (current_count < length){ |
| 403 | 411 | ||
| 404 | if (bytes > 0) { | 412 | // Send the read command |
| 405 | bytes = receive_AFC_data(client, &input); | 413 | AFCFilePacket *packet = (AFCFilePacket*)malloc(sizeof(AFCFilePacket)); |
| 406 | afc_unlock(client); | 414 | packet->unknown1 = packet->unknown2 = 0; |
| 407 | if (bytes < 0) { | 415 | packet->filehandle = file->filehandle; |
| 408 | if (input) free(input); | 416 | packet->size = ((length - current_count) < MAXIMUM_READ_SIZE) ? (length - current_count) : MAXIMUM_READ_SIZE; |
| 409 | return -1; | 417 | client->afc_packet->operation = AFC_READ; |
| 410 | } else if (bytes == 0) { | 418 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; |
| 411 | if (input) free(input); | 419 | bytes = dispatch_AFC_packet(client, (char*)packet, sizeof(AFCFilePacket)); |
| 412 | return 0; | 420 | |
| 421 | // If we get a positive reponse to the command gather the data | ||
| 422 | if (bytes > 0) { | ||
| 423 | bytes = receive_AFC_data(client, &input); | ||
| 424 | if (bytes < 0) { | ||
| 425 | if (input) free(input); | ||
| 426 | return -1; | ||
| 427 | } else if (bytes == 0) { | ||
| 428 | if (input) free(input); | ||
| 429 | return current_count; | ||
| 430 | } else { | ||
| 431 | if (input) { | ||
| 432 | printf("afc_read_file: %d\n", bytes); | ||
| 433 | memcpy(data+current_count, input, (bytes > length) ? length : bytes); | ||
| 434 | free(input); | ||
| 435 | input = NULL; | ||
| 436 | current_count += (bytes > length) ? length : bytes; | ||
| 437 | } | ||
| 438 | } | ||
| 413 | } else { | 439 | } else { |
| 414 | if (input) | 440 | afc_unlock(client); |
| 415 | memcpy(data, input, (bytes > length) ? length : bytes); | 441 | return -1; |
| 416 | free(input); | ||
| 417 | return (bytes > length) ? length : bytes; | ||
| 418 | } | 442 | } |
| 419 | } else { | ||
| 420 | afc_unlock(client); | ||
| 421 | return -1; | ||
| 422 | } | 443 | } |
| 423 | return 0; | 444 | afc_unlock(client); |
| 445 | return current_count; | ||
| 424 | } | 446 | } |
| 425 | 447 | ||
| 426 | int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length) { | 448 | int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length) { |
diff --git a/src/ifuse.c b/src/ifuse.c index 7d6f72a..a56289d 100644 --- a/src/ifuse.c +++ b/src/ifuse.c | |||
| @@ -103,6 +103,9 @@ static int ifuse_read(const char *path, char *buf, size_t size, off_t offset, | |||
| 103 | AFCFile *file; | 103 | AFCFile *file; |
| 104 | AFClient *afc = fuse_get_context()->private_data; | 104 | AFClient *afc = fuse_get_context()->private_data; |
| 105 | 105 | ||
| 106 | if (size == 0) | ||
| 107 | return 0; | ||
| 108 | |||
| 106 | file = g_hash_table_lookup(file_handles, &(fi->fh)); | 109 | file = g_hash_table_lookup(file_handles, &(fi->fh)); |
| 107 | if (!file){ | 110 | if (!file){ |
| 108 | return -ENOENT; | 111 | return -ENOENT; |
