From 36a1faf94819dd17b65be43ab5a3534675bb19ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexe=C3=AF=20KADIR?= Date: Sat, 17 Feb 2024 12:55:21 +0100 Subject: [PATCH] Added an inefficient listing for entries --- src/entry.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/entry.h | 11 +++++--- src/utils.c | 31 ++++++++++++++++++++++ src/utils.h | 11 +++++++- 4 files changed, 123 insertions(+), 4 deletions(-) diff --git a/src/entry.c b/src/entry.c index 7785016..522371d 100644 --- a/src/entry.c +++ b/src/entry.c @@ -8,6 +8,7 @@ #include #include #include +#include #include bool is_entry_id_valid(const char* entry_id) { @@ -230,6 +231,79 @@ Result remove_entry(const char* entry_id) { return SUCCESS; } +Result list_entries(char*** out_entries) { + *out_entries = malloc(sizeof(char*)); + if (*out_entries == NULL) { + log_message(LOG_LEVEL_ERROR, "Failed to allocate memory for the entries."); + return OUT_OF_MEMORY; + } + + (*out_entries)[0] = NULL; + + // Open the directory + DIR* dir = opendir(ENTRY_POOL_DIR); + if (dir == NULL) { + log_message(LOG_LEVEL_ERROR, "Failed to open the directory '%s' (%s).", ENTRY_POOL_DIR, strerror(errno)); + return FAILURE; + } + + // Read the directory + int entry_count = 0; + + struct dirent* entry; + + while ((entry = readdir(dir)) != NULL) { + // Skip the current and parent directories + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) + continue; + + // Check that the entry exists + bool exists; + Result result = entry_exists(entry->d_name, &exists); + if (result != SUCCESS || !exists) + continue; + + // Reallocate the entries array + // TODO: More efficient reallocation + char** new_entries = realloc(*out_entries, (entry_count + 2) * sizeof(char*)); + if (new_entries == NULL) { + log_message(LOG_LEVEL_ERROR, "Failed to allocate memory for the entries."); + closedir(dir); + + for (int i = 0; i < entry_count; i++) + free((*out_entries)[i]); + free(*out_entries); + + return OUT_OF_MEMORY; + } + + *out_entries = new_entries; + + // Copy the entry name + (*out_entries)[entry_count] = strdup(entry->d_name); + if ((*out_entries)[entry_count] == NULL) { + log_message(LOG_LEVEL_ERROR, "Failed to allocate memory for the entry name."); + closedir(dir); + + for (int i = 0; i < entry_count; i++) + free((*out_entries)[i]); + free(*out_entries); + + return OUT_OF_MEMORY; + } + + // Null-terminate the array + (*out_entries)[entry_count + 1] = NULL; + + entry_count++; + } + + // Close the directory + closedir(dir); + + return SUCCESS; +} + Result reset_entry(const char* entry_id) { // Check that it exists bool exists; diff --git a/src/entry.h b/src/entry.h index 03a9ae5..3731dae 100644 --- a/src/entry.h +++ b/src/entry.h @@ -16,9 +16,9 @@ typedef enum { ENTRY_TYPE_AUTOMATIC } EntryType; -#define ENTRY_TYPE_ROOT_STRING "root" -#define ENTRY_TYPE_BACKED_STRING "backed" -#define ENTRY_TYPE_AUTOMATIC_STRING "automatic" +#define ENTRY_TYPE_ROOT_STRING "ROOT" +#define ENTRY_TYPE_BACKED_STRING "BACKED" +#define ENTRY_TYPE_AUTOMATIC_STRING "AUTOMATIC" typedef struct { EntryType type; @@ -103,6 +103,11 @@ Result reset_entry(const char* entry_id); /// @return The result of the operation. Result update_entry(const char* entry_id); +/// @brief Checks whether the given entry needs to be updated, and updates it if needed. This function will only update automatic entries. +/// @param entry_id The entry id. +/// @return The result of the operation. +Result check_update_entry(const char* entry_id); + /// @brief Gathers information about the given entry. /// @param entry_id The entry id. /// @param out_info The pointer to the output entry information. diff --git a/src/utils.c b/src/utils.c index b7c69aa..d1a3dcd 100644 --- a/src/utils.c +++ b/src/utils.c @@ -342,3 +342,34 @@ Result write_file(const char* path, const char* string) { return result; } + +Result format_size(uint64_t size, char** out_string) { + *out_string = NULL; + + // Determine the unit + const char* unit; + double value; + + if (size < 1024ULL) { + unit = "B"; + value = size; + } else if (size < 1024ULL * 1024) { + unit = "KiB"; + value = (double)size / 1024; + } else if (size < 1024ULL * 1024 * 1024) { + unit = "MiB"; + value = (double)size / (1024 * 1024); + } else if (size < 1024ULL * 1024 * 1024 * 1024) { + unit = "GiB"; + value = (double)size / (1024 * 1024 * 1024); + } else if (size < 1024ULL * 1024 * 1024 * 1024 * 1024) { + unit = "TiB"; + value = (double)size / (1024 * 1024 * 1024 * 1024); + } else { + unit = "PiB"; + value = (double)size / (1024 * 1024 * 1024 * 1024 * 1024); + } + + // Format the string + return format(out_string, "%.2f%s", value, unit); +} diff --git a/src/utils.h b/src/utils.h index c952661..d41dadf 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,5 +1,8 @@ #pragma once +#include +#include + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) typedef enum { @@ -64,4 +67,10 @@ Result write_fd(int fd, const char* string); /// @param path The path of the file to write. /// @param string The string to write. /// @return The result of the operation. -Result write_file(const char* path, const char* string); \ No newline at end of file +Result write_file(const char* path, const char* string); + +/// @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