#include "instance.h" #include #include #include #define CREATE_FILE_OR_THROW(inst, path, out_file) \ do { \ b_result result = b_file_open( \ inst->inst_root, \ B_RV_PATH(path), \ B_FILE_READ_WRITE | B_FILE_CREATE, \ out_file); \ \ if (b_result_is_error(result)) { \ return b_error_with_template_caused_by_error( \ ROPKG_ERROR_VENDOR, \ ROPKG_ERR_INSTANCE_DIR_CREATE_FAILED, \ result, \ B_ERROR_PARAM( \ "instancepath", \ b_directory_get_rel_path_cstr( \ inst->inst_root)), \ B_ERROR_PARAM("subdirpath", path)); \ } \ } while (0) #define CREATE_DIRECTORY_OR_THROW(inst, path, out_dir) \ do { \ b_result result = b_directory_open( \ inst->inst_root, \ B_RV_PATH(path), \ B_DIRECTORY_OPEN_CREATE_INTERMEDIATE, \ out_dir); \ \ if (b_result_is_error(result)) { \ return b_error_with_template_caused_by_error( \ ROPKG_ERROR_VENDOR, \ ROPKG_ERR_INSTANCE_DIR_CREATE_FAILED, \ result, \ B_ERROR_PARAM( \ "instancepath", \ b_directory_get_rel_path_cstr( \ inst->inst_root)), \ B_ERROR_PARAM("subdirpath", path)); \ } \ } while (0) static b_result bootstrap_base(struct ropkg_instance *instance) { CREATE_DIRECTORY_OR_THROW( instance, ROPKG_INSTANCE_DIRPATH_CACHE, &instance->inst_dir_cache); CREATE_DIRECTORY_OR_THROW( instance, ROPKG_INSTANCE_DIRPATH_CONFIG, &instance->inst_dir_config); CREATE_DIRECTORY_OR_THROW( instance, ROPKG_INSTANCE_DIRPATH_DATABASE, &instance->inst_dir_database); return B_RESULT_SUCCESS; } static b_result bootstrap_config(struct ropkg_instance *instance) { b_directory *dir; CREATE_DIRECTORY_OR_THROW( instance, ROPKG_INSTANCE_DIRPATH_CONFIG_COLLECTION, &dir); b_directory_release(dir); CREATE_DIRECTORY_OR_THROW( instance, ROPKG_INSTANCE_DIRPATH_SOURCES, &dir); b_directory_release(dir); return B_RESULT_SUCCESS; } static b_result bootstrap_cache(struct ropkg_instance *instance) { b_directory *dir; CREATE_DIRECTORY_OR_THROW( instance, ROPKG_INSTANCE_DIRPATH_ARCHIVES, &dir); b_directory_release(dir); return B_RESULT_SUCCESS; } static b_result bootstrap_database(struct ropkg_instance *instance) { b_file *file; CREATE_FILE_OR_THROW( instance, ROPKG_INSTANCE_FILEPATH_AVAILABLE, &file); b_file_release(file); CREATE_FILE_OR_THROW( instance, ROPKG_INSTANCE_FILEPATH_INSTALLED, &file); b_file_release(file); return B_RESULT_SUCCESS; } b_result ropkg_instance_open(const char *cpath, struct ropkg_instance **out) { struct ropkg_instance *inst = malloc(sizeof *inst); if (!inst) { return ROPKG_RESULT_ERR(NO_MEMORY); } memset(inst, 0x0, sizeof *inst); b_path *path = b_path_create_from_cstr(cpath); if (!path) { free(inst); return ROPKG_RESULT_ERR(NO_MEMORY); } b_result result = b_directory_open(NULL, path, 0, &inst->inst_root); b_path_release(path); if (b_result_is_error(result)) { free(inst); return b_result_propagate(result); } *out = inst; return ROPKG_RESULT_SUCCESS; } b_result ropkg_instance_bootstrap( const char *cpath, struct ropkg_instance **out) { struct ropkg_instance *inst = malloc(sizeof *inst); if (!inst) { return ROPKG_RESULT_ERR(NO_MEMORY); } memset(inst, 0x0, sizeof *inst); b_path *path = b_path_create_from_cstr(cpath); if (!path) { free(inst); return ROPKG_RESULT_ERR(NO_MEMORY); } b_result result = b_directory_open(NULL, path, 0, &inst->inst_root); b_path_release(path); if (b_result_is_error(result)) { free(inst); return b_error_with_template_caused_by_error( ROPKG_ERROR_VENDOR, ROPKG_ERR_DIR_OPEN_FAILED, result, B_ERROR_PARAM("filepath", cpath)); } result = bootstrap_base(inst); if (b_result_is_error(result)) { return b_result_propagate(result); } result = bootstrap_config(inst); if (b_result_is_error(result)) { return b_result_propagate(result); } result = bootstrap_cache(inst); if (b_result_is_error(result)) { return b_result_propagate(result); } result = bootstrap_database(inst); if (b_result_is_error(result)) { return b_result_propagate(result); } *out = inst; return B_RESULT_SUCCESS; }