#include "entry.h" #include "utils.h" #include "disk.h" #include #include #include #include #include bool is_entry_id_valid(const char* entry_id) { if (entry_id == NULL) return false; size_t length = strlen(entry_id); // Check that the length is valid if (length == 0 || length > MAX_ENTRY_LENGTH) return false; // Check that the entry id does not contain any slashes for (size_t i = 0; i < length; i++) if (entry_id[i] == '/') return false; // Check that the entry id is not a reserved name if (strcmp(entry_id, ".") == 0 || strcmp(entry_id, "..") == 0) return false; return true; } Result get_entry_path(const char* entry_id, char** out_path) { *out_path = NULL; // Check that the entry id is valid if (!is_entry_id_valid(entry_id)) { log_message(LOG_LEVEL_ERROR, "Invalid entry id '%s'.", entry_id); return FAILURE; } return format(out_path, "%s/%s", ENTRY_POOL_DIR, entry_id); } Result entry_exists(const char* entry_id, bool* out_exists) { *out_exists = false; // Get the path of the entry char* path; Result result = get_entry_path(entry_id, &path); if (result != SUCCESS) return result; // Check if the entry exists and is a directory struct stat st; bool exists = stat(path, &st) == 0 && S_ISDIR(st.st_mode); // Free the path free(path); // Output the result *out_exists = exists; return SUCCESS; } Result add_root_entry(const char* entry_id, uint64_t size) { // Check that the entry does not exist bool exists; Result result = entry_exists(entry_id, &exists); if (result != SUCCESS) return result; if (exists) { log_message(LOG_LEVEL_ERROR, "Entry '%s' already exists.", entry_id); return FAILURE; } // Get the path of the entry char* path; result = get_entry_path(entry_id, &path); if (result != SUCCESS) return result; // Create the directory int return_code = mkdir(path, 0755); // Free the path as it is no longer needed free(path); // Check if the directory was created if (return_code != 0) { log_message(LOG_LEVEL_ERROR, "Failed to create the entry '%s' (%s).", entry_id, strerror(errno)); return FAILURE; } // Get the disk path char* disk_path; result = get_entry_disk_path(entry_id, &disk_path); if (result != SUCCESS) { remove_entry(entry_id); return result; } // Create the disk result = create_root_disk(disk_path, size, 0644); // Free the disk path as it is no longer needed free(disk_path); // Remove the entry if the disk could not be created if (result != SUCCESS) { remove_entry(entry_id); return result; } return SUCCESS; } Result remove_entry(const char* entry_id) { // Remove the disk char* disk_path; Result result = get_entry_disk_path(entry_id, &disk_path); if (result == SUCCESS) { unlink(disk_path); free(disk_path); } // Get the path of the entry char* path; result = get_entry_path(entry_id, &path); if (result != SUCCESS) return result; // Remove the directory int return_code = rmdir(path); // Free the path as it is no longer needed free(path); // Check if the directory was removed if (return_code != 0) { log_message(LOG_LEVEL_ERROR, "Failed to remove the entry '%s' (%s).", entry_id, strerror(errno)); return FAILURE; } return SUCCESS; } Result get_entry_disk_path(const char* entry_id, char** out_path) { *out_path = NULL; // Get the path of the entry char* path; Result result = get_entry_path(entry_id, &path); if (result != SUCCESS) return result; // Format the disk path result = format(out_path, "%s/disk", path); // Free the path as it is no longer needed free(path); return result; }