Added an inefficient listing for entries

This commit is contained in:
Alexei KADIR 2024-02-17 12:55:21 +01:00
parent 2d1f228ad0
commit 36a1faf948
4 changed files with 123 additions and 4 deletions

View File

@ -8,6 +8,7 @@
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <libgen.h> #include <libgen.h>
#include <dirent.h>
#include <sys/stat.h> #include <sys/stat.h>
bool is_entry_id_valid(const char* entry_id) { bool is_entry_id_valid(const char* entry_id) {
@ -230,6 +231,79 @@ Result remove_entry(const char* entry_id) {
return SUCCESS; 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) { Result reset_entry(const char* entry_id) {
// Check that it exists // Check that it exists
bool exists; bool exists;

View File

@ -16,9 +16,9 @@ typedef enum {
ENTRY_TYPE_AUTOMATIC ENTRY_TYPE_AUTOMATIC
} EntryType; } EntryType;
#define ENTRY_TYPE_ROOT_STRING "root" #define ENTRY_TYPE_ROOT_STRING "ROOT"
#define ENTRY_TYPE_BACKED_STRING "backed" #define ENTRY_TYPE_BACKED_STRING "BACKED"
#define ENTRY_TYPE_AUTOMATIC_STRING "automatic" #define ENTRY_TYPE_AUTOMATIC_STRING "AUTOMATIC"
typedef struct { typedef struct {
EntryType type; EntryType type;
@ -103,6 +103,11 @@ Result reset_entry(const char* entry_id);
/// @return The result of the operation. /// @return The result of the operation.
Result update_entry(const char* entry_id); 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. /// @brief Gathers information about the given entry.
/// @param entry_id The entry id. /// @param entry_id The entry id.
/// @param out_info The pointer to the output entry information. /// @param out_info The pointer to the output entry information.

View File

@ -342,3 +342,34 @@ Result write_file(const char* path, const char* string) {
return result; 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);
}

View File

@ -1,5 +1,8 @@
#pragma once #pragma once
#include <stdbool.h>
#include <stdint.h>
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
typedef enum { typedef enum {
@ -64,4 +67,10 @@ Result write_fd(int fd, const char* string);
/// @param path The path of the file to write. /// @param path The path of the file to write.
/// @param string The string to write. /// @param string The string to write.
/// @return The result of the operation. /// @return The result of the operation.
Result write_file(const char* path, const char* string); 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);