aboutsummaryrefslogtreecommitdiffstats
path: root/src/cmd-instance.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd-instance.c')
-rw-r--r--src/cmd-instance.c120
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;
}
-