7 #include <talloc/talloc.h>
11 #include "pb-config.h"
14 static const char *partition = "common";
15 static const char *prefix = "petitboot,";
21 struct list_item list;
24 struct powerpc_nvram_storage {
25 struct config_storage storage;
29 #define to_powerpc_nvram_storage(s) \
30 container_of(s, struct powerpc_nvram_storage, storage)
32 /* a partition max a max size of 64k * 16bytes = 1M */
33 static const int max_partition_size = 64 * 1024 * 16;
35 static int parse_nvram_params(struct powerpc_nvram_storage *nv,
38 char *pos, *name, *value;
39 unsigned int paramlen;
42 /* discard 2 header lines:
49 for (i = 0; i < len; i++) {
57 fprintf(stderr, "failure parsing nvram output\n");
61 for (pos = buf + i; pos < buf + len; pos += paramlen) {
65 paramlen = strlen(pos);
68 value = strchr(pos, '=');
72 namelen = name - value;
73 if (namelen <= strlen(prefix))
76 if (strncmp(name, prefix, strlen(prefix)))
79 name += strlen(prefix);
82 param = talloc(nv, struct param);
83 param->modified = false;
84 param->name = talloc_strndup(nv, name, namelen);
85 param->value = talloc_strdup(nv, value);
86 list_add(&nv->params, ¶m->list);
92 static int parse_nvram(struct powerpc_nvram_storage *nv)
95 int pipefds[2], status;
115 dup2(pipefds[1], STDOUT_FILENO);
116 execlp("nvram", "nvram", "--print-config",
117 "--partition", partition, NULL);
124 buf_len = max_partition_size;
125 buf = talloc_array(nv, char, buf_len);
128 rc = read(pipefds[0], buf + len, buf_len - len);
141 waitpid(pid, &status, 0);
142 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
143 fprintf(stderr, "nvram process returned "
144 "non-zero exit status\n");
151 return parse_nvram_params(nv, buf, len);
154 static const char *get_param(struct powerpc_nvram_storage *nv,
159 list_for_each_entry(&nv->params, param, list)
160 if (!strcmp(param->name, name))
165 static int parse_hwaddr(struct network_config *config, char *str)
169 if (strlen(str) != strlen("00:00:00:00:00:00"))
172 for (i = 0; i < HWADDR_SIZE; i++) {
176 byte[0] = str[i * 3 + 0];
177 byte[1] = str[i * 3 + 1];
180 x = strtoul(byte, &endp, 16);
181 if (endp != byte + 2)
184 config->hwaddr[i] = x & 0xff;
190 static int parse_one_network_config(struct network_config *config,
195 if (!confstr || !strlen(confstr))
198 /* first token should be the mac address */
199 tok = strtok_r(confstr, ",", &saveptr);
203 if (parse_hwaddr(config, tok))
206 /* second token is the method */
207 tok = strtok_r(NULL, ",", &saveptr);
208 if (!tok || !strlen(tok) || !strcmp(tok, "ignore")) {
209 config->ignore = true;
213 if (!strcmp(tok, "dhcp")) {
214 config->method = CONFIG_METHOD_DHCP;
216 } else if (!strcmp(tok, "static")) {
217 config->method = CONFIG_METHOD_STATIC;
219 /* ip/mask, [optional] gateway, [optional] dns */
220 tok = strtok_r(NULL, ",", &saveptr);
223 config->static_config.address =
224 talloc_strdup(config, tok);
226 tok = strtok_r(NULL, ",", &saveptr);
228 config->static_config.gateway =
229 talloc_strdup(config, tok);
230 tok = strtok_r(NULL, ",", &saveptr);
234 config->static_config.dns =
235 talloc_strdup(config, tok);
238 pb_log("Unknown network configuration method %s\n", tok);
245 static void populate_network_config(struct powerpc_nvram_storage *nv,
246 struct config *config)
252 cval = get_param(nv, "network");
253 if (!cval || !strlen(cval))
256 val = talloc_strdup(config, cval);
259 struct network_config *netconf;
263 tok = strtok_r(i == 0 ? val : NULL, " ", &saveptr);
267 netconf = talloc(nv, struct network_config);
269 rc = parse_one_network_config(netconf, tok);
271 talloc_free(netconf);
275 config->network_configs = talloc_realloc(nv,
276 config->network_configs,
277 struct network_config *,
278 ++config->n_network_configs);
280 config->network_configs[config->n_network_configs - 1] =
287 static void populate_config(struct powerpc_nvram_storage *nv,
288 struct config *config)
292 /* if the "auto-boot?' property is present and "false", disable auto
294 val = get_param(nv, "auto-boot?");
295 config->autoboot_enabled = !val || strcmp(val, "false");
297 populate_network_config(nv, config);
300 static int load(struct config_storage *st, struct config *config)
302 struct powerpc_nvram_storage *nv = to_powerpc_nvram_storage(st);
305 rc = parse_nvram(nv);
309 populate_config(nv, config);
314 struct config_storage *create_powerpc_nvram_storage(void *ctx)
316 struct powerpc_nvram_storage *nv;
318 nv = talloc(ctx, struct powerpc_nvram_storage);
319 nv->storage.load = load;
320 list_init(&nv->params);