discover/grub2: Implement load_env
[petitboot] / discover / grub2 / env.c
1
2 #include <stdio.h>
3 #include <string.h>
4
5 #include <log/log.h>
6 #include <types/types.h>
7 #include <talloc/talloc.h>
8 #include <array-size/array-size.h>
9
10 #include <discover/parser.h>
11 #include <discover/file.h>
12
13 #include "grub2.h"
14
15 static const char *default_envfile = "grubenv";
16 static const char *signature = "# GRUB Environment Block\n";
17
18 static int parse_buf_to_env(struct grub2_script *script, void *buf, int len)
19 {
20         char *tmp, *line, *sep;
21         int siglen;
22
23         siglen = strlen(signature);
24
25         if (len < siglen) {
26                 pb_log("grub environment block too small\n");
27                 return -1;
28         }
29
30         if (memcmp(buf, signature, siglen)) {
31                 pb_log("grub environment block has invalid signature\n");
32                 return -1;
33         }
34
35         buf += siglen;
36
37         for (line = strtok_r(buf, "\n", &tmp); line;
38                                 line = strtok_r(NULL, "\n", &tmp)) {
39
40                 if (*line == '#')
41                         continue;
42
43                 sep = strchr(line, '=');
44                 if (!sep)
45                         continue;
46                 if (sep == line)
47                         continue;
48
49                 *sep = '\0';
50                 script_env_set(script, line, sep + 1);
51         }
52
53         return 0;
54 }
55
56 int builtin_load_env(struct grub2_script *script,
57                 void *data __attribute__((unused)),
58                 int argc, char *argv[]);
59
60 int builtin_load_env(struct grub2_script *script,
61                 void *data __attribute__((unused)),
62                 int argc, char *argv[])
63 {
64         struct discover_device *dev = script->ctx->device;
65         const char *envfile;
66         char *buf, *envpath;
67         int rc, len;
68
69         /* we only support local filesystems */
70         if (!dev->mounted) {
71                 pb_log("load_env: can't load from a non-mounted device (%s)\n",
72                                 dev->device->id);
73                 return -1;
74         }
75
76         if (argc == 3 && !strcmp(argv[1], "-f"))
77                 envfile = argv[2];
78         else
79                 envfile = default_envfile;
80
81         envpath = talloc_asprintf(script, "%s/%s",
82                                 script_env_get(script, "prefix") ? : "",
83                                 envfile);
84
85         rc = parser_request_file(script->ctx, dev, envpath, &buf, &len);
86
87         if (!rc)
88                 rc = parse_buf_to_env(script, buf, len);
89
90         talloc_free(buf);
91
92         return 0;
93 }
94
95 int builtin_save_env(struct grub2_script *script,
96                 void *data __attribute__((unused)),
97                 int argc, char *argv[]);
98
99 int builtin_save_env(struct grub2_script *script __attribute__((unused)),
100                 void *data __attribute__((unused)),
101                 int argc __attribute__((unused)),
102                 char *argv[] __attribute__((unused)))
103 {
104         /* todo: save */
105         return 0;
106 }
107