2 * This program is is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 * @brief Translates timestrings between formats.
21 * @author Artur Malinowski <artur@wow.com>
23 * @copyright 2013 Artur Malinowski <artur@wow.com>
24 * @copyright 1999-2013 The FreeRADIUS Server Project.
27 #include <freeradius-devel/radiusd.h>
28 #include <freeradius-devel/modules.h>
32 typedef struct rlm_date_t {
33 char const *xlat_name;
37 static const CONF_PARSER module_config[] = {
38 { "format", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_date_t, fmt), "%b %e %Y %H:%M:%S %Z" },
39 CONF_PARSER_TERMINATOR
42 DIAG_OFF(format-nonliteral)
43 static ssize_t xlat_date_convert(void *instance, REQUEST *request, char const *fmt, char *out, size_t outlen)
45 rlm_date_t *inst = instance;
50 memset(&tminfo, 0, sizeof(tminfo));
52 if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) {
57 switch (vp->da->type) {
59 * These are 'to' types, i.e. we'll convert the integers
60 * to a time structure, and then output it in the specified
68 case PW_TYPE_INTEGER64:
69 date = (time_t) vp->vp_integer;
72 if (localtime_r(&date, &tminfo) == NULL) {
73 REDEBUG("Failed converting time string to localtime");
76 return strftime(out, outlen, inst->fmt, &tminfo);
79 * These are 'from' types, i.e. we'll convert the input string
80 * into a time structure, and then output it as an integer
84 if (strptime(vp->vp_strvalue, inst->fmt, &tminfo) == NULL) {
85 REDEBUG("Failed to parse time string \"%s\" as format '%s'", vp->vp_strvalue, inst->fmt);
89 date = mktime(&tminfo);
91 REDEBUG("Failed converting parsed time into unix time");
94 return snprintf(out, outlen, "%" PRIu64, (uint64_t) date);
97 REDEBUG("Can't convert type %s into date", fr_int2str(dict_attr_types, vp->da->type, "<INVALID>"));
104 DIAG_ON(format-nonliteral)
106 static int mod_bootstrap(CONF_SECTION *conf, void *instance)
108 rlm_date_t *inst = instance;
110 inst->xlat_name = cf_section_name2(conf);
111 if (!inst->xlat_name) {
112 inst->xlat_name = cf_section_name1(conf);
115 xlat_register(inst->xlat_name, xlat_date_convert, NULL, inst);
120 extern module_t rlm_date;
121 module_t rlm_date = {
122 .magic = RLM_MODULE_INIT,
124 .inst_size = sizeof(rlm_date_t),
125 .config = module_config,
126 .bootstrap = mod_bootstrap