aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2017-08-17 15:04:14 +0200
committerTobias Brunner <tobias@strongswan.org>2017-11-02 10:04:03 +0100
commitb93ebb4ea995214b774ecde9080f15eb07712811 (patch)
tree876fc87fe8171164b41cba985c60ff7aaa822cab /src
parentc782d367c60c888e4dfedad142706480550063e5 (diff)
downloadstrongswan-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.c38
-rw-r--r--src/libstrongswan/tests/suites/test_utils.c52
-rw-r--r--src/libstrongswan/utils/utils/time.c68
-rw-r--r--src/libstrongswan/utils/utils/time.h16
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: