diff --git a/src/backing.c b/src/backing.c index e3b06db..8efc96f 100644 --- a/src/backing.c +++ b/src/backing.c @@ -68,3 +68,18 @@ Status GetBackingDiskPath(const char* backing_identifier, char** _backing_path) return status; } + +Status DoesBackingExist(const char* backing_identifier, bool* _result) { + // Get the backing path + char* backing_path = NULL; + Status status = GetBackingDiskPath(backing_identifier, &backing_path); + if (status != SUCCESS) + return status; + + // Check if the backing exists and is a regular file + struct stat st; + *_result = stat(backing_path, &st) == 0 && S_ISREG(st.st_mode); + free(backing_path); + + return SUCCESS; +} diff --git a/src/backing.h b/src/backing.h index f189000..3127780 100644 --- a/src/backing.h +++ b/src/backing.h @@ -8,6 +8,8 @@ int GetBackingIndex(const char* backing_identifier); Status GetBackingPoolPath(char** _backing_pool_path); Status GetBackingDiskPath(const char* backing_identifier, char** _backing_path); +Status DoesBackingExist(const char* backing_identifier, bool* _result); + Status AddBacking(const char* backing_identifier, const char* entry_identifier); Status RemoveBacking(const char* backing_identifier); diff --git a/src/entry.c b/src/entry.c index 40faf9a..1126f60 100644 --- a/src/entry.c +++ b/src/entry.c @@ -1,6 +1,7 @@ #include "entry.h" #include "disk.h" +#include "backing.h" #include #include @@ -199,6 +200,11 @@ Status ListEntries(char*** _entries) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; + bool exists; + Status status = DoesEntryExist(entry->d_name, &exists); + if (status != SUCCESS || !exists) + continue; + char** new_entries = realloc(*_entries, (count + 2) * sizeof(char*)); // +2 for the new entry and the NULL terminator if (new_entries == NULL) { Log(LOG_LEVEL_ERROR, "Failed to reallocate memory for the entries list (%s).", strerror(errno)); @@ -282,6 +288,40 @@ Status AddRootEntryDisk(const char* entry_identifier, uint64_t disk_size) { return status; } +Status AddBackedEntryDisk(const char* entry_identifier, const char* backing_identifier) { + // Check if the disk already exists + bool exists; + Status status = DoesEntryDiskExist(entry_identifier, &exists); + if (status != SUCCESS) + return status; + + if (exists) { + Log(LOG_LEVEL_ERROR, "The disk for the entry '%s' already exists.", entry_identifier); + return FAILURE; + } + + // Get the backing disk path + char* backing_disk_path = NULL; + status = GetBackingDiskPath(backing_identifier, &backing_disk_path); + if (status != SUCCESS) + return status; + + // Get the disk path + char* entry_disk_path = NULL; + status = GetEntryDiskPath(entry_identifier, &entry_disk_path); + if (status != SUCCESS) { + free(backing_disk_path); + return status; + } + + // Create the disk + status = CreateBackedDisk(entry_disk_path, backing_disk_path); + free(backing_disk_path); + free(entry_disk_path); + + return status; +} + Status RemoveEntryDisk(const char* entry_identifier) { // Check if the disk exists bool exists; diff --git a/src/entry.h b/src/entry.h index 40b9690..dd41747 100644 --- a/src/entry.h +++ b/src/entry.h @@ -20,5 +20,5 @@ Status ClearEntries(); Status AddRootEntryDisk(const char* entry_identifier, uint64_t disk_size); Status AddBackedEntryDisk(const char* entry_identifier, const char* backing_identifier); Status RemoveEntryDisk(const char* entry_identifier); -Status ResetEntryDisk(const char* entry_identifier, const char* backing_identifier); +Status ResetEntryDisk(const char* entry_identifier, const char* backing_identifier); // TODO Status TrimEntryDisk(const char* entry_identifier); \ No newline at end of file diff --git a/src/sandbox.c b/src/sandbox.c index 1998cf5..68439d8 100644 --- a/src/sandbox.c +++ b/src/sandbox.c @@ -59,6 +59,7 @@ int main(int argc, char* argv[]) { const char* input = argv[1]; size_t input_length = strlen(input); + // Try and find the best matching command const Command* command = NULL; for (size_t i = 0; i < sizeof(COMMANDS) / sizeof(COMMANDS[0]); i++) { if (COMMANDS[i].name == NULL) @@ -68,6 +69,7 @@ int main(int argc, char* argv[]) { continue; if (strncmp(input, COMMANDS[i].name, input_length) == 0) { + // If we have already found a matching command, then the input is ambiguous if (command != NULL) { Log(LOG_LEVEL_ERROR, "Ambiguous command '%s'.", input); return EXIT_FAILURE; @@ -86,6 +88,7 @@ int main(int argc, char* argv[]) { } int CommandHelp(int argc, char* argv[]) { + // If there are no arguments, print the general help message if (argc == 0) { fprintf(stdout, "Usage: sandbox [arguments] [options]\n"); fprintf(stdout, "\n"); @@ -105,7 +108,7 @@ int CommandHelp(int argc, char* argv[]) { fprintf(stdout, "\nFor more information, run 'sandbox help '.\n"); return EXIT_SUCCESS; - } else if (argc == 1) { + } else if (argc == 1) { // If there is one argument, print the help message for the command const char* input = argv[0]; for (size_t i = 0; i < sizeof(COMMANDS) / sizeof(COMMANDS[0]); i++) { @@ -124,7 +127,7 @@ int CommandHelp(int argc, char* argv[]) { Log(LOG_LEVEL_ERROR, "Unknown command '%s'.", input); return EXIT_FAILURE; - } else { + } else { // If there are too many arguments, print an error message Log(LOG_LEVEL_ERROR, "Too many arguments supplied to 'help'."); return EXIT_FAILURE; }