#include "sandbox.h" #include "utils.h" #include "entry.h" #include #include #include const Command COMMANDS[] = { {command_help, "help", "[command]", "Prints the help message.", "Prints the help message for the given command. If no command is given, prints the help message for all commands."}, {command_version, "version", "", "Prints the version.", "Prints the version of the program."}, {}, {command_add_entry, "add-entry", " [--root|-r ] [--backed|-b ]", "Adds an entry to the entry pool.", "Adds an entry to the entry pool with the given id. The entry can either be a root entry or a backed entry. If the entry is a root entry, the size of the entry must be specified. If the entry is a backed entry, the backing id must be specified. By default, the entry is backed by the latest backing disk available."}, }; int main(int argc, char* argv[]) { if (argc < 2) return command_help(0, NULL); size_t input_length = strlen(argv[1]); const Command* command = NULL; for (int i = 0; i < ARRAY_SIZE(COMMANDS); i++) { if (COMMANDS[i].name == NULL) continue; // Check that the length of the input is equal or less than the length of the command name if (input_length > strlen(COMMANDS[i].name)) continue; // Check that the input matches the command name if (strncmp(argv[1], COMMANDS[i].name, input_length) == 0) { // Check for multiple matches if (command != NULL) { log_message(LOG_LEVEL_ERROR, "Ambiguous command '%s'.", argv[1]); return EXIT_FAILURE; } command = &COMMANDS[i]; } } // Check if the command is NULL (no matches) if (command == NULL) { log_message(LOG_LEVEL_ERROR, "Unknown command '%s'.", argv[1]); return EXIT_FAILURE; } return command->handler(argc - 2, argv + 2); } int command_help(int argc, char* argv[]) { // Check the number of arguments if (argc == 0) { fprintf(stdout, "Usage: sandbox [command] [arguments]\n\n"); fprintf(stdout, "Commands:\n"); for (int i = 0; i < ARRAY_SIZE(COMMANDS); i++) if (COMMANDS[i].name == NULL) printf("\n"); else fprintf(stdout, " %s %s - %s\n", COMMANDS[i].name, COMMANDS[i].arguments, COMMANDS[i].description); fprintf(stdout, "\nRun 'sandbox help [command]' for more information on a command.\n"); return EXIT_SUCCESS; } else if (argc == 1) { // Find the command that matches the given name const Command* command = NULL; for (int i = 0; i < ARRAY_SIZE(COMMANDS); i++) { if (COMMANDS[i].name == NULL) continue; if (strcmp(argv[0], COMMANDS[i].name) == 0) { command = &COMMANDS[i]; break; } } // Check if the command is NULL (no matches) if (command == NULL) { log_message(LOG_LEVEL_ERROR, "Unknown command '%s'.", argv[0]); return EXIT_FAILURE; } // Print the help message for the command fprintf(stdout, "Usage: sandbox %s %s\n\n", command->name, command->arguments); fprintf(stdout, " %s\n", command->details); return EXIT_SUCCESS; } else { log_message(LOG_LEVEL_ERROR, "Too many arguments for 'help' command."); return EXIT_FAILURE; } } int command_version(int argc, char* argv[]) { fprintf(stdout, "Sandbox manager v%s\n", VERSION); return EXIT_SUCCESS; } int command_add_entry(int argc, char* argv[]) { if (argc < 1) { log_message(LOG_LEVEL_ERROR, "Missing entry id."); return EXIT_FAILURE; } // Extract the entry id const char* entry_id = argv[0]; // Check if the entry id is valid if (!is_entry_id_valid(entry_id)) { log_message(LOG_LEVEL_ERROR, "Invalid entry id '%s'.", entry_id); return EXIT_FAILURE; } // Check if the entry already exists bool exists; if (entry_exists(entry_id, &exists) != SUCCESS) return EXIT_FAILURE; if (exists) { log_message(LOG_LEVEL_ERROR, "Entry '%s' already exists.", entry_id); return EXIT_FAILURE; } // Create the entry // TODO // Add the disk to the entry // TODO // If this fails, remove the entry return EXIT_SUCCESS; }