ptp4l: Accept any configuration option as a command line argument.
This patch provides a way to use the entire table of configuration options as "long" command line switches. Signed-off-by: Richard Cochran <richardcochran@gmail.com>master
parent
891d56e429
commit
4e8dbd8492
64
config.c
64
config.c
|
@ -329,6 +329,7 @@ static enum parser_result parse_section_line(char *s, enum config_section *secti
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum parser_result parse_item(struct config *cfg,
|
static enum parser_result parse_item(struct config *cfg,
|
||||||
|
int commandline,
|
||||||
const char *section,
|
const char *section,
|
||||||
const char *option,
|
const char *option,
|
||||||
const char *value)
|
const char *value)
|
||||||
|
@ -387,7 +388,7 @@ static enum parser_result parse_item(struct config *cfg,
|
||||||
return NOT_PARSED;
|
return NOT_PARSED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (cgi->flags & CFG_ITEM_LOCKED) {
|
} else if (!commandline && cgi->flags & CFG_ITEM_LOCKED) {
|
||||||
/* This global option was set on the command line. */
|
/* This global option was set on the command line. */
|
||||||
return PARSED_OK;
|
return PARSED_OK;
|
||||||
} else {
|
} else {
|
||||||
|
@ -415,6 +416,10 @@ static enum parser_result parse_item(struct config *cfg,
|
||||||
dst->flags |= CFG_ITEM_DYNSTR;
|
dst->flags |= CFG_ITEM_DYNSTR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (commandline) {
|
||||||
|
dst->flags &= CFG_ITEM_LOCKED;
|
||||||
|
}
|
||||||
return PARSED_OK;
|
return PARSED_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,6 +495,25 @@ static void check_deprecated_options(const char **option)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct option *config_alloc_longopts(struct config *cfg)
|
||||||
|
{
|
||||||
|
struct config_item *ci;
|
||||||
|
struct option *opts;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
opts = calloc(1, (1 + N_CONFIG_ITEMS) * sizeof(*opts));
|
||||||
|
if (!opts) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (i = 0; i < N_CONFIG_ITEMS; i++) {
|
||||||
|
ci = &config_tab[i];
|
||||||
|
opts[i].name = ci->label;
|
||||||
|
opts[i].has_arg = required_argument;
|
||||||
|
}
|
||||||
|
|
||||||
|
return opts;
|
||||||
|
}
|
||||||
|
|
||||||
int config_read(char *name, struct config *cfg)
|
int config_read(char *name, struct config *cfg)
|
||||||
{
|
{
|
||||||
enum config_section current_section = UNKNOWN_SECTION;
|
enum config_section current_section = UNKNOWN_SECTION;
|
||||||
|
@ -554,7 +578,7 @@ int config_read(char *name, struct config *cfg)
|
||||||
|
|
||||||
check_deprecated_options(&option);
|
check_deprecated_options(&option);
|
||||||
|
|
||||||
parser_res = parse_item(cfg, current_section == GLOBAL_SECTION ?
|
parser_res = parse_item(cfg, 0, current_section == GLOBAL_SECTION ?
|
||||||
NULL : current_port->name, option, value);
|
NULL : current_port->name, option, value);
|
||||||
|
|
||||||
switch (parser_res) {
|
switch (parser_res) {
|
||||||
|
@ -627,8 +651,15 @@ struct config *config_create(void)
|
||||||
}
|
}
|
||||||
STAILQ_INIT(&cfg->interfaces);
|
STAILQ_INIT(&cfg->interfaces);
|
||||||
|
|
||||||
|
cfg->opts = config_alloc_longopts(cfg);
|
||||||
|
if (!cfg->opts) {
|
||||||
|
free(cfg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
cfg->htab = hash_create();
|
cfg->htab = hash_create();
|
||||||
if (!cfg->htab) {
|
if (!cfg->htab) {
|
||||||
|
free(cfg->opts);
|
||||||
free(cfg);
|
free(cfg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -657,6 +688,7 @@ struct config *config_create(void)
|
||||||
return cfg;
|
return cfg;
|
||||||
fail:
|
fail:
|
||||||
hash_destroy(cfg->htab, NULL);
|
hash_destroy(cfg->htab, NULL);
|
||||||
|
free(cfg->opts);
|
||||||
free(cfg);
|
free(cfg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -670,6 +702,7 @@ void config_destroy(struct config *cfg)
|
||||||
free(iface);
|
free(iface);
|
||||||
}
|
}
|
||||||
hash_destroy(cfg->htab, config_item_free);
|
hash_destroy(cfg->htab, config_item_free);
|
||||||
|
free(cfg->opts);
|
||||||
free(cfg);
|
free(cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -720,6 +753,33 @@ char *config_get_string(struct config *cfg, const char *section,
|
||||||
return ci->val.s;
|
return ci->val.s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_parse_option(struct config *cfg, const char *opt, const char *val)
|
||||||
|
{
|
||||||
|
enum parser_result result;
|
||||||
|
|
||||||
|
result = parse_item(cfg, 1, NULL, opt, val);
|
||||||
|
|
||||||
|
switch (result) {
|
||||||
|
case PARSED_OK:
|
||||||
|
return 0;
|
||||||
|
case NOT_PARSED:
|
||||||
|
fprintf(stderr, "unknown option %s\n", opt);
|
||||||
|
break;
|
||||||
|
case BAD_VALUE:
|
||||||
|
fprintf(stderr, "%s is a bad value for option %s\n", val, opt);
|
||||||
|
break;
|
||||||
|
case MALFORMED:
|
||||||
|
fprintf(stderr, "%s is a malformed value for option %s\n",
|
||||||
|
val, opt);
|
||||||
|
break;
|
||||||
|
case OUT_OF_RANGE:
|
||||||
|
fprintf(stderr, "%s is an out of range value for option %s\n",
|
||||||
|
val, opt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int config_set_double(struct config *cfg, const char *option, double val)
|
int config_set_double(struct config *cfg, const char *option, double val)
|
||||||
{
|
{
|
||||||
struct config_item *ci = config_find_item(cfg, NULL, option);
|
struct config_item *ci = config_find_item(cfg, NULL, option);
|
||||||
|
|
11
config.h
11
config.h
|
@ -20,6 +20,7 @@
|
||||||
#ifndef HAVE_CONFIG_H
|
#ifndef HAVE_CONFIG_H
|
||||||
#define HAVE_CONFIG_H
|
#define HAVE_CONFIG_H
|
||||||
|
|
||||||
|
#include <getopt.h>
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
|
|
||||||
#include "ds.h"
|
#include "ds.h"
|
||||||
|
@ -43,6 +44,9 @@ struct config {
|
||||||
STAILQ_HEAD(interfaces_head, interface) interfaces;
|
STAILQ_HEAD(interfaces_head, interface) interfaces;
|
||||||
int n_interfaces;
|
int n_interfaces;
|
||||||
|
|
||||||
|
/* for parsing command line options */
|
||||||
|
struct option *opts;
|
||||||
|
|
||||||
/* hash of all non-legacy items */
|
/* hash of all non-legacy items */
|
||||||
struct hash *htab;
|
struct hash *htab;
|
||||||
};
|
};
|
||||||
|
@ -64,6 +68,13 @@ int config_get_int(struct config *cfg, const char *section,
|
||||||
char *config_get_string(struct config *cfg, const char *section,
|
char *config_get_string(struct config *cfg, const char *section,
|
||||||
const char *option);
|
const char *option);
|
||||||
|
|
||||||
|
static inline struct option *config_long_options(struct config *cfg)
|
||||||
|
{
|
||||||
|
return cfg->opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
int config_parse_option(struct config *cfg, const char *opt, const char *val);
|
||||||
|
|
||||||
int config_set_double(struct config *cfg, const char *option, double val);
|
int config_set_double(struct config *cfg, const char *option, double val);
|
||||||
|
|
||||||
int config_set_section_int(struct config *cfg, const char *section,
|
int config_set_section_int(struct config *cfg, const char *section,
|
||||||
|
|
11
ptp4l.c
11
ptp4l.c
|
@ -73,8 +73,9 @@ static void usage(char *progname)
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char *config = NULL, *req_phc = NULL, *progname;
|
char *config = NULL, *req_phc = NULL, *progname;
|
||||||
int c, err = -1, print_level;
|
int c, err = -1, index, print_level;
|
||||||
struct clock *clock = NULL;
|
struct clock *clock = NULL;
|
||||||
|
struct option *opts;
|
||||||
struct config *cfg;
|
struct config *cfg;
|
||||||
|
|
||||||
if (handle_term_signals())
|
if (handle_term_signals())
|
||||||
|
@ -84,12 +85,18 @@ int main(int argc, char *argv[])
|
||||||
if (!cfg) {
|
if (!cfg) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
opts = config_long_options(cfg);
|
||||||
|
|
||||||
/* Process the command line arguments. */
|
/* Process the command line arguments. */
|
||||||
progname = strrchr(argv[0], '/');
|
progname = strrchr(argv[0], '/');
|
||||||
progname = progname ? 1+progname : argv[0];
|
progname = progname ? 1+progname : argv[0];
|
||||||
while (EOF != (c = getopt(argc, argv, "AEP246HSLf:i:p:sl:mqvh"))) {
|
while (EOF != (c = getopt_long(argc, argv, "AEP246HSLf:i:p:sl:mqvh",
|
||||||
|
opts, &index))) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 0:
|
||||||
|
if (config_parse_option(cfg, opts[index].name, optarg))
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
if (config_set_int(cfg, "delay_mechanism", DM_AUTO))
|
if (config_set_int(cfg, "delay_mechanism", DM_AUTO))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
Loading…
Reference in New Issue