#include "amduat/asl/asl_store_index_fs.h" #include "amduat/asl/store.h" #include "amduat/enc/asl1_core.h" #include "amduat/hash/asl1.h" #include #include #include #include #include #include #include #include #include #include static bool join_path(const char *base, const char *segment, char **out_path) { size_t base_len; size_t seg_len; bool needs_sep; size_t total_len; char *buffer; size_t offset; if (base == NULL || segment == NULL || out_path == NULL) { return false; } base_len = strlen(base); seg_len = strlen(segment); if (base_len == 0u || seg_len == 0u) { return false; } needs_sep = base[base_len - 1u] != '/'; total_len = base_len + (needs_sep ? 1u : 0u) + seg_len + 1u; buffer = (char *)malloc(total_len); if (buffer == NULL) { return false; } offset = 0u; memcpy(buffer + offset, base, base_len); offset += base_len; if (needs_sep) { buffer[offset++] = '/'; } memcpy(buffer + offset, segment, seg_len); offset += seg_len; buffer[offset] = '\0'; *out_path = buffer; return true; } static bool remove_tree(const char *path) { struct stat st; DIR *dir; struct dirent *entry; if (path == NULL) { return false; } if (lstat(path, &st) != 0) { return errno == ENOENT; } if (!S_ISDIR(st.st_mode)) { return unlink(path) == 0; } dir = opendir(path); if (dir == NULL) { return false; } while ((entry = readdir(dir)) != NULL) { char *child = NULL; if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { continue; } if (!join_path(path, entry->d_name, &child)) { closedir(dir); return false; } if (!remove_tree(child)) { free(child); closedir(dir); return false; } free(child); } if (closedir(dir) != 0) { return false; } return rmdir(path) == 0; } static char *make_temp_root(void) { char *tmpl = NULL; char *root = NULL; tmpl = strdup("/tmp/amduat-index-putget-XXXXXX"); if (tmpl == NULL) { return NULL; } if (mkdtemp(tmpl) == NULL) { free(tmpl); return NULL; } root = tmpl; return root; } int main(void) { amduat_asl_store_config_t config; amduat_asl_store_index_fs_t fs; amduat_asl_store_t store; char *root = NULL; int rc = 1; size_t i; root = make_temp_root(); if (root == NULL) { fprintf(stderr, "temp root creation failed\n"); return 1; } memset(&config, 0, sizeof(config)); config.encoding_profile_id = AMDUAT_ENC_ASL1_CORE_V1; config.hash_id = AMDUAT_HASH_ASL1_ID_SHA256; if (!amduat_asl_store_index_fs_init(&fs, config, root)) { fprintf(stderr, "index fs init failed\n"); goto cleanup; } amduat_asl_store_init(&store, config, amduat_asl_store_index_fs_ops(), &fs); for (i = 0u; i < 128u; ++i) { char payload_buf[64]; size_t payload_len; amduat_artifact_t artifact; amduat_reference_t ref; amduat_artifact_t loaded; amduat_asl_store_error_t err; payload_len = (size_t)snprintf(payload_buf, sizeof(payload_buf), "payload-%zu", i); if (payload_len == 0u || payload_len >= sizeof(payload_buf)) { fprintf(stderr, "payload format failed at %zu\n", i); goto cleanup; } artifact = amduat_artifact( amduat_octets((const uint8_t *)payload_buf, payload_len)); ref = amduat_reference(0u, amduat_octets(NULL, 0u)); err = amduat_asl_store_put(&store, artifact, &ref); if (err != AMDUAT_ASL_STORE_OK) { fprintf(stderr, "put failed at %zu: %d\n", i, (int)err); goto cleanup; } loaded = amduat_artifact(amduat_octets(NULL, 0u)); err = amduat_asl_store_get(&store, ref, &loaded); if (err != AMDUAT_ASL_STORE_OK) { fprintf(stderr, "get after put failed at %zu: %d\n", i, (int)err); amduat_reference_free(&ref); goto cleanup; } amduat_artifact_free(&loaded); amduat_reference_free(&ref); } rc = 0; cleanup: if (root != NULL) { if (!remove_tree(root)) { fprintf(stderr, "warning: cleanup failed for %s\n", root); } free(root); } return rc; }