From fcbb46482c413192756ce865a7336c5638fda6d3 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 27 Sep 2013 14:21:53 +0800 Subject: discover/grub2: Implement load_env Use the new parser_request_file API to access the GRUB environment block. Signed-off-by: Jeremy Kerr --- discover/grub2/Makefile.am | 1 + discover/grub2/builtins.c | 8 ++++ discover/grub2/env.c | 107 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 discover/grub2/env.c (limited to 'discover') 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 +#include + +#include +#include +#include +#include + +#include +#include + +#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; +} + -- cgit v1.2.1