X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=lib%2Fpb-config%2Fstorage-powerpc-nvram.c;h=7c8b9e156dfc6a1e4540d24fc3bc4c61f689d52d;hp=96d279c4041dc65d7a950e883d3342575de16bb2;hb=823958fb;hpb=4a9725bb74e7a05731eff0b9166c4d1e99b7064d diff --git a/lib/pb-config/storage-powerpc-nvram.c b/lib/pb-config/storage-powerpc-nvram.c index 96d279c..7c8b9e1 100644 --- a/lib/pb-config/storage-powerpc-nvram.c +++ b/lib/pb-config/storage-powerpc-nvram.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "pb-config.h" #include "storage.h" @@ -78,9 +79,16 @@ static int parse_nvram_params(struct powerpc_nvram_storage *nv, return -1; } - for (pos = buf + i; pos < buf + len; pos += paramlen) { + for (pos = buf + i; pos < buf + len; pos += paramlen + 1) { unsigned int namelen; struct param *param; + char *newline; + + newline = strchr(pos, '\n'); + if (!newline) + break; + + *newline = '\0'; paramlen = strlen(pos); @@ -89,7 +97,9 @@ static int parse_nvram_params(struct powerpc_nvram_storage *nv, if (!value) continue; - namelen = name - value; + namelen = value - name; + if (namelen == 0) + continue; if (!param_is_known(name, namelen)) continue; @@ -108,64 +118,35 @@ static int parse_nvram_params(struct powerpc_nvram_storage *nv, static int parse_nvram(struct powerpc_nvram_storage *nv) { - int rc, len, buf_len; - int pipefds[2], status; - char *buf; - pid_t pid; - - rc = pipe(pipefds); - if (rc) { - perror("pipe"); - return -1; - } - - pid = fork(); - - if (pid < 0) { - perror("fork"); - return -1; - } - - if (pid == 0) { - close(STDIN_FILENO); - close(pipefds[0]); - dup2(pipefds[1], STDOUT_FILENO); - execlp("nvram", "nvram", "--print-config", - "--partition", partition, NULL); - exit(EXIT_FAILURE); - } - - close(pipefds[1]); - - len = 0; - buf_len = max_partition_size; - buf = talloc_array(nv, char, buf_len); + struct process *process; + const char *argv[5]; + int rc; - for (;;) { - rc = read(pipefds[0], buf + len, buf_len - len); + argv[0] = "nvram"; + argv[1] = "--print-config"; + argv[2] = "--partition"; + argv[3] = partition; + argv[4] = NULL; - if (rc < 0) { - perror("read"); - break; - } + process = process_create(nv); + process->path = "nvram"; + process->argv = argv; + process->keep_stdout = true; - if (rc == 0) - break; - - len += rc; - } + rc = process_run_sync(process); - waitpid(pid, &status, 0); - if (!WIFEXITED(status) || WEXITSTATUS(status)) { + if (rc || !WIFEXITED(process->exit_status) + || WEXITSTATUS(process->exit_status)) { fprintf(stderr, "nvram process returned " "non-zero exit status\n"); - return -1; + rc = -1; + } else { + rc = parse_nvram_params(nv, process->stdout_buf, + process->stdout_len); } - if (rc < 0) - return rc; - - return parse_nvram_params(nv, buf, len); + process_release(process); + return rc; } static const char *get_param(struct powerpc_nvram_storage *nv, @@ -179,7 +160,7 @@ static const char *get_param(struct powerpc_nvram_storage *nv, return NULL; } -static int parse_hwaddr(struct network_config *config, char *str) +static int parse_hwaddr(struct interface_config *ifconf, char *str) { int i; @@ -198,62 +179,89 @@ static int parse_hwaddr(struct network_config *config, char *str) if (endp != byte + 2) return -1; - config->hwaddr[i] = x & 0xff; + ifconf->hwaddr[i] = x & 0xff; } return 0; } -static int parse_one_network_config(struct network_config *config, +static int parse_one_interface_config(struct config *config, char *confstr) { + struct interface_config *ifconf; char *tok, *saveptr; + ifconf = talloc(config, struct interface_config); + if (!confstr || !strlen(confstr)) - return -1; + goto out_err; /* first token should be the mac address */ tok = strtok_r(confstr, ",", &saveptr); if (!tok) - return -1; + goto out_err; - if (parse_hwaddr(config, tok)) - return -1; + if (parse_hwaddr(ifconf, tok)) + goto out_err; /* second token is the method */ tok = strtok_r(NULL, ",", &saveptr); if (!tok || !strlen(tok) || !strcmp(tok, "ignore")) { - config->ignore = true; - return 0; - } + ifconf->ignore = true; - if (!strcmp(tok, "dhcp")) { - config->method = CONFIG_METHOD_DHCP; + } else if (!strcmp(tok, "dhcp")) { + ifconf->method = CONFIG_METHOD_DHCP; } else if (!strcmp(tok, "static")) { - config->method = CONFIG_METHOD_STATIC; + ifconf->method = CONFIG_METHOD_STATIC; - /* ip/mask, [optional] gateway, [optional] dns */ + /* ip/mask, [optional] gateway */ tok = strtok_r(NULL, ",", &saveptr); if (!tok) - return -1; - config->static_config.address = - talloc_strdup(config, tok); + goto out_err; + ifconf->static_config.address = + talloc_strdup(ifconf, tok); tok = strtok_r(NULL, ",", &saveptr); if (tok) { - config->static_config.gateway = - talloc_strdup(config, tok); - tok = strtok_r(NULL, ",", &saveptr); + ifconf->static_config.gateway = + talloc_strdup(ifconf, tok); } - if (tok) { - config->static_config.dns = - talloc_strdup(config, tok); - } } else { pb_log("Unknown network configuration method %s\n", tok); - return -1; + goto out_err; + } + + config->network.interfaces = talloc_realloc(config, + config->network.interfaces, + struct interface_config *, + ++config->network.n_interfaces); + + config->network.interfaces[config->network.n_interfaces - 1] = ifconf; + + return 0; +out_err: + talloc_free(ifconf); + return -1; +} + +static int parse_one_dns_config(struct config *config, + char *confstr) +{ + char *tok, *saveptr; + + for (tok = strtok_r(confstr, ",", &saveptr); tok; + tok = strtok_r(NULL, ",", &saveptr)) { + + char *server = talloc_strdup(config, tok); + + config->network.dns_servers = talloc_realloc(config, + config->network.dns_servers, const char *, + ++config->network.n_dns_servers); + + config->network.dns_servers[config->network.n_dns_servers - 1] + = server; } return 0; @@ -273,29 +281,17 @@ static void populate_network_config(struct powerpc_nvram_storage *nv, val = talloc_strdup(config, cval); for (i = 0; ; i++) { - struct network_config *netconf; char *tok, *saveptr; - int rc; tok = strtok_r(i == 0 ? val : NULL, " ", &saveptr); if (!tok) break; - netconf = talloc(nv, struct network_config); - - rc = parse_one_network_config(netconf, tok); - if (rc) { - talloc_free(netconf); - continue; - } - - config->network_configs = talloc_realloc(nv, - config->network_configs, - struct network_config *, - ++config->n_network_configs); + if (!strncasecmp(tok, "dns,", strlen("dns,"))) + parse_one_dns_config(config, tok + strlen("dns,")); + else + parse_one_interface_config(config, tok); - config->network_configs[config->n_network_configs - 1] = - netconf; } talloc_free(val);