summaryrefslogtreecommitdiffstats
path: root/discover
diff options
context:
space:
mode:
Diffstat (limited to 'discover')
-rw-r--r--discover/grub2/Makefile.am1
-rw-r--r--discover/grub2/builtins.c8
-rw-r--r--discover/grub2/env.c107
3 files changed, 116 insertions, 0 deletions
diff --git a/discover/grub2/Makefile.am b/discover/grub2/Makefile.am
index 71f3282..902f94f 100644
--- a/discover/grub2/Makefile.am
+++ b/discover/grub2/Makefile.am
@@ -30,6 +30,7 @@ grub2-parser.ro$(EXEEXT): $(grub2_parser_ro_OBJECTS)
grub2_parser_ro_SOURCES = \
builtins.c \
+ env.c \
grub2.h \
grub2.c \
lexer.l \
diff --git a/discover/grub2/builtins.c b/discover/grub2/builtins.c
index 7a5d867..71ae61a 100644
--- a/discover/grub2/builtins.c
+++ b/discover/grub2/builtins.c
@@ -256,6 +256,10 @@ static int builtin_nop(struct grub2_script *script __attribute__((unused)),
return 0;
}
+extern int builtin_load_env(struct grub2_script *script,
+ void *data __attribute__((unused)),
+ int argc, char *argv[]);
+
static struct {
const char *name;
grub2_function fn;
@@ -296,6 +300,10 @@ static struct {
.name = "false",
.fn = builtin_false,
},
+ {
+ .name = "load_env",
+ .fn = builtin_load_env,
+ },
};
static const char *nops[] = {
diff --git a/discover/grub2/env.c b/discover/grub2/env.c
new file mode 100644
index 0000000..e28c9fe
--- /dev/null
+++ b/discover/grub2/env.c
@@ -0,0 +1,107 @@
+
+#include <stdio.h>
+#include <string.h>
+
+#include <log/log.h>
+#include <types/types.h>
+#include <talloc/talloc.h>
+#include <array-size/array-size.h>
+
+#include <discover/parser.h>
+#include <discover/file.h>
+
+#include "grub2.h"
+
+static const char *default_envfile = "grubenv";
+static const char *signature = "# GRUB Environment Block\n";
+
+static int parse_buf_to_env(struct grub2_script *script, void *buf, int len)
+{
+ char *tmp, *line, *sep;
+ int siglen;
+
+ siglen = strlen(signature);
+
+ if (len < siglen) {
+ pb_log("grub environment block too small\n");
+ return -1;
+ }
+
+ if (memcmp(buf, signature, siglen)) {
+ pb_log("grub environment block has invalid signature\n");
+ return -1;
+ }
+
+ buf += siglen;
+
+ for (line = strtok_r(buf, "\n", &tmp); line;
+ line = strtok_r(NULL, "\n", &tmp)) {
+
+ if (*line == '#')
+ continue;
+
+ sep = strchr(line, '=');
+ if (!sep)
+ continue;
+ if (sep == line)
+ continue;
+
+ *sep = '\0';
+ script_env_set(script, line, sep + 1);
+ }
+
+ return 0;
+}
+
+int builtin_load_env(struct grub2_script *script,
+ void *data __attribute__((unused)),
+ int argc, char *argv[]);
+
+int builtin_load_env(struct grub2_script *script,
+ void *data __attribute__((unused)),
+ int argc, char *argv[])
+{
+ struct discover_device *dev = script->ctx->device;
+ const char *envfile;
+ char *buf, *envpath;
+ int rc, len;
+
+ /* we only support local filesystems */
+ if (!dev->mounted) {
+ pb_log("load_env: can't load from a non-mounted device (%s)\n",
+ dev->device->id);
+ return -1;
+ }
+
+ if (argc == 3 && !strcmp(argv[1], "-f"))
+ envfile = argv[2];
+ else
+ envfile = default_envfile;
+
+ envpath = talloc_asprintf(script, "%s/%s",
+ script_env_get(script, "prefix") ? : "",
+ envfile);
+
+ rc = parser_request_file(script->ctx, dev, envpath, &buf, &len);
+
+ if (!rc)
+ rc = parse_buf_to_env(script, buf, len);
+
+ talloc_free(buf);
+
+ return 0;
+}
+
+int builtin_save_env(struct grub2_script *script,
+ void *data __attribute__((unused)),
+ int argc, char *argv[]);
+
+int builtin_save_env(struct grub2_script *script __attribute__((unused)),
+ void *data __attribute__((unused)),
+ int argc __attribute__((unused)),
+ char *argv[] __attribute__((unused)))
+{
+ /* todo: save */
+ return 0;
+}
+
OpenPOWER on IntegriCloud