refclock: check all driver options

In each driver provide a list of supported options and abort when an
unknown option is specified in the refclock directive.
This commit is contained in:
Miroslav Lichvar 2019-04-18 15:56:15 +02:00
parent 34e9dd13ce
commit a78031ce0d
6 changed files with 58 additions and 14 deletions

View file

@ -325,25 +325,57 @@ RCL_GetDriverParameter(RCL_Instance instance)
return instance->driver_parameter; return instance->driver_parameter;
} }
static char *
get_next_driver_option(RCL_Instance instance, char *option)
{
if (option == NULL)
option = instance->driver_parameter;
option += strlen(option) + 1;
if (option >= instance->driver_parameter + instance->driver_parameter_length)
return NULL;
return option;
}
void
RCL_CheckDriverOptions(RCL_Instance instance, const char **options)
{
char *option;
int i, len;
for (option = get_next_driver_option(instance, NULL);
option;
option = get_next_driver_option(instance, option)) {
for (i = 0; options && options[i]; i++) {
len = strlen(options[i]);
if (!strncmp(options[i], option, strlen(options[i])) &&
(option[len] == '=' || option[len] == '\0'))
break;
}
if (!options || !options[i])
LOG_FATAL("Invalid refclock driver option %s", option);
}
}
char * char *
RCL_GetDriverOption(RCL_Instance instance, char *name) RCL_GetDriverOption(RCL_Instance instance, char *name)
{ {
char *s, *e; char *option;
int n; int len;
s = instance->driver_parameter; len = strlen(name);
e = s + instance->driver_parameter_length;
n = strlen(name);
while (1) { for (option = get_next_driver_option(instance, NULL);
s += strlen(s) + 1; option;
if (s >= e) option = get_next_driver_option(instance, option)) {
break; if (!strncmp(name, option, len)) {
if (!strncmp(name, s, n)) { if (option[len] == '=')
if (s[n] == '=') return option + len + 1;
return s + n + 1; if (option[len] == '\0')
if (s[n] == '\0') return option + len;
return s + n;
} }
} }

View file

@ -72,6 +72,7 @@ extern void RCL_ReportSource(RPT_SourceReport *report, struct timespec *now);
extern void RCL_SetDriverData(RCL_Instance instance, void *data); extern void RCL_SetDriverData(RCL_Instance instance, void *data);
extern void *RCL_GetDriverData(RCL_Instance instance); extern void *RCL_GetDriverData(RCL_Instance instance);
extern char *RCL_GetDriverParameter(RCL_Instance instance); extern char *RCL_GetDriverParameter(RCL_Instance instance);
extern void RCL_CheckDriverOptions(RCL_Instance instance, const char **options);
extern char *RCL_GetDriverOption(RCL_Instance instance, char *name); extern char *RCL_GetDriverOption(RCL_Instance instance, char *name);
extern int RCL_AddSample(RCL_Instance instance, struct timespec *sample_time, double offset, int leap); extern int RCL_AddSample(RCL_Instance instance, struct timespec *sample_time, double offset, int leap);
extern int RCL_AddPulse(RCL_Instance instance, struct timespec *pulse_time, double second); extern int RCL_AddPulse(RCL_Instance instance, struct timespec *pulse_time, double second);

View file

@ -56,10 +56,13 @@ static void read_ext_pulse(int sockfd, int event, void *anything);
static int phc_initialise(RCL_Instance instance) static int phc_initialise(RCL_Instance instance)
{ {
const char *options[] = {"nocrossts", "extpps", "pin", "channel", "clear", NULL};
struct phc_instance *phc; struct phc_instance *phc;
int phc_fd, rising_edge; int phc_fd, rising_edge;
char *path, *s; char *path, *s;
RCL_CheckDriverOptions(instance, options);
path = RCL_GetDriverParameter(instance); path = RCL_GetDriverParameter(instance);
phc_fd = SYS_Linux_OpenPHC(path, 0); phc_fd = SYS_Linux_OpenPHC(path, 0);

View file

@ -48,12 +48,15 @@ struct pps_instance {
}; };
static int pps_initialise(RCL_Instance instance) { static int pps_initialise(RCL_Instance instance) {
const char *options[] = {"clear", NULL};
pps_handle_t handle; pps_handle_t handle;
pps_params_t params; pps_params_t params;
struct pps_instance *pps; struct pps_instance *pps;
int fd, edge_clear, mode; int fd, edge_clear, mode;
char *path; char *path;
RCL_CheckDriverOptions(instance, options);
path = RCL_GetDriverParameter(instance); path = RCL_GetDriverParameter(instance);
edge_clear = RCL_GetDriverOption(instance, "clear") ? 1 : 0; edge_clear = RCL_GetDriverOption(instance, "clear") ? 1 : 0;

View file

@ -59,10 +59,13 @@ struct shmTime {
}; };
static int shm_initialise(RCL_Instance instance) { static int shm_initialise(RCL_Instance instance) {
const char *options[] = {"perm", NULL};
int id, param, perm; int id, param, perm;
char *s; char *s;
struct shmTime *shm; struct shmTime *shm;
RCL_CheckDriverOptions(instance, options);
param = atoi(RCL_GetDriverParameter(instance)); param = atoi(RCL_GetDriverParameter(instance));
s = RCL_GetDriverOption(instance, "perm"); s = RCL_GetDriverOption(instance, "perm");
perm = s ? strtol(s, NULL, 8) & 0777 : 0600; perm = s ? strtol(s, NULL, 8) & 0777 : 0600;

View file

@ -101,6 +101,8 @@ static int sock_initialise(RCL_Instance instance)
int sockfd; int sockfd;
char *path; char *path;
RCL_CheckDriverOptions(instance, NULL);
path = RCL_GetDriverParameter(instance); path = RCL_GetDriverParameter(instance);
s.sun_family = AF_UNIX; s.sun_family = AF_UNIX;