summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AFC.c82
-rw-r--r--src/ifuse.c3
2 files changed, 55 insertions, 30 deletions
diff --git a/src/AFC.c b/src/AFC.c
index d7a4dda..680a08f 100644
--- a/src/AFC.c
+++ b/src/AFC.c
@@ -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 */
389int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) { 398int 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
426int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length) { 448int 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;