6 #include <types/types.h>
7 #include <talloc/talloc.h>
8 #include <array-size/array-size.h>
13 static int builtin_set(struct grub2_script *script,
14 void *data __attribute__((unused)),
15 int argc, char *argv[])
17 char *name, *value, *p;
23 p = strchr(argv[1], '=');
27 name = talloc_strndup(script, argv[1], p - argv[1]);
28 value = talloc_strdup(script, p+1);
30 for (i = 2; i < argc; i++)
31 value = talloc_asprintf_append(value, " %s", argv[i]);
33 script_env_set(script, name, value);
38 static int builtin_linux(struct grub2_script *script,
39 void *data __attribute__((unused)),
40 int argc, char *argv[])
42 struct discover_boot_option *opt = script->opt;
47 pb_log("grub2 syntax error: 'linux' statement outside "
53 pb_log("grub2 syntax error: no filename provided to "
58 root = script_env_get(script, "root");
60 opt->boot_image = create_grub2_resource(opt, script->ctx->device,
62 opt->option->boot_args = NULL;
65 opt->option->boot_args = talloc_strdup(opt, argv[2]);
67 for (i = 3; i < argc; i++)
68 opt->option->boot_args = talloc_asprintf_append(
69 opt->option->boot_args,
74 static int builtin_initrd(struct grub2_script *script,
75 void *data __attribute__((unused)),
76 int argc, char *argv[])
78 struct discover_boot_option *opt = script->opt;
82 pb_log("grub2 syntax error: 'initrd' statement outside "
88 pb_log("grub2 syntax error: no filename provided to "
89 "initrd statement\n");
93 root = script_env_get(script, "root");
94 opt->initrd = create_grub2_resource(opt, script->ctx->device,
100 static int builtin_search(struct grub2_script *script,
101 void *data __attribute__((unused)),
102 int argc, char *argv[])
104 const char *env_var, *spec;
109 for (i = 1; i < argc - 1; i++) {
110 if (!strncmp(argv[i], "--set=", strlen("--set="))) {
111 env_var = argv[i] + strlen("--set=");
119 spec = argv[argc - 1];
121 script_env_set(script, env_var, spec);
126 static bool builtin_test_op(int argc, char **argv, int *consumed)
137 if (!strcmp(op, "=") || !strcmp(op, "==")) {
139 return !strcmp(a1, a2);
142 if (!strcmp(op, "!=")) {
144 return strcmp(a1, a2);
147 if (!strcmp(op, "<")) {
149 return strcmp(a1, a2) < 0;
152 if (!strcmp(op, ">")) {
154 return strcmp(a1, a2) > 0;
164 if (!strcmp(op, "-z")) {
166 return strlen(a1) == 0;
169 if (!strcmp(op, "-n")) {
171 return strlen(a1) != 0;
174 /* todo: implement file checks */
175 if (!strcmp(op, "-s") || !strcmp(op, "-f")) {
182 return strlen(op) > 0;
185 static int builtin_test(struct grub2_script *script __attribute__((unused)),
186 void *data __attribute__((unused)),
187 int argc, char *argv[])
192 if (!strcmp(argv[0], "[") && !strcmp(argv[argc - 1], "]"))
195 /* skip command name */
202 for (consumed = 0; argc > 0; argv += consumed, argc -= consumed) {
204 if (!strcmp(argv[0], "!")) {
210 if (!strcmp(argv[0], "-a")) {
217 if (!strcmp(argv[0], "-o")) {
224 rc = builtin_test_op(argc, argv, &consumed);
234 static int builtin_nop(struct grub2_script *script __attribute__((unused)),
235 void *data __attribute__((unused)),
236 int argc __attribute__((unused)),
237 char *argv[] __attribute__((unused)))
260 .fn = builtin_initrd,
264 .fn = builtin_search,
276 static const char *nops[] = {
277 "echo", "export", "insmod", "loadfont", "terminfo",
280 void register_builtins(struct grub2_script *script)
284 for (i = 0; i < ARRAY_SIZE(builtins); i++)
285 script_register_function(script, builtins[i].name,
286 builtins[i].fn, NULL);
288 for (i = 0; i < ARRAY_SIZE(nops); i++)
289 script_register_function(script, nops[i], builtin_nop, NULL);