177 lines
4.1 KiB
C
177 lines
4.1 KiB
C
#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 <dirent.h>
|
|
#include <errno.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
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;
|
|
}
|