diff --git a/src/backing.c b/src/backing.c index 773d256..aab8fe1 100644 --- a/src/backing.c +++ b/src/backing.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include char* get_backings_path(void) { @@ -182,3 +184,44 @@ char* find_latest_backing(void) { return latest_backing; } + +bool create_backing(const char* disk, const char* description) { + // Create the backing disk name + uint64_t timestamp = (uint64_t)time(NULL); + char* backing_name = NULL; + + if (description == NULL || strlen(description) == 0) + backing_name = format("%lu", timestamp); + else + backing_name = format("%lu-%s", timestamp, description); + + if (backing_name == NULL) { + log_msg(LOG_ERROR, "Failed to create the backing disk name."); + return false; + } + + // Create the backing disk path + char* backings_path = get_backings_path(); + if (backings_path == NULL) { + free(backing_name); + return false; + } + + char* backing_path = format("%s/%s", backings_path, backing_name); + free(backing_name); + free(backings_path); + + if (backing_path == NULL) + return false; + + // Copy the disk to the backing disk + if (!copy_file(disk, backing_path, 0755, 0, 0)) { + free(backing_path); + return false; + } + + // Free the backing disk path + free(backing_path); + + return true; +} diff --git a/src/backing.h b/src/backing.h index 962e5f0..0e5d0d0 100644 --- a/src/backing.h +++ b/src/backing.h @@ -36,7 +36,7 @@ uint64_t get_backing_creation_time(const char* backing); char* find_latest_backing(void); /// @brief Creates a new backing disk. -/// @param backing_disk The disk to use as the backing disk. Warning: the disk must be part of the backing disks. +/// @param disk The disk to use as the backing disk. Warning: the disk must be part of the backing disks. /// @param description The description of the backing disk. /// @return true if the backing disk was created, otherwise false. -bool create_backing(const char* backing_disk, const char* description); \ No newline at end of file +bool create_backing(const char* disk, const char* description); \ No newline at end of file diff --git a/src/entry.c b/src/entry.c index 62ede8e..e20bf1d 100644 --- a/src/entry.c +++ b/src/entry.c @@ -237,3 +237,20 @@ uint64_t get_available_space(void) { return statbuf.f_bsize * statbuf.f_bavail; } + +bool reserve_space(uint64_t space) { + // While the available space is not enough, delete the oldest entry + while (get_available_space() < space) { + char* oldest_entry = find_oldest_entry(); + if (oldest_entry == NULL) + return false; + + bool result = delete_entry(oldest_entry); + free(oldest_entry); + + if (!result) + return false; + } + + return true; +} diff --git a/src/sandbox.c b/src/sandbox.c index fbfb88e..f806c40 100644 --- a/src/sandbox.c +++ b/src/sandbox.c @@ -14,8 +14,18 @@ #include int main(int argc, char* argv[]) { - while (1) { - char* oldest_entry = find_oldest_entry(); - free(oldest_entry); + char** backings = list_backings(); + + if (backings == NULL) { + fprintf(stderr, "Failed to list the backing disks: %s\n", strerror(errno)); + return EXIT_FAILURE; } + + for (size_t i = 0; backings[i] != NULL; i++) + printf("%s\n", backings[i]); + + for (size_t i = 0; backings[i] != NULL; i++) + free(backings[i]); + + free(backings); } \ No newline at end of file diff --git a/src/utils.c b/src/utils.c index c8a8d0e..8dc47db 100755 --- a/src/utils.c +++ b/src/utils.c @@ -359,3 +359,49 @@ bool delete_directory(const char* directory, int level) { return true; } + +bool copy_file(const char* source, const char* destination, mode_t mode, uid_t uid, gid_t gid) { + // Open the source file + FILE* source_file = fopen(source, "r"); + if (source_file == NULL) { + log_msg(LOG_ERROR, "Failed to open file '%s' for reading (%s).", source, strerror(errno)); + return false; + } + + // Open the destination file + FILE* destination_file = fopen(destination, "w"); + if (destination_file == NULL) { + log_msg(LOG_ERROR, "Failed to open file '%s' for writing (%s).", destination, strerror(errno)); + fclose(source_file); + return false; + } + + // Copy the file + char buffer[4096]; + size_t bytes_read; + while ((bytes_read = fread(buffer, 1, sizeof(buffer), source_file)) > 0) + if (fwrite(buffer, 1, bytes_read, destination_file) != bytes_read) { + log_msg(LOG_ERROR, "Failed to write to file '%s' (%s).", destination, strerror(errno)); + fclose(source_file); + fclose(destination_file); + return false; + } + + // Close the files + fclose(source_file); + fclose(destination_file); + + // Change the mode of the destination file + if (chmod(destination, mode) != 0) { + log_msg(LOG_ERROR, "Failed to change the mode of file '%s' (%s).", destination, strerror(errno)); + return false; + } + + // Change the owner of the destination file + if (chown(destination, uid, gid) != 0) { + log_msg(LOG_ERROR, "Failed to change the owner of file '%s' (%s).", destination, strerror(errno)); + return false; + } + + return true; +} diff --git a/src/utils.h b/src/utils.h index c31ff7a..74b08a8 100755 --- a/src/utils.h +++ b/src/utils.h @@ -47,3 +47,12 @@ bool create_directory(const char* directory, mode_t mode, uid_t uid, gid_t gid); /// @param level The current level of recursion. This parameter is used internally and should be set to 0. /// @return true if the directory was deleted, otherwise false. bool delete_directory(const char* directory, int level); + +/// @brief Copies the specified file to the specified destination. +/// @param source The source file to copy. +/// @param destination The destination file. +/// @param mode The mode to use when creating the destination file. +/// @param uid The user ID to use when creating the destination file. +/// @param gid The group ID to use when creating the destination file. +/// @return true if the file was copied, otherwise false. +bool copy_file(const char* source, const char* destination, mode_t mode, uid_t uid, gid_t gid); \ No newline at end of file