diff options
| author | 2023-12-26 22:33:51 -0600 | |
|---|---|---|
| committer | 2023-12-26 22:33:51 -0600 | |
| commit | 7f4b7142b09205dc773a915e3fe3cb7954f6d041 (patch) | |
| tree | 34fed74ba2f3715ce2a6a6922cfbd440882b2895 /src | |
| parent | implement remaining commands (but badly) (diff) | |
refactor instances
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd-instance.c | 286 | ||||
| -rw-r--r-- | src/command.c | 64 | ||||
| -rw-r--r-- | src/command.h | 42 | ||||
| -rw-r--r-- | src/instance.c | 36 | ||||
| -rw-r--r-- | src/instance.h | 9 |
5 files changed, 217 insertions, 220 deletions
diff --git a/src/cmd-instance.c b/src/cmd-instance.c index 6982eb3..c81eb7c 100644 --- a/src/cmd-instance.c +++ b/src/cmd-instance.c @@ -15,9 +15,39 @@ #include <ftw.h> #include <unistd.h> +#define CMD_MSG_INSTANCE_LOAD_ERR "Error loading instances" +#define CMD_MSG_INSTANCE_ADD_ERR "Error adding the instance" +#define CMD_MSG_INSTANCE_SAVE_ERR "Error saving the instance" +#define CMD_MSG_INSTANCE_DEL_ERR "Error removing the instance" +#define CMD_MSG_INSTANCE_RENAME_ERR "Error renaming the instance" + +#define CMD_MSG_INSTANCE_INVALID_NAME "The instance name is invalid." +#define CMD_MSG_INSTANCE_DUPLICATE "An instance named '%s' already exists." +#define CMD_MSG_INSTANCE_DIR_CREATE_E "Error creating instance directory: %s" +#define CMD_MSG_INSTANCE_DIR_CHECK_E "Error checking instance directory: %s" +#define CMD_MSG_INSTANCE_DIR_DIRTY "The instance directory '%s' is not empty. If this is intentional, rerun the command with --force." + +#define CMD_MSG_INSTANCE_NAME_NOT_FOUND "An instance by the name '%s' could not be found." +#define CMD_MSG_INSTANCE_UUID_NOT_FOUND "An instance by the UUID '%s' could not be found." + +#define CMD_MSG_INSTANCE_DELDIR_ERR(_msg) "Error deleting instance directory: " _msg + +#define CMD_INSTANCE_CHECK(_res, _v, _msg) do { \ + switch (((_res) = (_v))) { \ + case INSTANCE_SUCCESS: break; \ + case INSTANCE_ERRNO: \ + CMD_FATAL(_msg ": %s: %s", l2_instance_errormsg[(_res)], strerror(errno)); \ + break; \ + default: \ + CMD_FATAL(_msg ": %s", l2_instance_errormsg[(_res)]); \ + } \ +} while (0) + +void cmd_instance__check_name(const char *instname); + unsigned cmd_instance_add(struct l2_context_node *ctx, char **args) { - int res = l2_instance_load_all(); + int res; char *name = NULL; char *path = NULL; char *newpath = NULL; @@ -30,78 +60,40 @@ unsigned cmd_instance_add(struct l2_context_node *ctx, char **args) if (!strcmp(*cur, "--force")) { flag_force = true; } else { - fprintf(stderr, "fatal: Unknown argument '%s'.\n", *cur); - return CMD_RESULT_FAIL; + CMD_FATAL(CMD_MSG_UNKNOWN_ARGUMENT, *cur); } } - if (res != INSTANCE_SUCCESS) { - if (res == INSTANCE_ERRNO) { - fprintf(stderr, "fatal: Error loading instances: %s\n", strerror(errno)); - } else { - fprintf(stderr, "fatal: Error loading instances (%d)\n", res); - } - return CMD_RESULT_FAIL; - } + CMD_INSTANCE_CHECK(res, l2_instance_load_all(), CMD_MSG_INSTANCE_LOAD_ERR); /* 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; - } - } + l2_cmd_collect_args(ctx, 2, "name", &name, "#location", &path); /* 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; - } - } + cmd_instance__check_name(name); /* 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; - } + if (l2_instance_find_by_name(name)) { + CMD_FATAL(CMD_MSG_INSTANCE_DUPLICATE, name); } /* also find an unused UUID through rejection sampling */ - bool found; - do { - found = false; + while (true) { 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); + if (!l2_instance_find_by_uuid(&uuid)) break; + } /* create the directory at "path" (if it isn't empty, complain) */ if (path) { newpath = realpath(path, NULL); if (!newpath) { - fprintf(stderr, "fatal: Failed to canonicalize specified path: %s\n", strerror(errno)); - return CMD_RESULT_FAIL; + CMD_FATAL0(CMD_MSG_ALLOCATION_FAILED); } } 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; + CMD_FATAL0(CMD_MSG_ALLOCATION_FAILED); } newpath = l2_launcher_strapp(newpath, "/instances/"); @@ -116,38 +108,32 @@ unsigned cmd_instance_add(struct l2_context_node *ctx, char **args) /* TODO: now create the directory for realsies */ if (l2_launcher_mkdir_parents(path) < 0) { - fprintf(stderr, "fatal: Could not create instance directory: %s\n", strerror(errno)); - res = CMD_RESULT_FAIL; - goto cleanup; + CMD_FATAL(CMD_MSG_INSTANCE_DIR_CREATE_E, strerror(errno)); } if (!flag_force) { dir = opendir(path); if (!dir) { - fprintf(stderr, "fatal: Could not check instance directory: %s\n", strerror(errno)); - res = CMD_RESULT_FAIL; - goto cleanup; + CMD_FATAL(CMD_MSG_INSTANCE_DIR_CHECK_E, strerror(errno)); } struct dirent *ent; - errno = 0; + errno = 0; /* readdir can return NULL on success */ while ((ent = readdir(dir))) { if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, "..")) { - fprintf(stderr, "fatal: Instance directory '%s' is not empty. If this is intentional, rerun the command with --force.\n", path); - res = CMD_RESULT_FAIL; - goto cleanup; + CMD_FATAL(CMD_MSG_INSTANCE_DIR_DIRTY, path); } - } - closedir(dir); - dir = NULL; + errno = 0; + } if (errno) { - fprintf(stderr, "fatal: Error scanning instance directory: %s\n", strerror(errno)); - res = CMD_RESULT_FAIL; - goto cleanup; + CMD_FATAL(CMD_MSG_INSTANCE_DIR_CHECK_E, strerror(errno)); } - } + + closedir(dir); + dir = NULL; + } /* add the instance */ @@ -157,24 +143,14 @@ unsigned cmd_instance_add(struct l2_context_node *ctx, char **args) inst.name = name; inst.path = path; - 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; - } + CMD_INSTANCE_CHECK(res, l2_instance_add_instance(&inst), CMD_MSG_INSTANCE_ADD_ERR); - res = CMD_RESULT_SUCCESS; + CMD_INSTANCE_CHECK(res, l2_instance_save_all(), CMD_MSG_INSTANCE_SAVE_ERR); -cleanup: if (dir) closedir(dir); free(newpath); - return res; + + return CMD_RESULT_SUCCESS; } int cmd__delete_with_reckless_abandon(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) @@ -208,6 +184,7 @@ unsigned cmd_instance_remove(struct l2_context_node *ctx, char **args) uuid_t instid = UUID_NULL_INIT; struct l2_instance *to_remove = NULL; char *removepath = NULL; + char instid_pretty[UUID_STRLEN + 1]; for (char **cur = args; *cur; ++cur) { if (!strcmp("--delete", *cur)) { @@ -215,121 +192,73 @@ unsigned cmd_instance_remove(struct l2_context_node *ctx, char **args) } else if (!strcmp("--id", *cur)) { flag_byid = true; } else { - fprintf(stderr, "fatal: Unknown argument '%s'\n", *cur); - return CMD_RESULT_FAIL; - } - } - - 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; + CMD_FATAL(CMD_MSG_UNKNOWN_ARGUMENT, *cur); } } - if (!name) { - fputs("fatal: Name not specified\n", stderr); - return CMD_RESULT_FAIL; - } + l2_cmd_collect_args(ctx, 1, "name", &name); if (flag_byid && !l2_uuid_from_string(&instid, name)) { - fprintf(stderr, "Failed to parse instance UUID '%s'.\n", name); - return CMD_RESULT_FAIL; + CMD_FATAL(CMD_MSG_INVALID_UUID, name); } - res = l2_instance_load_all(); - if (res != INSTANCE_SUCCESS) { - fprintf(stderr, "fatal: Failed to load instances (%d).\n", res); - return CMD_RESULT_FAIL; - } + CMD_INSTANCE_CHECK(res, l2_instance_load_all(), CMD_MSG_INSTANCE_LOAD_ERR); /* find the thing */ if (flag_byid) { - for (struct l2_instance *inst = l2_state.instance_head; inst; inst = inst->next) { - if (!l2_uuid_compare(&inst->uuid, &instid)) { - to_remove = inst; - break; - } + to_remove = l2_instance_find_by_uuid(&instid); + if (!to_remove) { + l2_uuid_to_string(&instid, instid_pretty); + CMD_FATAL(CMD_MSG_INSTANCE_UUID_NOT_FOUND, instid_pretty); } } else { - for (struct l2_instance *inst = l2_state.instance_head; inst; inst = inst->next) { - if (!strcmp(inst->name, name)) { - to_remove = inst; - break; - } - } - } - - if (!to_remove) { - fputs("fatal: Instance not found.\n", stderr); - return CMD_RESULT_FAIL; + to_remove = l2_instance_find_by_name(name); + if (!to_remove) CMD_FATAL(CMD_MSG_INSTANCE_NAME_NOT_FOUND, name); } if (flag_remove) { removepath = strdup(to_remove->path); if (!removepath) { - fputs("fatal: Failed to create path.\n", stderr); - return CMD_RESULT_FAIL; + CMD_FATAL0(CMD_MSG_ALLOCATION_FAILED); } } /* remove the thing */ - if ((res = l2_instance_del_instance(to_remove)) != INSTANCE_SUCCESS) { - fprintf(stderr, "fatal: Failed to remove instance (%d).\n", res); - return CMD_RESULT_FAIL; - } + CMD_INSTANCE_CHECK(res, l2_instance_del_instance(to_remove), CMD_MSG_INSTANCE_DEL_ERR); to_remove = NULL; /* del_instance frees the instance */ - if ((res = l2_instance_save_all()) != INSTANCE_SUCCESS) { - fprintf(stderr, "fatal: Failed to save instances (%d).\n", res); - return CMD_RESULT_FAIL; - } + CMD_INSTANCE_CHECK(res, l2_instance_save_all(), CMD_MSG_INSTANCE_SAVE_ERR); /* delete the thing if it is necessary */ if (flag_remove) { res = nftw(removepath, &cmd__delete_with_reckless_abandon, 128, FTW_DEPTH | FTW_PHYS); switch (res) { case -2: - fputs("Unreadable file/folder encountered while walking file tree.\n", stderr); - res = CMD_RESULT_FAIL; - goto cleanup; + CMD_FATAL0(CMD_MSG_INSTANCE_DELDIR_ERR("unreadable file/folder encountered")); case -1: - fputs("Error walking file tree.\n", stderr); - res = CMD_RESULT_FAIL; - goto cleanup; + CMD_FATAL0(CMD_MSG_INSTANCE_DELDIR_ERR("error walking file tree")); case 0: break; default: - fprintf(stderr, "Error removing a file: %s\n", strerror(res)); - res = CMD_RESULT_FAIL; - goto cleanup; + CMD_FATAL(CMD_MSG_INSTANCE_DELDIR_ERR("error removing a file: %s"), strerror(res)); } } - res = CMD_RESULT_SUCCESS; - -cleanup: if (removepath) free(removepath); - return res; + return CMD_RESULT_SUCCESS; } unsigned cmd_instance_list(struct l2_context_node *ctx, char **args) { L2_UNUSED(ctx); + int res; if (*args) { - fprintf(stderr, "fatal: Unknown argument '%s'.\n", *args); - return CMD_RESULT_FAIL; + CMD_FATAL(CMD_MSG_UNKNOWN_ARGUMENT, *args); } - int res = l2_instance_load_all(); - - if (res != INSTANCE_SUCCESS) { - fprintf(stderr, "fatal: Failed to load instances. (%d)\n", res); - return CMD_RESULT_FAIL; - } + CMD_INSTANCE_CHECK(res, l2_instance_load_all(), CMD_MSG_INSTANCE_LOAD_ERR); if (l2_state.instance_head) { char idstr[UUID_STRLEN + 1]; @@ -352,53 +281,40 @@ unsigned cmd_instance_rename(struct l2_context_node *ctx, char **args) struct l2_instance *to_rename = NULL; if (*args) { - fprintf(stderr, "fatal: Unknown argument '%s'.\n", *args); - return CMD_RESULT_FAIL; + CMD_FATAL(CMD_MSG_UNKNOWN_ARGUMENT, *args); } - res = l2_instance_load_all(); + CMD_INSTANCE_CHECK(res, l2_instance_load_all(), CMD_MSG_INSTANCE_LOAD_ERR); - if (res != INSTANCE_SUCCESS) { - fprintf(stderr, "fatal: Failed to load instances. (%d)\n", res); - return CMD_RESULT_FAIL; - } + l2_cmd_collect_args(ctx, 2, "oldname", &oldname, "newname", &newname); - for (struct l2_context_node *cur = ctx; cur; cur = cur->next) { - if (!strcmp("oldname", cur->node->name)) { - oldname = cur->value; - } else if (!strcmp("newname", cur->node->name)) { - newname = cur->value; - } - } + cmd_instance__check_name(newname); - if (!(oldname && newname)) { /* TODO: sanitize newname like in "instance add" */ - fputs("fatal: Invalid usage.\n", stderr); - return CMD_RESULT_FAIL; + if (l2_instance_find_by_name(newname)) { + CMD_FATAL(CMD_MSG_INSTANCE_DUPLICATE, newname); } - for (struct l2_instance *cur = l2_state.instance_head; cur; cur = cur->next) { - if (!strcmp(cur->name, oldname)) { - to_rename = cur; - } else if (!strcmp(cur->name, newname)) { - fprintf(stderr, "fatal: An instance by the name '%s' already exists.\n", newname); - return CMD_RESULT_FAIL; - } + if (!(to_rename = l2_instance_find_by_name(oldname))) { + CMD_FATAL(CMD_MSG_INSTANCE_NAME_NOT_FOUND, oldname); } - if (!to_rename) { - fprintf(stderr, "fatal: No instance found by the name '%s'.\n", oldname); - return CMD_RESULT_FAIL; - } + CMD_INSTANCE_CHECK(res, l2_instance_rename_instance(to_rename, newname), CMD_MSG_INSTANCE_RENAME_ERR); - if ((res = l2_instance_rename_instance(to_rename, newname)) != INSTANCE_SUCCESS) { - fprintf(stderr, "fatal: Failed to rename the instance. (%d)\n", res); - return CMD_RESULT_FAIL; - } + CMD_INSTANCE_CHECK(res, l2_instance_save_all(), CMD_MSG_INSTANCE_SAVE_ERR); + + return CMD_RESULT_SUCCESS; +} - if ((res = l2_instance_save_all()) != INSTANCE_SUCCESS) { - fprintf(stderr, "fatal: Failed to save instances. (%d)\n", res); - return CMD_RESULT_FAIL; +void cmd_instance__check_name(const char *instname) +{ + if (!*instname) goto failure; + + for (const char *cur = instname; *cur; ++cur) { + if (*cur <= ' ') goto failure; /* not like you couldn't just use a unicode NBSP or something */ } - return CMD_RESULT_SUCCESS; + return; + +failure: + CMD_FATAL0(CMD_MSG_INSTANCE_INVALID_NAME); } diff --git a/src/command.c b/src/command.c index 6be2fb5..2f91db0 100644 --- a/src/command.c +++ b/src/command.c @@ -199,41 +199,45 @@ void l2_cmd_free_ctx(struct l2_context_node *ctx) } while (ctx); } -#if 0 -#include "uuid/uuid.h" -#include <inttypes.h> - -int main(int argc, char **argv) +void l2_cmd_collect_args(struct l2_context_node *ctx, unsigned argc, ...) { - char **argvcur = argv + 1; - - if (!*argvcur) { - printf("done\n"); - return 1; + va_list ap; + if (argc == 0) return; + + struct tag_cmd_arg_t { + const char *name; + char **target; + bool optional; + } args[argc]; /* ooooo c99 VLA this is exciting */ + + va_start(ap, argc); + + for (unsigned i = 0; i < argc; ++i) { + args[i].name = va_arg(ap, const char *); + args[i].target = va_arg(ap, char **); + if (*args[i].name == '#') { + ++args[i].name; + args[i].optional = true; + } else { + args[i].optional = false; + } } - ((void)argc); - - struct l2_context_node *cur; - struct l2_parseinfo parseinfo; - memset(&parseinfo, 0, sizeof(struct l2_parseinfo)); - - unsigned res = l2_cmd_parse_command(argv + 1, &parseinfo); - - printf("%p %s\n", (void *)parseinfo.ctx, parseinfo.argv ? *parseinfo.argv : "(null)"); + va_end(ap); - if (res == CMD_PARSE_SUCCESS) { - cur = parseinfo.ctx; - while (cur) { - printf("%s\n", cur->value); - cur = cur->next; + for (struct l2_context_node *cur = ctx; cur; cur = cur->next) { + if (cur->node->type != CMD_NODE_TYPE_ARGUMENT) continue; + for (unsigned i = 0; i < argc; ++i) { + if (!strcmp(cur->node->name, args[i].name)) { + *args[i].target = cur->value; + args[i].optional = true; + } } - - printf("command returned: %u\n", (parseinfo.proc)(parseinfo.ctx, parseinfo.argv)); - - l2_cmd_free_ctx(parseinfo.ctx); } - return 0; + for (unsigned i = 0; i < argc; ++i) { + if (!args[i].optional) { + CMD_FATAL(CMD_MSG_REQ_ARG_UNSPECIFIED, args[i].name); + } + } } -#endif diff --git a/src/command.h b/src/command.h index 469422c..7709292 100644 --- a/src/command.h +++ b/src/command.h @@ -3,6 +3,11 @@ #include <stddef.h> +/* for CMD_ macros */ +#include <stdlib.h> +#include <string.h> +#include <errno.h> + enum { CMD_NODE_TYPE_NULL, CMD_NODE_TYPE_LITERAL, @@ -32,6 +37,29 @@ enum { CMD_PARSE_EUSAGE /* function was called with NULL arguments */ }; +#define CMD_FATAL_(_op) do { \ + _op; \ + exit(EXIT_FAILURE); \ +} while (0) + +#define CMD_MSG(_l, _s, ...) fprintf(stderr, _l ": " _s "\n", __VA_ARGS__) +#define CMD_MSG0(_l, _s) fputs(_l ": " _s "\n", stderr); + +#define CMD_FATAL(_s, ...) CMD_FATAL_(CMD_MSG("fatal", _s, __VA_ARGS__)) +#define CMD_FATAL0(_s) CMD_FATAL_(CMD_MSG0("fatal", _s)) + +#define CMD_ERROR(_s, ...) CMD_MSG("error", _s, __VA_ARGS__) +#define CMD_ERROR0(_s) CMD_MSG0("error", _s) + +#define CMD_WARN(_s, ...) CMD_MSG("warn", _s, __VA_ARGS__) +#define CMD_WARN0(_s) CMD_MSG0("warn", _s) + +#define CMD_MSG_UNKNOWN_ARGUMENT "Unknown argument '%s'." +#define CMD_MSG_REQ_ARG_UNSPECIFIED "Required argument '%s' not specified." +#define CMD_MSG_INVALID_UUID "Invalid UUID '%s'." + +#define CMD_MSG_ALLOCATION_FAILED "Allocation failed." + struct l2_command_node; struct l2_context_node { @@ -74,4 +102,18 @@ struct l2_parseinfo { unsigned l2_cmd_parse_command(char **argv, struct l2_parseinfo *parseinfo); void l2_cmd_free_ctx(struct l2_context_node *ctx); +/* DESCRIPTION: + * This function is for unpacking a bunch of arguments from a parsed command into + * string variables. + * + * HOW TO USE: + * Pass your command context followed by your arguments (const char *name, char **pvalue). + * Prefix the name with "#" if it is optional. + * + * This function will exit if a required value was not present. + * + * Example: l2_cmd_collect_args(ctx, 2, "name", &name, "#location", &path); + */ +void l2_cmd_collect_args(struct l2_context_node *ctx, unsigned argc, ...); + #endif /* include guard */ diff --git a/src/instance.c b/src/instance.c index ca80a45..8d62e1e 100644 --- a/src/instance.c +++ b/src/instance.c @@ -11,6 +11,14 @@ #include <errno.h> +const char *const l2_instance_errormsg[] = { + "Success", + "OS error", + "JSON error", + "Malformed instance file", + NULL +}; + int l2_instance__load_all_from_object(json_t *obj); json_t *l2_instance__save_all_to_object(void); @@ -116,8 +124,8 @@ int l2_instance_del_instance(struct l2_instance *inst) l2_state.instance_head = inst->next; } - free((char *)inst->name); /* okay to cast away const because any instance in the list will be allocated with strdup */ - free((char *)inst->path); + free(inst->name); /* okay to cast away const because any instance in the list will be allocated with strdup */ + free(inst->path); free(inst); return INSTANCE_SUCCESS; @@ -128,11 +136,33 @@ int l2_instance_rename_instance(struct l2_instance *inst, const char *newname) char *nn = strdup(newname); if (!nn) return INSTANCE_ERRNO; - free((char *)inst->name); + free(inst->name); inst->name = nn; return INSTANCE_SUCCESS; } +struct l2_instance *l2_instance_find_by_uuid(const uuid_t *id) +{ + for (struct l2_instance *inst = l2_state.instance_head; inst; inst = inst->next) { + if (!memcmp(id, &inst->uuid, sizeof(uuid_t))) { + return inst; + } + } + + return NULL; +} + +struct l2_instance *l2_instance_find_by_name(const char *name) +{ + for (struct l2_instance *inst = l2_state.instance_head; inst; inst = inst->next) { + if (!strcmp(inst->name, name)) { + return inst; + } + } + + return NULL; +} + /* internal utilities */ int l2_instance__load_all_from_object(json_t *obj) diff --git a/src/instance.h b/src/instance.h index 1e60df8..bcded1c 100644 --- a/src/instance.h +++ b/src/instance.h @@ -5,8 +5,8 @@ struct l2_instance { uuid_t uuid; - const char *name; - const char *path; + char *name; + char *path; struct l2_instance *next; struct l2_instance *prev; @@ -19,6 +19,8 @@ enum { INSTANCE_EFORMAT /* instance file is malformed */ }; +extern const char *const l2_instance_errormsg[]; + /* load all instances (must be called after initialization) */ int l2_instance_load_all(void); @@ -28,4 +30,7 @@ int l2_instance_add_instance(const struct l2_instance *inst); int l2_instance_del_instance(struct l2_instance *inst); int l2_instance_rename_instance(struct l2_instance *inst, const char *newname); +struct l2_instance *l2_instance_find_by_uuid(const uuid_t *id); +struct l2_instance *l2_instance_find_by_name(const char *name); + #endif /* include guard */ |
