Add new member get_pair to conf parser context
[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         /* fixup for bare values */
25
26         if (!name)
27                 return;
28
29         if (conf_param_in_list(ignored_names, name))
30                 return;
31
32         if (conf_set_global_option(conf, name, value))
33                 return;
34
35         /* opt must be associated with dc */
36
37         opt = talloc_zero(conf->dc->device, struct boot_option);
38
39         if (!opt)
40                 return;
41
42         opt->id = talloc_asprintf(opt, "%s#%s", conf->dc->device->id, name);
43         opt->name = talloc_strdup(opt, name);
44
45         args = talloc_strdup(opt, "");
46         initrd = conf_get_global_option(conf, "initrd");
47         root = conf_get_global_option(conf, "root");
48
49         pos = strchr(value, ' ');
50
51         /* if there's no space, it's only a kernel image with no params */
52
53         if (!pos)
54                 goto out_add;
55         *pos = 0;
56
57         for (pos++; pos;) {
58                 char *cl_name, *cl_value;
59
60                 pos = conf_get_pair_equal(conf, pos, &cl_name, &cl_value, ' ');
61
62                 if (!cl_name) {
63                         args = talloc_asprintf_append(args, "%s ", cl_value);
64                         continue;
65                 }
66
67                 if (streq(cl_name, "initrd")) {
68                         initrd = cl_value;
69                         continue;
70                 }
71
72                 if (streq(cl_name, "root")) {
73                         root = cl_value;
74                         continue;
75                 }
76
77                 args = talloc_asprintf_append(args, "%s=%s ", cl_name,
78                         cl_value);
79         }
80
81 out_add:
82         opt->boot_image_file = resolve_path(opt, value, conf->dc->device_path);
83
84         if (root) {
85                 opt->boot_args = talloc_asprintf(opt, "root=%s %s", root, args);
86                 talloc_free(args);
87         } else
88                 opt->boot_args = args;
89
90         if (initrd) {
91                 opt->initrd_file = resolve_path(opt, initrd,
92                                 conf->dc->device_path);
93
94                 opt->description = talloc_asprintf(opt, "%s initrd=%s %s",
95                         value, initrd, opt->boot_args);
96         } else
97                 opt->description = talloc_asprintf(opt, "%s %s", value,
98                         opt->boot_args);
99
100         conf_strip_str(opt->boot_args);
101         conf_strip_str(opt->description);
102
103         device_add_boot_option(conf->dc->device, opt);
104 }
105
106 static struct conf_global_option kboot_global_options[] = {
107         { .name = "initrd" },
108         { .name = "root" },
109         { .name = "video" },
110         { .name = NULL }
111 };
112
113 static const char *const kboot_conf_files[] = {
114         "/kboot.conf",
115         "/kboot.cnf",
116         "/etc/kboot.conf",
117         "/etc/kboot.cnf",
118         "/KBOOT.CONF",
119         "/KBOOT.CNF",
120         "/ETC/KBOOT.CONF",
121         "/ETC/KBOOT.CNF",
122         NULL
123 };
124
125 static const char *const kboot_ignored_names[] = {
126         "default",
127         "delay",
128         "message",
129         "timeout",
130         NULL
131 };
132
133 static int kboot_parse(struct discover_context *dc)
134 {
135         struct conf_context *conf;
136         int rc;
137
138         conf = talloc_zero(dc, struct conf_context);
139
140         if (!conf)
141                 return 0;
142
143         conf->dc = dc;
144         conf->global_options = kboot_global_options,
145         conf_init_global_options(conf);
146         conf->conf_files = kboot_conf_files,
147         conf->get_pair = conf_get_pair_equal;
148         conf->process_pair = kboot_process_pair;
149         conf->parser_info = (void *)kboot_ignored_names,
150
151         rc = conf_parse(conf);
152
153         talloc_free(conf);
154         return rc;
155 }
156
157 define_parser(kboot, kboot_parse);