7 #include <talloc/talloc.h>
11 #include "pb-config.h"
14 static const char *partition = "common";
20 struct list_item list;
23 struct powerpc_nvram_storage {
24 struct config_storage storage;
28 static const char *known_params[] = {
34 #define to_powerpc_nvram_storage(s) \
35 container_of(s, struct powerpc_nvram_storage, storage)
37 /* a partition max a max size of 64k * 16bytes = 1M */
38 static const int max_partition_size = 64 * 1024 * 16;
40 static bool param_is_known(const char *param, unsigned int len)
42 const char *known_param;
45 for (i = 0; known_params[i]; i++) {
46 known_param = known_params[i];
47 if (len == strlen(known_param) &&
48 !strncmp(param, known_param, len))
55 static int parse_nvram_params(struct powerpc_nvram_storage *nv,
58 char *pos, *name, *value;
59 unsigned int paramlen;
62 /* discard 2 header lines:
69 for (i = 0; i < len; i++) {
77 fprintf(stderr, "failure parsing nvram output\n");
81 for (pos = buf + i; pos < buf + len; pos += paramlen + 1) {
86 newline = strchr(pos, '\n');
92 paramlen = strlen(pos);
95 value = strchr(pos, '=');
99 namelen = value - name;
103 if (!param_is_known(name, namelen))
108 param = talloc(nv, struct param);
109 param->modified = false;
110 param->name = talloc_strndup(nv, name, namelen);
111 param->value = talloc_strdup(nv, value);
112 list_add(&nv->params, ¶m->list);
118 static int parse_nvram(struct powerpc_nvram_storage *nv)
120 int rc, len, buf_len;
121 int pipefds[2], status;
141 dup2(pipefds[1], STDOUT_FILENO);
142 execlp("nvram", "nvram", "--print-config",
143 "--partition", partition, NULL);
150 buf_len = max_partition_size;
151 buf = talloc_array(nv, char, buf_len);
154 rc = read(pipefds[0], buf + len, buf_len - len);
167 waitpid(pid, &status, 0);
168 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
169 fprintf(stderr, "nvram process returned "
170 "non-zero exit status\n");
177 return parse_nvram_params(nv, buf, len);
180 static const char *get_param(struct powerpc_nvram_storage *nv,
185 list_for_each_entry(&nv->params, param, list)
186 if (!strcmp(param->name, name))
191 static int parse_hwaddr(struct network_config *config, char *str)
195 if (strlen(str) != strlen("00:00:00:00:00:00"))
198 for (i = 0; i < HWADDR_SIZE; i++) {
202 byte[0] = str[i * 3 + 0];
203 byte[1] = str[i * 3 + 1];
206 x = strtoul(byte, &endp, 16);
207 if (endp != byte + 2)
210 config->hwaddr[i] = x & 0xff;
216 static int parse_one_network_config(struct network_config *config,
221 if (!confstr || !strlen(confstr))
224 /* first token should be the mac address */
225 tok = strtok_r(confstr, ",", &saveptr);
229 if (parse_hwaddr(config, tok))
232 /* second token is the method */
233 tok = strtok_r(NULL, ",", &saveptr);
234 if (!tok || !strlen(tok) || !strcmp(tok, "ignore")) {
235 config->ignore = true;
239 if (!strcmp(tok, "dhcp")) {
240 config->method = CONFIG_METHOD_DHCP;
242 } else if (!strcmp(tok, "static")) {
243 config->method = CONFIG_METHOD_STATIC;
245 /* ip/mask, [optional] gateway, [optional] dns */
246 tok = strtok_r(NULL, ",", &saveptr);
249 config->static_config.address =
250 talloc_strdup(config, tok);
252 tok = strtok_r(NULL, ",", &saveptr);
254 config->static_config.gateway =
255 talloc_strdup(config, tok);
256 tok = strtok_r(NULL, ",", &saveptr);
260 config->static_config.dns =
261 talloc_strdup(config, tok);
264 pb_log("Unknown network configuration method %s\n", tok);
271 static void populate_network_config(struct powerpc_nvram_storage *nv,
272 struct config *config)
278 cval = get_param(nv, "petitboot,network");
279 if (!cval || !strlen(cval))
282 val = talloc_strdup(config, cval);
285 struct network_config *netconf;
289 tok = strtok_r(i == 0 ? val : NULL, " ", &saveptr);
293 netconf = talloc(nv, struct network_config);
295 rc = parse_one_network_config(netconf, tok);
297 talloc_free(netconf);
301 config->network_configs = talloc_realloc(nv,
302 config->network_configs,
303 struct network_config *,
304 ++config->n_network_configs);
306 config->network_configs[config->n_network_configs - 1] =
313 static void populate_config(struct powerpc_nvram_storage *nv,
314 struct config *config)
318 /* if the "auto-boot?' property is present and "false", disable auto
320 val = get_param(nv, "auto-boot?");
321 config->autoboot_enabled = !val || strcmp(val, "false");
323 populate_network_config(nv, config);
326 static int load(struct config_storage *st, struct config *config)
328 struct powerpc_nvram_storage *nv = to_powerpc_nvram_storage(st);
331 rc = parse_nvram(nv);
335 populate_config(nv, config);
340 struct config_storage *create_powerpc_nvram_storage(void *ctx)
342 struct powerpc_nvram_storage *nv;
344 nv = talloc(ctx, struct powerpc_nvram_storage);
345 nv->storage.load = load;
346 list_init(&nv->params);