diff options
23 files changed, 955 insertions, 460 deletions
@@ -393,3 +393,20 @@ $ ak pkg --help # --uninstall Uninstalls a module selected from a menu # ``` + +Donations +--------- +While this project is developed with enthusiasm and it uses the spare time of +the only developer that is coding for it, donations would help allocating more +time on the project instead of the developer looking for different occupations +to support their life and project. + +If you do appreciate the project's goals and the developers efforts towards it, +take your time and consider donating some satoshis to the developer via BTC at +the following address + +``` +bc1q70rgp65t7acfgpwp74m7vdz0g4eduxm6a43gd8 +``` + +Thank you! diff --git a/c_implementation/Makefile.am b/c_implementation/Makefile.am index 57fd80a..f1834d5 100644 --- a/c_implementation/Makefile.am +++ b/c_implementation/Makefile.am @@ -3,45 +3,58 @@ AM_CPPFLAGS = -Wall -Werror -Wextra -Wpedantic -ggdb -I$(top_srcdir)/include #AM_CFLAGS = -Wall -Werror -Wextra -Wpedantic -ggdb -I$(top_srcdir)/include lib_LTLIBRARIES = libaklog.la libaksettings.la libakfs.la libakdatetime.la libakutils.la -libaklog_la_SOURCES = $(top_srcdir)/src/aklog.c -libaksettings_la_SOURCES = $(top_srcdir)/src/aksettings.c +libaklog_la_SOURCES = $(top_srcdir)/src/ak_log.c $(top_srcdir)/src/ak_log_main.c -libakfs_LDADD = libaksettings.la -libakfs_la_SOURCES = $(top_srcdir)/src/akfs.c $(top_srcdir)/src/aksettings.c $(top_srcdir)/src/akfs_sha512sum.c $(top_srcdir)/src/akfs_map_v3.c $(top_srcdir)/src/akfs_map_v4.c $(top_srcdir)/src/akfs_main.c +libaksettings_la_SOURCES = $(top_srcdir)/src/ak_settings.c -libakutils_la_SOURCES = $(top_srcdir)/src/akutils.c +libakfs_LDADD = libaksettings.la libaklog.la +libakfs_la_SOURCES = $(top_srcdir)/src/ak_fs.c \ + $(top_srcdir)/src/ak_fs_main.c \ + $(top_srcdir)/src/ak_fs_maps_v3.c \ + $(top_srcdir)/src/ak_fs_map_v3.c \ + $(top_srcdir)/src/ak_fs_map_v4.c \ + $(top_srcdir)/src/ak_fs_mt.c \ + $(top_srcdir)/src/ak_fs_sha512sum.c -libakdatetime_la_SOURCES = $(top_srcdir)/src/akdatetime.c +libakutils_la_SOURCES = $(top_srcdir)/src/ak_utils.c -include_HEADERS = include/libaklog.h include/libaksettings.h include/libakfs.h +libakdatetime_la_SOURCES = $(top_srcdir)/src/ak_datetime.c -bin_PROGRAMS = akt akdefuse aklog akfs +#include_HEADERS = "$(wildcard include/*.h)" +include_HEADERS = $(top_srcdir)/include/libaklog.h \ + $(top_srcdir)/include/libaksettings.h \ + $(top_srcdir)/include/libakfs.h \ + $(top_srcdir)/include/libak.h + +bin_PROGRAMS = akfs akdefuse #akt akdefuse aklog akfs_LDADD = libaklog.la libakfs.la libaksettings.la -akfs_SOURCES = src/akfs_main.c -akt_SOURCES = src/ak.c +akfs_SOURCES = src/ak_fs_main.c + akt_LDADD = libaklog.la libakfs.la libaksettings.la akt_SOURCES = src/ak.c + akdefuse_CFLAGS = -I/usr/include/fuse3 -lfuse3 -lpthread akdefuse_LDADD = libaklog.la libakfs.la -akdefuse_SOURCES = src/akfs_defuse.c +akdefuse_SOURCES = src/ak_fs_defuse.c + aklog_LDADD = libaklog.la -aklog_SOURCES = src/aklog_main.c +aklog_SOURCES = src/ak_log_main.c check_PROGRAMS = test_aklog test_aksettings test_akfs test_akutils test_akdatetime -test_akdatetime_SOURCES = ./tests/test_akdatetime.c ./src/akdatetime.c +test_akdatetime_SOURCES = ./tests/test_akdatetime.c ./src/ak_datetime.c test_akdatetime_LDADD = libakdatetime.la -test_akutils_SOURCES = ./tests/test_akutils.c ./src/akutils.c +test_akutils_SOURCES = ./tests/test_akutils.c ./src/ak_utils.c test_akutils_LDADD = libakutils.la -test_aklog_SOURCES = ./tests/test_aklog.c ./src/aklog.c +test_aklog_SOURCES = ./tests/test_aklog.c ./src/ak_log.c test_aklog_LDADD = libaklog.la -test_akfs_SOURCES = ./tests/test_akfs.c ./src/akfs.c +test_akfs_SOURCES = ./tests/test_akfs.c ./src/ak_fs.c test_akfs_LDADD = libakfs.la libaklog.la -test_aksettings_SOURCES = ./tests/test_aksettings.c ./src/aksettings.c ./src/aklog.c +test_aksettings_SOURCES = ./tests/test_aksettings.c ./src/ak_settings.c ./src/ak_log.c test_aksettings_LDADD = libaksettings.la tests_test_main_CPPFLAGS = -I$(top_srcdir)/include diff --git a/c_implementation/include/libakdatetime.h b/c_implementation/include/libakdatetime.h new file mode 100644 index 0000000..435c3d8 --- /dev/null +++ b/c_implementation/include/libakdatetime.h @@ -0,0 +1,14 @@ +#include <stdbool.h> +#include <stddef.h> +#ifndef AK_DATETIME_H +#define AK_DATETIME_H + +long ak_datetime_unix(); +void ak_datetime_unix_nanosecs(char *buffer, size_t size); +void ak_datetime_human(char *buffer, size_t size); +void ak_datetime_human_date_only(char *buffer, size_t size); +void ak_datetime_human_date_only_yesterday(char *buffer, size_t size); +//static bool is_digits_only(const char *str); +bool ak_datetime_unix_to_human(const char *timestamp_str, char *buffer, size_t size); + +#endif // AK_DATETIME_H diff --git a/c_implementation/include/libakfs.h b/c_implementation/include/libakfs.h index d8d8c85..3eb0ba3 100644 --- a/c_implementation/include/libakfs.h +++ b/c_implementation/include/libakfs.h @@ -21,10 +21,9 @@ typedef struct { } sha512sum; /** - * This struct describes explicitly the structure of a root_hash. It is the root - * of a hash merkle tree. Note, that this structure can be used for roots and - * branches. Possibly, the name will change to something more generic in the - * future. + * This struct describes explicitly the structure of a mt_branch. Note, + * that this structure can be used for roots and branches. + * * Another note is that instead of approaching this as left and right, as seen * in other codebases, we do a head-tail naming. That's because of the BASH * implementation that you can find at lib/_ak_fs. @@ -43,7 +42,7 @@ typedef struct { * Hash of tail */ sha512sum tail; -} root_hash; +} mt_branch; /** * This is the current structure of an akfs_map. Due to potential short-comings @@ -129,9 +128,9 @@ char* ak_fs_return_hash_dir(const char*); * Verify that string looks like a SHA512 hash * * param char* string to be checked - * returns boolean + * @return boolean */ -bool ak_fs_verify_input_is_hash(const char*); +bool ak_fs_verify_input_is_hash(const char*, size_t); /** * Unused @@ -142,26 +141,30 @@ int ak_fs_create_dir_for_hash(const char*); * Converts string hash to struct * @param char* Hash as string * @param sha512sum* Pointer to a sha512sum - * @returns int Status of exit + * @return int Status of exit */ int ak_fs_sha512sum_string_to_struct(const char*, sha512sum*); /** * Returns struct from string hash * @param char* Hash as string - * @returns sha512sum* Pointer to a sha512sum + * @return sha512sum* Pointer to a sha512sum */ sha512sum* ak_fs_sha512sum_from_string(char*); /** * Converts hash struct to string + * @param sha512sum* Pointer to a sha512sum + * @param char* Hash as string */ void ak_fs_sha512sum_struct_to_string(const sha512sum*, char*); /** * Opens a map file to an akfs_map_v3 struct + * @param akfs_map_v3* + * @return int */ -int ak_fs_open_map_v3_file(char*, akfs_map_v3*); +int ak_fs_map_v3_open_from_file(akfs_map_v3*); /** * Unused @@ -169,64 +172,91 @@ int ak_fs_open_map_v3_file(char*, akfs_map_v3*); int ak_fs_map_v3_to_file(akfs_map_v3); /** - * Unused + * Converts a string to an akfs_map_v3 struct + * @param char* + * @param size_t + * @param akfs_map_v3* + * @return int */ int ak_fs_convert_map_v3_string_to_struct(const char *, size_t, akfs_map_v3*); /** - * Unused + * Prints an akfs_map_v3 in struct-like format + * @param akfs_map_v3* + */ +void ak_fs_map_v3_print(akfs_map_v3*); + +/** + * Prints an array of akfs_map_v3 in struct-like format + * @param akfs_map_v3* + * @param size_t + */ +void ak_fs_maps_v3_print(akfs_map_v3**, size_t); + +/** + * Prints the map hash out of a akfs_map_v3 + * @param akfs_map_v3* */ void ak_fs_map_v3_print_map_hash(akfs_map_v3*); /** - * Unused + * Prints the original hash out of a akfs_map_v3 + * @param akfs_map_v3* */ void ak_fs_map_v3_print_original_hash(akfs_map_v3*); /** - * Unused + * Prints the root hash out of a akfs_map_v3 + * @param akfs_map_v3* */ void ak_fs_map_v3_print_root_hash(akfs_map_v3*); /** - * Unused + * Prints the filename out of a akfs_map_v3 + * @param akfs_map_v3* */ void ak_fs_map_v3_print_filename(akfs_map_v3*); /** - * Unused + * Prints the filenames out of an array of akfs_map_v3 + * @param akfs_map_v3** + * @param size_t */ -void ak_fs_map_v3_print(akfs_map_v3*); +void ak_fs_maps_v3_print_filenames(akfs_map_v3**, size_t); /** - * Takes an array of sha512sums (maps) and puts it in an array of maps (v3) + * Prints an array of akfs_map_v3 in JSON format + * @param akfs_map_v3** + * @param size_t */ -int ak_fs_load_available_maps(sha512sum**, size_t, akfs_map_v3**, size_t); +void ak_fs_maps_v3_print_as_json(akfs_map_v3**, size_t); /** - * Unused - */ -void ak_fs_print_available_maps(sha512sum**, size_t); - -/** - * Unused + * Prints an akfs_map_v3 in JSON format + * @param akfs_map_v3* */ -void ak_fs_print_loaded_maps(akfs_map_v3**, size_t); +void ak_fs_map_v3_print_as_json(akfs_map_v3*); /** - * Reads maps_dir and outputs it in an array of sha512sum + * Prints an array of akfs_map_v3 in bif format + * @param akfs_map_v3** + * @param size_t */ -void ak_fs_prepare_available_maps(sha512sum**, size_t); +void ak_fs_maps_v3_print_bif(akfs_map_v3**, size_t); /** - * Unused + * Prints an akfs_map_v3 in bif format + * @param akfs_map_v3* */ -void ak_fs_get_available_maps_from_fs(sha512sum**, size_t); +void ak_fs_map_v3_print_bif(akfs_map_v3*); /** - * Unused + * Takes an array of sha512sums (maps) and puts it in an array of maps (v3) + * @param akfs_map_v3** Pointer to an array of akfs_map_v3 + * @param size_t Length of the array + * @return int Exit code (0 on success) */ -void ak_fs_print_map_all_avail(sha512sum**, size_t); +int ak_fs_maps_v3_resolve(akfs_map_v3**, size_t); /** * Unused @@ -236,20 +266,29 @@ char* ak_fs_sha512sum_struct_read_as_string(const sha512sum *); /** * Unused */ -void ak_fs_init_string(char *, size_t ); +void ak_fs_init_string(char *, size_t); /** - * Unused + * Compares two sha512sum structs + * @param sha512sum* + * @param sha512sum* + * @return bool */ bool ak_fs_sha512sum_compare(const sha512sum*, const sha512sum*); + /** - * Unused + * Checks if an sha512sum struct is NULL + * @param sha512sum* + * @return bool */ bool ak_fs_sha512sum_is_null(const sha512sum*); + /** - * Unused + * Initializes a sha512sum struct + * @param sha512sum* */ void ak_fs_sha512sum_init(sha512sum*); + /** * Unused */ @@ -263,31 +302,47 @@ void ak_fs_map_v3_init(akfs_map_v3*); /** * Initializes an array of akfs_map_v3 */ -void ak_fs_map_v3_init_store(akfs_map_v3**, size_t); +void ak_fs_maps_v3_init(akfs_map_v3**, size_t); /** - * returns: boolean - * param: akfs_map_v3 + * @param akfs_map_v3 + * @return boolean */ bool ak_fs_map_v3_is_null(akfs_map_v3*); + /** - * Unused + * Gets filename out of the akfs_map_v3 + * @param akfs_map_v3* + * @return pointer to char */ char* ak_fs_map_v3_get_filename(akfs_map_v3*); + /** - * Unused + * Gets map hash out of the akfs_map_v3 + * @param akfs_map_v3 + * @return pointer to sha512sum */ sha512sum* ak_fs_map_v3_get_map_hash(akfs_map_v3*); + /** - * Unused + * Gets root hash out of the akfs_map_v3 + * @param akfs_map_v3 + * @return pointer to sha512sum */ sha512sum* ak_fs_map_v3_get_root_hash(akfs_map_v3*); + /** - * Unused + * Gets original hash out of the akfs_map_v3 + * @param akfs_map_v3 + * @return pointer to sha512sum */ sha512sum* ak_fs_map_v3_get_orig_hash(akfs_map_v3*); + /** - * Unused + * Compares two akfs_map_v3 structs + * @param akfs_map_v3* + * @param akfs_map_v3* + * @return bool */ bool ak_fs_map_v3_compare(akfs_map_v3*, akfs_map_v3*); @@ -296,19 +351,12 @@ bool ak_fs_map_v3_compare(akfs_map_v3*, akfs_map_v3*); */ 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*); @@ -334,14 +382,53 @@ sha512sum* ak_fs_map_v4_get_root_hash(akfs_map_v4*); sha512sum* ak_fs_map_v4_get_orig_hash(akfs_map_v4*); /** - * Unused + * + * @return size_t Number of files found in maps fs location + */ +size_t ak_fs_maps_v3_found_in_fs(); + +/** + * Prints a list of the maps (version 3 format) available on the local fs along + * with their root hash and file name. + * + * @return int Status value */ int ak_fs_ls(); /** - * Main function + * Main function for call from other programs + * + * @return int Exit value */ int ak_fs_main(int, char**); +/** + * Compares an mt_branch with a NULL one + * @param mt_branch* + * @return boolean + */ +bool ak_fs_mt_branch_is_null(mt_branch*); + +/** + * Compares two mt_branch between them + * @param mt_branch* + * @return boolean + */ +bool ak_fs_mt_branch_compare(mt_branch*, mt_branch*); + +/** + * Concatenates a file from a root hash. + * @param sha512sum* + * @return int status + */ +int ak_fs_cat_file_from_root_hash(const sha512sum*); + +/** + * Concatenates a file from a akfs_map_v3 map + * @param akfs_map_v3* + * @return int status + */ +int ak_fs_cfm(akfs_map_v3*); + #endif // AKFS diff --git a/c_implementation/include/libaksettings.h b/c_implementation/include/libaksettings.h index 0f53218..505e502 100644 --- a/c_implementation/include/libaksettings.h +++ b/c_implementation/include/libaksettings.h @@ -8,15 +8,14 @@ typedef struct { char *value; } AKSetting; -int ak_settings(); void ak_settings_print_setting(AKSetting); int ak_settings_from_file(); int ak_setting_to_file(AKSetting); AKSetting* ak_settings_get_all(); -char *ak_settings_get_setting(const char *key); -bool ak_settings_set_setting(const char *key, const char *value); +char *ak_settings_get_setting(const char*); +bool ak_settings_set_setting(const char*, const char*); bool ak_settings_save_settings(); bool ak_settings_load_settings_binary(); int ak_settings_find_setting(const char *key); diff --git a/c_implementation/src/ak_datetime.c b/c_implementation/src/ak_datetime.c new file mode 100644 index 0000000..71dcb18 --- /dev/null +++ b/c_implementation/src/ak_datetime.c @@ -0,0 +1,70 @@ +#include <libakdatetime.h> +#include <stdio.h> +#include <time.h> +#include <string.h> +#include <stdbool.h> +#include <ctype.h> +#include <stdlib.h> + +// Returns Unix timestamp (seconds since epoch) +long ak_datetime_unix() { + return time(NULL); +} + +// Returns Unix timestamp with nanoseconds +void ak_datetime_unix_nanosecs(char *buffer, size_t size) { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + snprintf(buffer, size, "%ld.%09ld", ts.tv_sec, ts.tv_nsec); +} + +// Returns human-readable datetime in format YYYYMMDD_HHMMSS +void ak_datetime_human(char *buffer, size_t size) { + time_t now = time(NULL); + const struct tm *tm = gmtime(&now); + strftime(buffer, size, "%Y%m%d_%H%M%S", tm); +} + +// Returns human-readable date in format YYYYMMDD +void ak_datetime_human_date_only(char *buffer, size_t size) { + time_t now = time(NULL); + const struct tm *tm = gmtime(&now); + strftime(buffer, size, "%Y%m%d", tm); +} + +// Returns yesterday's date in format YYYYMMDD +void ak_datetime_human_date_only_yesterday(char *buffer, size_t size) { + time_t now = time(NULL); + now -= 24 * 60 * 60; // Subtract one day + const struct tm *tm = gmtime(&now); + strftime(buffer, size, "%Y%m%d", tm); +} + +// Checks if string contains only digits +static bool is_digits_only(const char *str) { + while (*str) { + if (!isdigit(*str)) { + return false; + } + str++; + } + return true; +} + +// Converts Unix timestamp to human-readable format YYYYMMDD_HHMMSS +bool ak_datetime_unix_to_human(const char *timestamp_str, char *buffer, size_t size) { + // Check if input is valid (10-digit number) + if (timestamp_str == NULL || strlen(timestamp_str) != 10 || !is_digits_only(timestamp_str)) { + return false; + } + + time_t timestamp = (time_t)atol(timestamp_str); + const struct tm *tm = gmtime(×tamp); + if (tm == NULL) { + return false; + } + + strftime(buffer, size, "%Y%m%d_%H%M%S", tm); + return true; +} + diff --git a/c_implementation/src/akfs.c b/c_implementation/src/ak_fs.c index f9abc34..8ede3f6 100644 --- a/c_implementation/src/akfs.c +++ b/c_implementation/src/ak_fs.c @@ -10,14 +10,9 @@ #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(const char* str) { - if ( ak_fs_verify_input_is_hash(str) ) + if ( ak_fs_verify_input_is_hash(str, strlen(str)) ) { unsigned int i = 0; char *result = malloc((128*2)+1); @@ -48,7 +43,7 @@ char* ak_fs_return_hash_path(const char* str) char* ak_fs_return_hash_dir(const char* str) { - if ( ak_fs_verify_input_is_hash(str) ) + if ( ak_fs_verify_input_is_hash(str, strlen(str)) ) { unsigned int i = 0; char *result = malloc((128*2)+1); @@ -74,19 +69,23 @@ char* ak_fs_return_hash_dir(const char* str) } } -bool ak_fs_verify_input_is_hash(const char* str) +bool ak_fs_verify_input_is_hash(const char* str, size_t len) { size_t i = 0; + if (len != 128) + { + return false; + } while ( str[i] != '\0' ) { if ( i < 128 && !( ( str[i] >= 0x30 ) && - (( str[i] <= 0x39) || ( str[i] >= 0x61 )) && + ( str[i] <= 0x39 || str[i] >= 0x61 ) && ( str[i] <= 0x66 ) - ) - ) + ) + ) { return false; } @@ -112,7 +111,7 @@ int ak_fs_create_dir_for_hash(const char* str) * 2. We might need to "lock" onto some version of glibc and be aware of * other systems that do not use that one. */ - if ( ak_fs_verify_input_is_hash(str) ) + if ( ak_fs_verify_input_is_hash(str, strlen(str)) ) { char* dir_path = ak_fs_return_hash_dir(str); // We will need to separate the string so we can create the path one @@ -185,13 +184,11 @@ int ak_fs_convert_map_v3_string_to_struct(const char *str, size_t ssize, akfs_ma { if ( str[i] == ' ' ) { - spaces_found++; - sa[spaces_found] = i; + sa[++spaces_found] = i; } if ( str[i] == '\n' ) { - newlines_found++; - na[newlines_found] = i; + na[++newlines_found] = i; } } int si = 0; @@ -201,7 +198,7 @@ int ak_fs_convert_map_v3_string_to_struct(const char *str, size_t ssize, akfs_ma si++; } original_hash_str[si] = '\0'; - if( !ak_fs_verify_input_is_hash(original_hash_str) ) + if( !ak_fs_verify_input_is_hash(original_hash_str, strlen(original_hash_str)) ) { ak_log_error(__func__, "original_hash_str not a hash"); return 1; @@ -218,7 +215,7 @@ int ak_fs_convert_map_v3_string_to_struct(const char *str, size_t ssize, akfs_ma si++; } root_hash_str[si] = '\0'; - if( !ak_fs_verify_input_is_hash(root_hash_str) ) + if( !ak_fs_verify_input_is_hash(root_hash_str, strlen(root_hash_str)) ) { ak_log_error(__func__, "root_hash_str not a hash"); return 1; @@ -242,185 +239,145 @@ int ak_fs_convert_map_v3_string_to_struct(const char *str, size_t ssize, akfs_ma return 0; } -void ak_fs_get_available_maps_from_fs(sha512sum **ma, size_t length) +void ak_fs_maps_v3_get_from_fs(akfs_map_v3 **ma, size_t length) { + (void)length; DIR *d; d = opendir(ak_fs_maps_v3_get_dir()); - sha512sum *ptr = NULL; + akfs_map_v3 *ptr = NULL; + ptr = *ma; if (d) { - for ( ptr = *ma; ptr < *ma+length; ++ptr) + const struct dirent *dir; + while((dir = readdir(d)) != NULL ) { - const struct dirent *dir; - 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); + if (!ak_fs_verify_input_is_hash(dir->d_name, 128)) continue; + ak_fs_sha512sum_string_to_struct(dir->d_name, &(ptr->mh)); + ++ptr; } } closedir(d); } -int ak_fs_load_available_maps(sha512sum **ma, size_t ma_len, akfs_map_v3 **ms, size_t ms_len) -{ - sha512sum *ptr = NULL; - akfs_map_v3 *mptr = NULL; - mptr = *ms; - (void)ms_len; - for ( ptr = *ma; ptr < *ma+ma_len; ++ptr) - { - if ( ak_fs_sha512sum_is_null(ptr)) - { - continue; - } - if( ak_fs_open_map_v3_file(ak_fs_sha512sum_struct_read_as_string(ptr), mptr) != 2) - { - ++(mptr); - continue; - } - else - { - ++(mptr); - // return 1; - } - } - return 0; -} - -void ak_fs_print_loaded_maps(akfs_map_v3 **map_store, size_t length) +void ak_fs_init_string(char *str, size_t len) { - akfs_map_v3 *ptr = NULL; - for ( ptr = *map_store; ptr < *map_store + length; ++ptr) + for (size_t i = 0; i < len; ++i) { - if ( !ak_fs_map_v3_is_null(ptr) ) ak_fs_map_v3_print(ptr); + str[i] = '\0'; } } -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) +int ak_fs_ls() { - akfs_map_v3 n; - ak_fs_map_v3_init(&n); - return ak_fs_map_v3_compare(m, &n); + size_t len = ak_fs_maps_v3_found_in_fs(); + akfs_map_v3 map_store[len]; + akfs_map_v3* maps_ptr = &map_store[0]; + ak_fs_maps_v3_init(&maps_ptr, len); + ak_fs_maps_v3_get_from_fs(&maps_ptr, len); + ak_fs_maps_v3_resolve(&maps_ptr, len); + ak_fs_maps_v3_print_bif(&maps_ptr, len); + return 0; } -void ak_fs_print_available_maps(sha512sum **ma, size_t ma_len) +int ak_fs_cat_file_from_root_hash(const sha512sum* rh) { - sha512sum *ptr = NULL; - for ( ptr = *ma; ptr < *ma+ma_len; ++ptr) + const char* chunks_dir = getenv("AK_CHUNKSDIR"); + if ( chunks_dir == NULL ) { - ak_log_debug(__func__, ak_fs_sha512sum_struct_read_as_string(ptr)); + ak_log_error(__func__, "No directory for chunks found"); + return -2; } - -} - -void ak_fs_init_string(char *str, size_t len) -{ - for (size_t i = 0; i < len; ++i) + const char* leafs_dir = getenv("AK_LEAFSDIR"); + if ( leafs_dir == NULL ) { - str[i] = '\0'; + ak_log_error(__func__, "No directory for leafs found"); + return -3; } -} - - -void ak_fs_print_map_avail(const sha512sum* m) -{ - 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) + FILE *fd; + char *fullpath; + bool is_chunk = false; + char root_hash_str[129] = {0}; + ak_fs_sha512sum_struct_to_string(rh, root_hash_str); + if ( asprintf(&fullpath, "%s/%s", leafs_dir, root_hash_str) == -1 ) return -1; + fd = fopen(fullpath, "r"); + if ( fd == NULL ) { - ak_fs_print_map_avail(ptr); + free(fullpath); + if ( asprintf(&fullpath, "%s/%s", chunks_dir, ak_fs_sha512sum_struct_read_as_string(rh)) == -1 ) return -1; + fd = fopen(fullpath, "r"); + if ( fd == NULL ) + { + ak_log_error(__func__, "Could not be found"); + free(fullpath); + return 1; + } + is_chunk = true; } -} - -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 ( !is_chunk ) { - if ( !ak_fs_map_v3_is_null(ptr) ) ak_fs_map_v3_print_filename(ptr); + char buffer[258] = {0}; + size_t bytes_read = fread(&buffer, 1, sizeof(buffer), fd); + if ( bytes_read < sizeof(buffer) ) + { + ak_log_error(__func__, "File is smaller than expected. Wrong format?"); + fclose(fd); + free(fullpath); + return 2; + } + if ( buffer[128] != '\n' || buffer[257] != '\n' ) + { + ak_log_error(__func__, "Unknown format"); + fclose(fd); + free(fullpath); + return 2; + } + char h_str[129] = {0}; + char t_str[129] = {0}; + mt_branch h0; + ak_fs_sha512sum_init(&h0.root); + ak_fs_sha512sum_init(&h0.head); + ak_fs_sha512sum_init(&h0.tail); + h0.root = *rh; + memcpy(h_str, buffer, 128); + h_str[128] = '\0'; + memcpy(t_str, buffer + 129, 128); + t_str[128] = '\0'; + fclose(fd); + // free(fullpath); + ak_fs_sha512sum_string_to_struct(h_str, &h0.head); + ak_fs_sha512sum_string_to_struct(t_str, &h0.tail); + ak_fs_cat_file_from_root_hash(&h0.head); + if ( !ak_fs_sha512sum_compare(&h0.head, &h0.tail) ) ak_fs_cat_file_from_root_hash(&h0.tail); } -} - -// 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) + else { - if (!ak_fs_map_v3_is_null(ptr)) ak_fs_map_v3_print(ptr); + struct stat sb; + if (stat(fullpath, &sb) == -1) { + perror("stat"); + fclose(fd); + free(fullpath); + return 2; + } + char buffer[(long long) sb.st_size+1]; + fread(&buffer, sizeof(buffer), 1, fd); + fclose(fd); + buffer[sizeof(buffer)-1] = '\0'; + printf("%s", buffer); } -} - -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); + free(fullpath); return 0; } -int ak_fs_usage() -{ - ak_log_debug(__func__, "Available commands:"); - ak_log_debug(__func__, "ak fs --list"); - return 1; -} - -int ak_fs_main(int c, char** v) +int ak_fs_cfm(akfs_map_v3* map) { - (void)c; - (void)v; - int option; - while ( (option = getopt(c, v, ":h|:help")) != -1 ) + sha512sum x; + ak_fs_sha512sum_init(&x); + const sha512sum *rh_ptr = ak_fs_map_v3_get_root_hash(map); + if ( rh_ptr == NULL ) { - printf("%d\n", option); - switch(option) - { - case 'h': |