diff --git a/src/entry.c b/src/entry.c index 701dc48..496e6da 100644 --- a/src/entry.c +++ b/src/entry.c @@ -384,9 +384,19 @@ Status RemoveEntryDisk(const char* entry_identifier) { } Status ResetEntryDisk(const char* entry_identifier, const char* backing_identifier) { - // Check if the disk exists + // Check that the entry exists bool exists; - Status status = DoesEntryDiskExist(entry_identifier, &exists); + Status status = DoesEntryExist(entry_identifier, &exists); + if (status != SUCCESS) + return status; + + if (!exists) { + Log(LOG_LEVEL_ERROR, "The entry '%s' does not exist.", entry_identifier); + return FAILURE; + } + + // Check if the disk exists + status = DoesEntryDiskExist(entry_identifier, &exists); if (status != SUCCESS) return status; @@ -438,7 +448,7 @@ Status ResetEntryDisk(const char* entry_identifier, const char* backing_identifi } Status TrimEntryDisk(const char* entry_identifier) { - // Check if the disk exists + // Check if the entry exists bool exists; Status status = DoesEntryDiskExist(entry_identifier, &exists); if (status != SUCCESS) @@ -449,6 +459,16 @@ Status TrimEntryDisk(const char* entry_identifier) { return FAILURE; } + // Check if the disk exists + status = DoesEntryDiskExist(entry_identifier, &exists); + if (status != SUCCESS) + return status; + + if (!exists) { + Log(LOG_LEVEL_ERROR, "The disk for the entry '%s' does not exist.", entry_identifier); + return FAILURE; + } + // Get the disk path char* entry_disk_path = NULL; status = GetEntryDiskPath(entry_identifier, &entry_disk_path); @@ -461,3 +481,4 @@ Status TrimEntryDisk(const char* entry_identifier) { return status; } + diff --git a/src/entry.h b/src/entry.h index dd41747..7fdb735 100644 --- a/src/entry.h +++ b/src/entry.h @@ -21,4 +21,6 @@ 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); // TODO -Status TrimEntryDisk(const char* entry_identifier); \ No newline at end of file +Status TrimEntryDisk(const char* entry_identifier); + +Status GetEntryBacking(const char* entry_identifier, char** _backing_identifier); \ No newline at end of file diff --git a/src/sandbox.c b/src/sandbox.c index 5b0f8ac..23f6fc6 100644 --- a/src/sandbox.c +++ b/src/sandbox.c @@ -9,6 +9,7 @@ #include #include #include +#include Command COMMANDS[] = { {CommandHelp, "help", "[command]", "Prints this help message.", @@ -29,7 +30,7 @@ Command COMMANDS[] = { "TODO: Add details."}, {CommandRemoveDisk, "remove-disk", "", "Removes the disk from an entry.", "TODO: Add details."}, - {CommandResetDisk, "reset-disk", " [--update|-u] [--backing|-b ]", "Resets the disk of an entry.", + {CommandResetDisk, "reset-disk", " [--update|-u] [--backed|-b ]", "Resets the disk of an entry.", "TODO: Add details."}, {CommandTrimDisk, "trim-disk", "", "Trims the disk of an entry.", "TODO: Add details."}}; @@ -114,8 +115,6 @@ int CommandHelp(int argc, char* argv[]) { } fprintf(stdout, "\nFor more information, run 'sandbox help '.\n"); - - return EXIT_SUCCESS; } else if (argc == 1) { // If there is one argument, print the help message for the command const char* input = argv[0]; @@ -136,7 +135,7 @@ int CommandHelp(int argc, char* argv[]) { Log(LOG_LEVEL_ERROR, "Unknown command '%s'.", input); return EXIT_FAILURE; } else { // If there are too many arguments, print an error message - Log(LOG_LEVEL_ERROR, "Too many arguments supplied to 'help'."); + Log(LOG_LEVEL_ERROR, "Too many arguments supplied to command 'help'."); return EXIT_FAILURE; } @@ -144,62 +143,91 @@ int CommandHelp(int argc, char* argv[]) { } int CommandVersion(int argc, char* argv[]) { + if (argc > 0) { + Log(LOG_LEVEL_ERROR, "Too many arguments supplied to command 'version'."); + return EXIT_FAILURE; + } + fprintf(stdout, "Sandbox utility v%s\n", VERSION); return EXIT_SUCCESS; } int CommandAddEntry(int argc, char* argv[]) { if (argc < 1) { - Log(LOG_LEVEL_ERROR, "Too few arguments supplied to 'add-entry'."); + Log(LOG_LEVEL_ERROR, "Too few arguments supplied to command 'add-entry'."); return EXIT_FAILURE; } else if (argc > 1) { - Log(LOG_LEVEL_ERROR, "Too many arguments supplied to 'add-entry'."); + Log(LOG_LEVEL_ERROR, "Too many arguments supplied to command 'add-entry'."); return EXIT_FAILURE; } - char* entry_identifier = argv[0]; + // Extract the entry identifier + const char* entry_id = argv[0]; - Status status = AddEntry(entry_identifier); + // Create the entry + Status status = AddEntry(entry_id); if (status != SUCCESS) return EXIT_FAILURE; - Log(LOG_LEVEL_INFO, "Added entry '%s'.", entry_identifier); + Log(LOG_LEVEL_INFO, "Successfully added entry '%s'.", entry_id); return EXIT_SUCCESS; } int CommandRemoveEntry(int argc, char* argv[]) { if (argc < 1) { - Log(LOG_LEVEL_ERROR, "Too few arguments supplied to 'remove-entry'."); + Log(LOG_LEVEL_ERROR, "Too few arguments supplied to command 'remove-entry'."); return EXIT_FAILURE; } else if (argc > 1) { - Log(LOG_LEVEL_ERROR, "Too many arguments supplied to 'remove-entry'."); + Log(LOG_LEVEL_ERROR, "Too many arguments supplied to command 'remove-entry'."); return EXIT_FAILURE; } - char* entry_identifier = argv[0]; + // Extract the entry identifier + const char* entry_id = argv[0]; - Status status = RemoveEntry(entry_identifier); + // Remove the entry + Status status = RemoveEntry(entry_id); if (status != SUCCESS) return EXIT_FAILURE; - Log(LOG_LEVEL_INFO, "Removed entry '%s'.", entry_identifier); + Log(LOG_LEVEL_INFO, "Successfully removed entry '%s'.", entry_id); return EXIT_SUCCESS; } int CommandListEntries(int argc, char* argv[]) { if (argc > 0) { - Log(LOG_LEVEL_ERROR, "Too many arguments supplied to 'list-entries'."); + Log(LOG_LEVEL_ERROR, "Too many arguments supplied to command 'list-entries'."); return EXIT_FAILURE; } + // List the entries char** entries = NULL; Status status = ListEntries(&entries); if (status != SUCCESS) return EXIT_FAILURE; - for (size_t i = 0; entries[i] != NULL; i++) - fprintf(stdout, "%s\n", entries[i]); + // Calculate the maximum length of the entries + size_t max_length = 0; + for (size_t i = 0; entries[i] != NULL; i++) { + size_t length = strlen(entries[i]); + if (length > max_length) + max_length = length; + } + // Print the entries + for (size_t i = 0; entries[i] != NULL; i++) { + bool has_disk; + status = DoesEntryDiskExist(entries[i], &has_disk); + if (status != SUCCESS) + return EXIT_FAILURE; + + if (has_disk) + fprintf(stdout, "%zu | %-*s | %s |\n", i, (int)max_length, entries[i], "Has disk"); + else + fprintf(stdout, "%zu | %-*s | %s |\n", i, (int)max_length, entries[i], "No disk "); + } + + // Free the entries for (size_t i = 0; entries[i] != NULL; i++) free(entries[i]); free(entries); @@ -209,158 +237,178 @@ int CommandListEntries(int argc, char* argv[]) { int CommandClearEntries(int argc, char* argv[]) { if (argc > 0) { - Log(LOG_LEVEL_ERROR, "Too many arguments supplied to 'clear-entries'."); + Log(LOG_LEVEL_ERROR, "Too many arguments supplied to command 'clear-entries'."); return EXIT_FAILURE; } + // Clear the entries Status status = ClearEntries(); if (status != SUCCESS) return EXIT_FAILURE; - Log(LOG_LEVEL_INFO, "Cleared all entries."); + Log(LOG_LEVEL_INFO, "Successfully cleared all entries."); return EXIT_SUCCESS; } int CommandAddDisk(int argc, char* argv[]) { if (argc < 1) { - Log(LOG_LEVEL_ERROR, "Too few arguments supplied to 'add-disk'."); + Log(LOG_LEVEL_ERROR, "Too few arguments supplied to command 'add-disk'."); return EXIT_FAILURE; } - char* entry_identifier = argv[0]; + // Extract the entry identifier + const char* entry_id = argv[0]; + // Extract the options bool root = false; - uint64_t size = 0; + const char* size_str = NULL; bool backed = false; - const char* backing_identifier = NULL; + const char* backing_id = NULL; for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "--root") == 0 || strcmp(argv[i], "-r") == 0) { + // Check if the option is duplicated if (root) { - Log(LOG_LEVEL_ERROR, "Duplicate '--root' argument supplied to 'add-disk'."); + Log(LOG_LEVEL_ERROR, "Duplicate option '--root'."); return EXIT_FAILURE; } - if (i + 1 >= argc) { - Log(LOG_LEVEL_ERROR, "Too few arguments supplied to 'add-disk'. Missing size for '--root '."); + // Check if the option is the last argument + if (i + 1 == argc) { + Log(LOG_LEVEL_ERROR, "Missing argument for option '--root '."); return EXIT_FAILURE; } + // Extract the size + size_str = argv[i + 1]; root = true; - Status status = ParseSize(argv[i + 1], &size); - if (status != SUCCESS) - return EXIT_FAILURE; - if (size == 0) { - Log(LOG_LEVEL_ERROR, "Invalid size '%s' supplied to 'add-disk'.", argv[i + 1]); - return EXIT_FAILURE; - } - - i++; // Consumes the next argument (the size) + // Skip the next argument as it is the size + i++; } else if (strcmp(argv[i], "--backed") == 0 || strcmp(argv[i], "-b") == 0) { + // Check if the option is duplicated if (backed) { - Log(LOG_LEVEL_ERROR, "Duplicate '--backed' argument supplied to 'add-disk'."); + Log(LOG_LEVEL_ERROR, "Duplicate option '--backed'."); return EXIT_FAILURE; } - if (i + 1 >= argc) { - Log(LOG_LEVEL_ERROR, "Too few arguments supplied to 'add-disk'. Missing backing identifier for '--backed '."); + // Check if the option is the last argument + if (i + 1 == argc) { + Log(LOG_LEVEL_ERROR, "Missing argument for option '--backed '."); return EXIT_FAILURE; } + // Extract the backing identifier + backing_id = argv[i + 1]; backed = true; - backing_identifier = argv[i + 1]; - if (!IsBackingIdentifierValid(backing_identifier)) { - Log(LOG_LEVEL_ERROR, "Invalid backing identifier '%s' supplied to 'add-disk'.", backing_identifier); - return EXIT_FAILURE; - } - - i++; // Consumes the next argument (the backing identifier) + // Skip the next argument as it is the backing identifier + i++; } else { - Log(LOG_LEVEL_ERROR, "Unknown argument '%s' supplied to 'add-disk'.", argv[i]); + Log(LOG_LEVEL_ERROR, "Unknown option '%s'.", argv[i]); return EXIT_FAILURE; } } + // Don't allow both root and backed options if (root && backed) { - Log(LOG_LEVEL_ERROR, "The options '--root' and '--backed' cannot be used together in 'add-disk'."); + Log(LOG_LEVEL_ERROR, "Cannot use both '--root' and '--backed' options."); return EXIT_FAILURE; } if (root) { - Status status = AddRootEntryDisk(entry_identifier, size); + // Parse the size + uint64_t size; + Status status = ParseSize(size_str, &size); if (status != SUCCESS) return EXIT_FAILURE; - char* size_str = NULL; - status = FormatSize(size, &size_str); - Log(LOG_LEVEL_INFO, "Added root disk to entry '%s' with size %s.", entry_identifier, size_str); - free(size_str); + // Add the root disk + status = AddRootEntryDisk(entry_id, size); + if (status != SUCCESS) + return EXIT_FAILURE; + + // Format the size + char* size_fmt; + status = FormatSize(size, &size_fmt); + + Log(LOG_LEVEL_INFO, "Successfully added root disk to entry '%s' of size %s.", entry_id, size_fmt); + + free(size_fmt); + return EXIT_SUCCESS; } else if (backed) { - Status status = AddBackedEntryDisk(entry_identifier, backing_identifier); + // Check if the backing exists + Status status = AddBackedEntryDisk(entry_id, backing_id); if (status != SUCCESS) return EXIT_FAILURE; - Log(LOG_LEVEL_INFO, "Added backed disk to entry '%s' with backing '%s'.", entry_identifier, backing_identifier); + Log(LOG_LEVEL_INFO, "Successfully added backed disk to entry '%s' with backing '%s'.", entry_id, backing_id); + return EXIT_SUCCESS; } else { - char* backing_identifier = NULL; - Status status = GetLatestBacking(&backing_identifier); - if (status != SUCCESS) - return EXIT_FAILURE; - - status = AddBackedEntryDisk(entry_identifier, backing_identifier); + // Get the latest backing to use as the default backing + char* backing_id; + Status status = GetLatestBacking(&backing_id); if (status != SUCCESS) { - free(backing_identifier); + Log(LOG_LEVEL_ERROR, "Failed to get the latest backing to use as the default backing."); return EXIT_FAILURE; } - Log(LOG_LEVEL_INFO, "Added backed disk to entry '%s' with backing '%s'.", entry_identifier, backing_identifier); - free(backing_identifier); - } + // Add the backed disk + status = AddBackedEntryDisk(entry_id, backing_id); + if (status != SUCCESS) { + free(backing_id); + return EXIT_FAILURE; + } - return EXIT_SUCCESS; + Log(LOG_LEVEL_INFO, "Successfully added backed disk to entry '%s' with backing '%s'.", entry_id, backing_id); + + free(backing_id); + return EXIT_SUCCESS; + } } int CommandRemoveDisk(int argc, char* argv[]) { if (argc < 1) { - Log(LOG_LEVEL_ERROR, "Too few arguments supplied to 'remove-disk'."); + Log(LOG_LEVEL_ERROR, "Too few arguments supplied to command 'remove-disk'."); return EXIT_FAILURE; } else if (argc > 1) { - Log(LOG_LEVEL_ERROR, "Too many arguments supplied to 'remove-disk'."); + Log(LOG_LEVEL_ERROR, "Too many arguments supplied to command 'remove-disk'."); return EXIT_FAILURE; } - char* entry_identifier = argv[0]; + // Extract the entry identifier + const char* entry_id = argv[0]; - Status status = RemoveEntryDisk(entry_identifier); + // Remove the disk + Status status = RemoveEntryDisk(entry_id); if (status != SUCCESS) return EXIT_FAILURE; - Log(LOG_LEVEL_INFO, "Removed disk from entry '%s'.", entry_identifier); + Log(LOG_LEVEL_INFO, "Successfully removed disk from entry '%s'.", entry_id); return EXIT_SUCCESS; } int CommandResetDisk(int argc, char* argv[]) { return 0; } - int CommandTrimDisk(int argc, char* argv[]) { if (argc < 1) { - Log(LOG_LEVEL_ERROR, "Too few arguments supplied to 'trim-disk'."); + Log(LOG_LEVEL_ERROR, "Too few arguments supplied to command 'trim-disk'."); return EXIT_FAILURE; } else if (argc > 1) { - Log(LOG_LEVEL_ERROR, "Too many arguments supplied to 'trim-disk'."); + Log(LOG_LEVEL_ERROR, "Too many arguments supplied to command 'trim-disk'."); return EXIT_FAILURE; } - char* entry_identifier = argv[0]; + // Extract the entry identifier + const char* entry_id = argv[0]; - Status status = TrimEntryDisk(entry_identifier); + // Trim the disk + Status status = TrimEntryDisk(entry_id); if (status != SUCCESS) return EXIT_FAILURE; - Log(LOG_LEVEL_INFO, "Trimmed disk of entry '%s'.", entry_identifier); + Log(LOG_LEVEL_INFO, "Successfully trimmed disk from entry '%s'.", entry_id); return EXIT_SUCCESS; }