]> git.ozlabs.org Git - petitboot/blob - discover/grub2/grub2.c
discover/grub2: Fixes for bison 3.x
[petitboot] / discover / grub2 / grub2.c
1
2 #include <assert.h>
3 #include <string.h>
4
5 #include <talloc/talloc.h>
6 #include <url/url.h>
7
8 #include <discover/resource.h>
9 #include <discover/parser.h>
10 #include <discover/parser-utils.h>
11
12 #include "grub2.h"
13
14 static const char *const grub2_conf_files[] = {
15         "/grub.cfg",
16         "/menu.lst",
17         "/grub/grub.cfg",
18         "/grub2/grub.cfg",
19         "/grub/menu.lst",
20         "/boot/grub/grub.cfg",
21         "/boot/grub2/grub.cfg",
22         "/boot/grub/menu.lst",
23         "/GRUB.CFG",
24         "/MENU.LST",
25         "/GRUB/GRUB.CFG",
26         "/GRUB2/GRUB.CFG",
27         "/GRUB/MENU.LST",
28         "/BOOT/GRUB/GRUB.CFG",
29         "/BOOT/GRUB/MENU.LST",
30         NULL
31 };
32
33 struct grub2_resource_info {
34         char *root;
35         char *path;
36 };
37
38 /* we use slightly different resources for grub2 */
39 struct resource *create_grub2_resource(struct discover_boot_option *opt,
40                 struct discover_device *orig_device,
41                 const char *root, const char *path)
42 {
43         struct grub2_resource_info *info;
44         struct resource *res;
45
46         if (strstr(path, "://")) {
47                 struct pb_url *url = pb_url_parse(opt, path);
48                 if (url)
49                         return create_url_resource(opt, url);
50         }
51
52         res = talloc(opt, struct resource);
53
54         if (root) {
55                 info = talloc(res, struct grub2_resource_info);
56                 talloc_reference(info, root);
57                 info->root = talloc_strdup(info, root);
58                 info->path = talloc_strdup(info, path);
59
60                 res->resolved = false;
61                 res->info = info;
62
63         } else
64                 resolve_resource_against_device(res, orig_device, path);
65
66         return res;
67 }
68
69 bool resolve_grub2_resource(struct device_handler *handler,
70                 struct resource *res)
71 {
72         struct grub2_resource_info *info = res->info;
73         struct discover_device *dev;
74
75         assert(!res->resolved);
76
77         dev = device_lookup_by_uuid(handler, info->root);
78
79         if (!dev)
80                 return false;
81
82         resolve_resource_against_device(res, dev, info->path);
83         talloc_free(info);
84
85         return true;
86 }
87
88 static int grub2_parse(struct discover_context *dc)
89 {
90         const char * const *filename;
91         struct grub2_parser *parser;
92         int len, rc;
93         char *buf;
94
95         /* Support block device boot only at present */
96         if (dc->event)
97                 return -1;
98
99         for (filename = grub2_conf_files; *filename; filename++) {
100                 rc = parser_request_file(dc, dc->device, *filename, &buf, &len);
101                 if (rc)
102                         continue;
103
104                 parser = grub2_parser_create(dc);
105                 grub2_parser_parse(parser, *filename, buf, len);
106                 talloc_free(buf);
107                 talloc_free(parser);
108                 break;
109         }
110
111
112         return 0;
113 }
114
115 static struct parser grub2_parser = {
116         .name                   = "grub2",
117         .parse                  = grub2_parse,
118         .resolve_resource       = resolve_grub2_resource,
119 };
120
121 register_parser(grub2_parser);