1 /*
2    Unix SMB/CIFS implementation.
3    time utility functions
4 
5    Copyright (C) Andrew Tridgell 		1992-2004
6    Copyright (C) Stefan (metze) Metzmacher	2002
7    Copyright (C) Jeremy Allison			2007
8    Copyright (C) Andrew Bartlett                2011
9 
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23 
24 #ifndef _SAMBA_TIME_H_
25 #define _SAMBA_TIME_H_
26 
27 #include <stdbool.h>
28 #include <stdint.h>
29 #include <talloc.h>
30 
31 #ifndef TIME_T_MIN
32 /* we use 0 here, because (time_t)-1 means error */
33 #define TIME_T_MIN 0
34 #endif
35 
36 /*
37  * we use the INT32_MAX here as on 64 bit systems,
38  * gmtime() fails with INT64_MAX
39  */
40 #ifndef TIME_T_MAX
41 #define TIME_T_MAX MIN(INT32_MAX,_TYPE_MAXIMUM(time_t))
42 #endif
43 
44 /*
45  * According to Windows API FileTimeToSystemTime() documentation the highest
46  * allowed value " ... must be less than 0x8000000000000000.".
47  */
48 #define NTTIME_MAX INT64_MAX
49 
50 /*
51  * The lowest possible value when NTTIME=0 is used as sentinel value.
52  */
53 #define NTTIME_MIN 1
54 
55 /*
56  * NTTIME_OMIT in a setinfo tells us to not modify the corresponding on-disk
57  * timestamp value.
58  */
59 #define NTTIME_OMIT 0
60 
61 /*
62  * Disable automatic timestamp updates, as described in MS-FSA. Samba doesn't
63  * implement this yet.
64  */
65 #define NTTIME_FREEZE UINT64_MAX
66 
67 #define SAMBA_UTIME_NOW UTIME_NOW
68 #define SAMBA_UTIME_OMIT UTIME_OMIT
69 
70 /* 64 bit time (100 nanosec) 1601 - cifs6.txt, section 3.5, page 30, 4 byte aligned */
71 typedef uint64_t NTTIME;
72 
73 /**
74  External access to time_t_min and time_t_max.
75 **/
76 time_t get_time_t_max(void);
77 
78 /**
79 a gettimeofday wrapper
80 **/
81 void GetTimeOfDay(struct timeval *tval);
82 
83 /**
84 a wrapper to preferably get the monotonic time
85 **/
86 void clock_gettime_mono(struct timespec *tp);
87 
88 /**
89 a wrapper to preferably get the monotonic time in s
90 **/
91 time_t time_mono(time_t *t);
92 
93 /**
94 interpret an 8 byte "filetime" structure to a time_t
95 It's originally in "100ns units since jan 1st 1601"
96 **/
97 time_t nt_time_to_unix(NTTIME nt);
98 
99 /**
100 put a 8 byte filetime from a time_t
101 This takes GMT as input
102 **/
103 void unix_to_nt_time(NTTIME *nt, time_t t);
104 
105 /**
106 check if it's a null unix time
107 **/
108 bool null_time(time_t t);
109 
110 /**
111 check if it's a null NTTIME
112 **/
113 bool null_nttime(NTTIME t);
114 
115 /**
116 put a dos date into a buffer (time/date format)
117 This takes GMT time and puts local time in the buffer
118 **/
119 void push_dos_date(uint8_t *buf, int offset, time_t unixdate, int zone_offset);
120 
121 /**
122 put a dos date into a buffer (date/time format)
123 This takes GMT time and puts local time in the buffer
124 **/
125 void push_dos_date2(uint8_t *buf,int offset,time_t unixdate, int zone_offset);
126 
127 /**
128 put a dos 32 bit "unix like" date into a buffer. This routine takes
129 GMT and converts it to LOCAL time before putting it (most SMBs assume
130 localtime for this sort of date)
131 **/
132 void push_dos_date3(uint8_t *buf,int offset,time_t unixdate, int zone_offset);
133 
134 /**
135   create a unix date (int GMT) from a dos date (which is actually in
136   localtime)
137 **/
138 time_t pull_dos_date(const uint8_t *date_ptr, int zone_offset);
139 
140 /**
141 like make_unix_date() but the words are reversed
142 **/
143 time_t pull_dos_date2(const uint8_t *date_ptr, int zone_offset);
144 
145 /**
146   create a unix GMT date from a dos date in 32 bit "unix like" format
147   these generally arrive as localtimes, with corresponding DST
148 **/
149 time_t pull_dos_date3(const uint8_t *date_ptr, int zone_offset);
150 
151 /**
152  Return a date and time as a string (optionally with microseconds)
153 
154  format is %Y/%m/%d %H:%M:%S if strftime is available
155 **/
156 
157 char *timeval_string(TALLOC_CTX *ctx, const struct timeval *tp, bool hires);
158 
159 struct timeval_buf;
160 const char *timespec_string_buf(const struct timespec *tp,
161 				bool hires,
162 				struct timeval_buf *buf);
163 
164 /**
165  Return the current date and time as a string (optionally with microseconds)
166 
167  format is %Y/%m/%d %H:%M:%S if strftime is available
168 **/
169 char *current_timestring(TALLOC_CTX *ctx, bool hires);
170 
171 /**
172  Return a date and time as a string (optionally with microseconds)
173 
174  format is %Y%m%d_%H%M%S or %Y%m%d_%H%M%S_%us
175 **/
176 
177 char *minimal_timeval_string(TALLOC_CTX *ctx, const struct timeval *tp, bool hires);
178 
179 /**
180  Return the current date and time as a string (optionally with microseconds)
181 
182  format is %Y%m%d_%H%M%S or %Y%m%d_%H%M%S_%us
183 **/
184 char *current_minimal_timestring(TALLOC_CTX *ctx, bool hires);
185 
186 /**
187 return a HTTP/1.0 time string
188 **/
189 char *http_timestring(TALLOC_CTX *mem_ctx, time_t t);
190 
191 /**
192  Return the date and time as a string
193 
194  format is %a %b %e %X %Y %Z
195 **/
196 char *timestring(TALLOC_CTX *mem_ctx, time_t t);
197 
198 /**
199   return a talloced string representing a NTTIME for human consumption
200 */
201 const char *nt_time_string(TALLOC_CTX *mem_ctx, NTTIME nt);
202 
203 /**
204   put a NTTIME into a packet
205 */
206 void push_nttime(uint8_t *base, uint16_t offset, NTTIME t);
207 
208 /**
209   pull a NTTIME from a packet
210 */
211 NTTIME pull_nttime(uint8_t *base, uint16_t offset);
212 
213 /**
214   return (tv1 - tv2) in microseconds
215 */
216 int64_t usec_time_diff(const struct timeval *tv1, const struct timeval *tv2);
217 
218 /**
219   return (tp1 - tp2) in nanoseconds
220 */
221 int64_t nsec_time_diff(const struct timespec *tp1, const struct timespec *tp2);
222 
223 /**
224   return a zero timeval
225 */
226 struct timeval timeval_zero(void);
227 
228 /**
229   return true if a timeval is zero
230 */
231 bool timeval_is_zero(const struct timeval *tv);
232 
233 /**
234   return a timeval for the current time
235 */
236 struct timeval timeval_current(void);
237 
238 /**
239   return a timeval struct with the given elements
240 */
241 struct timeval timeval_set(uint32_t secs, uint32_t usecs);
242 
243 /**
244   return a timeval ofs microseconds after tv
245 */
246 struct timeval timeval_add(const struct timeval *tv,
247 			   uint32_t secs, uint32_t usecs);
248 
249 /**
250   return the sum of two timeval structures
251 */
252 struct timeval timeval_sum(const struct timeval *tv1,
253 			   const struct timeval *tv2);
254 
255 /**
256   return a timeval secs/usecs into the future
257 */
258 struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs);
259 
260 /**
261   return a timeval milliseconds into the future
262 */
263 struct timeval timeval_current_ofs_msec(uint32_t msecs);
264 
265 /**
266   return a timeval microseconds into the future
267 */
268 struct timeval timeval_current_ofs_usec(uint32_t usecs);
269 
270 /**
271   compare two timeval structures.
272   Return -1 if tv1 < tv2
273   Return 0 if tv1 == tv2
274   Return 1 if tv1 > tv2
275 */
276 int timeval_compare(const struct timeval *tv1, const struct timeval *tv2);
277 
278 /**
279   return true if a timer is in the past
280 */
281 bool timeval_expired(const struct timeval *tv);
282 
283 /**
284   return the number of seconds elapsed between two times
285 */
286 double timeval_elapsed2(const struct timeval *tv1, const struct timeval *tv2);
287 
288 /**
289   return the number of seconds elapsed since a given time
290 */
291 double timeval_elapsed(const struct timeval *tv);
292 
293 /**
294   return the number of seconds elapsed between two times
295 */
296 double timespec_elapsed2(const struct timespec *ts1,
297 			 const struct timespec *ts2);
298 /**
299   return the number of seconds elapsed since a given time
300 */
301 double timespec_elapsed(const struct timespec *ts);
302 
303 /**
304   return the lesser of two timevals
305 */
306 struct timeval timeval_min(const struct timeval *tv1,
307 			   const struct timeval *tv2);
308 
309 /**
310   return the greater of two timevals
311 */
312 struct timeval timeval_max(const struct timeval *tv1,
313 			   const struct timeval *tv2);
314 
315 /**
316   return the difference between two timevals as a timeval
317   if tv1 comes after tv2, then return a zero timeval
318   (this is *tv2 - *tv1)
319 */
320 struct timeval timeval_until(const struct timeval *tv1,
321 			     const struct timeval *tv2);
322 
323 /**
324   convert a timeval to a NTTIME
325 */
326 NTTIME timeval_to_nttime(const struct timeval *tv);
327 
328 /**
329   convert a NTTIME to a timeval
330 */
331 void nttime_to_timeval(struct timeval *tv, NTTIME t);
332 
333 /**
334   return the UTC offset in seconds west of UTC, or 0 if it cannot be determined
335  */
336 int get_time_zone(time_t t);
337 
338 /**
339   check if 2 NTTIMEs are equal.
340 */
341 bool nt_time_equal(NTTIME *t1, NTTIME *t2);
342 
343 void interpret_dos_date(uint32_t date,int *year,int *month,int *day,int *hour,int *minute,int *second);
344 
345 struct timespec nt_time_to_unix_timespec(NTTIME nt);
346 
347 time_t convert_timespec_to_time_t(struct timespec ts);
348 
349 struct timespec convert_time_t_to_timespec(time_t t);
350 
351 bool null_timespec(struct timespec ts);
352 
353 struct timespec convert_timeval_to_timespec(const struct timeval tv);
354 struct timeval convert_timespec_to_timeval(const struct timespec ts);
355 struct timespec timespec_current(void);
356 struct timespec timespec_min(const struct timespec *ts1,
357 			     const struct timespec *ts2);
358 int timespec_compare(const struct timespec *ts1, const struct timespec *ts2);
359 void round_timespec_to_sec(struct timespec *ts);
360 void round_timespec_to_usec(struct timespec *ts);
361 void round_timespec_to_nttime(struct timespec *ts);
362 NTTIME unix_timespec_to_nt_time(struct timespec ts);
363 
364 /*
365  * Functions supporting the full range of time_t and struct timespec values,
366  * including 0, -1 and all other negative values. These functions don't use 0 or
367  * -1 values as sentinel to denote "unset" variables, but use the POSIX 2008
368  * define UTIME_OMIT from utimensat(2).
369  */
370 bool is_omit_timespec(const struct timespec *ts);
371 struct timespec make_omit_timespec(void);
372 NTTIME full_timespec_to_nt_time(const struct timespec *ts);
373 struct timespec nt_time_to_full_timespec(NTTIME nt);
374 time_t full_timespec_to_time_t(const struct timespec *ts);
375 time_t nt_time_to_full_time_t(NTTIME nt);
376 struct timespec time_t_to_full_timespec(time_t t);
377 
378 #endif /* _SAMBA_TIME_H_ */
379