Fix converting YYYY-DDD date string on musl
[libisds.git] / src / unix.c
blob35ed187cd428e4d541f9ef821d38b28e0c75ed29
1 #include "isds_priv.h"
2 #include <stdio.h>
3 #include <stdlib.h> /* for getenv */
4 #include <string.h>
5 #include <time.h>
6 #include "isds.h"
7 #include "utils.h"
9 static char *tz_orig; /* Copy of original TZ variable */
11 #if HAVE_LIBCURL
12 /* Convert UTF-8 @string representation of ISO 8601 date to @time.
13 * XXX: Not all ISO formats are supported */
14 _hidden isds_error _isds_datestring2tm(const xmlChar *string, struct tm *time) {
15 char *offset;
16 if (!string || !time) return IE_INVAL;
18 memset(time, 0, sizeof(*time));
20 /* xsd:date is ISO 8601 string, thus ASCII */
21 offset = strptime((char*)string, "%Y-%m-%d", time);
22 if (offset && *offset == '\0')
23 return IE_SUCCESS;
25 offset = strptime((char*)string, "%Y%m%d", time);
26 if (offset && *offset == '\0')
27 return IE_SUCCESS;
29 offset = strptime((char*)string, "%Y-%j", time);
30 if (offset && *offset == '\0') {
31 _isds_yday2mday(time);
32 return IE_SUCCESS;
35 return IE_NOTSUP;
37 #endif
39 /* Switches time zone to UTC.
40 * XXX: This is not reentrant and not thread-safe */
41 static void _isds_switch_tz_to_utc(void) {
42 char *tz;
44 tz = getenv("TZ");
45 if (tz) {
46 tz_orig = strdup(tz);
47 if (!tz_orig)
48 PANIC("Can not back original time zone up");
49 } else {
50 tz_orig = NULL;
53 if (setenv("TZ", "", 1))
54 PANIC("Can not change time zone to UTC temporarily");
56 tzset();
60 /* Switches time zone to original value.
61 * XXX: This is not reentrant and not thread-safe */
62 static void _isds_switch_tz_to_native(void) {
63 if (tz_orig) {
64 if (setenv("TZ", tz_orig, 1))
65 PANIC("Can not restore time zone by setting TZ variable");
66 free(tz_orig);
67 tz_orig = NULL;
68 } else {
69 if(unsetenv("TZ"))
70 PANIC("Can not restore time zone by unsetting TZ variable");
72 tzset();
75 /* Convert UTC broken time to time_t.
76 * @broken_utc it time in UTC in broken format. Despite its content is not
77 * touched, it'sw not-const because underlying POSIX function has non-const
78 * signature.
79 * @return (time_t) -1 in case of error */
80 _hidden time_t _isds_timegm(struct tm *broken_utc) {
81 time_t ret;
83 _isds_switch_tz_to_utc();
84 ret = mktime(broken_utc);
85 _isds_switch_tz_to_native();
87 return ret;