Use yaboot global boot option
[petitboot] / discover / kboot-parser.c
1 #define _GNU_SOURCE
2
3 #include <assert.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include "log/log.h"
8 #include "talloc/talloc.h"
9 #include "pb-protocol/pb-protocol.h"
10 #include "parser-conf.h"
11 #include "parser-utils.h"
12 #include "paths.h"
13
14 static void kboot_process_pair(struct conf_context *conf, const char *name,
15                 char *value)
16 {
17         const char *const *ignored_names = conf->parser_info;
18         char *pos;
19         char *args;
20         const char *initrd;
21         const char *root;
22         struct boot_option *opt;
23
24         if (conf_param_in_list(ignored_names, name))
25                 return;
26
27         if (conf_set_global_option(conf, name, value))
28                 return;
29
30         /* opt must be associated with dc */
31
32         opt = talloc_zero(conf->dc->device, struct boot_option);
33
34         if (!opt)
35                 return;
36
37         opt->id = talloc_asprintf(opt, "%s#%s", conf->dc->device->id, name);
38         opt->name = talloc_strdup(opt, name);
39
40         args = talloc_strdup(opt, "");
41         initrd = conf_get_global_option(conf, "initrd");
42         root = conf_get_global_option(conf, "root");
43
44         pos = strchr(value, ' ');
45
46         /* if there's no space, it's only a kernel image with no params */
47
48         if (!pos)
49                 goto out_add;
50         *pos = 0;
51
52         for (pos++; pos;) {
53                 char *cl_name, *cl_value;
54
55                 pos = conf_get_param_pair(pos, &cl_name, &cl_value, ' ');
56
57                 if (!cl_name) {
58                         args = talloc_asprintf_append(args, "%s ", cl_value);
59                         continue;
60                 }
61
62                 if (streq(cl_name, "initrd")) {
63                         initrd = cl_value;
64                         continue;
65                 }
66
67                 if (streq(cl_name, "root")) {
68                         root = cl_value;
69                         continue;
70                 }
71
72                 args = talloc_asprintf_append(args, "%s=%s ", cl_name,
73                         cl_value);
74         }
75
76 out_add:
77         opt->boot_image_file = resolve_path(opt, value, conf->dc->device_path);
78
79         if (root) {
80                 opt->boot_args = talloc_asprintf(opt, "root=%s %s", root, args);
81                 talloc_free(args);
82         } else
83                 opt->boot_args = args;
84
85         if (initrd) {
86                 opt->initrd_file = resolve_path(opt, initrd,
87                                 conf->dc->device_path);
88
89                 opt->description = talloc_asprintf(opt, "%s initrd=%s %s",
90                         value, initrd, opt->boot_args);
91         } else
92                 opt->description = talloc_asprintf(opt, "%s %s", value,
93                         opt->boot_args);
94
95         conf_strip_str(opt->boot_args);
96         conf_strip_str(opt->description);
97
98         device_add_boot_option(conf->dc->device, opt);
99 }
100
101 static struct conf_global_option kboot_global_options[] = {
102         { .name = "initrd" },
103         { .name = "root" },
104         { .name = "video" },
105         { .name = NULL }
106 };
107
108 static const char *const kboot_conf_files[] = {
109         "/kboot.conf",
110         "/kboot.cnf",
111         "/etc/kboot.conf",
112         "/etc/kboot.cnf",
113         "/KBOOT.CONF",
114         "/KBOOT.CNF",
115         "/ETC/KBOOT.CONF",
116         "/ETC/KBOOT.CNF",
117         NULL
118 };
119
120 static const char *const kboot_ignored_names[] = {
121         "default",
122         "delay",
123         "message",
124         "timeout",
125         NULL
126 };
127
128 static int kboot_parse(struct discover_context *dc)
129 {
130         struct conf_context *conf;
131         int rc;
132
133         conf = talloc_zero(dc, struct conf_context);
134
135         if (!conf)
136                 return -1;
137
138         conf->dc = dc;
139         conf->global_options = kboot_global_options,
140         conf_init_global_options(conf);
141         conf->conf_files = kboot_conf_files,
142         conf->process_pair = kboot_process_pair;
143         conf->parser_info = (void *)kboot_ignored_names,
144
145         rc = conf_parse(conf);
146
147         talloc_free(conf);
148         return rc;
149 }
150
151 define_parser(kboot, 98, kboot_parse);