]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
utils: Add helper function to parse time spans from strings
authorTobias Brunner <tobias@strongswan.org>
Thu, 17 Aug 2017 13:04:14 +0000 (15:04 +0200)
committerTobias Brunner <tobias@strongswan.org>
Thu, 2 Nov 2017 09:04:03 +0000 (10:04 +0100)
src/libstrongswan/settings/settings.c
src/libstrongswan/tests/suites/test_utils.c
src/libstrongswan/utils/utils/time.c
src/libstrongswan/utils/utils/time.h

index cdf3e704bfc06c4d9a66a70a8d5de37dc52930a6..c618d883741af77519231ed19c85939c37307dbd 100644 (file)
@@ -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;
 }
index de7b470d235133ce56b7db98fc8bee0720f29f47..3428f237fe4f53d0d447576303b6e864d51eb372 100644 (file)
@@ -114,6 +114,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);
index 48e5151c0bbbb0cd01182f9279247725dc343498..d96c918dacc33d04b816439c45ebf970d4476c9d 100644 (file)
@@ -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)
index 2626d9a337c5fe25eb1e0c7465122b058b99c372..2e210fbefd25ae2b243f0f3a1fc5a6b37b2d0a29 100644 (file)
@@ -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
@@ -70,6 +70,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.
  *