All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rlm_date.c
Go to the documentation of this file.
1 /*
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.
6  *
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.
11  *
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
15  */
16 
17 /**
18  * @file rlm_date.c
19  * @brief Translates timestrings between formats.
20  *
21  * @author Artur Malinowski <artur@wow.com>
22  *
23  * @copyright 2013 Artur Malinowski <artur@wow.com>
24  * @copyright 1999-2013 The FreeRADIUS Server Project.
25  */
26 
27 #include <freeradius-devel/radiusd.h>
28 #include <freeradius-devel/modules.h>
29 #include <ctype.h>
30 #include <time.h>
31 
32 typedef struct rlm_date_t {
33  char const *xlat_name;
34  char const *fmt;
35 } rlm_date_t;
36 
37 static const CONF_PARSER module_config[] = {
38  { FR_CONF_OFFSET("format", PW_TYPE_STRING, rlm_date_t, fmt), .dflt = "%b %e %Y %H:%M:%S %Z" },
40 };
41 
42 DIAG_OFF(format-nonliteral)
43 static ssize_t xlat_date_convert(char **out, size_t outlen,
44  void const *mod_inst, UNUSED void const *xlat_inst,
45  REQUEST *request, char const *fmt)
46 {
47  rlm_date_t const *inst = mod_inst;
48  time_t date = 0;
49  struct tm tminfo;
50  VALUE_PAIR *vp;
51 
52  if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) return 0;
53 
54  switch (vp->da->type) {
55  /*
56  * These are 'to' types, i.e. we'll convert the integers
57  * to a time structure, and then output it in the specified
58  * format as a string.
59  */
60  case PW_TYPE_DATE:
61  date = vp->vp_date;
62  goto encode;
63 
64  case PW_TYPE_INTEGER:
65  case PW_TYPE_INTEGER64:
66  date = (time_t) vp->vp_integer;
67 
68  encode:
69  if (localtime_r(&date, &tminfo) == NULL) {
70  REDEBUG("Failed converting time string to localtime");
71  goto error;
72  }
73  return strftime(*out, outlen, inst->fmt, &tminfo);
74 
75  /*
76  * These are 'from' types, i.e. we'll convert the input string
77  * into a time structure, and then output it as an integer
78  * unix timestamp.
79  */
80  case PW_TYPE_STRING:
81  if (strptime(vp->vp_strvalue, inst->fmt, &tminfo) == NULL) {
82  REDEBUG("Failed to parse time string \"%s\" as format '%s'", vp->vp_strvalue, inst->fmt);
83  goto error;
84  }
85 
86  date = mktime(&tminfo);
87  if (date < 0) {
88  REDEBUG("Failed converting parsed time into unix time");
89 
90  }
91  return snprintf(*out, outlen, "%" PRIu64, (uint64_t) date);
92 
93  default:
94  REDEBUG("Can't convert type %s into date", fr_int2str(dict_attr_types, vp->da->type, "<INVALID>"));
95  }
96 
97 error:
98  return -1;
99 }
100 DIAG_ON(format-nonliteral)
101 
102 static int mod_bootstrap(CONF_SECTION *conf, void *instance)
103 {
104  rlm_date_t *inst = instance;
105 
106  inst->xlat_name = cf_section_name2(conf);
107  if (!inst->xlat_name) {
108  inst->xlat_name = cf_section_name1(conf);
109  }
110 
111  xlat_register(inst, inst->xlat_name, xlat_date_convert, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN);
112 
113  return 0;
114 }
115 
116 extern module_t rlm_date;
117 module_t rlm_date = {
119  .name = "date",
120  .inst_size = sizeof(rlm_date_t),
121  .config = module_config,
122  .bootstrap = mod_bootstrap
123 };
124 
#define DIAG_ON(_x)
Definition: build.h:103
int xlat_register(void *mod_inst, char const *name, xlat_func_t func, xlat_escape_t escape, xlat_instantiate_t instantiate, size_t inst_size, size_t buf_len)
Register an xlat function.
Definition: xlat.c:717
module_t rlm_date
Definition: rlm_date.c:117
Metadata exported by the module.
Definition: modules.h:134
#define DIAG_OFF(_x)
Definition: build.h:102
static int mod_bootstrap(CONF_SECTION *conf, void *instance)
Definition: rlm_date.c:102
#define UNUSED
Definition: libradius.h:134
#define RLM_MODULE_INIT
Definition: modules.h:86
#define CONF_PARSER_TERMINATOR
Definition: conffile.h:289
static const CONF_PARSER module_config[]
Definition: rlm_date.c:37
static ssize_t xlat_date_convert(char **out, size_t outlen, void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Definition: rlm_date.c:43
char const * fmt
Definition: rlm_date.c:34
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition: snprintf.c:686
#define inst
#define XLAT_DEFAULT_BUF_LEN
Definition: xlat.h:89
Defines a CONF_PAIR to C data type mapping.
Definition: conffile.h:267
const FR_NAME_NUMBER dict_attr_types[]
Map data types to names representing those types.
Definition: dict.c:85
void void int radius_get_vp(VALUE_PAIR **out, REQUEST *request, char const *name)
Return a VP from the specified request.
Definition: pair.c:815
Stores an attribute, a value and various bits of other data.
Definition: pair.h:112
32 Bit unsigned integer.
Definition: radius.h:34
struct rlm_date_t rlm_date_t
static rs_t * conf
Definition: radsniff.c:46
64 Bit unsigned integer.
Definition: radius.h:51
char const * cf_section_name1(CONF_SECTION const *cs)
Definition: conffile.c:3592
uint64_t magic
Used to validate module struct.
Definition: modules.h:135
32 Bit Unix timestamp.
Definition: radius.h:36
#define FR_CONF_OFFSET(_n, _t, _s, _f)
Definition: conffile.h:168
#define REDEBUG(fmt,...)
Definition: log.h:254
char const * xlat_name
Definition: rlm_date.c:33
char const * fr_int2str(FR_NAME_NUMBER const *table, int number, char const *def)
Definition: token.c:506
String of printable characters.
Definition: radius.h:33
struct tm * localtime_r(time_t const *l_clock, struct tm *result)
Definition: missing.c:152
char const * cf_section_name2(CONF_SECTION const *cs)
Definition: conffile.c:3601