a304f0c989e32f4e124d1f62647547b067d952b5
[petitboot] / discover / parser.c
1
2 #include <fcntl.h>
3 #include <stdlib.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6
7 #include "types/types.h"
8 #include <log/log.h>
9 #include <talloc/talloc.h>
10
11 #include "device-handler.h"
12 #include "parser.h"
13 #include "parser-utils.h"
14 #include "paths.h"
15 #include "file.h"
16
17 struct p_item {
18         struct list_item list;
19         struct parser *parser;
20 };
21
22 STATIC_LIST(parsers);
23
24 static char *local_path(struct discover_context *ctx,
25                 const char *filename)
26 {
27         return join_paths(ctx, ctx->device->mount_path, filename);
28 }
29
30 static int download_config(struct discover_context *ctx, char **buf, int *len)
31 {
32         struct load_url_result *result;
33         int rc;
34
35         result = load_url(ctx, ctx->conf_url);
36         if (!result)
37                 return -1;
38
39         rc = read_file(ctx, result->local, buf, len);
40         if (rc)
41                 goto out_clean;
42
43         return 0;
44
45 out_clean:
46         if (result->cleanup_local)
47                 unlink(result->local);
48         return -1;
49 }
50
51 static void iterate_parser_files(struct discover_context *ctx,
52                 const struct parser *parser)
53 {
54         const char * const *filename;
55         const char *path;
56
57         if (!parser->filenames)
58                 return;
59
60         for (filename = parser->filenames; *filename; filename++) {
61                 int rc, len;
62                 char *buf;
63
64                 path = local_path(ctx, *filename);
65                 if (!path)
66                         continue;
67
68                 rc = read_file(ctx, path, &buf, &len);
69                 if (!rc) {
70                         pb_log("Running parser %s on file %s\n",
71                                         parser->name, *filename);
72                         parser->parse(ctx, buf, len);
73                         talloc_free(buf);
74                 }
75         }
76 }
77
78 void iterate_parsers(struct discover_context *ctx, enum conf_method method)
79 {
80         struct p_item* i;
81         int rc, len;
82         char *buf;
83
84         pb_log("trying parsers for %s\n", ctx->device->device->id);
85
86         switch (method) {
87         case CONF_METHOD_LOCAL_FILE:
88                 list_for_each_entry(&parsers, i, list) {
89                         if (i->parser->method != CONF_METHOD_LOCAL_FILE)
90                                 continue;
91
92                         pb_log("\ttrying parser '%s'\n", i->parser->name);
93                         ctx->parser = i->parser;
94                         iterate_parser_files(ctx, ctx->parser);
95                 }
96                 ctx->parser = NULL;
97                 break;
98
99         case CONF_METHOD_DHCP:
100                 rc = download_config(ctx, &buf, &len);
101                 if (rc) {
102                         pb_log("\tdownload failed, aborting\n");
103                         return;
104                 }
105
106                 list_for_each_entry(&parsers, i, list) {
107                         if (i->parser->method != method)
108                                 continue;
109
110                         pb_log("\ttrying parser '%s'\n", i->parser->name);
111                         ctx->parser = i->parser;
112                         i->parser->parse(ctx, buf, len);
113                 }
114
115                 break;
116
117         case CONF_METHOD_UNKNOWN:
118                 break;
119
120         }
121 }
122
123 void __register_parser(struct parser *parser)
124 {
125         struct p_item* i = talloc(NULL, struct p_item);
126
127         printf("%s: %s\n", __func__, parser->name);
128
129         i->parser = parser;
130         list_add(&parsers, &i->list);
131 }
132
133 void parser_init(void)
134 {
135 }