From ac6fbacce69ad8d53099f1e6ab922c2e4bd6f9cc Mon Sep 17 00:00:00 2001 From: kaotisk Date: Sun, 27 Apr 2025 06:57:51 +0300 Subject: Updates.. better file names --- c_implementation/Makefile.am | 46 ++-- c_implementation/src/ak_datetime.c | 70 ++++++ c_implementation/src/ak_fs.c | 332 ++++++++++++++++++++++++++++ c_implementation/src/ak_fs_defuse.c | 98 +++++++++ c_implementation/src/ak_fs_main.c | 43 ++++ c_implementation/src/ak_fs_map_v3.c | 232 ++++++++++++++++++++ c_implementation/src/ak_fs_map_v4.c | 8 + c_implementation/src/ak_fs_maps_v3.c | 63 ++++++ c_implementation/src/ak_fs_sha512sum.c | 220 +++++++++++++++++++ c_implementation/src/ak_log.c | 240 ++++++++++++++++++++ c_implementation/src/ak_log_main.c | 32 +++ c_implementation/src/ak_logcatter.c | 36 +++ c_implementation/src/ak_settings.c | 153 +++++++++++++ c_implementation/src/ak_utils.c | 8 + c_implementation/src/akfs.c | 388 --------------------------------- c_implementation/src/akfs_defuse.c | 97 --------- c_implementation/src/akfs_main.c | 43 ---- c_implementation/src/akfs_map_v3.c | 147 ------------- c_implementation/src/akfs_map_v4.c | 8 - c_implementation/src/akfs_sha512sum.c | 218 ------------------ c_implementation/src/aklog.c | 268 ----------------------- c_implementation/src/aklog_main.c | 6 - c_implementation/src/aklogcatter.c | 36 --- c_implementation/src/aksettings.c | 153 ------------- c_implementation/src/akutils.c | 8 - 25 files changed, 1564 insertions(+), 1389 deletions(-) create mode 100644 c_implementation/src/ak_datetime.c create mode 100644 c_implementation/src/ak_fs.c create mode 100644 c_implementation/src/ak_fs_defuse.c create mode 100644 c_implementation/src/ak_fs_main.c create mode 100644 c_implementation/src/ak_fs_map_v3.c create mode 100644 c_implementation/src/ak_fs_map_v4.c create mode 100644 c_implementation/src/ak_fs_maps_v3.c create mode 100644 c_implementation/src/ak_fs_sha512sum.c create mode 100644 c_implementation/src/ak_log.c create mode 100644 c_implementation/src/ak_log_main.c create mode 100644 c_implementation/src/ak_logcatter.c create mode 100644 c_implementation/src/ak_settings.c create mode 100644 c_implementation/src/ak_utils.c delete mode 100644 c_implementation/src/akfs.c delete mode 100644 c_implementation/src/akfs_defuse.c delete mode 100644 c_implementation/src/akfs_main.c delete mode 100644 c_implementation/src/akfs_map_v3.c delete mode 100644 c_implementation/src/akfs_map_v4.c delete mode 100644 c_implementation/src/akfs_sha512sum.c delete mode 100644 c_implementation/src/aklog.c delete mode 100644 c_implementation/src/aklog_main.c delete mode 100644 c_implementation/src/aklogcatter.c delete mode 100644 c_implementation/src/aksettings.c delete mode 100644 c_implementation/src/akutils.c diff --git a/c_implementation/Makefile.am b/c_implementation/Makefile.am index 57fd80a..9b6cd65 100644 --- a/c_implementation/Makefile.am +++ b/c_implementation/Makefile.am @@ -3,45 +3,57 @@ 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_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/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 +#include +#include +#include +#include +#include +#include + +// 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/ak_fs.c b/c_implementation/src/ak_fs.c new file mode 100644 index 0000000..1d30744 --- /dev/null +++ b/c_implementation/src/ak_fs.c @@ -0,0 +1,332 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char* ak_fs_return_hash_path(const char* str) +{ + if ( ak_fs_verify_input_is_hash(str) ) + { + unsigned int i = 0; + char *result = malloc((128*2)+1); + if ( result == NULL ) + { + return ""; + } + while ( str[i] != '\0' ) + { + result[i*2] = str[i]; + if ( (i*2) + 1 <= 254 ) + { + result[(i*2)+1] = '/'; + } + else + { + result[(i*2)+1] = '\0'; + } + ++i; + } + return result; + } + else + { + return NULL; + } +} + +char* ak_fs_return_hash_dir(const char* str) +{ + if ( ak_fs_verify_input_is_hash(str) ) + { + unsigned int i = 0; + char *result = malloc((128*2)+1); + if ( result == NULL ) return ""; + while ( str[i] != '\0' ) + { + result[i*2] = str[i]; + if ( (i*2) + 1 <= 254-2 ) + { + result[(i*2)+1] = '/'; + } + else + { + result[(i*2)+1] = '\0'; + } + ++i; + } + return result; + } + else + { + return NULL; + } +} + +bool ak_fs_verify_input_is_hash(const char* str) +{ + size_t i = 0; + while ( str[i] != '\0' ) + { + if ( + i < 128 && + !( + ( str[i] >= 0x30 ) && + (( str[i] <= 0x39) || ( str[i] >= 0x61 )) && + ( str[i] <= 0x66 ) + ) + ) + { + return false; + } + else { + i++; + } + } + if ( i > 128 ) + { + return false; + } + return true; +} + +int ak_fs_create_dir_for_hash(const char* str) +{ + /* TODO + * Some aspects of this function + * 1. We need a "root" place to put our dirs into, this is not specified + * anywhere in this code but it is spartially specified in other files + * like lib/_ak_fs bash script and the rc/config file we currently source + * in $HOME/.bashrc + * 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) ) + { + char* dir_path = ak_fs_return_hash_dir(str); + // We will need to separate the string so we can create the path one + // directory at the time + int len = strlen(dir_path); + for ( int i = 0; i < len+1; ++i) + { + if ( dir_path[i] == '/' ) + { + //printf("%c\n", dir_path[i]); + //char* test = strndup(dir_path, i); + //printf("A: [i:%d] [c:%c] - %s\n", i, dir_path[i], test); + continue; + } + else + { + char* incremental_dir_path = strndup(dir_path, i+1); + // printf("B: [i:%d] [c:%c] - %s\n", i, dir_path[i], test); + struct stat sb; + if (stat(incremental_dir_path, &sb) == 0 && S_ISDIR(sb.st_mode)) + { + continue; + } + else + { + int return_code = mkdir(incremental_dir_path, 0777); + if ( return_code == 0 ) + { + continue; + } + else + { + // should be unreachable I guess since previous checks + // though it could be caused by some other kind of error + // like, no permission, or exists but is not a directory + // but a file, dev, char, pipe whatever this thing + // supports anyway + free(incremental_dir_path); + free(dir_path); + return -3; + } + } + free(incremental_dir_path); + } + } + free(dir_path); + return 0; + } + else + { + return -2; + } +} + +int ak_fs_convert_map_v3_string_to_struct(const char *str, size_t ssize, akfs_map_v3* map) +{ + 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_str[129] = {0}; + char root_hash_str[129] = {0}; + char filename[256] = {0}; + if ( map == 0x0 ) + { + printf("FAILED IN %s! : %p \n", __func__, (void*)map); + return 1; + } + for ( size_t i = 0; i < ssize; ++i) + { + if ( str[i] == ' ' ) + { + // spaces_found++; + sa[++spaces_found] = i; + } + if ( str[i] == '\n' ) + { + // newlines_found++; + na[++newlines_found] = i; + } + } + int si = 0; + for ( size_t i = 0; i < sa[1]; ++i) + { + original_hash_str[si] = str[i]; + si++; + } + original_hash_str[si] = '\0'; + if( !ak_fs_verify_input_is_hash(original_hash_str) ) + { + ak_log_error(__func__, "original_hash_str not a hash"); + return 1; + } + if ( ak_fs_sha512sum_string_to_struct(original_hash_str, &(map->oh)) != 0 ) + { + ak_log_error(__func__, "String convertion of original_hash_str"); + return 1; + } + si = 0; + for ( size_t i = na[1]+1; i < sa[3]; ++i) + { + root_hash_str[si] = str[i]; + si++; + } + root_hash_str[si] = '\0'; + if( !ak_fs_verify_input_is_hash(root_hash_str) ) + { + ak_log_error(__func__, "root_hash_str not a hash"); + return 1; + } + if ( ak_fs_sha512sum_string_to_struct(root_hash_str, &(map->rh)) != 0 ) + { + ak_log_error(__func__, "String convertion of root_hash_str"); + return 1; + } + si = 0; + if ( sa[2] < na[1] ) + { + for ( size_t i = sa[2]+1; i < na[1]; ++i) + { + filename[si] = str[i]; + si++; + } + filename[si] = '\0'; + } + strncpy(map->filename, filename, sizeof(map->filename)); + return 0; +} + +void ak_fs_get_available_maps_from_fs(sha512sum **ma, size_t length) +{ + DIR *d; + d = opendir(ak_fs_maps_v3_get_dir()); + sha512sum *ptr = NULL; + if (d) + { + for ( ptr = *ma; ptr < *ma+length; ++ptr) + { + 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); + } + } + closedir(d); +} + +int ak_fs_map_v3_resolve_maps(akfs_map_v3 **ms, size_t ms_len) +{ + akfs_map_v3 *ptr = NULL; + for ( ptr = *ms; ptr < *ms+ms_len; ++ptr) + { + if ( ak_fs_sha512sum_is_null(&(ptr->mh)) ) + { + continue; + } + if( ak_fs_map_v3_open_from_file(ptr) != 2) + { + ++(ptr); + continue; + } + else + { + ++(ptr); + // return 1; + } + } + return 0; +} + +// void ak_fs_print_available_maps(sha512sum **ma, size_t ma_len) +// { +// sha512sum *ptr = NULL; +// for ( ptr = *ma; ptr < *ma+ma_len; ++ptr) +// { +// ak_log_debug(__func__, ak_fs_sha512sum_struct_read_as_string(ptr)); +// } +// } + +void ak_fs_init_string(char *str, size_t len) +{ + for (size_t i = 0; i < len; ++i) + { + str[i] = '\0'; + } +} + +// 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) +// { +// ak_fs_print_map_avail(ptr); +// } +// } + +int ak_fs_ls() +{ + size_t len = ak_fs_maps_v3_found_in_fs(); + printf("Found: %lu\n", len); + akfs_map_v3 map_store[len]; + akfs_map_v3* maps_ptr = &map_store[0]; + void* mps_start = &map_store[0]; + (void)mps_start; + ak_fs_maps_v3_init(&maps_ptr, len); + ak_fs_maps_v3_print(&maps_ptr, len); + + // TODO Rename the following to "ak_fs_resolve_map_v3_array" or close to it + ak_fs_map_v3_resolve_maps(&maps_ptr, len); + + // TODO Decide what we should be printing + // Possibly, something like "maphex(6)_filename" so we can put multiple + // files with the same name into the list + ak_fs_maps_v3_print(&maps_ptr, len); + ak_fs_maps_v3_print_filenames(&maps_ptr, len); + return 0; +} diff --git a/c_implementation/src/ak_fs_defuse.c b/c_implementation/src/ak_fs_defuse.c new file mode 100644 index 0000000..10617cc --- /dev/null +++ b/c_implementation/src/ak_fs_defuse.c @@ -0,0 +1,98 @@ +#define FUSE_USE_VERSION 31 +#include +#include +#include +#include +#include +#include +#include +#include + +// 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); + filler(buf, "..", NULL, 0, 0); + + // example file + filler(buf, "hello", NULL, 0, 0); + + // ak fs integration + size_t ms_len = ak_fs_maps_v3_found_in_fs(); + akfs_map_v3 map_store[ms_len]; + akfs_map_v3* mps_ptr = &map_store[0]; + void* mps_start = &map_store[0]; + (void)mps_start; + ak_fs_maps_v3_init(&mps_ptr, ms_len); + ak_fs_map_v3_resolve_maps(&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; + 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/ak_fs_main.c b/c_implementation/src/ak_fs_main.c new file mode 100644 index 0000000..f1660cf --- /dev/null +++ b/c_implementation/src/ak_fs_main.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include + +static int ak_fs_usage() +{ + ak_log_debug(__func__, "Available commands:"); + ak_log_debug(__func__, "ak fs --list"); + return 1; +} + +int ak_fs_main(int argc, char** argv) +{ + int option; + int logind = 0; + static struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"list", no_argument, 0, 'l'}, + {0,0,0,0} + }; + while(1) + { + option = getopt_long(argc, argv, "hl", long_options, &logind); + if ( option == -1 ) return ak_fs_usage(); + switch(option) + { + case 'h': + return ak_fs_usage(); + case 'l': + return ak_fs_ls(); + default: + printf("double lol\n"); + return 4; + } + } + return 0; +} + +int main(int argc, char **argv) +{ + return ak_fs_main(argc, argv); +} diff --git a/c_implementation/src/ak_fs_map_v3.c b/c_implementation/src/ak_fs_map_v3.c new file mode 100644 index 0000000..1b26d89 --- /dev/null +++ b/c_implementation/src/ak_fs_map_v3.c @@ -0,0 +1,232 @@ +#include +#include +#include +#include +#include + +// 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); +} + +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); + if ( ak_fs_map_v3_compare(m, &n) ) + { + ak_log_debug(__func__, "true"); + } + else + { + ak_log_debug(__func__, "false"); + } + return ak_fs_map_v3_compare(m, &n); +} + +void ak_fs_map_v3_print_map_hash(akfs_map_v3 *map) +{ + if( !ak_fs_sha512sum_is_null(&(map->mh)) ) + { + char str[129] = {0}; + char* s = &str[0]; + ak_fs_sha512sum_struct_to_string(&(map->mh), s); + printf("%s", s); + } + else + { + ak_log_debug(__func__,"hash is null"); + } +} + +void ak_fs_map_v3_print_original_hash(akfs_map_v3 *map) +{ + if (!ak_fs_sha512sum_is_null(&(map->oh))) + { + printf("%s", ak_fs_sha512sum_struct_read_as_string(&(map->oh))); + } + else + { + ak_log_debug(__func__,"hash is null"); + } +} + +void ak_fs_map_v3_print_root_hash(akfs_map_v3 *map) +{ + if (!ak_fs_sha512sum_is_null(&(map->rh))) + { + printf("%s", ak_fs_sha512sum_struct_read_as_string(&(map->rh))); + } + else + { + ak_log_debug(__func__,"hash is null"); + } +} + +sha512sum* ak_fs_map_v3_get_map_hash(akfs_map_v3 *map) +{ + return &(map->mh); +} + +char* ak_fs_map_v3_get_root_hash(akfs_map_v3 *map) +{ + if (!ak_fs_sha512sum_is_null(&(map->rh))) + { + return ak_fs_sha512sum_struct_read_as_string(&(map->rh)); + } + else + { + return ""; + } +} + +char* ak_fs_map_v3_get_filename(akfs_map_v3 *map) +{ + return map->filename; +} + +void ak_fs_map_v3_print_filename(akfs_map_v3 *map) +{ + printf(" .fn: %s\n", ak_fs_map_v3_get_filename(map)); +} + +void ak_fs_map_v3_print(akfs_map_v3 *map) +{ + printf("map_v3 {\n"); + printf("\n .mh: "); + ak_fs_map_v3_print_map_hash(map); + printf("\n .oh: "); + ak_fs_map_v3_print_original_hash(map); + printf("\n .rh: "); + ak_fs_map_v3_print_root_hash(map); + printf("\n .fn: "); + ak_fs_map_v3_print_filename(map); + printf("\n}\n"); +} + +void ak_fs_map_v3_print_as_json(akfs_map_v3 *map) +{ + printf("{\"type\":\"map_v3\","); + printf("\"map\":\""); + ak_fs_map_v3_print_map_hash(map); + printf("\","); + printf("{\"original\":\""); + ak_fs_map_v3_print_original_hash(map); + printf("\","); + printf("{\"root\":\""); + ak_fs_map_v3_print_root_hash(map); + printf("\","); + printf("{\"filename\":\""); + ak_fs_map_v3_print_filename(map); + printf("\""); + printf("}\n"); +} + +int ak_fs_map_v3_open_from_file(akfs_map_v3 * map) +{ + ak_log_debug(__func__, "Started"); + if (map==0x0) + { + ak_log_debug(__func__, "Zeropointer"); + return 1; + } + FILE *fd; + char *full_path = {0}; + asprintf(&full_path, + "%s/%s", + ak_fs_maps_v3_get_dir(), + ak_fs_sha512sum_struct_read_as_string(ak_fs_map_v3_get_map_hash(map)) + ); + // printf("Trying path: %s\n", full_path); + fd = fopen(full_path, "rb"); + if (!fd) + { + // perror("fopen"); + ak_log_debug(__func__, "File not found or other error"); + return 1; + } + struct stat sb; + if (stat(full_path, &sb) == -1) { + perror("stat"); + fclose(fd); + 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_open_map_v3_file(char* maphash, akfs_map_v3 * map) +{ + ak_log_debug(__func__, "Started"); + if (map==0x0) + { + 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"); + ak_log_debug(__func__, "file not found"); + return 1; + } + struct stat sb; + if (stat(full_path, &sb) == -1) { + perror("stat"); + fclose(fd); + 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/ak_fs_map_v4.c b/c_implementation/src/ak_fs_map_v4.c new file mode 100644 index 0000000..3fea244 --- /dev/null +++ b/c_implementation/src/ak_fs_map_v4.c @@ -0,0 +1,8 @@ +#include +#include + +void ak_fs_map_v4_init(akfs_map_v4* map) +{ + (void)map; + ak_log_debug(__func__, "Not implemented"); +} diff --git a/c_implementation/src/ak_fs_maps_v3.c b/c_implementation/src/ak_fs_maps_v3.c new file mode 100644 index 0000000..9b047b0 --- /dev/null +++ b/c_implementation/src/ak_fs_maps_v3.c @@ -0,0 +1,63 @@ +#include +#include +#include + +const char* ak_fs_maps_v3_get_dir() +{ + return getenv("AK_MAPSDIR"); +} + +void ak_fs_maps_v3_init(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_maps_v3_print_map_hashes(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_map_hash(ptr); + } +} + +void ak_fs_maps_v3_print_filenames(akfs_map_v3** m, size_t s) +{ + akfs_map_v3 *ptr = NULL; + for (ptr = *m; ptr < *m+s; ++ptr) + { + if ( ptr != NULL ) ak_fs_map_v3_print_filename(ptr); + } +} + +void ak_fs_maps_v3_print(akfs_map_v3 **map_store, size_t length) +{ + akfs_map_v3 *ptr = NULL; + for ( ptr = *map_store; ptr < *map_store + length; ++ptr) + { + ak_fs_map_v3_print(ptr); + ak_fs_map_v3_print_as_json(ptr); + } +} + + +size_t ak_fs_maps_v3_found_in_fs() +{ + DIR *d; + size_t counter = 0; + d = opendir(ak_fs_maps_v3_get_dir()); + if (d) + { + const struct dirent *dir; + while ((dir = readdir(d)) != NULL ) + { + if (ak_fs_verify_input_is_hash(dir->d_name)) counter++; + } + } + closedir(d); + return counter; +} diff --git a/c_implementation/src/ak_fs_sha512sum.c b/c_implementation/src/ak_fs_sha512sum.c new file mode 100644 index 0000000..2e10544 --- /dev/null +++ b/c_implementation/src/ak_fs_sha512sum.c @@ -0,0 +1,220 @@ +#include +#include +#include +#include + +void ak_fs_sha512sum_init(sha512sum *hash) +{ + for (int i = 0; i < 8; ++i) + { + hash->sum[i] = 0x0; + } +} + +bool ak_fs_sha512sum_compare(const sha512sum* a, const 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(const sha512sum *ptr) +{ + char *str = malloc(129*sizeof(char)); + ak_fs_sha512sum_struct_to_string(ptr, str); + ak_log_debug(__func__, str); + return str; +} + +bool ak_fs_sha512sum_is_null(const sha512sum *h) +{ + sha512sum n; + ak_fs_sha512sum_init(&n); + return ak_fs_sha512sum_compare(h,&n); +} + +int ak_fs_sha512sum_string_to_struct(const char* str, sha512sum* hash) +{ + if ( ak_fs_verify_input_is_hash(str) ) + { + 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 ( str[i] != '\0' ) + { + assert( i < 128 && "Length exceeded limit"); + if ( i % 16 == 0 ) j = i / 16; + switch (str[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++; + } + if ( i != 128 ) + { + return 1; + } + return 0; + } + else + { + return 0; + } +} + +void ak_fs_sha512sum_struct_to_string(const sha512sum* hash, char* str) +{ + int count = 0; + sha512sum lhash = *hash; + for (size_t i = 0; i < 8; ++i) + { + for (size_t j = 0; j < 16; ++j) + { + long unsigned first = lhash.sum[i]/0xfffffffffffffff; + switch(first){ + case 0: + str[count] = '0'; + break; + case 1: + str[count] = '1'; + break; + case 2: + str[count] = '2'; + break; + case 3: + str[count] = '3'; + break; + case 4: + str[count] = '4'; + break; + case 5: + str[count] = '5'; + break; + case 6: + str[count] = '6'; + break; + case 7: + str[count] = '7'; + break; + case 8: + str[count] = '8'; + break; + case 9: + str[count] = '9'; + break; + case 0xa: + str[count] = 'a'; + break; + case 0xb: + str[count] = 'b'; + break; + case 0xc: + str[count] = 'c'; + break; + case 0xd: + str[count] = 'd'; + break; + case 0xe: + str[count] = 'e'; + break; + case 0xf: + str[count] = 'f'; + break; + default: + assert(0 && "Should be unreachable"); + } + count++; + lhash.sum[i] = lhash.sum[i] << 4; + } + } + str[128] = '\0'; +} + diff --git a/c_implementation/src/ak_log.c b/c_implementation/src/ak_log.c new file mode 100644 index 0000000..e3af865 --- /dev/null +++ b/c_implementation/src/ak_log.c @@ -0,0 +1,240 @@ +#include +#include +#include +#include +#include +#include +#include "libaklog.h" + +#define AK_DEBUG true +#define AK_DEBUG_LEVEL DEBUG + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +int ak_log_write_to_file(const char* message) +{ + FILE *fp; + char *fullpath_to_log_file={0}; + char *relative_location = "/.arching-kaos/logs/log"; + char *home_dir = getenv("HOME"); + asprintf(&fullpath_to_log_file, "%s%s", home_dir, relative_location); + fp = fopen(fullpath_to_log_file, "ab"); + if (!fp) + { + perror("fopen"); + return EXIT_FAILURE; + } + fwrite(message, strlen(message),1,fp); + fwrite("\n", strlen("\n"),1,fp); + fclose(fp); + return 0; +} + +void ak_log_print_log_line(const char* line) +{ + int spaces_found = 0; + int sa[] = { -1, -1, -1, -1 }; + long int l = 1000000000; + long int ts = 0; + const struct tm *timeInfo; + char ts_string[16]; // %Y%Y%Y%Y%m%m%d%d_%H%H%M%M%S%S + for (size_t i = 0; i < strlen(line); ++i) + { + if ( line[i] == ' ' && spaces_found < 3 ) + { + spaces_found++; + sa[spaces_found] = i; + } + } + for ( int k = 0; k < sa[1]; ++k) + { + switch(line[k]) + { + case '0': + ts = 0*l + ts; + break; + case '1': + ts = 1*l + ts; + break; + case '2': + ts = 2*l + ts; + break; + case '3': + ts = 3*l + ts; + break; + case '4': + ts = 4*l + ts; + break; + case '5': + ts = 5*l + ts; + break; + case '6': + ts = 6*l + ts; + break; + case '7': + ts = 7*l + ts; + break; + case '8': + ts = 8*l + ts; + break; + case '9': + ts = 9*l + ts; + break; + } + l = l/10; + } + timeInfo = localtime(&ts); + strftime(ts_string, sizeof(ts_string), "%Y%m%d_%H%M%S", timeInfo); + fprintf(stderr, "%s", ts_string); + fprintf(stderr, " \033[1;32m"); + for ( int k = sa[1]+1; k < sa[2]; ++k) + { + fprintf(stderr, "%c", line[k]); + } + fprintf(stderr, "\033[0m \033[1;31m"); + for ( int k = sa[2]+1; k < sa[3]; ++k) + { + fprintf(stderr, "%c", line[k]); + } + fprintf(stderr, "\033[0m "); + for ( size_t k = sa[3]+1; k < strlen(line); ++k) + { + fprintf(stderr, "%c", line[k]); + } + fprintf(stderr, "\033[0m"); + fprintf(stderr, "\n"); +} + +void ak_log_follow() +{ + // tail -f $AK_LOGSFILE | while read -r p || [ -n "$p" ] + // do + // ak_log_print_log_line "$p" + // done +} + +void ak_log_grep(char* message) +{ + (void)message; + printf("ak_log_grep: not implemented\n"); + return; + // exit(2); + // if ( message ) + // { + // if ( strcmp(message, "-h") || strcmp(message, "--help") ) + // { + // // description(); + // printf("Launch with no arguments and select from the menu that will appear\n"); + // exit(1); + // } + // } + // printf("The following scripts have entries in the log file.\n"); + // printf("Select one of those by entering the number of it below and hit enter:\n"); + // select x in $(cat $AK_LOGSFILE | cut -d ' ' -f 2 | sort | uniq) + // do + // grep $x $AK_LOGSFILE | while read line + // do + // ak_log_print_log_line "$line" + // done + // break + // done +} + +void ak_log_rotate() +{ + // if [ -f $AK_LOGSFILE ] + // then + // tar cvfz $AK_ARCHIVESDIR/logs_$(date -u +%s).tar.gz $AK_WORKDIR/logs + // cat /dev/null > $AK_WORKDIR/logs + // fi + // if [ -f $AK_WORKDIR/akd.log ] + // then + // tar cvfz $AK_ARCHIVESDIR/akd-logs_$(date -u +%s).tar.gz $AK_WORKDIR/akd.log + // cat /dev/null > $AK_WORKDIR/akd.log + // fi + printf("ak_log_rotate: not implemented\n"); + return; + // exit(2); +} + +void ak_log_message(const char* program, LogMessageType lmtype, char* message) +{ + time_t ts = time(NULL); + time(&ts); + char* some_string = {0}; + char* type = {0}; + if ( program == NULL ) + { + // echo "$TS" "<$(basename $0)>" "[ERROR]" "No arguments given" >> $AK_LOGSFILE + asprintf(&some_string, "%ld [ERROR] No arguments given\n", ts); + ak_log_write_to_file(some_string); + if ( AK_DEBUG ) ak_log_print_log_line(some_string); + return; + } + if ( message == NULL ) + { + asprintf(&some_string, "%ld <%s> [ERROR] No message\n", ts, program); + ak_log_write_to_file(some_string); + if ( AK_DEBUG ) ak_log_print_log_line(some_string); + return; + } + switch(lmtype) + { + case ERROR: + type = "ERROR"; + break; + case INFO: + type = "INFO"; + break; + case WARNING: + type = "WARNING"; + break; + case EXIT: + type = "EXIT"; + break; + case DEBUG: + type = "DEBUG"; + break; + case TEST: + type = "TEST"; + break; + default: + asprintf(&some_string, "%ld <%s> [ERROR] No message type\n", ts, program); + ak_log_write_to_file(some_string); + if ( AK_DEBUG ) ak_log_print_log_line(some_string); + return; + } + asprintf(&some_string, "%ld <%s> [%s] %s", ts, program, type, message); + ak_log_write_to_file(some_string); + if ( lmtype <= AK_DEBUG_LEVEL ) ak_log_print_log_line(some_string); +} + +void ak_log_exit(const char* program, char* message) +{ + ak_log_message(program, EXIT, message); +} + +void ak_log_warning(const char* program, char* message) +{ + ak_log_message(program, WARNING, message); +} + +void ak_log_debug(const char* program, char* message) +{ + ak_log_message(program, DEBUG, message); +} + +void ak_log_error(const char* program, char* message) +{ + ak_log_message(program, ERROR, message); +} + +void ak_log_info(const char* program, char* message) +{ + ak_log_message(program, INFO, message); +} + +void ak_log_test(const char* program, char* message) +{ + ak_log_message(program, TEST, message); +} diff --git a/c_implementation/src/ak_log_main.c b/c_implementation/src/ak_log_main.c new file mode 100644 index 0000000..abeb691 --- /dev/null +++ b/c_implementation/src/ak_log_main.c @@ -0,0 +1,32 @@ +#include +#include + +static int ak_log_usage() +{ + ak_log_info(__func__, "Available commands:"); + ak_log_info(__func__, " ak_log"); + return 1; +} + +int ak_log_main(int argc, char **argv) +{ + int option; + while ( (option = getopt(argc, argv, ":h|:help")) != -1 ) + { + switch(option) + { + case 'h': + return ak_log_usage(); + case ':': + return 1; + case '?': + return 2; + } + } + return 0; +} + +int main(int argc, char** argv) +{ + return ak_log_main(argc, argv); +} diff --git a/c_implementation/src/ak_logcatter.c b/c_implementation/src/ak_logcatter.c new file mode 100644 index 0000000..c002eda --- /dev/null +++ b/c_implementation/src/ak_logcatter.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +int ak_logcatter() +{ + printf("Testing: %s\n", __func__); + FILE *fp; + fp = fopen("/home/kaotisk/.arching-kaos/logs", "r"); + if (!fp) + { + perror("fopen"); + return EXIT_FAILURE; + } + char buffer[1] = {0}; + char line[1024] = {0}; + unsigned int i = 0; + while ( fread(buffer, sizeof(char), sizeof(char), fp) ) + { + if ( buffer[0] == '\n' ) + { + line[i] = '\0'; + ak_log_print_log_line(line); + i = 0; + } + else + { + line[i] = buffer[0]; + line[i+1] = '\0'; + i++; + } + } + fclose(fp); + return 0; +} diff --git a/c_implementation/src/ak_settings.c b/c_implementation/src/ak_settings.c new file mode 100644 index 0000000..324eda2 --- /dev/null +++ b/c_implementation/src/ak_settings.c @@ -0,0 +1,153 @@ +#include +#include +#include +#include +#include + +#define MAX_SETTINGS 100 + +AKSetting settings[MAX_SETTINGS]; +int settings_count = 0; + +AKSetting* ak_settings_get_all(){ + return settings; +} + +void ak_settings_import_from_environment() +{ + ak_settings_set_setting("AK_BINDIR",getenv("AK_BINDIR")); + ak_settings_set_setting("AK_BLOCKDIR",getenv("AK_BLOCKDIR")); + ak_settings_set_setting("AK_CACHEDIR",getenv("AK_CACHEDIR")); + ak_settings_set_setting("AK_CHUNKSDIR",getenv("AK_CHUNKSDIR")); + ak_settings_set_setting("AK_CONFIGDIR",getenv("AK_CONFIGDIR")); + ak_settings_set_setting("AK_DATADIR",getenv("AK_DATADIR")); + ak_settings_set_setting("AK_GENESIS",getenv("AK_GENESIS")); + ak_settings_set_setting("AK_GENESISASC",getenv("AK_GENESISASC")); + ak_settings_set_setting("AK_GPGHOME",getenv("AK_GPGHOME")); + ak_settings_set_setting("AK_IPFS",getenv("AK_IPFS")); + ak_settings_set_setting("AK_LEAFSDIR",getenv("AK_LEAFSDIR")); + ak_settings_set_setting("AK_LIBDIR",getenv("AK_LIBDIR")); + ak_settings_set_setting("AK_MAPSDIR",getenv("AK_MAPSDIR")); + ak_settings_set_setting("AK_MINEDBLOCKSDIR",getenv("AK_MINEDBLOCKSDIR")); + ak_settings_set_setting("AK_MODULESDIR",getenv("AK_MODULESDIR")); + ak_settings_set_setting("AK_ROOT",getenv("AK_ROOT")); + ak_settings_set_setting("AK_SETTINGS",getenv("AK_SETTINGS")); + ak_settings_set_setting("AK_WORKDIR",getenv("AK_WORKDIR")); + ak_settings_set_setting("AK_ZBLOCKDIR",getenv("AK_ZBLOCKDIR")); + ak_settings_set_setting("AK_ZBLOCKSFILE",getenv("AK_ZBLOCKSFILE")); + ak_settings_set_setting("AK_ZCHAIN",getenv("AK_ZCHAIN")); + ak_settings_set_setting("AK_ZCHAINASC",getenv("AK_ZCHAINASC")); + ak_settings_set_setting("AK_ZGENESIS",getenv("AK_ZGENESIS")); + ak_settings_set_setting("AK_ZGENESISASC",getenv("AK_ZGENESISASC")); + ak_settings_set_setting("AK_ZLATEST",getenv("AK_ZLATEST")); + ak_settings_set_setting("AK_ZLATEST_HISTORY",getenv("AK_ZLATEST_HISTORY")); + ak_settings_set_setting("AK_ZLIST",getenv("AK_ZLIST")); + ak_settings_set_setting("AK_ZPAIRSFILE",getenv("AK_ZPAIRSFILE")); + ak_settings_set_setting("AK_ZPEERSDIR",getenv("AK_ZPEERSDIR")); + ak_settings_set_setting("AK_ZPEERSFILE",getenv("AK_ZPEERSFILE")); + ak_settings_set_setting("AK_ZZCHAIN",getenv("AK_ZZCHAIN")); + ak_settings_set_setting("AK_ARCHIVESDIR",getenv("AK_ARCHIVESDIR")); +} + +bool ak_settings_write_string(FILE *file, const char *str) { + size_t len = strlen(str) + 1; // Include null terminator + if (fwrite(&len, sizeof(size_t), 1, file) != 1) return false; + if (fwrite(str, sizeof(char), len, file) != len) return false; + return true; +} + +char *ak_settings_read_string(FILE *file) { + size_t len; + if (fread(&len, sizeof(size_t), 1, file) != 1) return NULL; + char *str = malloc(len); + if (!str) return NULL; + if (fread(str, sizeof(char), len, file) != len) { + free(str); + return NULL; + } + return str; +} + +void ak_settings_free_settings() { + for (int i = 0; i < settings_count; i++) { + free(settings[i].key); + free(settings[i].value); + } + settings_count = 0; +} + +static int ak_settings_find_setting(const char *key) { + for (int i = 0; i < settings_count; i++) { + if (strcmp(settings[i].key, key) == 0) { + return i; + } + } + return -1; +} + +bool ak_settings_load_settings_binary() { + FILE *file = fopen("settings.bin", "rb"); + if (!file) return false; + if (fread(&settings_count, sizeof(int), 1, file) != 1) { + fclose(file); + return false; + } + for (int i = 0; i < settings_count; i++) { + settings[i].key = ak_settings_read_string(file); + settings[i].value = ak_settings_read_string(file); + if (!settings[i].key || !settings[i].value) { + ak_settings_free_settings(); + fclose(file); + return false; + } + } + fclose(file); + return true; +} + +bool ak_settings_save_settings_binary() { + FILE *file = fopen("settings.bin", "wb"); + if (!file) return false; + if (fwrite(&settings_count, sizeof(int), 1, file) != 1) { + fclose(file); + return false; + } + for (int i = 0; i < settings_count; i++) { + if (!ak_settings_write_string(file, settings[i].key)) { + fclose(file); + return false; + } + if (!ak_settings_write_string(file, settings[i].value)) { + fclose(file); + return false; + } + } + fclose(file); + return true; +} + +bool ak_settings_set_setting(const char *key, const char *value) { + int index = ak_settings_find_setting(key); + if (index == -1) { + if (settings_count >= MAX_SETTINGS) return false; + settings[settings_count].key = strdup(key); + settings[settings_count].value = strdup(value); + if (!settings[settings_count].key || !settings[settings_count].value) { + free(settings[settings_count].key); + free(settings[settings_count].value); + return false; + } + settings_count++; + } else { + char *new_value = strdup(value); + if (!new_value) return false; + free(settings[index].value); + settings[index].value = new_value; + } + return true; +} + +char *ak_settings_get_setting(const char *key) { + int index = ak_settings_find_setting(key); + return (index == -1) ? NULL : settings[index].value; +} diff --git a/c_implementation/src/ak_utils.c b/c_implementation/src/ak_utils.c new file mode 100644 index 0000000..d58e0a3 --- /dev/null +++ b/c_implementation/src/ak_utils.c @@ -0,0 +1,8 @@ +#include +#include + +int ak_utils() +{ + printf("Testing: %s\n", __func__); + return 0; +} diff --git a/c_implementation/src/akfs.c b/c_implementation/src/akfs.c deleted file mode 100644 index 0e362aa..0000000 --- a/c_implementation/src/akfs.c +++ /dev/null @@ -1,388 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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) ) - { - unsigned int i = 0; - char *result = malloc((128*2)+1); - if ( result == NULL ) - { - return ""; - } - while ( str[i] != '\0' ) - { - result[i*2] = str[i]; - if ( (i*2) + 1 <= 254 ) - { - result[(i*2)+1] = '/'; - } - else - { - result[(i*2)+1] = '\0'; - } - ++i; - } - return result; - } - else - { - return NULL; - } -} - -char* ak_fs_return_hash_dir(const char* str) -{ - if ( ak_fs_verify_input_is_hash(str) ) - { - unsigned int i = 0; - char *result = malloc((128*2)+1); - if ( result == NULL ) return ""; - while ( str[i] != '\0' ) - { - result[i*2] = str[i]; - if ( (i*2) + 1 <= 254-2 ) - { - result[(i*2)+1] = '/'; - } - else - { - result[(i*2)+1] = '\0'; - } - ++i; - } - return result; - } - else - { - return NULL; - } -} - -bool ak_fs_verify_input_is_hash(const char* str) -{ - size_t i = 0; - while ( str[i] != '\0' ) - { - if ( - i < 128 && - !( - ( str[i] >= 0x30 ) && - (( str[i] <= 0x39) || ( str[i] >= 0x61 )) && - ( str[i] <= 0x66 ) - ) - ) - { - return false; - } - else { - i++; - } - } - if ( i > 128 ) - { - return false; - } - return true; -} - -int ak_fs_create_dir_for_hash(const char* str) -{ - /* TODO - * Some aspects of this function - * 1. We need a "root" place to put our dirs into, this is not specified - * anywhere in this code but it is spartially specified in other files - * like lib/_ak_fs bash script and the rc/config file we currently source - * in $HOME/.bashrc - * 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) ) - { - char* dir_path = ak_fs_return_hash_dir(str); - // We will need to separate the string so we can create the path one - // directory at the time - int len = strlen(dir_path); - for ( int i = 0; i < len+1; ++i) - { - if ( dir_path[i] == '/' ) - { - //printf("%c\n", dir_path[i]); - //char* test = strndup(dir_path, i); - //printf("A: [i:%d] [c:%c] - %s\n", i, dir_path[i], test); - continue; - } - else - { - char* incremental_dir_path = strndup(dir_path, i+1); - // printf("B: [i:%d] [c:%c] - %s\n", i, dir_path[i], test); - struct stat sb; - if (stat(incremental_dir_path, &sb) == 0 && S_ISDIR(sb.st_mode)) - { - continue; - } - else - { - int return_code = mkdir(incremental_dir_path, 0777); - if ( return_code == 0 ) - { - continue; - } - else - { - // should be unreachable I guess since previous checks - // though it could be caused by some other kind of error - // like, no permission, or exists but is not a directory - // but a file, dev, char, pipe whatever this thing - // supports anyway - free(incremental_dir_path); - free(dir_path); - return -3; - } - } - free(incremental_dir_path); - } - } - free(dir_path); - return 0; - } - else - { - return -2; - } -} - -int ak_fs_convert_map_v3_string_to_struct(const char *str, size_t ssize, akfs_map_v3* map) -{ - 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_str[129] = {0}; - char root_hash_str[129] = {0}; - char filename[256] = {0}; - if ( map == 0x0 ) - { - printf("FAILED IN %s! : %p \n", __func__, (void*)map); - return 1; - } - for ( size_t i = 0; i < ssize; ++i) - { - if ( str[i] == ' ' ) - { - spaces_found++; - sa[spaces_found] = i; - } - if ( str[i] == '\n' ) - { - newlines_found++; - na[newlines_found] = i; - } - } - int si = 0; - for ( size_t i = 0; i < sa[1]; ++i) - { - original_hash_str[si] = str[i]; - si++; - } - original_hash_str[si] = '\0'; - if( !ak_fs_verify_input_is_hash(original_hash_str) ) - { - ak_log_error(__func__, "original_hash_str not a hash"); - return 1; - } - if ( ak_fs_sha512sum_string_to_struct(original_hash_str, &(map->oh)) != 0 ) - { - ak_log_error(__func__, "String convertion of original_hash_str"); - return 1; - } - si = 0; - for ( size_t i = na[1]+1; i < sa[3]; ++i) - { - root_hash_str[si] = str[i]; - si++; - } - root_hash_str[si] = '\0'; - if( !ak_fs_verify_input_is_hash(root_hash_str) ) - { - ak_log_error(__func__, "root_hash_str not a hash"); - return 1; - } - if ( ak_fs_sha512sum_string_to_struct(root_hash_str, &(map->rh)) != 0 ) - { - ak_log_error(__func__, "String convertion of root_hash_str"); - return 1; - } - si = 0; - if ( sa[2] < na[1] ) - { - for ( size_t i = sa[2]+1; i < na[1]; ++i) - { - filename[si] = str[i]; - si++; - } - filename[si] = '\0'; - } - strncpy(map->filename, filename, sizeof(map->filename)); - return 0; -} - -void ak_fs_get_available_maps_from_fs(sha512sum **ma, size_t length) -{ - DIR *d; - d = opendir(ak_fs_maps_v3_get_dir()); - sha512sum *ptr = NULL; - if (d) - { - for ( ptr = *ma; ptr < *ma+length; ++ptr) - { - 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); - } - } - 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) -{ - akfs_map_v3 *ptr = NULL; - for ( ptr = *map_store; ptr < *map_store + length; ++ptr) - { - if ( !ak_fs_map_v3_is_null(ptr) ) ak_fs_map_v3_print(ptr); - } -} - -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) - ); -} - -void ak_fs_print_available_maps(sha512sum **ma, size_t ma_len) -{ - sha512sum *ptr = NULL; - for ( ptr = *ma; ptr < *ma+ma_len; ++ptr) - { - ak_log_debug(__func__, ak_fs_sha512sum_struct_read_as_string(ptr)); - } - -} - -void ak_fs_init_string(char *str, size_t len) -{ - for (size_t i = 0; i < len; ++i) - { - str[i] = '\0'; - } -} - - -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) - { - 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 deleted file mode 100644 index da0c3d0..0000000 --- a/c_implementation/src/akfs_defuse.c +++ /dev/null @@ -1,97 +0,0 @@ -#define FUSE_USE_VERSION 31 -#include -#include -#include -#include -#include -#include -#include -#include - -// 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_main.c b/c_implementation/src/akfs_main.c deleted file mode 100644 index f1660cf..0000000 --- a/c_implementation/src/akfs_main.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include -#include - -static int ak_fs_usage() -{ - ak_log_debug(__func__, "Available commands:"); - ak_log_debug(__func__, "ak fs --list"); - return 1; -} - -int ak_fs_main(int argc, char** argv) -{ - int option;