From: Nick Porter Date: Tue, 23 Mar 2021 10:10:52 +0000 (+0000) Subject: v4: Convert %(nexttime: ) to new xlat api (#4015) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3b75ea99ebe39aff6b3ad0b683342992dc36684a;p=thirdparty%2Ffreeradius-server.git v4: Convert %(nexttime: ) to new xlat api (#4015) * Convert %{nexttime: } to new xlat api * Add tests for %(nexttime: ) --- diff --git a/src/lib/unlang/xlat_builtin.c b/src/lib/unlang/xlat_builtin.c index 174cb150af0..9fd2727edfe 100644 --- a/src/lib/unlang/xlat_builtin.c +++ b/src/lib/unlang/xlat_builtin.c @@ -1298,9 +1298,14 @@ static ssize_t xlat_func_map(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, } +static xlat_arg_parser_t const xlat_func_next_time_args[] = { + { .required = true, .concat = true, .type = FR_TYPE_STRING }, + XLAT_ARG_PARSER_TERMINATOR +}; + /** Calculate number of seconds until the next n hour(s), day(s), week(s), year(s). * - * For example, if it were 16:18 %{nexttime:1h} would expand to 2520. + * For example, if it were 16:18 %(nexttime:1h) would expand to 2520. * * The envisaged usage for this function is to limit sessions so that they don't * cross billing periods. The output of the xlat should be combined with %{rand:} to create @@ -1309,9 +1314,9 @@ static ssize_t xlat_func_map(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, * * @ingroup xlat_functions */ -static ssize_t xlat_func_next_time(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, - UNUSED void const *mod_inst, UNUSED void const *xlat_inst, - request_t *request, char const *fmt) +static xlat_action_t xlat_func_next_time(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, + UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, + fr_value_box_list_t *in) { long num; @@ -1319,16 +1324,18 @@ static ssize_t xlat_func_next_time(UNUSED TALLOC_CTX *ctx, char **out, size_t ou char *q; time_t now; struct tm *local, local_buff; + fr_value_box_t *in_head = fr_dlist_head(in); + fr_value_box_t *vb; now = time(NULL); local = localtime_r(&now, &local_buff); - p = fmt; + p = in_head->vb_strvalue; num = strtoul(p, &q, 10); if (!q || *q == '\0') { REDEBUG("nexttime: must be followed by period specifier (h|d|w|m|y)"); - return -1; + return XLAT_ACTION_FAIL; } if (p == q) { @@ -1370,10 +1377,13 @@ static ssize_t xlat_func_next_time(UNUSED TALLOC_CTX *ctx, char **out, size_t ou default: REDEBUG("nexttime: Invalid period specifier '%c', must be h|d|w|m|y", *p); - return -1; + return XLAT_ACTION_FAIL; } - return snprintf(*out, outlen, "%" PRIu64, (uint64_t)(mktime(local) - now)); + MEM(vb=fr_value_box_alloc_null(ctx)); + fr_value_box_uint64(vb, NULL, (uint64_t)(mktime(local) - now), false); + fr_dcursor_append(out, vb); + return XLAT_ACTION_DONE; } /** xlat expand string attribute value @@ -3144,7 +3154,6 @@ int xlat_init(void) XLAT_REGISTER(integer); XLAT_REGISTER(map); - xlat_register_legacy(NULL, "nexttime", xlat_func_next_time, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN); xlat_register_legacy(NULL, "trigger", trigger_xlat, NULL, NULL, 0, 0); /* On behalf of trigger.c */ XLAT_REGISTER(xlat); @@ -3161,6 +3170,7 @@ do { \ XLAT_REGISTER_ARGS("hmacmd5", xlat_func_hmac_md5, xlat_hmac_args); XLAT_REGISTER_ARGS("hmacsha1", xlat_func_hmac_sha1, xlat_hmac_args); XLAT_REGISTER_ARGS("join", xlat_func_join, xlat_func_join_args); + XLAT_REGISTER_ARGS("nexttime", xlat_func_next_time, xlat_func_next_time_args); XLAT_REGISTER_ARGS("pairs", xlat_func_pairs, xlat_func_pairs_args); XLAT_REGISTER_ARGS("lpad", xlat_func_lpad, xlat_func_pad_args); XLAT_REGISTER_ARGS("rpad", xlat_func_rpad, xlat_func_pad_args); diff --git a/src/tests/keywords/nexttime b/src/tests/keywords/nexttime new file mode 100644 index 00000000000..efd02c73468 --- /dev/null +++ b/src/tests/keywords/nexttime @@ -0,0 +1,34 @@ +# +# PRE: update expr +# + +# +# Calculations based on month and year are not consistent due to +# different numbers of days involved. Check hour / day / week +# + +update request { + &Tmp-Integer-0 := "%{expr:%(nexttime:2h) - %(nexttime:1h)}" +} + +if (&Tmp-Integer-0 != 3600) { + test_fail +} + +update request { + &Tmp-Integer-0 := "%{expr:%(nexttime:3d) - %(nexttime:1d)}" +} + +if (&Tmp-Integer-0 != 172800) { + test_fail +} + +update request { + &Tmp-Integer-0 := "%{expr:%(nexttime:4w) - %(nexttime:2w)}" +} + +if (&Tmp-Integer-0 != 1209600) { + test_fail +} + +success