2 /* >= 500: strdup(3) from string.h, strptime(3) from time.h */
3 /* >= 600: setenv(3) */
4 #define _XOPEN_SOURCE 600
6 #include "../test-tools.h"
7 #include <stdlib.h> /* for getenv(), abort() */
8 #include <string.h> /* for strdup() */
9 #include <stdio.h> /* for stderr */
13 /* PANIC macro aborts current process without any clean up.
14 * Use it as last resort fatal error solution */
15 #define PANIC(message) { \
16 if (stderr != NULL ) fprintf(stderr, \
17 "SERVER PANIC (%s:%d): %s\n", __FILE__, __LINE__, (message)); \
21 static char *tz_orig
; /* Copy of original TZ variable */
23 /* Convert UTF-8 @string representation of ISO 8601 date to @time.
24 * XXX: Not all ISO formats are supported */
25 _hidden http_error
_server_datestring2tm(const char *string
, struct tm
*time
) {
27 if (!string
|| !time
) return HTTP_ERROR_SERVER
;
29 /* xsd:date is ISO 8601 string, thus ASCII */
30 offset
= strptime(string
, "%Y-%m-%d", time
);
31 if (offset
&& *offset
== '\0')
32 return HTTP_ERROR_SUCCESS
;
34 offset
= strptime(string
, "%Y%m%d", time
);
35 if (offset
&& *offset
== '\0')
36 return HTTP_ERROR_SUCCESS
;
38 offset
= strptime(string
, "%Y-%j", time
);
39 if (offset
&& *offset
== '\0')
40 return HTTP_ERROR_SUCCESS
;
42 return HTTP_ERROR_SERVER
;
45 /* Switches time zone to UTC.
46 * XXX: This is not reentrant and not thread-safe */
47 static void _isds_switch_tz_to_utc(void) {
54 PANIC("Can not back original time zone up");
59 if (setenv("TZ", "", 1))
60 PANIC("Can not change time zone to UTC temporarily");
66 /* Switches time zone to original value.
67 * XXX: This is not reentrant and not thread-safe */
68 static void _isds_switch_tz_to_native(void) {
70 if (setenv("TZ", tz_orig
, 1))
71 PANIC("Can not restore time zone by setting TZ variable");
76 PANIC("Can not restore time zone by unsetting TZ variable");
81 /* Convert UTC broken time to time_t.
82 * @broken_utc it time in UTC in broken format. Despite its content is not
83 * touched, it'sw not-const because underlying POSIX function has non-const
85 * @return (time_t) -1 in case of error */
86 _hidden
time_t _isds_timegm(struct tm
*broken_utc
) {
89 _isds_switch_tz_to_utc();
90 ret
= mktime(broken_utc
);
91 _isds_switch_tz_to_native();