diff options
Diffstat (limited to 'src/cmd-instance.c')
| -rw-r--r-- | src/cmd-instance.c | 120 |
1 files changed, 117 insertions, 3 deletions
diff --git a/src/cmd-instance.c b/src/cmd-instance.c index 9e346e2..89494af 100644 --- a/src/cmd-instance.c +++ b/src/cmd-instance.c @@ -1,11 +1,126 @@ #include "commands.h" -#include "src/command.h" +#include "command.h" +#include "instance.h" +#include "l2su.h" + #include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> +#include <stdbool.h> unsigned cmd_instance_add(struct l2_context_node *ctx, char **args) { + int res = l2_instance_load_all(); + char *name = NULL; + char *path = NULL; + char *newpath = NULL; + uuid_t uuid; + char uuidstr[UUID_STRLEN+1]; + + if (res != INSTANCE_SUCCESS) { + if (res == INSTANCE_ERRNO) { + fprintf(stderr, "fatal: Error loading instances: %s", strerror(errno)); + } else { + fprintf(stderr, "fatal: Error loading instances (%d)\n", res); + } + return CMD_RESULT_FAIL; + } + + /* get the name and path (if it exists) */ + for (struct l2_context_node *cur = ctx; cur; cur = cur->next) { + if (cur->node->type != CMD_NODE_TYPE_ARGUMENT) continue; + if (!strcmp("name", cur->node->name)) { + name = cur->value; + } else if (!strcmp("location", cur->node->name)) { + path = cur->value; + } + } + + /* make sure the name and path make sense (path should be an absolute path, name shouldn't be empty) */ + if (!name || !*name) { + fputs("fatal: The specified name is invalid\n", stderr); + return CMD_RESULT_FAIL; + } + + for (char *cur = name; *cur; ++cur) { + if (*cur < ' ') { + fputs("fatal: The specified name contains invalid characters\n", stderr); + return CMD_RESULT_FAIL; + } + } + + /* make sure there is not a profile with that name already */ + for (struct l2_instance *cur = l2_state.instance_head; cur; cur = cur->next) { + if (!strcmp(cur->name, name)) { + fprintf(stderr, "fatal: An instance by the name '%s' already exists.\n", cur->name); + return CMD_RESULT_FAIL; + } + } + + /* also find an unused UUID through rejection sampling */ + bool found; + do { + found = false; + l2_uuid_random(&uuid); + for (struct l2_instance *cur = l2_state.instance_head; cur; cur = cur->next) { + if (!l2_uuid_compare(&cur->uuid, &uuid)) { + found = true; + break; + } + } + } while (found); + + /* create the directory at "path" (if it isn't empty, complain) */ + if (path && *path != '/') { + fputs("fatal: Specified path is not an absolute path\n", stderr); + return CMD_RESULT_FAIL; + } else if (!path) { + newpath = strdup(l2_state.paths.data); + if (!newpath) { + newpath_append_fail: + free(newpath); + fprintf(stderr, "fatal: Allocation failed: %s\n", strerror(errno)); + return CMD_RESULT_FAIL; + } + + newpath = l2_launcher_strapp(newpath, "/instances/"); + if (!newpath) goto newpath_append_fail; + + l2_uuid_to_string(&uuid, uuidstr); + newpath = l2_launcher_strapp(newpath, uuidstr); + if (!newpath) goto newpath_append_fail; + } + + /* TODO: now create the directory for realsies */ + + /* add the instance */ + + struct l2_instance inst; + + inst.uuid = uuid; + inst.name = name; + inst.path = path ? path : newpath; + + if ((res = l2_instance_add_instance(&inst)) != INSTANCE_SUCCESS) { + fprintf(stderr, "fatal: Failed to add instance (%d)\n", res); + res = CMD_RESULT_FAIL; + goto cleanup; + } + + if ((res = l2_instance_save_all()) != INSTANCE_SUCCESS) { + fprintf(stderr, "fatal: Failed to add instance (%d)\n", res); + res = CMD_RESULT_FAIL; + goto cleanup; + } + printf("add command yay\n"); - return CMD_RESULT_SUCCESS; + + res = CMD_RESULT_SUCCESS; + +cleanup: + free(newpath); + return res; } unsigned cmd_instance_remove(struct l2_context_node *ctx, char **args) @@ -22,4 +137,3 @@ unsigned cmd_instance_rename(struct l2_context_node *ctx, char **args) { return CMD_RESULT_SUCCESS; } - |
