diff options
author | Tobias Brunner <tobias@strongswan.org> | 2017-08-17 15:04:14 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2017-11-02 10:04:03 +0100 |
commit | b93ebb4ea995214b774ecde9080f15eb07712811 (patch) | |
tree | 876fc87fe8171164b41cba985c60ff7aaa822cab /src | |
parent | c782d367c60c888e4dfedad142706480550063e5 (diff) | |
download | strongswan-b93ebb4ea995214b774ecde9080f15eb07712811.tar.bz2 strongswan-b93ebb4ea995214b774ecde9080f15eb07712811.tar.xz |
utils: Add helper function to parse time spans from strings
Diffstat (limited to 'src')
-rw-r--r-- | src/libstrongswan/settings/settings.c | 38 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_utils.c | 52 | ||||
-rw-r--r-- | src/libstrongswan/utils/utils/time.c | 68 | ||||
-rw-r--r-- | src/libstrongswan/utils/utils/time.h | 16 |
4 files changed, 132 insertions, 42 deletions
diff --git a/src/libstrongswan/settings/settings.c b/src/libstrongswan/settings/settings.c index cdf3e704b..c618d8837 100644 --- a/src/libstrongswan/settings/settings.c +++ b/src/libstrongswan/settings/settings.c @@ -605,41 +605,11 @@ METHOD(settings_t, get_double, double, */ inline uint32_t settings_value_as_time(char *value, uint32_t def) { - char *endptr; - uint32_t timeval; - if (value) + time_t val; + + if (timespan_from_string(value, NULL, &val)) { - errno = 0; - timeval = strtoul(value, &endptr, 10); - if (endptr == value) - { - return def; - } - if (errno == 0) - { - while (isspace(*endptr)) - { - endptr++; - } - switch (*endptr) - { - case 'd': /* time in days */ - timeval *= 24 * 3600; - break; - case 'h': /* time in hours */ - timeval *= 3600; - break; - case 'm': /* time in minutes */ - timeval *= 60; - break; - case 's': /* time in seconds */ - case '\0': - break; - default: - return def; - } - return timeval; - } + return val; } return def; } diff --git a/src/libstrongswan/tests/suites/test_utils.c b/src/libstrongswan/tests/suites/test_utils.c index de7b470d2..3428f237f 100644 --- a/src/libstrongswan/tests/suites/test_utils.c +++ b/src/libstrongswan/tests/suites/test_utils.c @@ -115,6 +115,54 @@ START_TEST(test_timeval_add_ms) END_TEST /******************************************************************************* + * timespan_from_string + */ + +static struct { + char *s; + char *u; + bool v; + time_t t; +} ts_data[] = { + {NULL, NULL, FALSE, 0}, + {"", NULL, FALSE, 0}, + {"a", NULL, FALSE, 0}, + {"0", NULL, TRUE, 0}, + {"5", NULL, TRUE, 5}, + {"5s", NULL, TRUE, 5}, + {"5m", NULL, TRUE, 300}, + {"5ms", NULL, TRUE, 300}, + {"5h", NULL, TRUE, 18000}, + {"5d", NULL, TRUE, 432000}, + {"5x", NULL, FALSE, 0}, + {"5", "", TRUE, 5}, + {"5", "m", TRUE, 300}, + {"5", "ms", TRUE, 300}, + {"5", "x", FALSE, 0}, + {"5x", "m", FALSE, 0}, + {"18446744073709551616", NULL, FALSE, 0}, +}; + +START_TEST(test_timespan_from_string) +{ + time_t val = 42; + + ck_assert(timespan_from_string(ts_data[_i].s, ts_data[_i].u, + NULL) == ts_data[_i].v); + ck_assert(timespan_from_string(ts_data[_i].s, ts_data[_i].u, + &val) == ts_data[_i].v); + if (ts_data[_i].v) + { + ck_assert_int_eq(val, ts_data[_i].t); + } + else + { + ck_assert_int_eq(val, 42); + } +} +END_TEST + +/******************************************************************************* * htoun/untoh */ @@ -921,6 +969,10 @@ Suite *utils_suite_create() tcase_add_test(tc, test_timeval_add_ms); suite_add_tcase(s, tc); + tc = tcase_create("timespan_from_string"); + tcase_add_loop_test(tc, test_timespan_from_string, 0, countof(ts_data)); + suite_add_tcase(s, tc); + tc = tcase_create("htoun,untoh"); tcase_add_test(tc, test_htoun); tcase_add_test(tc, test_untoh); diff --git a/src/libstrongswan/utils/utils/time.c b/src/libstrongswan/utils/utils/time.c index 48e5151c0..d96c918da 100644 --- a/src/libstrongswan/utils/utils/time.c +++ b/src/libstrongswan/utils/utils/time.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2008-2014 Tobias Brunner + * Copyright (C) 2008-2017 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi - * Hochschule fuer Technik Rapperswil + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -23,7 +23,9 @@ #include <utils/utils.h> #include <inttypes.h> +#include <ctype.h> #include <time.h> +#include <errno.h> /** * Return monotonic time @@ -77,8 +79,62 @@ time_t time_monotonic(timeval_t *tv) #endif /* !WIN32 */ } -/** - * Described in header. +/* + * Described in header + */ +bool timespan_from_string(char *str, char *defunit, time_t *val) +{ + char *endptr, unit; + time_t timeval; + + if (str) + { + errno = 0; + timeval = strtoull(str, &endptr, 10); + if (endptr == str) + { + return FALSE; + } + if (errno == 0) + { + while (isspace(*endptr)) + { + endptr++; + } + unit = *endptr; + if (!unit && defunit) + { + unit = *defunit; + } + switch (unit) + { + case 'd': /* time in days */ + timeval *= 24 * 3600; + break; + case 'h': /* time in hours */ + timeval *= 3600; + break; + case 'm': /* time in minutes */ + timeval *= 60; + break; + case 's': /* time in seconds */ + case '\0': + break; + default: + return FALSE; + } + if (val) + { + *val = timeval; + } + return TRUE; + } + } + return FALSE; +} + +/* + * Described in header */ int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args) @@ -112,8 +168,8 @@ int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, t.tm_sec, utc ? " UTC " : " ", t.tm_year + 1900); } -/** - * Described in header. +/* + * Described in header */ int time_delta_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args) diff --git a/src/libstrongswan/utils/utils/time.h b/src/libstrongswan/utils/utils/time.h index 2626d9a33..2e210fbef 100644 --- a/src/libstrongswan/utils/utils/time.h +++ b/src/libstrongswan/utils/utils/time.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 2008-2014 Tobias Brunner + * Copyright (C) 2008-2017 Tobias Brunner * Copyright (C) 2008 Martin Willi - * Hochschule fuer Technik Rapperswil + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -71,6 +71,18 @@ static inline void timeval_add_ms(timeval_t *tv, u_int ms) } /** + * Parse the given string as time span and return the number of seconds, + * optionally with a default unit ('s' for seconds, 'm' for minutes, 'h' for + * hours, 'd' for days - default is 's'). + * + * @param str value to parse + * @param defunit optional default unit + * @param[out] val parsed value + * @return TRUE if a value was parsed + */ +bool timespan_from_string(char *str, char *defunit, time_t *val); + +/** * printf hook for time_t. * * Arguments are: |