# microseconds; and
# - calculate the time elapsed since a given time.
#
-# Syntax is: %{time_since:BASE[:(number|&attribute)]}
+# Syntax is: %{time_since:BASE[ (number|&attribute)]}
# where "BASE" is "s", "ms" or "us".
#
# Examples:
# %{time_since:s}
# - time in seconds since the epoch, same as %c
#
-# %{time_since:s:1695753388}
+# %{time_since:s 1695753388}
# - time in seconds since Tue 26 Sep 19:36:28 BST 2023
# (which is 1695753388 in UNIX time)
#
-# %{time_since:s:&Tmp-Integer-0}
+# %{time_since:s &Tmp-Integer-0}
# - Time since the number of seconds in Tmp-Integer-0
#
# %{time_since:ms}
# }
# ldap
# update request {
-# &Tmp-Integer64-1 := %{time_since:us:&Tmp-Integer64-0}"
+# &Tmp-Integer64-1 := %{time_since:us &Tmp-Integer64-0}"
# }
/** Get time in ms since either epoch or another value
*
* %{time_since:s} - return seconds since epoch
- * %{time_since:ms:0} - return milliseconds since epoch
- * %{time_since:us:1695745763034443} - return microseconds since Tue 26 Sep 17:29:23.034443 BST 2023
- * %{time_since:us:&Tmp-Integer64-1} - return microseconds since value in &Tmp-Integer64-1
+ * %{time_since:ms 0} - return milliseconds since epoch
+ * %{time_since:us 1695745763034443} - return microseconds since Tue 26 Sep 17:29:23.034443 BST 2023
+ * %{time_since:us &Tmp-Integer64-1} - return microseconds since value in &Tmp-Integer64-1
*/
static ssize_t xlat_time_since(UNUSED void *instance, REQUEST *request, char const *fmt, char *out, size_t outlen)
return -1;
}
- if (fmt[0] != '\0' && fmt[0] != ':') {
+ if (fmt[0] != '\0' && fmt[0] != ' ') {
REDEBUG("Invalid arguments passed to time_since xlat");
goto error;
}
- if (fmt[0] == ':') fmt++;
+ while (isspace((uint8_t) *fmt)) fmt++;
/*
* Handle the different formats that we can be passed
*/
if (fmt[0] == '\0') {
/*
- * %{time_since:[mu]?s:} - epoch
+ * %{time_since:[mu]?s} - epoch
*/
time_since = 0;
/*
* We were provided with an attribute
*
- * %{time_since:[mu]?s:&Attr-Name}
+ * %{time_since:[mu]?s &Attr-Name}
*/
value_data_t outnum;
VALUE_PAIR *vp;
/*
* Otherwise we hope we were provided with an integer value
*
- * %{time_since:[mu]?s:12345}
+ * %{time_since:[mu]?s 12345}
*/
if (sscanf(fmt, "%" PRIu64, &time_since) != 1) {
REDEBUG("Failed parsing \"%s\" as integer", fmt);
# comparisons rather than actual value checks.
#
+#
+# %{time_since:...} should never return 0
+#
+update {
+ &Tmp-Integer64-0 := "%{time_since:s}"
+ &Tmp-Integer64-1 := "%{time_since:ms}"
+ &Tmp-Integer64-2 := "%{time_since:us}"
+}
+
+if (&Tmp-Integer64-0 == 0 || &Tmp-Integer64-1 == 0 || &Tmp-Integer64-2 == 0) {
+ test_fail
+}
+
#
# %c and %{time_since:s:0} should match
#
update {
&Tmp-Integer-0 := "%c"
- &Tmp-Integer-1 := "%{time_since:s:0}"
- &Tmp-Integer-2 := "%{time_since:s:&Tmp-Integer-9}"
+ &Tmp-Integer-1 := "%{time_since:s 0}"
+ &Tmp-Integer-2 := "%{time_since:s &Tmp-Integer-9}"
}
if (&Tmp-Integer-0 != &Tmp-Integer-1) {
if (&Tmp-Integer-0 != "%{expr:&Tmp-Integer-1 - 1}") {
- # at a push, %{time_since:s:0} might be one second later,
+ # at a push, %{time_since:s 0} might be one second later,
# depending on when the test ran
test_fail
}
# If we run time_since 3 times, they should be the same or increasing
#
update {
- &Tmp-Integer64-0 := "%{time_since:s:0}"
+ &Tmp-Integer64-0 := "%{time_since:s 0}"
}
update {
- &Tmp-Integer64-1 := "%{time_since:s:}"
+ &Tmp-Integer64-1 := "%{time_since:s }"
}
update {
# Similar for milliseconds
#
update {
- &Tmp-Integer64-3 := "%{time_since:ms:0}"
+ &Tmp-Integer64-3 := "%{time_since:ms 0}"
}
update {
- &Tmp-Integer64-4 := "%{time_since:ms:}"
+ &Tmp-Integer64-4 := "%{time_since:ms}"
}
update {
- &Tmp-Integer64-5 := "%{time_since:ms}"
+ &Tmp-Integer64-5 := "%{time_since:ms &Tmp-Integer-9}"
}
if (&Tmp-Integer64-3 > &Tmp-Integer64-4 || \
# ...and microseconds
#
update {
- &Tmp-Integer64-6 := "%{time_since:us:0}"
+ &Tmp-Integer64-6 := "%{time_since:us 0}"
}
update {
- &Tmp-Integer64-7 := "%{time_since:us:}"
+ &Tmp-Integer64-7 := "%{time_since:us }"
}
update {
# Seconds component * 1000 must always be same or less than
# milliseconds, and microseconds.
#
-if ("%{expr:%{time_since:s:0} * 1000}" > "%{time_since:ms:0}") {
+if ("%{expr:%{time_since:s 0} * 1000}" > "%{time_since:ms 0}") {
test_fail
}
-if ("%{expr:%{time_since:ms:0} * 1000}" > "%{time_since:us:0}") {
+if ("%{expr:%{time_since:ms 0} * 1000}" > "%{time_since:us 0}") {
test_fail
}
-if ("%{expr:%{time_since:s:0} * 1000000}" > "%{time_since:us:0}") {
+if ("%{expr:%{time_since:s 0} * 1000000}" > "%{time_since:us 0}") {
test_fail
}
# negative values
update {
- &Tmp-Integer-0 := "%{time_since:ms:-1234}"
+ &Tmp-Integer-0 := "%{time_since:ms -1234}"
}
if (!(&Module-Failure-Message[*] == 'time_since xlat only accepts positive integers')) {
# invalid attribute
update {
- &Tmp-Integer-0 := "%{time_since:us:&Test-Non-Existant-Attr}"
+ &Tmp-Integer-0 := "%{time_since:us &Test-Non-Existant-Attr}"
}
if (!(&Module-Failure-Message[*] == 'Unable to parse attribute in time_ms_since xlat')) {
# silly text
update {
- &Tmp-Integer-0 := "%{time_since:us:test random text}"
+ &Tmp-Integer-0 := "%{time_since:us test random text}"
}
if (!(&Module-Failure-Message[*] == 'Failed parsing "test random text" as integer')) {