54 |
55 |
55 #include "utils.h" |
56 #include "utils.h" |
56 #include "crypto.h" |
57 #include "crypto.h" |
57 #include "webdav.h" |
58 #include "webdav.h" |
58 |
59 |
|
60 static int parse_iso8601(char *str, time_t *result) { |
|
61 |
|
62 // safety |
|
63 if(!str || !result) { |
|
64 return 1; |
|
65 } |
|
66 |
|
67 struct tm tparts; |
|
68 memset(&tparts, 0, sizeof(struct tm)); |
|
69 *result = 0; |
|
70 long val; |
|
71 |
|
72 // skip leading spaces |
|
73 while(isspace(*str)) { |
|
74 str++; |
|
75 } |
|
76 |
|
77 // ensure we have numeric values (maybe with sign) |
|
78 if(!isdigit(*str) && *str != '-' && *str != '+') { |
|
79 return 1; |
|
80 } |
|
81 |
|
82 // starting parsing the year |
|
83 val = strtoul(str, &str, 10); |
|
84 |
|
85 if(*str == '-') { |
|
86 // month (and day) seem to be dash separated |
|
87 tparts.tm_year = val - 1900; |
|
88 str++; |
|
89 tparts.tm_mon = strtoul(str, &str, 10) - 1; |
|
90 |
|
91 if (*str++ != '-') { |
|
92 return 1; |
|
93 } |
|
94 |
|
95 tparts.tm_mday = strtoul(str, &str, 10); |
|
96 } else { |
|
97 // year, month, day was parsed as one big integer |
|
98 tparts.tm_mday = val % 100; |
|
99 tparts.tm_mon = (val % 10000) / 100 - 1; |
|
100 tparts.tm_year = val / 10000 - 1900; |
|
101 } |
|
102 |
|
103 // time separator |
|
104 if(*str != 'T') { |
|
105 return 1; |
|
106 } |
|
107 str++; |
|
108 |
|
109 // ensure we have numeric values (unsigned) |
|
110 if(!isdigit(*str)) { |
|
111 return 1; |
|
112 } |
|
113 |
|
114 // start parsing the hour |
|
115 val = strtoul(str, &str, 10); |
|
116 if(*str == ':') { |
|
117 // minutes (and seconds) are separated by colon |
|
118 tparts.tm_hour = val; |
|
119 str++; |
|
120 tparts.tm_min = strtoul(str, &str, 10); |
|
121 |
|
122 if(*str++ != ':') { |
|
123 return 1; |
|
124 } |
|
125 |
|
126 tparts.tm_sec = strtoul(str, &str, 10); |
|
127 } else { |
|
128 // minutes (and seconds) are one big integer |
|
129 tparts.tm_sec = val % 100; |
|
130 tparts.tm_min = (val % 10000) / 100; |
|
131 tparts.tm_hour = val / 10000; |
|
132 } |
|
133 |
|
134 // parse fractional seconds, but skip them (we return a time_t) |
|
135 if(*str == ',' || *str == '.') { |
|
136 do { |
|
137 str++; |
|
138 } while(isdigit(*str)); |
|
139 } |
|
140 |
|
141 // parse time zone (if any) |
|
142 if(*str == 'Z') { |
|
143 str++; |
|
144 *result = mktime(&tparts) - timezone; |
|
145 } else if (*str == '+' || *str == '-') { |
|
146 int sign = (*str == '+') ? -1 : 1; |
|
147 |
|
148 val = strtoul(str + 1, &str, 10); |
|
149 |
|
150 if (*str == ':') { |
|
151 val = 60 * val + strtoul(str + 1, &str, 10); |
|
152 } else { |
|
153 val = 60 * (val / 100) + (val % 100); |
|
154 } |
|
155 |
|
156 *result = mktime(&tparts) - timezone + (time_t) (60 * val * sign); |
|
157 } else { |
|
158 // local time |
|
159 tparts.tm_isdst = -1; |
|
160 *result = mktime(&tparts); |
|
161 } |
|
162 |
|
163 // skip trailing spaces |
|
164 while(isspace(*str)) { |
|
165 str++; |
|
166 } |
|
167 |
|
168 // string must be zero terminated, no further characters may follow |
|
169 return *str != '\0'; // return zero on success |
|
170 } |
|
171 |
59 |
172 |
60 time_t util_parse_creationdate(char *str) { |
173 time_t util_parse_creationdate(char *str) { |
61 // parse a ISO-8601 date |
174 // parse a ISO-8601 date (rfc-3339) |
62 // example: 2012-11-29T21:35:35Z |
175 // example: 2012-11-29T21:35:35Z |
63 if(!str) { |
176 if(!str) { |
64 return 0; |
177 return 0; |
65 } |
178 } |
66 // TODO: implement |
179 |
67 return 0; |
180 time_t result; |
|
181 if(!parse_iso8601(str, &result)) { |
|
182 return result; |
|
183 } else { |
|
184 return 0; |
|
185 } |
68 } |
186 } |
69 |
187 |
70 time_t util_parse_lastmodified(char *str) { |
188 time_t util_parse_lastmodified(char *str) { |
71 // parse a rfc-1123 date |
189 // parse a rfc-1123 date |
72 // example: Thu, 29 Nov 2012 21:35:35 GMT |
190 // example: Thu, 29 Nov 2012 21:35:35 GMT |