7 #include <talloc/talloc.h>
10 #include <process/process.h>
12 #include "pb-config.h"
15 static const char *partition = "common";
21 struct list_item list;
24 struct powerpc_nvram_storage {
25 struct config_storage storage;
29 static const char *known_params[] = {
35 #define to_powerpc_nvram_storage(s) \
36 container_of(s, struct powerpc_nvram_storage, storage)
38 /* a partition max a max size of 64k * 16bytes = 1M */
39 static const int max_partition_size = 64 * 1024 * 16;
41 static bool param_is_known(const char *param, unsigned int len)
43 const char *known_param;
46 for (i = 0; known_params[i]; i++) {
47 known_param = known_params[i];
48 if (len == strlen(known_param) &&
49 !strncmp(param, known_param, len))
56 static int parse_nvram_params(struct powerpc_nvram_storage *nv,
59 char *pos, *name, *value;
60 unsigned int paramlen;
63 /* discard 2 header lines:
70 for (i = 0; i < len; i++) {
78 fprintf(stderr, "failure parsing nvram output\n");
82 for (pos = buf + i; pos < buf + len; pos += paramlen + 1) {
87 newline = strchr(pos, '\n');
93 paramlen = strlen(pos);
96 value = strchr(pos, '=');
100 namelen = value - name;
104 if (!param_is_known(name, namelen))
109 param = talloc(nv, struct param);
110 param->modified = false;
111 param->name = talloc_strndup(nv, name, namelen);
112 param->value = talloc_strdup(nv, value);
113 list_add(&nv->params, ¶m->list);
119 static int parse_nvram(struct powerpc_nvram_storage *nv)
121 struct process *process;
126 argv[1] = "--print-config";
127 argv[2] = "--partition";
131 process = process_create(nv);
132 process->path = "nvram";
133 process->argv = argv;
134 process->keep_stdout = true;
136 rc = process_run_sync(process);
138 if (rc || !WIFEXITED(process->exit_status)
139 || WEXITSTATUS(process->exit_status)) {
140 fprintf(stderr, "nvram process returned "
141 "non-zero exit status\n");
144 rc = parse_nvram_params(nv, process->stdout_buf,
145 process->stdout_len);
148 process_release(process);
152 static const char *get_param(struct powerpc_nvram_storage *nv,
157 list_for_each_entry(&nv->params, param, list)
158 if (!strcmp(param->name, name))
163 static int parse_hwaddr(struct interface_config *ifconf, char *str)
167 if (strlen(str) != strlen("00:00:00:00:00:00"))
170 for (i = 0; i < HWADDR_SIZE; i++) {
174 byte[0] = str[i * 3 + 0];
175 byte[1] = str[i * 3 + 1];
178 x = strtoul(byte, &endp, 16);
179 if (endp != byte + 2)
182 ifconf->hwaddr[i] = x & 0xff;
188 static int parse_one_interface_config(struct config *config,
191 struct interface_config *ifconf;
194 ifconf = talloc(config, struct interface_config);
196 if (!confstr || !strlen(confstr))
199 /* first token should be the mac address */
200 tok = strtok_r(confstr, ",", &saveptr);
204 if (parse_hwaddr(ifconf, tok))
207 /* second token is the method */
208 tok = strtok_r(NULL, ",", &saveptr);
209 if (!tok || !strlen(tok) || !strcmp(tok, "ignore")) {
210 ifconf->ignore = true;
212 } else if (!strcmp(tok, "dhcp")) {
213 ifconf->method = CONFIG_METHOD_DHCP;
215 } else if (!strcmp(tok, "static")) {
216 ifconf->method = CONFIG_METHOD_STATIC;
218 /* ip/mask, [optional] gateway */
219 tok = strtok_r(NULL, ",", &saveptr);
222 ifconf->static_config.address =
223 talloc_strdup(ifconf, tok);
225 tok = strtok_r(NULL, ",", &saveptr);
227 ifconf->static_config.gateway =
228 talloc_strdup(ifconf, tok);
232 pb_log("Unknown network configuration method %s\n", tok);
236 config->network.interfaces = talloc_realloc(config,
237 config->network.interfaces,
238 struct interface_config *,
239 ++config->network.n_interfaces);
241 config->network.interfaces[config->network.n_interfaces - 1] = ifconf;
249 static int parse_one_dns_config(struct config *config,
254 for (tok = strtok_r(confstr, ",", &saveptr); tok;
255 tok = strtok_r(NULL, ",", &saveptr)) {
257 char *server = talloc_strdup(config, tok);
259 config->network.dns_servers = talloc_realloc(config,
260 config->network.dns_servers, const char *,
261 ++config->network.n_dns_servers);
263 config->network.dns_servers[config->network.n_dns_servers - 1]
270 static void populate_network_config(struct powerpc_nvram_storage *nv,
271 struct config *config)
277 cval = get_param(nv, "petitboot,network");
278 if (!cval || !strlen(cval))
281 val = talloc_strdup(config, cval);
286 tok = strtok_r(i == 0 ? val : NULL, " ", &saveptr);
290 if (!strncasecmp(tok, "dns,", strlen("dns,")))
291 parse_one_dns_config(config, tok + strlen("dns,"));
293 parse_one_interface_config(config, tok);
300 static void populate_config(struct powerpc_nvram_storage *nv,
301 struct config *config)
305 /* if the "auto-boot?' property is present and "false", disable auto
307 val = get_param(nv, "auto-boot?");
308 config->autoboot_enabled = !val || strcmp(val, "false");
310 populate_network_config(nv, config);
313 static int load(struct config_storage *st, struct config *config)
315 struct powerpc_nvram_storage *nv = to_powerpc_nvram_storage(st);
318 rc = parse_nvram(nv);
322 populate_config(nv, config);
327 struct config_storage *create_powerpc_nvram_storage(void *ctx)
329 struct powerpc_nvram_storage *nv;
331 nv = talloc(ctx, struct powerpc_nvram_storage);
332 nv->storage.load = load;
333 list_init(&nv->params);