aboutsummaryrefslogtreecommitdiffstats
path: root/src/cmd-instance.c
blob: 89494af1c92c85fe085e2ea2cd58a9ff824c1dbf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "commands.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");

  res = CMD_RESULT_SUCCESS;

cleanup:
  free(newpath);
  return res;
}

unsigned cmd_instance_remove(struct l2_context_node *ctx, char **args)
{
  return CMD_RESULT_SUCCESS;
}

unsigned cmd_instance_list(struct l2_context_node *ctx, char **args)
{
return CMD_RESULT_SUCCESS;
}

unsigned cmd_instance_rename(struct l2_context_node *ctx, char **args)
{
  return CMD_RESULT_SUCCESS;
}