diff options
Diffstat (limited to 'c_implementation/src/ak_fs.c')
-rw-r--r-- | c_implementation/src/ak_fs.c | 332 |
1 files changed, 332 insertions, 0 deletions
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 <stdio.h> +#include <unistd.h> +#include <stdbool.h> +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <libakfs.h> +#include <libaklog.h> +#include <libaksettings.h> +#include <sys/stat.h> +#include <dirent.h> + +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; +} |