Commit 4184f7ea authored by Alessandro Rubini's avatar Alessandro Rubini

config: allow passing "-f <file>" on the command line

This commit factorizes some code in lib/conf.c from the two hosted
startup files, but the aim is passing "-f <filename>" on the command
line, to test with unconventional setups without touching the "real"
filesystem.

Now ppsi looks for the configuration file is from threee places, in
this order:
    - command line, if any
    - architecture-specific, if any (e.g. "/wr/etc/ppsi.conf")
    - compile-time default ("/etc/ppsi.conf")
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 494697b0
......@@ -24,18 +24,11 @@
CONST_VERBOSITY int pp_diag_verbosity = 0;
/* FIXME: make conf_path definable at compile time */
#define CONF_PATH "/etc/ppsi.conf"
int main(int argc, char **argv)
{
struct pp_globals *ppg;
struct pp_instance *ppi;
int i, ret;
struct stat conf_fs;
char *conf_buf;
FILE *f;
int conf_len = 0;
int i;
setbuf(stdout, NULL);
......@@ -46,44 +39,22 @@ int main(int argc, char **argv)
ppg->max_links = PP_MAX_LINKS;
ppg->links = calloc(ppg->max_links, sizeof(struct pp_link));
f = fopen(CONF_PATH, "r");
if (!f || stat(CONF_PATH, &conf_fs) < 0) {
fprintf(stderr, "%s: Warning: %s: %s -- default to eth0 only\n",
argv[0], CONF_PATH, strerror(errno));
conf_buf = "link 0\niface eth0\n";
conf_len = strlen(conf_buf);
} else {
/* The parser needs a trailing newline, add one to be sure */
conf_len = conf_fs.st_size + 1;
conf_buf = calloc(1, conf_len + 1); /* trailing \0 */
i = fread(conf_buf, 1, conf_len, f);
if (i > 0) conf_buf[i] = '\n';
fclose(f);
}
ppg->rt_opts = &default_rt_opts;
if ((ret = pp_parse_conf(ppg, conf_buf, conf_len)) < 0) {
fprintf(stderr, "%s: %s:%d: parse error\n", argv[0],
CONF_PATH, -ret);
exit(__LINE__);
}
ppg->defaultDS = calloc(1, sizeof(*ppg->defaultDS));
ppg->currentDS = calloc(1, sizeof(*ppg->currentDS));
ppg->parentDS = calloc(1, sizeof(*ppg->parentDS));
ppg->timePropertiesDS = calloc(1, sizeof(*ppg->timePropertiesDS));
ppg->arch_data = calloc(1, sizeof(struct unix_arch_data));
ppg->pp_instances = calloc(ppg->max_links, sizeof(struct pp_instance));
ppg->servo = calloc(1, sizeof(*ppg->servo));
ppg->rt_opts = &default_rt_opts;
if ((!ppg->defaultDS) || (!ppg->currentDS) || (!ppg->parentDS)
|| (!ppg->timePropertiesDS) || (!ppg->arch_data)
|| (!ppg->pp_instances))
|| (!ppg->pp_instances) || (!ppg->servo))
exit(__LINE__);
ppg->servo = calloc(1, sizeof(*ppg->servo));
pp_config_file(ppg, &argc, argv, NULL,
"link 0\niface eth0\n" /* mandatory trailing \n */);
for (i = 0; i < ppg->nlinks; i++) {
......
......@@ -27,9 +27,6 @@
CONST_VERBOSITY int pp_diag_verbosity = 0;
/* FIXME: make conf_path definable at compile time */
#define CONF_PATH "/etc/ppsi.conf"
struct minipc_ch *hal_ch;
struct minipc_ch *ppsi_ch;
......@@ -37,11 +34,7 @@ int main(int argc, char **argv)
{
struct pp_globals *ppg;
struct pp_instance *ppi;
int i = 0, ret;
struct stat conf_fs;
char *conf_buf;
int conf_fd;
int conf_len = 0;
int i;
setbuf(stdout, NULL);
......@@ -66,53 +59,24 @@ int main(int argc, char **argv)
ppg->max_links = PP_MAX_LINKS;
ppg->links = calloc(ppg->max_links, sizeof(struct pp_link));
conf_fd = open(CONF_PATH, O_RDONLY);
if ((stat(CONF_PATH, &conf_fs) < 0) || (conf_fd < 0)) {
pp_printf("Warning: could not open %s, using wr0 only "
"built-in config\n", CONF_PATH);
conf_buf = "link 0\niface wr0\n";
conf_len = strlen(conf_buf) - 1;
} else {
int r = 0, next_r;
conf_buf = calloc(1, conf_fs.st_size + 2);
do {
next_r = conf_fs.st_size - conf_len;
r = read(conf_fd, &conf_buf[conf_len], next_r);
if (r <= 0)
break;
conf_len = strlen(conf_buf);
} while (conf_len < conf_fs.st_size);
close(conf_fd);
}
conf_buf[conf_len + 1] = '\n';
ppg->rt_opts = &default_rt_opts;
if ((ret = pp_parse_conf(ppg, conf_buf, conf_len)) < 0) {
pp_printf("Fatal: Error in %s file at line %d\n", CONF_PATH, -ret);
exit(__LINE__);
}
ppg->defaultDS = calloc(1, sizeof(*ppg->defaultDS));
ppg->currentDS = calloc(1, sizeof(*ppg->currentDS));
ppg->parentDS = calloc(1, sizeof(*ppg->parentDS));
ppg->timePropertiesDS = calloc(1, sizeof(*ppg->timePropertiesDS));
ppg->arch_data = calloc(1, sizeof(struct unix_arch_data));
ppg->pp_instances = calloc(ppg->max_links, sizeof(struct pp_instance));
ppg->servo = calloc(1, sizeof(*ppg->servo));
ppg->rt_opts = &default_rt_opts;
if ((!ppg->defaultDS) || (!ppg->currentDS) || (!ppg->parentDS)
|| (!ppg->timePropertiesDS) || (!ppg->arch_data)
|| (!ppg->pp_instances))
|| (!ppg->pp_instances) || (!ppg->servo))
exit(__LINE__);
ppg->servo = calloc(1, sizeof(*ppg->servo));
pp_config_file(ppg, &argc, argv, "/wr/etc/ppsi.conf",
"link 0\niface wr0\n" /* mandatory trailing \n */);
for (; i < ppg->nlinks; i++) {
for (i = 0; i < ppg->nlinks; i++) {
struct pp_link *lnk = &ppg->links[i];
......
......@@ -14,6 +14,8 @@
/* implementation specific constants */
#define PP_MAX_LINKS 64
#define PP_DEFAULT_CONFIGFILE "/etc/ppsi.conf"
#define PP_DEFAULT_INBOUND_LATENCY 0 /* in nsec */
#define PP_DEFAULT_OUTBOUND_LATENCY 0 /* in nsec */
#define PP_DEFAULT_NO_RESET_CLOCK 0
......
......@@ -255,7 +255,8 @@ extern int pp_close_globals(struct pp_globals *ppg);
extern int pp_parse_cmdline(struct pp_globals *ppg, int argc, char **argv);
extern int pp_parse_conf(struct pp_globals *ppg, char *conf, int len);
extern int pp_config_file(struct pp_globals *ppg, int *argcp, char **argv,
char *default_name, char *default_conf);
/* Servo */
extern void pp_servo_init(struct pp_instance *ppi);
......
......@@ -6,6 +6,12 @@
*/
#include <ppsi/ppsi.h>
/* This file is build in hosted environments, so following headers are Ok */
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
/* Each pre-defined keyword is handled in the keywords list, so that the
* same code is used to parse every token in the conf file */
......@@ -151,7 +157,7 @@ static int handle_key_val(struct pp_globals *ppg, char *key, char *val)
}
/* Parse configuration (e.g. coming from /etc/ppsi.conf file) */
int pp_parse_conf(struct pp_globals *ppg, char *conf, int len)
static int pp_parse_conf(struct pp_globals *ppg, char *conf, int len)
{
int st = 0;
char c;
......@@ -242,3 +248,88 @@ ret_invalid_line:
ln--;
return -ln;
}
/* Open about a file, warn if not found */
static int pp_open_conf_file(char **argv, char *name)
{
int fd;
if (!name)
return -1;
fd = open(name, O_RDONLY);
if (fd >= 0) {
pp_printf("%s: Using config file %s\n", argv[0], name);
return fd;
}
pp_printf("%s: Warning: %s: %s\n", argv[0], name,
strerror(errno));
return -1;
}
/*
* This is the public entry point, that is passed both a default name
* and a default value for the configuration file. This only builds
* in hosted environment.
*
* The function allows "-f <config>" to appear on the command line,
* and modifies the command line accordingly (hackish, I admit)
*/
int pp_config_file(struct pp_globals *ppg, int *argcp, char **argv,
char *default_name, char *default_conf)
{
char *name = NULL;
int conf_fd, i, conf_len = 0;
struct stat conf_fs;
char *conf_buf;
/* First, look for fname on the command line (which is parsed later) */
for (i = 1; i < *argcp - 1; i++) {
if (strcmp(argv[i], "-f"))
continue;
/* found: remove it from argv */
name = argv[i + 1];
for (;i < *argcp - 2; i++)
argv[i] = argv[i + 2];
*argcp -= 2;
}
conf_fd = pp_open_conf_file(argv, name);
/* Then try the caller-provided name */
if (conf_fd < 0)
conf_fd = pp_open_conf_file(argv, default_name);
/* Finally, the project-wide name */
if (conf_fd < 0)
conf_fd = pp_open_conf_file(argv, PP_DEFAULT_CONFIGFILE);
/* If nothing, use provided string */
if (conf_fd < 0) { /* Read it, if any */
conf_buf = strdup(default_conf);
conf_len = strlen(conf_buf) - 1;
} else {
int r = 0, next_r;
fstat(conf_fd, &conf_fs);
conf_buf = calloc(1, conf_fs.st_size + 2);
do {
next_r = conf_fs.st_size - conf_len;
r = read(conf_fd, &conf_buf[conf_len], next_r);
if (r <= 0)
break;
conf_len = strlen(conf_buf);
} while (conf_len < conf_fs.st_size);
close(conf_fd);
}
/* We need this trailing \n for the parser */
conf_buf[conf_len + 1] = '\n';
if ((i = pp_parse_conf(ppg, conf_buf, conf_len)) < 0) {
pp_printf("%s: configuration: error at line %d\n", argv[0], -1);
exit(1);
}
free(conf_buf);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment