Implemented the add-entry command
This commit is contained in:
parent
8821519a12
commit
f0dd2ca5fb
54
src/entry.c
54
src/entry.c
@ -199,6 +199,18 @@ Result add_root_entry(const char* entry_id, uint64_t size) {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
Result add_backed_entry(const char* entry_id, const char* backing_id) {
|
||||
// TODO: Implement
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
Result add_automatic_entry(const char* entry_id) {
|
||||
// TODO: Implement
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
Result remove_entry(const char* entry_id) {
|
||||
// Check that it exists
|
||||
bool exists;
|
||||
@ -217,6 +229,48 @@ Result remove_entry(const char* entry_id) {
|
||||
if (result != SUCCESS)
|
||||
return result;
|
||||
|
||||
// Remove all the files in the directory
|
||||
DIR* dir = opendir(entry_path);
|
||||
if (dir == NULL) {
|
||||
log_message(LOG_LEVEL_ERROR, "Failed to open the directory '%s' (%s).", entry_path, strerror(errno));
|
||||
|
||||
free(entry_path);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// Get the path of the file
|
||||
char* file_path;
|
||||
result = format(&file_path, "%s/%s", entry_path, entry->d_name);
|
||||
if (result != SUCCESS) {
|
||||
closedir(dir);
|
||||
free(entry_path);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Remove the file
|
||||
if (unlink(file_path) == -1) {
|
||||
log_message(LOG_LEVEL_ERROR, "Failed to remove the file '%s' (%s).", file_path, strerror(errno));
|
||||
|
||||
free(file_path);
|
||||
closedir(dir);
|
||||
free(entry_path);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// Free the entry file path
|
||||
free(file_path);
|
||||
}
|
||||
|
||||
// Close the directory
|
||||
closedir(dir);
|
||||
|
||||
// Remove the directory
|
||||
if (rmdir(entry_path) == -1) {
|
||||
log_message(LOG_LEVEL_ERROR, "Failed to remove the directory '%s' (%s).", entry_path, strerror(errno));
|
||||
|
@ -119,7 +119,71 @@ int command_version(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
int command_add_entry(int argc, char* argv[]) {
|
||||
// TODO: Call add_root_entry or add_backed_entry depending on the options
|
||||
// Extract the primary arguments
|
||||
if (argc < 1) {
|
||||
log_message(LOG_LEVEL_ERROR, "Missing entry id.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
const char* entry_id = argv[0];
|
||||
|
||||
// Extract the options
|
||||
bool is_root = false;
|
||||
uint64_t size = 0;
|
||||
|
||||
bool is_backed = false;
|
||||
const char* backing_id = NULL;
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--root") == 0 || strcmp(argv[i], "-r") == 0) {
|
||||
if (is_backed) {
|
||||
log_message(LOG_LEVEL_ERROR, "Cannot specify both --root and --backed options.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
is_root = true;
|
||||
|
||||
if (i + 1 >= argc) {
|
||||
log_message(LOG_LEVEL_ERROR, "Missing size for root entry.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
Result result = parse_size(argv[i + 1], &size);
|
||||
if (result != SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
i++; // Consume the next argument
|
||||
} else if (strcmp(argv[i], "--backed") == 0 || strcmp(argv[i], "-b") == 0) {
|
||||
if (is_root) {
|
||||
log_message(LOG_LEVEL_ERROR, "Cannot specify both --root and --backed options.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
is_backed = true;
|
||||
|
||||
if (i + 1 >= argc) {
|
||||
log_message(LOG_LEVEL_ERROR, "Missing backing id for backed entry.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
backing_id = argv[i + 1];
|
||||
i++; // Consume the next argument
|
||||
} else {
|
||||
log_message(LOG_LEVEL_ERROR, "Unknown option '%s'.", argv[i]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
Result result;
|
||||
if (is_root)
|
||||
result = add_root_entry(entry_id, size);
|
||||
else if (is_backed)
|
||||
result = add_backed_entry(entry_id, backing_id);
|
||||
else
|
||||
result = add_automatic_entry(entry_id);
|
||||
|
||||
if (result != SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
37
src/utils.c
37
src/utils.c
@ -427,3 +427,40 @@ Result format_size(uint64_t size, char** out_string) {
|
||||
// Format the string
|
||||
return format(out_string, "%.2f%s", value, unit);
|
||||
}
|
||||
|
||||
Result parse_size(const char* string, uint64_t* out_size) {
|
||||
// Parse the size
|
||||
char* endptr;
|
||||
uint64_t size = strtoull(string, &endptr, 10);
|
||||
|
||||
if (endptr == string) {
|
||||
log_message(LOG_LEVEL_ERROR, "Failed to parse the size '%s'.", string);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// Determine the unit
|
||||
if (*endptr == '\0') {
|
||||
// No unit
|
||||
*out_size = size;
|
||||
} else if (strcmp(endptr, "K") == 0 || strcmp(endptr, "KB") == 0 || strcmp(endptr, "KiB") == 0) {
|
||||
// Kilobytes
|
||||
*out_size = size * 1024;
|
||||
} else if (strcmp(endptr, "M") == 0 || strcmp(endptr, "MB") == 0 || strcmp(endptr, "MiB") == 0) {
|
||||
// Megabytes
|
||||
*out_size = size * 1024 * 1024;
|
||||
} else if (strcmp(endptr, "G") == 0 || strcmp(endptr, "GB") == 0 || strcmp(endptr, "GiB") == 0) {
|
||||
// Gigabytes
|
||||
*out_size = size * 1024 * 1024 * 1024;
|
||||
} else if (strcmp(endptr, "T") == 0 || strcmp(endptr, "TB") == 0 || strcmp(endptr, "TiB") == 0) {
|
||||
// Terabytes
|
||||
*out_size = size * 1024 * 1024 * 1024 * 1024;
|
||||
} else if (strcmp(endptr, "P") == 0 || strcmp(endptr, "PB") == 0 || strcmp(endptr, "PiB") == 0) {
|
||||
// Petabytes
|
||||
*out_size = size * 1024 * 1024 * 1024 * 1024 * 1024;
|
||||
} else {
|
||||
log_message(LOG_LEVEL_ERROR, "Unknown unit '%s'.", endptr);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
@ -82,3 +82,9 @@ Result copy_file(const char* src_path, const char* dst_path, mode_t mode);
|
||||
/// @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);
|
||||
|
||||
/// @brief Parses a size from a human-readable string.
|
||||
/// @param string The string to parse.
|
||||
/// @param out_size The pointer to the output size.
|
||||
/// @return The result of the operation.
|
||||
Result parse_size(const char* string, uint64_t* out_size);
|
Loading…
Reference in New Issue
Block a user