]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
start splitting out %time(everything)
authorAlan T. DeKok <aland@freeradius.org>
Wed, 7 May 2025 15:03:23 +0000 (11:03 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Wed, 7 May 2025 15:38:11 +0000 (11:38 -0400)
into use-specific cases

doc/antora/modules/reference/pages/xlat/builtin.adoc
src/lib/unlang/xlat_builtin.c

index 760ed0e21aeb2e0cdf482c687aaf0e7d0881b0b4..f0da97d120daf0b62fb83231e584449991eaf309 100644 (file)
@@ -183,7 +183,30 @@ reply.Reply-Message := "You should wait for %time.next(1h)s"
 You should wait for 2520s
 ```
 
-### %str.subst(<subject>, <find>, <replace>)
+=== %time.now()
+
+Return the current time.  This time should be used for actions which
+involve the file system, or for actions which happen after the request
+has been received.
+
+=== %time.request()
+
+Return the time when the request was received.  This time should be
+used as the basis any actions which involve the "start time of the
+request".
+
+=== %time.offset()
+
+Return a `time_delta` of the current offset from UTC.  This offset can
+change while the server is running, due to daylight savings updates.
+
+=== %time.is_dst()
+
+Return a `bool` indicating whether or not the system is currently
+operating in daylight savings.
+
+
+=== %str.subst(<subject>, <find>, <replace>)
 
 Substitute text.
 
index 2221dc49ab0d9946de608846ded07fffa8583236..9696322769145d1620a7db626e10a79b4c13e884 100644 (file)
@@ -3608,6 +3608,106 @@ append:
        return XLAT_ACTION_DONE;
 }
 
+/** Return the current time as a #FR_TYPE_DATE
+ *
+ *  Note that all operations are UTC.
+ *
+@verbatim
+%time.now()
+@endverbatim
+ *
+ * Example:
+@verbatim
+update reply {
+       &Reply-Message := "%{%time.now() - %time.request()}"
+}
+@endverbatim
+ *
+ * @ingroup xlat_functions
+ */
+static xlat_action_t xlat_func_time_now(TALLOC_CTX *ctx, fr_dcursor_t *out,
+                                       UNUSED xlat_ctx_t const *xctx,
+                                       UNUSED request_t *request, UNUSED fr_value_box_list_t *args)
+{
+       fr_value_box_t          *vb;
+
+       MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_DATE, NULL));
+       vb->vb_date = fr_time_to_unix_time(fr_time());
+
+       fr_dcursor_append(out, vb);
+
+       return XLAT_ACTION_DONE;
+}
+
+/** Return the request receive time as a #FR_TYPE_DATE
+ *
+ *  Note that all operations are UTC.
+ *
+@verbatim
+%time.request()
+@endverbatim
+ *
+ * Example:
+@verbatim
+update reply {
+       &Reply-Message := "%{%time.now() - %time.request()}"
+}
+@endverbatim
+ *
+ * @ingroup xlat_functions
+ */
+static xlat_action_t xlat_func_time_request(TALLOC_CTX *ctx, fr_dcursor_t *out,
+                                           UNUSED xlat_ctx_t const *xctx,
+                                           request_t *request, UNUSED fr_value_box_list_t *args)
+{
+       fr_value_box_t          *vb;
+
+       MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_DATE, NULL));
+       vb->vb_date = fr_time_to_unix_time(request->packet->timestamp);
+
+       fr_dcursor_append(out, vb);
+
+       return XLAT_ACTION_DONE;
+}
+
+
+/** Return the current time offset from gmt
+ *
+ * @ingroup xlat_functions
+ */
+static xlat_action_t xlat_func_time_offset(TALLOC_CTX *ctx, fr_dcursor_t *out,
+                                          UNUSED xlat_ctx_t const *xctx,
+                                          UNUSED request_t *request, UNUSED fr_value_box_list_t *args)
+{
+       fr_value_box_t          *vb;
+
+       MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_TIME_DELTA, NULL));
+       vb->vb_time_delta = fr_time_gmtoff();
+
+       fr_dcursor_append(out, vb);
+
+       return XLAT_ACTION_DONE;
+}
+
+
+/** Return whether we are in daylight savings or not
+ *
+ * @ingroup xlat_functions
+ */
+static xlat_action_t xlat_func_time_is_dst(TALLOC_CTX *ctx, fr_dcursor_t *out,
+                                          UNUSED xlat_ctx_t const *xctx,
+                                          UNUSED request_t *request, UNUSED fr_value_box_list_t *args)
+{
+       fr_value_box_t          *vb;
+
+       MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_BOOL, NULL));
+       vb->vb_bool = fr_time_is_dst();
+
+       fr_dcursor_append(out, vb);
+
+       return XLAT_ACTION_DONE;
+}
+
 
 /** Change case of a string
  *
@@ -4268,6 +4368,13 @@ do { \
        xlat_func_flags_set(xlat, XLAT_FUNC_FLAG_INTERNAL); \
 } while (0)
 
+#undef XLAT_REGISTER_VOID
+#define XLAT_REGISTER_VOID(_xlat, _func, _return_type) \
+do { \
+       if (unlikely((xlat = xlat_func_register(xlat_ctx, _xlat, _func, _return_type)) == NULL)) return -1; \
+       xlat_func_flags_set(xlat, XLAT_FUNC_FLAG_INTERNAL); \
+} while (0)
+
        XLAT_REGISTER_ARGS("debug", xlat_func_debug, FR_TYPE_INT8, xlat_func_debug_args);
        XLAT_REGISTER_ARGS("debug_attr", xlat_func_debug_attr, FR_TYPE_NULL, xlat_func_debug_attr_args);
        XLAT_REGISTER_ARGS("file.exists", xlat_func_file_exists, FR_TYPE_BOOL, xlat_func_file_name_args);
@@ -4299,6 +4406,11 @@ do { \
 #endif
 
        XLAT_REGISTER_ARGS("time", xlat_func_time, FR_TYPE_VOID, xlat_func_time_args);
+       XLAT_REGISTER_VOID("time.now", xlat_func_time_now, FR_TYPE_DATE);
+       XLAT_REGISTER_VOID("time.request", xlat_func_time_request, FR_TYPE_DATE);
+       XLAT_REGISTER_VOID("time.offset", xlat_func_time_offset, FR_TYPE_TIME_DELTA);
+       XLAT_REGISTER_VOID("time.is_dst", xlat_func_time_is_dst, FR_TYPE_BOOL);
+
        XLAT_REGISTER_ARGS("trigger", trigger_xlat, FR_TYPE_STRING, trigger_xlat_args);
        XLAT_REGISTER_ARGS("base64.encode", xlat_func_base64_encode, FR_TYPE_STRING, xlat_func_base64_encode_arg);
        XLAT_REGISTER_ARGS("base64.decode", xlat_func_base64_decode, FR_TYPE_OCTETS, xlat_func_base64_decode_arg);