32 #include <stdlib.h> |
32 #include <stdlib.h> |
33 #include <string.h> |
33 #include <string.h> |
34 #include <unistd.h> |
34 #include <unistd.h> |
35 #include <errno.h> |
35 #include <errno.h> |
36 #include <sys/stat.h> |
36 #include <sys/stat.h> |
37 |
37 #include <limits.h> |
38 #include <ucx/string.h> |
38 |
39 #include <ucx/list.h> |
39 #include <cx/string.h> |
|
40 #include <cx/list.h> |
|
41 #include <cx/array_list.h> |
40 #include <libidav/crypto.h> |
42 #include <libidav/crypto.h> |
41 #include <libidav/utils.h> |
43 #include <libidav/utils.h> |
42 |
44 |
43 #include "libxattr.h" |
45 #include "libxattr.h" |
44 |
46 |
45 uint32_t parse_finfo_settings(const char *str, char **error) { |
47 uint32_t parse_finfo_settings(const char *str, char **error) { |
46 scstr_t s = scstr(str); |
48 cxstring s = cx_str(str); |
47 |
49 |
48 if(!sstrcmp(s, SC("*")) || !sstrcmp(s, SC("a")) || !sstrcmp(s, SC("all"))) { |
50 if(!cx_strcmp(s, CX_STR("*")) || !cx_strcmp(s, CX_STR("a")) || !cx_strcmp(s, CX_STR("all"))) { |
49 return FINFO_MTIME|FINFO_OWNER|FINFO_MODE|FINFO_XATTR; |
51 return FINFO_MTIME|FINFO_OWNER|FINFO_MODE|FINFO_XATTR; |
50 } |
52 } |
51 |
53 |
52 ssize_t count = 0; |
54 CxStrtokCtx fs = cx_strtok(s, CX_STR(","), INT_MAX); |
53 sstr_t *fs = sstrsplit(s, SC(","), &count); |
55 cxstring f; |
54 |
56 uint32_t finfo = 0; |
55 char *err = NULL; |
57 char *err = NULL; |
56 |
58 while(cx_strtok_next(&fs, &f)) { |
57 uint32_t finfo = 0; |
59 if(!cx_strcasecmp(f, CX_STR("mtime"))) { |
58 for(int i=0;i<count;i++) { |
|
59 sstr_t f = fs[i]; |
|
60 if(!sstrcasecmp(f, SC("mtime"))) { |
|
61 finfo |= FINFO_MTIME; |
60 finfo |= FINFO_MTIME; |
62 } else if(!sstrcasecmp(f, SC("owner"))) { |
61 } else if(!cx_strcasecmp(f, CX_STR("owner"))) { |
63 finfo |= FINFO_OWNER; |
62 finfo |= FINFO_OWNER; |
64 } else if(!sstrcasecmp(f, SC("mode"))) { |
63 } else if(!cx_strcasecmp(f, CX_STR("mode"))) { |
65 finfo |= FINFO_MODE; |
64 finfo |= FINFO_MODE; |
66 } else if(!sstrcasecmp(f, SC("xattr"))) { |
65 } else if(!cx_strcasecmp(f, CX_STR("xattr"))) { |
67 finfo |= FINFO_XATTR; |
66 finfo |= FINFO_XATTR; |
68 } else if(error && !err) { |
67 } else if(error && !err) { |
69 err = fs[i].ptr; |
68 err = cx_strdup(f).ptr; |
70 continue; |
69 continue; |
71 } |
70 } |
72 free(f.ptr); |
71 } |
73 } |
72 |
74 |
|
75 free(fs); |
|
76 return err ? 0 : finfo; |
73 return err ? 0 : finfo; |
77 } |
74 } |
78 |
75 |
79 int resource_set_finfo(const char *path, DavResource *res, uint32_t finfo) { |
76 int resource_set_finfo(const char *path, DavResource *res, uint32_t finfo) { |
80 if(!path || finfo == 0) { |
77 if(!path || finfo == 0) { |
127 dav_set_property_ns(res, DAV_PROPS_NS, "finfo", content);; |
124 dav_set_property_ns(res, DAV_PROPS_NS, "finfo", content);; |
128 |
125 |
129 return 0; |
126 return 0; |
130 } |
127 } |
131 |
128 |
|
129 |
|
130 static void* array_realloc(void *array, |
|
131 size_t capacity, |
|
132 size_t elem_size, |
|
133 struct cx_array_reallocator_s *alloc) |
|
134 { |
|
135 return realloc(array, capacity * elem_size); |
|
136 } |
|
137 |
132 XAttributes* xml_get_attributes(DavXmlNode *xml) { |
138 XAttributes* xml_get_attributes(DavXmlNode *xml) { |
133 UcxList *names = NULL; |
139 XAttributes *attributes = calloc(1, sizeof(XAttributes)); |
134 UcxList *values = NULL; |
140 size_t x_names_size = 0; |
135 |
141 size_t x_names_alloc = 8; |
|
142 size_t x_values_size = 0; |
|
143 size_t x_values_alloc = 8; |
|
144 attributes->names = calloc(x_names_alloc, sizeof(char*)); |
|
145 attributes->values = calloc(x_values_alloc, sizeof(cxmutstr)); |
|
146 |
|
147 struct cx_array_reallocator_s re = { .realloc = array_realloc }; |
|
148 |
136 size_t count = 0; |
149 size_t count = 0; |
137 |
150 |
138 char *hash = NULL; |
151 char *hash = NULL; |
139 |
152 |
140 DavXmlNode *node = xml; |
153 DavXmlNode *node = xml; |
143 if(!strcmp(node->name, "hash")) { |
156 if(!strcmp(node->name, "hash")) { |
144 hash = dav_xml_getstring(node->children); |
157 hash = dav_xml_getstring(node->children); |
145 } else if(!strcmp(node->name, "xattr")) { |
158 } else if(!strcmp(node->name, "xattr")) { |
146 char *xattr_name = dav_xml_get_attr(node, "name"); |
159 char *xattr_name = dav_xml_get_attr(node, "name"); |
147 if(xattr_name) { |
160 if(xattr_name) { |
148 names = ucx_list_append(names, strdup(xattr_name)); |
161 char *xname = strdup(xattr_name); |
|
162 cx_array_copy( |
|
163 (void**)&attributes->names, |
|
164 &x_names_size, |
|
165 &x_names_alloc, |
|
166 count, |
|
167 &xname, |
|
168 sizeof(void*), |
|
169 1, |
|
170 &re); |
149 |
171 |
150 char *text = dav_xml_getstring(node->children); |
172 char *text = dav_xml_getstring(node->children); |
151 if(!text) { |
173 if(!text) { |
152 text = ""; |
174 text = ""; |
153 } |
175 } |
154 |
176 |
155 int len = 0; |
177 int len = 0; |
156 char *val = util_base64decode_len(text, &len); |
178 char *val = util_base64decode_len(text, &len); |
157 |
179 |
158 sstr_t *value = malloc(sizeof(sstr_t)); |
180 cxmutstr value; |
159 value->ptr = val; |
181 value.ptr = val; |
160 value->length = len; |
182 value.length = len; |
161 |
183 |
162 values = ucx_list_append(values, value); |
184 cx_array_copy( |
|
185 (void**)&attributes->values, |
|
186 &x_values_size, |
|
187 &x_values_alloc, |
|
188 count, |
|
189 &value, |
|
190 sizeof(cxmutstr), |
|
191 1, |
|
192 &re); |
163 |
193 |
164 count++; |
194 count++; |
165 } |
195 } |
166 } |
196 } |
167 } |
197 } |
168 } |
198 } |
169 |
199 |
170 XAttributes *attributes = NULL; |
200 if(count == 0) { |
171 if(count > 0) { |
201 free(attributes->names); |
172 attributes = calloc(1, sizeof(XAttributes)); |
202 free(attributes->values); |
173 attributes->hash = hash ? strdup(hash) : NULL; |
203 free(attributes); |
174 attributes->nattr = count; |
204 return NULL; |
175 attributes->names = calloc(count, sizeof(char*)); |
205 } |
176 attributes->values = calloc(count, sizeof(sstr_t)); |
206 |
177 int i=0; |
207 attributes->hash = hash ? strdup(hash) : NULL; |
178 UCX_FOREACH(elm, names) { |
208 attributes->nattr = count; |
179 attributes->names[i] = elm->data; |
209 |
180 i++; |
|
181 } |
|
182 i=0; |
|
183 UCX_FOREACH(elm, values) { |
|
184 attributes->values[i] = *(sstr_t*)elm->data; |
|
185 i++; |
|
186 } |
|
187 } |
|
188 return attributes; |
210 return attributes; |
189 } |
211 } |
190 |
212 |
191 XAttributes* file_get_attributes( |
213 XAttributes* file_get_attributes( |
192 const char *path, |
214 const char *path, |
200 } |
222 } |
201 |
223 |
202 XAttributes *xattr = malloc(sizeof(XAttributes)); |
224 XAttributes *xattr = malloc(sizeof(XAttributes)); |
203 xattr->nattr = 0; |
225 xattr->nattr = 0; |
204 xattr->names = calloc(nelm, sizeof(char*)); |
226 xattr->names = calloc(nelm, sizeof(char*)); |
205 xattr->values = calloc(nelm, sizeof(sstr_t)); |
227 xattr->values = calloc(nelm, sizeof(cxmutstr)); |
206 |
228 |
207 DAV_SHA_CTX *sha256 = dav_hash_init(); |
229 DAV_SHA_CTX *sha256 = dav_hash_init(); |
208 |
230 |
209 size_t nattr = 0; |
231 size_t nattr = 0; |
210 for(int i=0;i<nelm;i++) { |
232 for(int i=0;i<nelm;i++) { |
221 if(valuelen >= 0) { |
243 if(valuelen >= 0) { |
222 dav_hash_update(sha256, attributes[i], strlen(attributes[i])); |
244 dav_hash_update(sha256, attributes[i], strlen(attributes[i])); |
223 dav_hash_update(sha256, value, valuelen); |
245 dav_hash_update(sha256, value, valuelen); |
224 // add name and value |
246 // add name and value |
225 xattr->names[nattr] = attributes[i]; |
247 xattr->names[nattr] = attributes[i]; |
226 sstr_t v; |
248 cxmutstr v; |
227 v.ptr = value; |
249 v.ptr = value; |
228 v.length = valuelen; |
250 v.length = valuelen; |
229 xattr->values[nattr] = v; |
251 xattr->values[nattr] = v; |
230 nattr++; |
252 nattr++; |
231 } else { |
253 } else { |
262 DavXmlNode *attr = dav_xml_createnode(DAV_PROPS_NS, "xattr"); |
284 DavXmlNode *attr = dav_xml_createnode(DAV_PROPS_NS, "xattr"); |
263 dav_xml_add_attr(attr, "name", xattr->names[i]); |
285 dav_xml_add_attr(attr, "name", xattr->names[i]); |
264 last->next = attr; |
286 last->next = attr; |
265 last = attr; |
287 last = attr; |
266 |
288 |
267 sstr_t value = xattr->values[i]; |
289 cxmutstr value = xattr->values[i]; |
268 if(value.length > 0) { |
290 if(value.length > 0) { |
269 char *encval = util_base64encode(value.ptr, value.length); |
291 char *encval = util_base64encode(value.ptr, value.length); |
270 attr->children = dav_xml_createtextnode(encval); |
292 attr->children = dav_xml_createtextnode(encval); |
271 free(encval); |
293 free(encval); |
272 } |
294 } |