#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, strlen(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, strlen(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 len) { size_t i = 0; printf("%s: this %lu is %lu: %s\n", __func__, i, len, str); if (len != 128) { ak_log_debug(__func__, "Hash string length not right"); return false; } while ( str[i] != '\0' ) { if ( i < 128 && !( ( str[i] >= 0x30 ) && ( str[i] <= 0x39 || str[i] >= 0x61 ) && ( str[i] <= 0x66 ) ) ) { ak_log_debug(__func__, "Char out of range"); return false; } else { i++; } } if ( i > 128 ) { ak_log_debug(__func__, "String exceeds limit"); return false; } ak_log_debug(__func__, "String okay"); 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, 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 // 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, strlen(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, strlen(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_maps_v3_get_from_fs(akfs_map_v3 **ma, size_t length) { (void)length; DIR *d; d = opendir(ak_fs_maps_v3_get_dir()); akfs_map_v3 *ptr = NULL; ptr = *ma; ak_log_debug(__func__, "gonna if"); if (d) { ak_log_debug(__func__, "in if"); const struct dirent *dir; while((dir = readdir(d)) != NULL ) { ak_log_debug(__func__, "in while"); // if ( ptr >= *ma+length ) break; printf("iMH: %s\n", dir->d_name); if (!ak_fs_verify_input_is_hash(dir->d_name, 128)) continue; ak_fs_sha512sum_string_to_struct(dir->d_name, &(ptr->mh)); ++ptr; } ak_log_debug(__func__, "out while"); } ak_log_debug(__func__, "out if"); closedir(d); } int ak_fs_map_v3_resolve_maps(akfs_map_v3 **ms, size_t ms_len) { akfs_map_v3 *ptr = NULL; // char s[129] = {0}; printf("%s: %lu\n", __func__, ms_len); for ( ptr = *ms; ptr < *ms+ms_len; ++ptr) { printf("MH: %s\n", ak_fs_sha512sum_struct_read_as_string(&(ptr->mh))); if ( ak_fs_sha512sum_is_null(&(ptr->mh)) ) { ak_log_debug(__func__, "map hash is null"); continue; } if( ak_fs_map_v3_open_from_file(ptr) != 2) { ak_log_debug(__func__, "not 2"); ++(ptr); continue; } else { ak_log_debug(__func__, "2"); ++(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); ak_fs_maps_v3_get_from_fs(&maps_ptr, len); ak_fs_maps_v3_print(&maps_ptr, len); 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; }