diff --git a/src/backing.c b/src/backing.c index 5a4a3b9..f49967b 100644 --- a/src/backing.c +++ b/src/backing.c @@ -1,5 +1,7 @@ #include "backing.h" +#include "entry.h" + #include #include #include @@ -61,3 +63,4 @@ Result backing_exists(const char* backing_id, bool* out_exists) { return SUCCESS; } + diff --git a/src/backing.h b/src/backing.h index 3da1884..ac97d1d 100644 --- a/src/backing.h +++ b/src/backing.h @@ -9,19 +9,49 @@ #define BACKING_POOL_DIR "/var/lib/sandbox/backings" #define MAX_BACKING_LENGTH 256 -/// @brief Checks whether the given backing id is valid. -/// @param backing_id The backing id to check. -/// @return True if the backing id is valid, false otherwise. +typedef struct { + DiskInfo disk_info; +} BackingInfo; + +/// @brief Checks whether the given backing disk id is valid. +/// @param backing_id The backing disk id to check. +/// @return True if the backing disk id is valid, false otherwise. bool is_valid_backing_id(const char* backing_id); -/// @brief Gets the path of the given backing. -/// @param backing_id The backing id. +/// @brief Gets the path of the given backing disk. +/// @param backing_id The backing disk id. /// @param out_path The pointer to the output path string. The caller is responsible for freeing the memory. /// @return The result of the operation. Result get_backing_path(const char* backing_id, char** out_path); -/// @brief Checks whether the given backing exists in the pool. -/// @param backing_id The backing id. +/// @brief Checks whether the given backing disk exists in the pool. +/// @param backing_id The backing disk id. /// @param out_exists The pointer to the output boolean. /// @return The result of the operation. -Result backing_exists(const char* backing_id, bool* out_exists); \ No newline at end of file +Result backing_exists(const char* backing_id, bool* out_exists); + +/// @brief Adds a backing disk to the pool from an entry. +/// @param backing_id The backing disk id. +/// @param entry_id The entry id. +/// @return The result of the operation. +Result add_backing_from_entry(const char* backing_id, const char* entry_id); + +/// @brief Removes a backing disk from the pool, and removes any backing disks that uses it. +/// @param backing_id The backing disk id. +/// @return The result of the operation. +Result remove_backing(const char* backing_id); + +/// @brief Lists the backing disks in the pool. +/// @param out_backings The pointer to the null-terminated array of backing disk ids. The caller is responsible for freeing the memory of the array and its elements. +/// @return The result of the operation. +Result list_backings(char*** out_backings, size_t* out_count); + +/// @brief Gathers information about a backing disk. +/// @param backing_id The backing disk id. +/// @param out_info The information about the backing disk. +/// @return The result of the operation. +Result get_backing_info(const char* backing_id, BackingInfo* out_info); + +/// @brief Frees the resources used by the given backing disk information. +/// @param info The backing disk information to free. +void free_backing_info(BackingInfo* info); \ No newline at end of file diff --git a/src/entry.h b/src/entry.h index d29c7e6..ac97dd5 100644 --- a/src/entry.h +++ b/src/entry.h @@ -85,7 +85,7 @@ Result add_automatic_entry(const char* entry_id); Result remove_entry(const char* entry_id); /// @brief Lists the entries in the pool. -/// @param out_entries The pointer to the output entries string. The caller is responsible for freeing the memory of the strings and the array. +/// @param out_entries The pointer to the null-terminated array of entry ids. The caller is responsible for freeing the memory of the array and its elements. /// @return The result of the operation. Result list_entries(char*** out_entries); diff --git a/src/utils.c b/src/utils.c index d1a3dcd..944c9f6 100644 --- a/src/utils.c +++ b/src/utils.c @@ -343,6 +343,60 @@ Result write_file(const char* path, const char* string) { return result; } +Result copy_file(const char* src_path, const char* dst_path, mode_t mode) { + // Open the source file + int src_fd = open(src_path, O_RDONLY); + if (src_fd == -1) { + log_message(LOG_LEVEL_ERROR, "Failed to open the source file '%s' (%s).", src_path, strerror(errno)); + return FAILURE; + } + + // Open the destination file + int dst_fd = open(dst_path, O_WRONLY | O_CREAT | O_TRUNC, mode); + if (dst_fd == -1) { + log_message(LOG_LEVEL_ERROR, "Failed to open the destination file '%s' (%s).", dst_path, strerror(errno)); + + close(src_fd); + return FAILURE; + } + + // Copy the file + char buffer[4096]; + ssize_t bytes_read; + + while ((bytes_read = read(src_fd, buffer, sizeof(buffer))) > 0) { + ssize_t bytes_written = 0; + + while (bytes_written < bytes_read) { + ssize_t result = write(dst_fd, buffer + bytes_written, bytes_read - bytes_written); + if (result == -1) { + log_message(LOG_LEVEL_ERROR, "Failed to write to the destination file '%s' (%s).", dst_path, strerror(errno)); + + close(src_fd); + close(dst_fd); + return FAILURE; + } + + bytes_written += result; + } + } + + // Check if an error occurred + if (bytes_read == -1) { + log_message(LOG_LEVEL_ERROR, "Failed to read from the source file '%s' (%s).", src_path, strerror(errno)); + + close(src_fd); + close(dst_fd); + return FAILURE; + } + + // Close the files + close(src_fd); + close(dst_fd); + + return SUCCESS; +} + Result format_size(uint64_t size, char** out_string) { *out_string = NULL; diff --git a/src/utils.h b/src/utils.h index d41dadf..ab55e7f 100644 --- a/src/utils.h +++ b/src/utils.h @@ -2,6 +2,7 @@ #include #include +#include #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -69,8 +70,15 @@ Result write_fd(int fd, const char* string); /// @return The result of the operation. Result write_file(const char* path, const char* string); +/// @brief Copies a file. +/// @param src_path The path of the source file. +/// @param dst_path The path of the destination file. +/// @param mode The mode of the destination file. +/// @return The result of the operation. +Result copy_file(const char* src_path, const char* dst_path, mode_t mode); + /// @brief Converts a size in bytes to a human-readable string. /// @param size The size in bytes. /// @param out_string The pointer to the output string. The caller is responsible for freeing the memory. /// @return The result of the operation. -Result format_size(uint64_t size, char** out_string); \ No newline at end of file +Result format_size(uint64_t size, char** out_string);