diff --git a/refclock.c b/refclock.c index 8f234f6..42fee4c 100644 --- a/refclock.c +++ b/refclock.c @@ -325,25 +325,57 @@ RCL_GetDriverParameter(RCL_Instance instance) 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 * RCL_GetDriverOption(RCL_Instance instance, char *name) { - char *s, *e; - int n; + char *option; + int len; - s = instance->driver_parameter; - e = s + instance->driver_parameter_length; - n = strlen(name); + len = strlen(name); - while (1) { - s += strlen(s) + 1; - if (s >= e) - break; - if (!strncmp(name, s, n)) { - if (s[n] == '=') - return s + n + 1; - if (s[n] == '\0') - return s + n; + for (option = get_next_driver_option(instance, NULL); + option; + option = get_next_driver_option(instance, option)) { + if (!strncmp(name, option, len)) { + if (option[len] == '=') + return option + len + 1; + if (option[len] == '\0') + return option + len; } } diff --git a/refclock.h b/refclock.h index 724f620..69a0152 100644 --- a/refclock.h +++ b/refclock.h @@ -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_GetDriverData(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 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); diff --git a/refclock_phc.c b/refclock_phc.c index 03450db..a000fe4 100644 --- a/refclock_phc.c +++ b/refclock_phc.c @@ -56,10 +56,13 @@ static void read_ext_pulse(int sockfd, int event, void *anything); static int phc_initialise(RCL_Instance instance) { + const char *options[] = {"nocrossts", "extpps", "pin", "channel", "clear", NULL}; struct phc_instance *phc; int phc_fd, rising_edge; char *path, *s; + RCL_CheckDriverOptions(instance, options); + path = RCL_GetDriverParameter(instance); phc_fd = SYS_Linux_OpenPHC(path, 0); diff --git a/refclock_pps.c b/refclock_pps.c index 85ff9e9..b9e8009 100644 --- a/refclock_pps.c +++ b/refclock_pps.c @@ -48,12 +48,15 @@ struct pps_instance { }; static int pps_initialise(RCL_Instance instance) { + const char *options[] = {"clear", NULL}; pps_handle_t handle; pps_params_t params; struct pps_instance *pps; int fd, edge_clear, mode; char *path; + RCL_CheckDriverOptions(instance, options); + path = RCL_GetDriverParameter(instance); edge_clear = RCL_GetDriverOption(instance, "clear") ? 1 : 0; diff --git a/refclock_shm.c b/refclock_shm.c index e8f6256..ed68095 100644 --- a/refclock_shm.c +++ b/refclock_shm.c @@ -59,10 +59,13 @@ struct shmTime { }; static int shm_initialise(RCL_Instance instance) { + const char *options[] = {"perm", NULL}; int id, param, perm; char *s; struct shmTime *shm; + RCL_CheckDriverOptions(instance, options); + param = atoi(RCL_GetDriverParameter(instance)); s = RCL_GetDriverOption(instance, "perm"); perm = s ? strtol(s, NULL, 8) & 0777 : 0600; diff --git a/refclock_sock.c b/refclock_sock.c index 176310c..492ee32 100644 --- a/refclock_sock.c +++ b/refclock_sock.c @@ -101,6 +101,8 @@ static int sock_initialise(RCL_Instance instance) int sockfd; char *path; + RCL_CheckDriverOptions(instance, NULL); + path = RCL_GetDriverParameter(instance); s.sun_family = AF_UNIX;