1 /*
2 * Copyright (c) 2002-2018 Balabit
3 * Copyright (c) 1998-2018 Balázs Scheidler
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 * As an additional exemption you are allowed to compile & link against the
20 * OpenSSL libraries as published by the OpenSSL project. See the file
21 * COPYING for details.
22 *
23 */
24
25 #ifndef WALLCLOCKTIME_H_INCLUDED
26 #define WALLCLOCKTIME_H_INCLUDED
27
28 #include "syslog-ng.h"
29
30 /*
31 * This is a simple wrapper over "struct tm" with fields that are not
32 * portable across all platforms or are not present at all, but which we
33 * would use.
34 *
35 * For instance, wct_gmtoff is not present on a number of platforms but would
36 * be very useful internally, so we _always_ have the capability to
37 * represent a broken-down time with all the properties needed for proper
38 * timezone reference.
39 *
40 * Another example is wct_usec, which represents the number of microseconds
41 * so we can carry fractions of a second information.
42 *
43 * The design of the class is so that we don't need to copy the contents of
44 * "struct tm" around for conversions, rather we contain one instance and
45 * provide wrapper macros so that fields that are present in struct tm are
46 * used from there, those that aren't will be part of the wrapper structure.
47 *
48 * NOTE on thread safety: the wct_zone field is a pointer to a dynamically
49 * allocated string, that is managed in a thread-specific location (in
50 * cache.c), the pointer could become stale across a syslog-ng reload. In
51 * general it is not a good idea to pass WallClockTime instances between
52 * threads, if the wct_zone field was initialized by cached_localtime() and
53 * friends, unless you ensure this field does not become stale.
54 */
55 typedef struct _WallClockTime WallClockTime;
56 struct _WallClockTime
57 {
58 #define wct_year tm.tm_year
59 #define wct_mon tm.tm_mon
60 #define wct_mday tm.tm_mday
61 #define wct_wday tm.tm_wday
62 #define wct_yday tm.tm_yday
63 #define wct_hour tm.tm_hour
64 #define wct_min tm.tm_min
65 #define wct_sec tm.tm_sec
66 #define wct_isdst tm.tm_isdst
67 struct tm tm;
68
69
70 /* We might need to separate tm_zone to a different conditional/autoconf
71 * check. At least on Linux/FreeBSD they were introduced the same time.
72 * Some platforms may lack tm_zone, even though they have tm_gmtoff */
73
74 #ifndef SYSLOG_NG_HAVE_STRUCT_TM_TM_GMTOFF
75 long wct_gmtoff;
76 const char *wct_zone;
77 #else
78 #define wct_gmtoff tm.tm_gmtoff
79 #define wct_zone tm.tm_zone
80 #endif
81 int wct_usec;
82 };
83
84 #ifdef SYSLOG_NG_HAVE_STRUCT_TM_TM_GMTOFF
85
86 #define WALL_CLOCK_TIME_INIT \
87 { \
88 .tm = \
89 { \
90 .tm_year = -1, \
91 .tm_mon = -1, \
92 .tm_mday = -1, \
93 .tm_wday = -1, \
94 .tm_yday = -1, \
95 .tm_hour = -1, \
96 .tm_min = -1, \
97 .tm_sec = -1, \
98 .tm_isdst = -1, \
99 .tm_gmtoff = -1, \
100 .tm_zone = NULL, \
101 }, \
102 .wct_usec = 0, \
103 }
104 #else
105
106 #define WALL_CLOCK_TIME_INIT \
107 { \
108 .tm = \
109 { \
110 .tm_year = -1, \
111 .tm_mon = -1, \
112 .tm_mday = -1, \
113 .tm_wday = -1, \
114 .tm_yday = -1, \
115 .tm_hour = -1, \
116 .tm_min = -1, \
117 .tm_sec = -1, \
118 .tm_isdst = -1, \
119 }, \
120 .wct_gmtoff = -1, \
121 .wct_zone = NULL, \
122 .wct_usec = 0, \
123 }
124
125 #endif
126
127 guint32 wall_clock_time_iso_week_number(WallClockTime *wct);
128
129 static inline gboolean
wall_clock_time_is_set(WallClockTime * wct)130 wall_clock_time_is_set(WallClockTime *wct)
131 {
132 return wct->wct_hour != -1;
133 }
134
135 void wall_clock_time_unset(WallClockTime *wct);
136 gchar *wall_clock_time_strptime(WallClockTime *wct, const gchar *format, const gchar *input);
137 void wall_clock_time_guess_missing_year(WallClockTime *self);
138 void wall_clock_time_guess_missing_fields(WallClockTime *self);
139
140 #endif
141