libidav/utils.c

changeset 160
ba8f1691c0ee
parent 159
7e0a8912ca25
child 161
97a52ce52b1a
equal deleted inserted replaced
159:7e0a8912ca25 160:ba8f1691c0ee
29 #include <time.h> 29 #include <time.h>
30 #include <stdio.h> 30 #include <stdio.h>
31 #include <stdlib.h> 31 #include <stdlib.h>
32 #include <string.h> 32 #include <string.h>
33 #include <errno.h> 33 #include <errno.h>
34 #include <ctype.h>
34 #include <ucx/string.h> 35 #include <ucx/string.h>
35 #include <ucx/buffer.h> 36 #include <ucx/buffer.h>
36 #include <ucx/utils.h> 37 #include <ucx/utils.h>
37 #include <libxml/tree.h> 38 #include <libxml/tree.h>
38 #include <curl/curl.h> 39 #include <curl/curl.h>
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

mercurial