aboutsummaryrefslogtreecommitdiff
path: root/c_implementation
diff options
context:
space:
mode:
authorkaotisk <kaotisk@arching-kaos.org>2025-04-24 01:59:36 +0300
committerkaotisk <kaotisk@arching-kaos.org>2025-04-24 01:59:36 +0300
commit22d9aeb0f3057c43cf7c561bc208c3acec45135e (patch)
tree2e0eca7350a778a0e9c1011b41eea18429a742b4 /c_implementation
parent07d2b7e430e17cceaab2715a816e4182f299f441 (diff)
downloadarching-kaos-tools-22d9aeb0f3057c43cf7c561bc208c3acec45135e.tar.gz
arching-kaos-tools-22d9aeb0f3057c43cf7c561bc208c3acec45135e.tar.bz2
arching-kaos-tools-22d9aeb0f3057c43cf7c561bc208c3acec45135e.zip
[libakfs] Updates
Diffstat (limited to 'c_implementation')
-rw-r--r--c_implementation/include/libakfs.h234
-rw-r--r--c_implementation/src/akfs.c372
-rw-r--r--c_implementation/src/akfs_defuse.c97
-rw-r--r--c_implementation/src/akfs_map_v3.c139
-rw-r--r--c_implementation/src/akfs_map_v4.c8
-rw-r--r--c_implementation/src/akfs_sha512sum.c218
-rw-r--r--c_implementation/tests/test_akfs.c151
-rw-r--r--c_implementation/tests/test_akfs_mkdir.c12
-rw-r--r--c_implementation/tests/test_sha512_string.c8
9 files changed, 1012 insertions, 227 deletions
diff --git a/c_implementation/include/libakfs.h b/c_implementation/include/libakfs.h
index bc5703c..0dbf60e 100644
--- a/c_implementation/include/libakfs.h
+++ b/c_implementation/include/libakfs.h
@@ -2,6 +2,7 @@
#define AKFS
#include <stdbool.h>
+#include <stddef.h>
/**
* This struct represents a HEX output of the SHA-512 algorithm.
@@ -61,17 +62,22 @@ typedef struct {
* Original file's name
*
*/
- char* filename;
+ char filename[256];
/**
* Root hash
*
*/
sha512sum rh;
/**
+ * Map hash
+ *
+ */
+ sha512sum mh;
+ /**
* Should be "level.1.map" at all times
*
*/
- char* root_name;
+ char *root_name;
} akfs_map_v3;
/**
@@ -96,24 +102,240 @@ typedef struct {
*
*/
sha512sum rh;
+ /**
+ * Map hash
+ *
+ */
+ sha512sum mh;
} akfs_map_v4;
//typedef char[64] sha512sum_as_string;
+/**
+ * Gets maps_dir
+ * return char*
+ */
+const char* ak_fs_maps_v3_get_dir();
+
+/**
+ * Experimental
+ */
char* ak_fs_return_hash_path(char*);
+/**
+ * Experimental
+ */
char* ak_fs_return_hash_dir(char*);
+/**
+ * Verify that string looks like a SHA512 hash
+ */
bool ak_fs_verify_input_is_hash(char*);
+/**
+ * Unused
+ */
int ak_fs_create_dir_for_hash(char*);
-sha512sum ak_fs_sha512sum_string_to_struct(char*);
+/**
+ * Converts string hash to struct
+ * @param char* Hash as string
+ * @param sha512sum* Pointer to a sha512sum
+ * @returns int Status of exit
+ */
+int ak_fs_sha512sum_string_to_struct(char*, sha512sum*);
+
+/**
+ * Returns struct from string hash
+ * @param char* Hash as string
+ * @returns sha512sum* Pointer to a sha512sum
+ */
+sha512sum* ak_fs_sha512sum_from_string(char*);
+
+/**
+ * Converts hash struct to string
+ */
+void ak_fs_sha512sum_struct_to_string(sha512sum*, char*);
+
+/**
+ * Opens a map file to an akfs_map_v3 struct
+ */
+int ak_fs_open_map_v3_file(char*, akfs_map_v3*);
+
+/**
+ * Unused
+ */
+int ak_fs_map_v3_to_file(akfs_map_v3);
+
+/**
+ * Unused
+ */
+int ak_fs_convert_map_v3_string_to_struct(char *, size_t, akfs_map_v3*);
+
+/**
+ * Unused
+ */
+void ak_fs_map_v3_print_map_hash(akfs_map_v3*);
+
+/**
+ * Unused
+ */
+void ak_fs_map_v3_print_original_hash(akfs_map_v3*);
+
+/**
+ * Unused
+ */
+void ak_fs_map_v3_print_root_hash(akfs_map_v3*);
+
+/**
+ * Unused
+ */
+void ak_fs_map_v3_print_filename(akfs_map_v3*);
+
+/**
+ * Unused
+ */
+void ak_fs_map_v3_print(akfs_map_v3*);
+
+/**
+ * Unused
+ */
+int ak_fs_load_available_maps(sha512sum**, size_t, akfs_map_v3**, size_t);
+
+/**
+ * Unused
+ */
+void ak_fs_print_available_maps(sha512sum**, size_t);
+
+/**
+ * Unused
+ */
+void ak_fs_print_loaded_maps(akfs_map_v3**, size_t);
+
+/**
+ * Reads maps_dir and outputs it in an array of sha512sum
+ */
+void ak_fs_prepare_available_maps(sha512sum**, size_t);
+
+/**
+ * Unused
+ */
+void ak_fs_get_available_maps_from_fs(sha512sum**, size_t);
+
+/**
+ * Unused
+ */
+void ak_fs_print_map_all_avail(sha512sum**, size_t);
+
+/**
+ * Unused
+ */
+char* ak_fs_sha512sum_struct_read_as_string(sha512sum *);
+
+/**
+ * Unused
+ */
+void ak_fs_init_string(char *, size_t );
+
+/**
+ * Unused
+ */
+bool ak_fs_sha512sum_compare(sha512sum*, sha512sum*);
+/**
+ * Unused
+ */
+bool ak_fs_sha512sum_is_null(sha512sum*);
+/**
+ * Unused
+ */
+void ak_fs_sha512sum_init(sha512sum*);
+/**
+ * Unused
+ */
+void ak_fs_sha512sum_init_avail(sha512sum**, size_t);
+
+/**
+ * Initialize an akfs_map_v3
+ */
+void ak_fs_map_v3_init(akfs_map_v3*);
-void ak_fs_sha512sum_struct_to_string(sha512sum, char*);
+/**
+ * Initializes an array of akfs_map_v3
+ */
+void ak_fs_map_v3_init_store(akfs_map_v3**, size_t);
-int ak_fs_open_map_v3(char*);
-int ak_fs_from_map_v3_to_file(akfs_map_v3);
+/**
+ * returns: boolean
+ * param: akfs_map_v3
+ */
+bool ak_fs_map_v3_is_null(akfs_map_v3*);
+/**
+ * Unused
+ */
+char* ak_fs_map_v3_get_filename(akfs_map_v3*);
+/**
+ * Unused
+ */
+sha512sum* ak_fs_map_v3_get_map_hash(akfs_map_v3*);
+/**
+ * Unused
+ */
+sha512sum* ak_fs_map_v3_get_root_hash(akfs_map_v3*);
+/**
+ * Unused
+ */
+sha512sum* ak_fs_map_v3_get_orig_hash(akfs_map_v3*);
+/**
+ * Unused
+ */
+bool ak_fs_map_v3_compare(akfs_map_v3*, akfs_map_v3*);
+
+/**
+ * Initializes an array of akfs_map_v4
+ */
+void ak_fs_init_map_v4_store(akfs_map_v4**, size_t);
+
+
+/**
+ * Unused
+ */
+void ak_fs_map_v4_init(akfs_map_v4*);
+
+/**
+ * Initializes an array of sha512sum
+ */
+void ak_fs_init_map_avail(sha512sum**, size_t);
+
+
+/**
+ * Unused
+ */
+bool ak_fs_map_v4_compare(akfs_map_v4*, akfs_map_v4*);
+/**
+ * Unused
+ */
+bool ak_fs_map_v4_is_null(akfs_map_v4*);
+/**
+ * Unused
+ */
+char* ak_fs_map_v4_get_filename(akfs_map_v4*);
+/**
+ * Unused
+ */
+sha512sum* ak_fs_map_v4_get_map_hash(akfs_map_v4*);
+/**
+ * Unused
+ */
+sha512sum* ak_fs_map_v4_get_root_hash(akfs_map_v4*);
+/**
+ * Unused
+ */
+sha512sum* ak_fs_map_v4_get_orig_hash(akfs_map_v4*);
+
+/**
+ * Unused
+ */
+int ak_fs_ls();
#endif // AKFS
diff --git a/c_implementation/src/akfs.c b/c_implementation/src/akfs.c
index 967a612..f1dcd38 100644
--- a/c_implementation/src/akfs.c
+++ b/c_implementation/src/akfs.c
@@ -4,7 +4,15 @@
#include <stdlib.h>
#include <string.h>
#include <libakfs.h>
+#include <libaklog.h>
+#include <libaksettings.h>
#include <sys/stat.h>
+#include <dirent.h>
+
+const char* ak_fs_maps_v3_get_dir()
+{
+ return getenv("AK_MAPSDIR");
+}
char* ak_fs_return_hash_path(char* string)
{
@@ -62,7 +70,7 @@ char* ak_fs_return_hash_dir(char* string)
bool ak_fs_verify_input_is_hash(char* string)
{
- unsigned int i = 0;
+ size_t i = 0;
while ( string[i] != '\0' )
{
if (
@@ -144,11 +152,6 @@ int ak_fs_create_dir_for_hash(char* string)
free(incremental_dir_path);
}
}
- //printf("%d\n", len);
- //printf("%s\n", dir_path);
- //const char *pathname = dir_path;
- //int ec = mkdir(pathname, 0777);
- //return ec;
free(dir_path);
return 0;
}
@@ -158,192 +161,231 @@ int ak_fs_create_dir_for_hash(char* string)
}
}
-sha512sum ak_fs_sha512sum_string_to_struct(char* string)
+int ak_fs_convert_map_v3_string_to_struct(char *string, size_t ssize, akfs_map_v3* map)
{
- sha512sum hash = {0};
- if ( ak_fs_verify_input_is_hash(string) )
+ size_t sa[] = { -1, -1, -1, -1, -1 };
+ size_t na[] = { -1, -1, -1 };
+ int spaces_found = 0;
+ int newlines_found = 0;
+ char original_hash_string[129] = {0};
+ char root_hash_string[129] = {0};
+ char filename[256] = {0};
+ if ( map == 0x0 || map == NULL)
{
- for (size_t l = 0; l < 8; ++l)
+ printf("FAILED IN %s! : %p \n", __func__, (void*)map);
+ return 1;
+ }
+ for ( size_t i = 0; i < ssize; ++i)
+ {
+ if ( string[i] == ' ' )
{
- hash.sum[l]=0;
+ spaces_found++;
+ sa[spaces_found] = i;
}
- unsigned int i = 0;
- unsigned int j = 0;
- unsigned int k = 4;
- while ( string[i] != '\0' )
+ if ( string[i] == '\n' )
{
- assert( i < 128 && "Length exceeded limit");
- if ( i % 16 == 0 ) j = i / 16;
- switch (string[i])
- {
- case 0x30:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0x0;
- break;
- case 0x31:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0x1;
- break;
- case 0x32:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0x2;
- break;
- case 0x33:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0x3;
- break;
- case 0x34:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0x4;
- break;
- case 0x35:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0x5;
- break;
- case 0x36:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0x6;
- break;
- case 0x37:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0x7;
- break;
- case 0x38:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0x8;
- break;
- case 0x39:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0x9;
- break;
- case 0x61:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0xa;
- break;
- case 0x62:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0xb;
- break;
- case 0x63:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0xc;
- break;
- case 0x64:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0xd;
- break;
- case 0x65:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0xe;
- break;
- case 0x66:
- hash.sum[j] = hash.sum[j] << k;
- hash.sum[j] += 0xf;
- break;
- default:
- assert(0 && "Character out of range");
- }
- i++;
+ newlines_found++;
+ na[newlines_found] = i;
}
- if ( i != 128 )
+ }
+ int si = 0;
+ for ( size_t i = 0; i < sa[1]; ++i)
+ {
+ original_hash_string[si] = string[i];
+ si++;
+ }
+ original_hash_string[si] = '\0';
+ if( !ak_fs_verify_input_is_hash(original_hash_string) )
+ {
+ ak_log_error(__func__, "original_hash_string not a hash");
+ return 1;
+ }
+ if ( ak_fs_sha512sum_string_to_struct(original_hash_string, &(map->oh)) != 0 )
+ {
+ ak_log_error(__func__, "String convertion of original_hash_string");
+ return 1;
+ }
+ si = 0;
+ for ( size_t i = na[1]+1; i < sa[3]; ++i)
+ {
+ root_hash_string[si] = string[i];
+ si++;
+ }
+ root_hash_string[si] = '\0';
+ if( !ak_fs_verify_input_is_hash(root_hash_string) )
+ {
+ ak_log_error(__func__, "root_hash_string not a hash");
+ return 1;
+ }
+ if ( ak_fs_sha512sum_string_to_struct(root_hash_string, &(map->rh)) != 0 )
+ {
+ ak_log_error(__func__, "String convertion of root_hash_string");
+ return 1;
+ }
+ si = 0;
+ if ( sa[2] < na[1] )
+ {
+ for ( size_t i = sa[2]+1; i < na[1]; ++i)
{
- sha512sum hash0 = {0};
- return hash0;
+ filename[si] = string[i];
+ si++;
}
- return hash;
+ filename[si] = '\0';
}
- else
+ strncpy(map->filename, filename, sizeof(map->filename));
+ return 0;
+}
+
+void ak_fs_get_available_maps_from_fs(sha512sum **ma, size_t length)
+{
+ DIR *d;
+ struct dirent *dir;
+ d = opendir(ak_fs_maps_v3_get_dir());
+ sha512sum *ptr = NULL;
+ ptr = *ma;
+ if (d)
{
- return hash;
+ for ( ptr = *ma; ptr < *ma+length; ++ptr)
+ {
+ if ((dir = readdir(d)) == NULL ) break;
+ if (!ak_fs_verify_input_is_hash(dir->d_name)) continue;
+ ak_fs_sha512sum_string_to_struct(dir->d_name, ptr);
+ }
}
+ closedir(d);
}
-void ak_fs_sha512sum_struct_to_string(sha512sum hash, char* string)
+int ak_fs_load_available_maps(sha512sum **ma, size_t ma_len, akfs_map_v3 **ms, size_t ms_len)
{
- int counter = 0;
- for (size_t i = 0; i < 8; ++i)
+ sha512sum *ptr = NULL;
+ akfs_map_v3 *mptr = NULL;
+ mptr = *ms;
+ (void)ms_len;
+ for ( ptr = *ma; ptr < *ma+ma_len; ++ptr)
{
- for (size_t j = 0; j < 16; ++j)
+ if ( ak_fs_sha512sum_is_null(ptr))
{
- long unsigned first = hash.sum[i]/0xfffffffffffffff;
- switch(first){
- case 0:
- string[counter] = '0';
- break;
- case 1:
- string[counter] = '1';
- break;
- case 2:
- string[counter] = '2';
- break;
- case 3:
- string[counter] = '3';
- break;
- case 4:
- string[counter] = '4';
- break;
- case 5:
- string[counter] = '5';
- break;
- case 6:
- string[counter] = '6';
- break;
- case 7:
- string[counter] = '7';
- break;
- case 8:
- string[counter] = '8';
- break;
- case 9:
- string[counter] = '9';
- break;
- case 0xa:
- string[counter] = 'a';
- break;
- case 0xb:
- string[counter] = 'b';
- break;
- case 0xc:
- string[counter] = 'c';
- break;
- case 0xd:
- string[counter] = 'd';
- break;
- case 0xe:
- string[counter] = 'e';
- break;
- case 0xf:
- string[counter] = 'f';
- break;
- default:
- assert(0 && "Should be unreachable");
- }
- counter++;
- hash.sum[i] = hash.sum[i] << 4;
+ continue;
+ }
+ if( ak_fs_open_map_v3_file(ak_fs_sha512sum_struct_read_as_string(ptr), mptr) != 2)
+ {
+ ++(mptr);
+ continue;
+ }
+ else
+ {
+ ++(mptr);
+ // return 1;
}
}
- string[128] = '\0';
+ return 0;
}
-int ak_fs_open_map_v3(char* maphash)
+void ak_fs_print_loaded_maps(akfs_map_v3 **map_store, size_t length)
{
- if ( ak_fs_verify_input_is_hash(maphash) )
+ akfs_map_v3 *ptr = NULL;
+ for ( ptr = *map_store; ptr < *map_store + length; ++ptr)
{
- //FILE *fd;
- //char *mapsdir = "/home/kaotisk/.arching-kaos/akfs/maps/";
- //strncat(mapsdir, maphash);
- // printf("%s\n", mapsdir);
- // exit(1);
- return 0;
+ if ( !ak_fs_map_v3_is_null(ptr) ) ak_fs_map_v3_print(ptr);
}
- else
+}
+
+bool ak_fs_map_v3_compare(akfs_map_v3* a, akfs_map_v3* b)
+{
+ return (
+ (ak_fs_sha512sum_compare(&a->oh, &b->oh) == true) &&
+ (ak_fs_sha512sum_compare(&a->rh, &b->rh) == true) &&
+ (ak_fs_sha512sum_compare(&a->mh, &b->mh) == true) &&
+ (strcmp(a->filename, b->filename) == 0)
+ );
+}
+
+bool ak_fs_map_v3_is_null(akfs_map_v3* m)
+{
+ akfs_map_v3 n;
+ ak_fs_map_v3_init(&n);
+ return ak_fs_map_v3_compare(m, &n);
+}
+
+void ak_fs_print_available_maps(sha512sum **ma, size_t ma_len)
+{
+ sha512sum *ptr = NULL;
+ for ( ptr = *ma; ptr < *ma+ma_len; ++ptr)
{
- return 1;
+ ak_log_debug(__func__, ak_fs_sha512sum_struct_read_as_string(ptr));
+ }
+
+}
+
+void ak_fs_init_string(char *string, size_t len)
+{
+ for (size_t i = 0; i < len; ++i)
+ {
+ string[i] = '\0';
}
}
-int ak_fs_from_map_v3_to_file(akfs_map_v3 maphash)
+
+void ak_fs_print_map_avail(sha512sum* m)
{
- (void)maphash;
+ printf(" .MA: %s\n", ak_fs_sha512sum_struct_read_as_string(m));
+}
+
+void ak_fs_print_map_all_avail(sha512sum** m, size_t s)
+{
+ sha512sum *ptr = NULL;
+ for (ptr = *m; ptr < *m+s; ++ptr)
+ {
+ ak_fs_print_map_avail(ptr);
+ }
+}
+
+void ak_fs_print_filenames_from_map_store(akfs_map_v3** m, size_t s)
+{
+ akfs_map_v3 *ptr = NULL;
+ for (ptr = *m; ptr < *m+s; ++ptr)
+ {
+ if ( !ak_fs_map_v3_is_null(ptr) ) ak_fs_map_v3_print_filename(ptr);
+ }
+}
+
+// char* ak_fs_fuse_list_filenames_from_map_store(akfs_map_v3** m, size_t s)
+// {
+// akfs_map_v3 *ptr = NULL;
+// for (ptr = *m; ptr < *m+s; ++ptr)
+// {
+// if ( !ak_fs_map_v3_is_null(ptr) ) ak_fs_map_v3_get_filename(ptr);
+// }
+// }
+
+void ak_fs_print_all_maps_from_map_store(akfs_map_v3** m, size_t s)
+{
+ akfs_map_v3 *ptr = NULL;
+ for (ptr = *m; ptr < *m+s; ++ptr)
+ {
+ if (!ak_fs_map_v3_is_null(ptr)) ak_fs_map_v3_print(ptr);
+ }
+}
+
+int ak_fs_ls()
+{
+ size_t ms_len = 100;
+ size_t ma_len = 100;
+ akfs_map_v3 map_store[ms_len];
+ akfs_map_v3* mps_ptr = &map_store[0];
+ void* mps_start = &map_store[0];
+ (void)mps_start;
+ sha512sum maps_avail[ma_len];
+ sha512sum *mav_ptr = &maps_avail[0];
+ void* mav_start = &map_store[0];
+ (void)mav_start;
+ ak_fs_map_v3_init_store(&mps_ptr, ms_len);
+ ak_fs_sha512sum_init_avail(&mav_ptr, ma_len);
+ ak_fs_print_all_maps_from_map_store(&mps_ptr, ms_len);
+ ak_fs_get_available_maps_from_fs(&mav_ptr, ma_len);
+ ak_fs_load_available_maps(&mav_ptr, ma_len, &mps_ptr, ms_len);
+ // ak_fs_print_loaded_maps(&mps_ptr, ms_len);
+ ak_fs_print_filenames_from_map_store(&mps_ptr, ms_len);
return 0;
}
+
diff --git a/c_implementation/src/akfs_defuse.c b/c_implementation/src/akfs_defuse.c
new file mode 100644
index 0000000..da0c3d0
--- /dev/null
+++ b/c_implementation/src/akfs_defuse.c
@@ -0,0 +1,97 @@
+#define FUSE_USE_VERSION 31
+#include <fuse3/fuse.h>
+#include <libakfs.h>
+#include <libaklog.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+// Called when a file is read
+static int akfs_fuse_read(const char *path, char *buf, size_t size, off_t offset,
+ struct fuse_file_info *fi)
+{
+ (void) fi; // Unused
+ const char *content = "Hello, World!\n";
+ size_t len = strlen(content);
+
+ if (strcmp(path, "/hello") != 0) // Only support "/hello"
+ return -ENOENT;
+
+ if (offset < 0 || (size_t)offset >= len)
+ return 0;
+
+ size = (size < len - offset) ? size : len - offset;
+ memcpy(buf, content + offset, size);
+ return size;
+}
+
+// Called to list files in the root directory
+static int akfs_fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
+ off_t offset, struct fuse_file_info *fi,
+ enum fuse_readdir_flags flags)
+{
+ (void) offset; (void) fi; (void) flags; // Unused
+
+ if (strcmp(path, "/") != 0) // Only support root dir
+ return -ENOENT;
+
+ filler(buf, ".", NULL, 0, 0); // Current dir
+ filler(buf, "..", NULL, 0, 0); // Parent dir
+ filler(buf, "hello", NULL, 0, 0); // Our file
+ size_t ms_len = 100;
+ size_t ma_len = 100;
+ akfs_map_v3 map_store[ms_len];
+ akfs_map_v3* mps_ptr = &map_store[0];
+ void* mps_start = &map_store[0];
+ (void)mps_start;
+ sha512sum maps_avail[ma_len];
+ sha512sum *mav_ptr = &maps_avail[0];
+ void* mav_start = &map_store[0];
+ (void)mav_start;
+ ak_fs_map_v3_init_store(&mps_ptr, ms_len);
+ ak_fs_sha512sum_init_avail(&mav_ptr, ma_len);
+ ak_fs_get_available_maps_from_fs(&mav_ptr, ma_len);
+ ak_fs_load_available_maps(&mav_ptr, ma_len, &mps_ptr, ms_len);
+ akfs_map_v3 *ptr = NULL;
+ for (ptr = mps_ptr; ptr < mps_ptr + ms_len; ++ptr)
+ {
+ if ( !ak_fs_map_v3_is_null(ptr) ) ak_fs_map_v3_print_filename(ptr);
+ filler(buf, ak_fs_map_v3_get_filename(ptr), NULL, 0, 0);
+ }
+ return 0;
+}
+
+// Called to get file attributes (metadata)
+static int akfs_fuse_getattr(const char *path, struct stat *st, struct fuse_file_info *fi)
+{
+ (void) fi; // Unused
+ st->st_uid = getuid();
+ st->st_gid = getgid();
+ st->st_atime = st->st_mtime = time(NULL);
+
+ if (strcmp(path, "/") == 0) {
+ st->st_mode = S_IFDIR | 0755; // Directory
+ st->st_nlink = 2;
+ } else if (strcmp(path, "/hello") == 0) {
+ st->st_mode = S_IFREG | 0644; // Regular file
+ st->st_nlink = 1;
+ st->st_size = strlen("Hello, World!\n");
+ } else {
+ return -ENOENT; // Not found
+ }
+ return 0;
+}
+
+// FUSE operations struct (only implementing needed functions)
+static struct fuse_operations akfs_fuse_ops = {
+ .getattr = akfs_fuse_getattr,
+ .readdir = akfs_fuse_readdir,
+ .read = akfs_fuse_read,
+};
+
+int main(int argc, char *argv[])
+{
+ return fuse_main(argc, argv, &akfs_fuse_ops, NULL);
+}
diff --git a/c_implementation/src/akfs_map_v3.c b/c_implementation/src/akfs_map_v3.c
new file mode 100644
index 0000000..7b7e75b
--- /dev/null
+++ b/c_implementation/src/akfs_map_v3.c
@@ -0,0 +1,139 @@
+#include <stdio.h>
+#include <string.h>
+#include <libakfs.h>
+#include <libaklog.h>
+#include <sys/stat.h>
+
+// const char maps_dir[] = "/home/kaotisk/.arching-kaos/akfs/maps/";
+
+void ak_fs_map_v3_init(akfs_map_v3 *map)
+{
+ ak_fs_sha512sum_init(&map->oh);
+ ak_fs_sha512sum_init(&map->rh);
+ ak_fs_sha512sum_init(&map->mh);
+ ak_fs_init_string(map->filename, 256);
+}
+
+void ak_fs_map_v3_init_store(akfs_map_v3** ms, size_t l)
+{
+ akfs_map_v3 *m = NULL;
+ for (m = *ms; m < *ms+l; ++m)
+ {
+ ak_fs_map_v3_init(m);
+ }
+}
+
+void ak_fs_map_v3_print_original_hash(akfs_map_v3 *map)
+{
+ if (!ak_fs_map_v3_is_null(map))
+ {
+ char string[129];
+ ak_fs_sha512sum_struct_to_string(&(map->oh), string);
+ printf(" .oh: %s\n", string);
+ }
+ else
+ {
+ ak_log_debug(__func__,"map is null");
+ }
+}
+
+void ak_fs_map_v3_print_root_hash(akfs_map_v3 *map)
+{
+ if (!ak_fs_map_v3_is_null(map))
+ {
+ char string[129];
+ ak_fs_sha512sum_struct_to_string(&(map->rh), string);
+ printf(" .rh: %s\n", string );
+ }
+ else
+ {
+ ak_log_debug(__func__,"map is null");
+ }
+}
+
+char* ak_fs_map_v3_get_filename(akfs_map_v3 *map)
+{
+ if (!ak_fs_map_v3_is_null(map))
+ {
+ return map->filename;
+ }
+ else
+ {
+ return "";
+ }
+}
+
+void ak_fs_map_v3_print_filename(akfs_map_v3 *map)
+{
+ if (!ak_fs_map_v3_is_null(map))
+ {
+ printf(" .fn: %s\n", ak_fs_map_v3_get_filename(map));
+ }
+}
+
+void ak_fs_map_v3_print_map_hash(akfs_map_v3 *map)
+{
+ if (!ak_fs_map_v3_is_null(map))
+ {
+ char string[129];
+ ak_fs_sha512sum_struct_to_string(&(map->mh), string);
+ printf(" .mh: %s\n", string );
+ }
+}
+
+void ak_fs_map_v3_print(akfs_map_v3 *map)
+{
+ printf("map_v3 {\n");
+ ak_fs_map_v3_print_map_hash(map);
+ ak_fs_map_v3_print_original_hash(map);
+ ak_fs_map_v3_print_root_hash(map);
+ ak_fs_map_v3_print_filename(map);
+ printf("}\n");
+}
+
+int ak_fs_open_map_v3_file(char* maphash, akfs_map_v3 * map)
+{
+ if (map==0x0||map==NULL)
+ {
+ ak_log_debug(__func__, "Zeropointer");
+ return 1;
+ }
+ if ( !ak_fs_verify_input_is_hash(maphash) )
+ {
+ ak_log_debug(__func__,"not a hash");
+ return 1;
+ }
+ FILE *fd;
+ char *full_path = {0};
+ asprintf(&full_path, "%s%s", ak_fs_maps_v3_get_dir(), maphash);
+ // printf("Trying path: %s\n", full_path);
+ fd = fopen(full_path, "rb");
+ if (!fd)
+ {
+ // perror("fopen");
+ return 1;
+ }
+ struct stat sb;
+ if (stat(full_path, &sb) == -1) {
+ perror("stat");
+ return 2;
+ }
+ // File size: %lld in bytes: (long long) sb.st_size);
+ char buffer[(long long) sb.st_size+1];
+ fread(&buffer, sizeof(buffer), (long long) sb.st_size, fd);
+ ak_fs_sha512sum_string_to_struct(maphash, &(map->mh));
+ if ( ak_fs_convert_map_v3_string_to_struct(buffer, strlen(buffer), map) != 0 )
+ {
+ ak_log_debug(__func__,"conversion failed");
+ fclose(fd);
+ return 1;
+ }
+ fclose(fd);
+ return 0;
+}
+
+int ak_fs_map_v3_to_file(akfs_map_v3 maphash)
+{
+ (void)maphash;
+ return 0;
+}
diff --git a/c_implementation/src/akfs_map_v4.c b/c_implementation/src/akfs_map_v4.c
new file mode 100644
index 0000000..3fea244
--- /dev/null
+++ b/c_implementation/src/akfs_map_v4.c
@@ -0,0 +1,8 @@
+#include <libaklog.h>
+#include <libakfs.h>
+
+void ak_fs_map_v4_init(akfs_map_v4* map)
+{
+ (void)map;
+ ak_log_debug(__func__, "Not implemented");
+}
diff --git a/c_implementation/src/akfs_sha512sum.c b/c_implementation/src/akfs_sha512sum.c
new file mode 100644
index 0000000..7752bf8
--- /dev/null
+++ b/c_implementation/src/akfs_sha512sum.c
@@ -0,0 +1,218 @@
+#include <libakfs.h>
+#include <stdlib.h>
+#include <assert.h>
+
+void ak_fs_sha512sum_init(sha512sum *hash)
+{
+ for (int i = 0; i < 8; ++i)
+ {
+ hash->sum[i] = 0x0;
+ }
+}
+
+bool ak_fs_sha512sum_compare(sha512sum* a, sha512sum* b)
+{
+ for ( int i = 0; i < 8; ++i )
+ {
+ if ( a->sum[i] != b->sum[i] ) return false;
+ }
+ return true;
+}
+
+void ak_fs_sha512sum_reset_struct(sha512sum* m)
+{
+ for (size_t i = 0; i < 8; ++i)
+ {
+ m->sum[i] = 0;
+ }
+}
+
+void ak_fs_sha512sum_init_avail(sha512sum** m, size_t s)
+{
+ sha512sum *ptr = NULL;
+ for (ptr = *m; ptr < *m+s; ++m)
+ {
+ ak_fs_sha512sum_reset_struct(ptr);
+ }
+}
+
+char* ak_fs_sha512sum_struct_read_as_string(sha512sum *ptr)
+{
+ char *string = malloc(129*sizeof(char));
+ ak_fs_sha512sum_struct_to_string(ptr, string);
+ return string;
+}
+
+bool ak_fs_sha512sum_is_null(sha512sum *h)
+{
+ sha512sum n;
+ ak_fs_sha512sum_init(&n);
+ return ak_fs_sha512sum_compare(h,&n);
+}
+
+int ak_fs_sha512sum_string_to_struct(char* string, sha512sum* hash)
+{
+ if ( ak_fs_verify_input_is_hash(string) )
+ {
+ for (size_t l = 0; l < 8; ++l)
+ {
+ hash->sum[l]=0;
+ }
+ unsigned int i = 0;
+ unsigned int j = 0;
+ unsigned int k = 4;
+ while ( string[i] != '\0' )
+ {
+ assert( i < 128 && "Length exceeded limit");
+ if ( i % 16 == 0 ) j = i / 16;
+ switch (string[i])
+ {
+ case 0x30:
+ hash->sum[j] = hash->sum[j] << k;
+ hash->sum[j] += 0x0;
+ break;
+ case 0x31:
+ hash->sum[j] = hash->sum[j] << k;
+ hash->sum[j] += 0x1;
+ break;
+ case 0x32:
+ hash->sum[j] = hash->sum[j] << k;
+ hash->sum[j] += 0x2;
+ break;
+ case 0x33:
+ hash->sum[j] = hash->sum[j] << k;
+ hash->sum[j] += 0x3;
+ break;
+ case 0x34:
+ hash->sum[j] = hash->sum[j] << k;
+ hash->sum[j] += 0x4;
+ break;
+ case 0x35:
+ hash->sum[j] = hash->sum[j] << k;
+ hash->sum[j] += 0x5;
+ break;
+ case 0x36:
+ hash->sum[j] = hash->sum[j] << k;
+ hash->sum[j] += 0x6;
+ break;
+ case 0x37:
+ hash->sum[j] = hash->sum[j] << k;
+ hash->sum[j] += 0x7;
+ break;
+ case 0x38:
+ hash->sum[j] = hash->sum[j] << k;
+ hash->sum[j] += 0x8;
+ break;
+ case 0x39:
+ hash->sum[j] = hash->sum[j] << k;
+ hash->sum[j] += 0x9;
+ break;
+ case 0x61:
+ hash->sum[j] = hash->sum[j] << k;
+ hash->sum[j] += 0xa;
+ break;
+ case 0x62:
+ hash->sum[j] = hash->sum[j] << k;
+ hash->sum[j] += 0xb;
+ break;
+ case 0x63:
+ hash->sum[j] = hash->sum[j] << k;
+ hash->sum[j] += 0xc;
+ break;
+ case 0x64:
+ hash->sum[j] = hash->sum[j] << k;
+ hash->sum[j] += 0xd;
+ break;
+ case 0x65:
<