libidav/resource.c

changeset 747
efbd59642577
parent 736
40be8db6fe45
child 789
378b5ab86f77
equal deleted inserted replaced
746:a569148841ff 747:efbd59642577
34 34
35 #include "utils.h" 35 #include "utils.h"
36 #include "session.h" 36 #include "session.h"
37 #include "methods.h" 37 #include "methods.h"
38 #include "crypto.h" 38 #include "crypto.h"
39 #include "ucx/buffer.h" 39 #include <cx/buffer.h>
40 #include "ucx/utils.h" 40 #include <cx/utils.h>
41 #include <cx/hash_map.h>
42 #include <cx/printf.h>
43 #include <cx/basic_mempool.h>
44 #include <cx/array_list.h>
41 45
42 #include "resource.h" 46 #include "resource.h"
43 #include "xml.h" 47 #include "xml.h"
44 #include "davqlexec.h" 48 #include "davqlexec.h"
45 49
46 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) 50 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b)
47 51
48 DavResource* dav_resource_new(DavSession *sn, char *path) { 52 DavResource* dav_resource_new(DavSession *sn, const char *path) {
49 //char *href = util_url_path(url); 53 //char *href = util_url_path(url);
50 //DavResource *res = dav_resource_new_href(sn, href); 54 //DavResource *res = dav_resource_new_href(sn, href);
51 char *parent = util_parent_path(path); 55 char *parent = util_parent_path(path);
52 char *name = util_resource_name(path); 56 const char *name = util_resource_name(path);
53 char *href = dav_session_create_plain_href(sn, path); 57 char *href = dav_session_create_plain_href(sn, path);
54 58
55 DavResource *res = dav_resource_new_full(sn, parent, name, href); 59 DavResource *res = dav_resource_new_full(sn, parent, name, href);
56 free(parent); 60 free(parent);
57 return res; 61 return res;
58 } 62 }
59 63
60 DavResource* dav_resource_new_child(DavSession *sn, DavResource *parent, char *name) { 64 DavResource* dav_resource_new_child(DavSession *sn, DavResource *parent, const char *name) {
61 char *path = util_concat_path(parent->path, name); 65 char *path = util_concat_path(parent->path, name);
62 char *href = dav_session_create_plain_href(sn, path); 66 char *href = dav_session_create_plain_href(sn, path);
63 DavResource *res = dav_resource_new_full(sn, parent->path, name, href); 67 DavResource *res = dav_resource_new_full(sn, parent->path, name, href);
64 free(path); 68 free(path);
65 return res; 69 return res;
66 } 70 }
67 71
68 72
69 DavResource* dav_resource_new_href(DavSession *sn, char *href) { 73 DavResource* dav_resource_new_href(DavSession *sn, const char *href) {
70 DavResource *res = ucx_mempool_calloc(sn->mp, 1, sizeof(DavResource)); 74 DavResource *res = cxCalloc(sn->mp->allocator, 1, sizeof(DavResource));
71 res->session = sn; 75 res->session = sn;
72 76
73 // set name, path and href 77 // set name, path and href
74 resource_set_info(res, href); 78 resource_set_info(res, href);
75 79
77 res->data = resource_data_new(sn); 81 res->data = resource_data_new(sn);
78 82
79 return res; 83 return res;
80 } 84 }
81 85
82 DavResource* dav_resource_new_full(DavSession *sn, char *parent_path, char *name, char *href) { 86 DavResource* dav_resource_new_full(DavSession *sn, const char *parent_path, const char *name, char *href) {
83 sstr_t n = sstr(name); 87 cxstring n = cx_str(name);
84 // the name must not contain path separators 88 // the name must not contain path separators
85 if(n.length > 0 && href) { 89 if(n.length > 0 && href) {
86 for(int i=0;i<n.length-1;i++) { 90 for(int i=0;i<n.length-1;i++) {
87 char c = n.ptr[i]; 91 char c = n.ptr[i];
88 if(c == '/' || c == '\\') { 92 if(c == '/' || c == '\\') {
89 n = sstr(util_resource_name(href)); 93 n = cx_str(util_resource_name(href));
90 break; 94 break;
91 } 95 }
92 } 96 }
93 } 97 }
94 // remove trailing '/' 98 // remove trailing '/'
95 if(n.length > 0 && n.ptr[n.length-1] == '/') { 99 if(n.length > 0 && n.ptr[n.length-1] == '/') {
96 n.length--; 100 n.length--;
97 } 101 }
98 102
99 DavResource *res = ucx_mempool_calloc(sn->mp, 1, sizeof(DavResource)); 103 DavResource *res = cxCalloc(sn->mp->allocator, 1, sizeof(DavResource));
100 res->session = sn; 104 res->session = sn;
101 105
102 // set name, path and href 106 // set name, path and href
103 res->name = sstrdup_a(sn->mp->allocator, n).ptr; 107 res->name = cx_strdup_a(sn->mp->allocator, n).ptr;
104 108
105 char *path = util_concat_path(parent_path, name); 109 char *path = util_concat_path(parent_path, name);
106 res->path = dav_session_strdup(sn, path); 110 res->path = dav_session_strdup(sn, path);
107 111
108 res->href = href; 112 res->href = href;
110 // initialize resource data 114 // initialize resource data
111 res->data = resource_data_new(sn); 115 res->data = resource_data_new(sn);
112 116
113 // cache href/path 117 // cache href/path
114 if(href) { 118 if(href) {
115 dav_session_cache_path(sn, sstr(path), sstr(href)); 119 dav_session_cache_path(sn, cx_str(path), cx_str(href));
116 } 120 }
117 free(path); 121 free(path);
118 122
119 return res; 123 return res;
120 } 124 }
121 125
122 void resource_free_properties(DavSession *sn, UcxMap *properties) { 126 void resource_free_properties(DavSession *sn, CxMap *properties) {
123 if(!properties) return; 127 if(!properties) return;
124 128
125 UcxMapIterator i = ucx_map_iterator(properties); 129 CxIterator i = cxMapIteratorValues(properties);
126 DavProperty *property; 130 DavProperty *property;
127 UCX_MAP_FOREACH(key, property, i) { 131 cx_foreach(DavProperty*, property, i) {
128 // TODO: free everything 132 // TODO: free everything
129 dav_session_free(sn, property); 133 dav_session_free(sn, property);
130 } 134 }
131 ucx_map_free(properties); 135 cxMapDestroy(properties);
132 } 136 }
133 137
134 void dav_resource_free(DavResource *res) { 138 void dav_resource_free(DavResource *res) {
135 DavSession *sn = res->session; 139 DavSession *sn = res->session;
136 140
142 146
143 DavResourceData *data = res->data; 147 DavResourceData *data = res->data;
144 resource_free_properties(sn, data->properties); 148 resource_free_properties(sn, data->properties);
145 resource_free_properties(sn, data->crypto_properties); 149 resource_free_properties(sn, data->crypto_properties);
146 150
147 UCX_FOREACH(elm, data->set) { 151 if(data->set) {
148 DavProperty *p = elm->data; 152 CxIterator i = cxListIterator(data->set);
149 dav_session_free(sn, p->ns->name); 153 cx_foreach(DavProperty *, p, i) {
150 if(p->ns->prefix) { 154 dav_session_free(sn, p->ns->name);
151 dav_session_free(sn, p->ns->prefix); 155 if(p->ns->prefix) {
152 } 156 dav_session_free(sn, p->ns->prefix);
153 dav_session_free(sn, p->ns); 157 }
154 158 dav_session_free(sn, p->ns);
155 dav_session_free(sn, p->name); 159
156 dav_free_xml_node_sn(sn, p->value); 160 dav_session_free(sn, p->name);
157 dav_session_free(sn, p); 161 dav_free_xml_node_sn(sn, p->value);
158 } 162 dav_session_free(sn, p);
159 163 }
160 UCX_FOREACH(elm, data->remove) { 164 }
161 DavProperty *p = elm->data; 165
162 dav_session_free(sn, p->ns->name); 166 if(data->remove) {
163 if(p->ns->prefix) { 167 CxIterator i = cxListIterator(data->remove);
164 dav_session_free(sn, p->ns->prefix); 168 cx_foreach(DavProperty *, p, i) {
165 } 169 dav_session_free(sn, p->ns->name);
166 dav_session_free(sn, p->ns); 170 if(p->ns->prefix) {
167 171 dav_session_free(sn, p->ns->prefix);
168 dav_session_free(sn, p->name); 172 }
169 dav_session_free(sn, p); 173 dav_session_free(sn, p->ns);
174
175 dav_session_free(sn, p->name);
176 dav_session_free(sn, p);
177 }
178 }
179
180 if(data->crypto_set) {
181 CxIterator i = cxListIterator(data->crypto_set);
182 cx_foreach(DavProperty *, p, i) {
183 dav_session_free(sn, p->ns->name);
184 if(p->ns->prefix) {
185 dav_session_free(sn, p->ns->prefix);
186 }
187 dav_session_free(sn, p->ns);
188
189 dav_session_free(sn, p->name);
190 dav_free_xml_node_sn(sn, p->value);
191 dav_session_free(sn, p);
192 }
193 }
194
195 if(data->crypto_remove) {
196 CxIterator i = cxListIterator(data->crypto_remove);
197 cx_foreach(DavProperty *, p, i) {
198 dav_session_free(sn, p->ns->name);
199 if(p->ns->prefix) {
200 dav_session_free(sn, p->ns->prefix);
201 }
202 dav_session_free(sn, p->ns);
203
204 dav_session_free(sn, p->name);
205 dav_session_free(sn, p);
206 }
170 } 207 }
171 208
172 if(!data->read && data->content) { 209 if(!data->read && data->content) {
173 dav_session_free(sn, data->content); 210 dav_session_free(sn, data->content);
174 } 211 }
185 dav_resource_free_all(child); 222 dav_resource_free_all(child);
186 child = next; 223 child = next;
187 } 224 }
188 } 225 }
189 226
190 void resource_set_href(DavResource *res, sstr_t href) { 227 void resource_set_href(DavResource *res, cxstring href) {
191 res->href = sstrdup_a(res->session->mp->allocator, href).ptr; 228 res->href = cx_strdup_a(res->session->mp->allocator, href).ptr;
192 } 229 }
193 230
194 void resource_set_info(DavResource *res, char *href_str) { 231 void resource_set_info(DavResource *res, const char *href_str) {
195 char *url_str = NULL; 232 char *url_str = NULL;
196 curl_easy_getinfo(res->session->handle, CURLINFO_EFFECTIVE_URL, &url_str); 233 curl_easy_getinfo(res->session->handle, CURLINFO_EFFECTIVE_URL, &url_str);
197 sstr_t name = sstr(util_resource_name(href_str)); 234 cxstring name = cx_str(util_resource_name(href_str));
198 sstr_t href = sstr(href_str); 235 cxstring href = cx_str(href_str);
199 236
200 sstr_t base_href = sstr(util_url_path(res->session->base_url)); 237 cxstring base_href = cx_str(util_url_path(res->session->base_url));
201 sstr_t path = sstrsubs(href, base_href.length - 1); 238 cxstring path = cx_strsubs(href, base_href.length - 1);
202 239
203 UcxAllocator *a = res->session->mp->allocator; 240 const CxAllocator *a = res->session->mp->allocator;
204 CURL *handle = res->session->handle; 241 CURL *handle = res->session->handle;
205 242
206 int nlen = 0; 243 int nlen = 0;
207 char *uname = curl_easy_unescape(handle, name.ptr, name.length , &nlen); 244 char *uname = curl_easy_unescape(handle, name.ptr, name.length , &nlen);
208 int plen = 0; 245 int plen = 0;
209 char *upath = curl_easy_unescape(handle, path.ptr, path.length, &plen); 246 char *upath = curl_easy_unescape(handle, path.ptr, path.length, &plen);
210 247
211 res->name = sstrdup_a(a, sstrn(uname, nlen)).ptr; 248 res->name = cx_strdup_a(a, cx_strn(uname, nlen)).ptr;
212 res->href = sstrdup_a(a, href).ptr; 249 res->href = cx_strdup_a(a, href).ptr;
213 res->path = sstrdup_a(a, sstrn(upath, plen)).ptr; 250 res->path = cx_strdup_a(a, cx_strn(upath, plen)).ptr;
214 251
215 curl_free(uname); 252 curl_free(uname);
216 curl_free(upath); 253 curl_free(upath);
217 } 254 }
218 255
219 DavResourceData* resource_data_new(DavSession *sn) { 256 DavResourceData* resource_data_new(DavSession *sn) {
220 DavResourceData *data = ucx_mempool_malloc( 257 DavResourceData *data = cxMalloc(
221 sn->mp, 258 sn->mp->allocator,
222 sizeof(DavResourceData)); 259 sizeof(DavResourceData));
223 if(!data) { 260 if(!data) {
224 return NULL; 261 return NULL;
225 } 262 }
226 data->properties = ucx_map_new_a(sn->mp->allocator, 32); 263 data->properties = cxHashMapCreate(sn->mp->allocator, CX_STORE_POINTERS, 32);
227 data->crypto_properties = NULL; 264 data->crypto_properties = NULL;
228 data->set = NULL; 265 data->set = NULL;
229 data->remove = NULL; 266 data->remove = NULL;
230 data->crypto_set = NULL; 267 data->crypto_set = NULL;
231 data->crypto_remove = NULL; 268 data->crypto_remove = NULL;
255 DavProperty *prop = dav_session_malloc(sn, sizeof(DavProperty)); 292 DavProperty *prop = dav_session_malloc(sn, sizeof(DavProperty));
256 prop->name = dav_session_strdup(sn, name); 293 prop->name = dav_session_strdup(sn, name);
257 prop->ns = namespace; 294 prop->ns = namespace;
258 prop->value = val; 295 prop->value = val;
259 296
260 sstr_t key = dav_property_key(ns, name); 297 cxmutstr keystr = dav_property_key(ns, name);
261 ucx_map_sstr_put(((DavResourceData*)res->data)->properties, key, prop); 298 CxHashKey key = cx_hash_key(keystr.ptr, keystr.length);
262 free(key.ptr); 299 cxMapPut(((DavResourceData*)res->data)->properties, key, prop);
300 free(keystr.ptr);
263 } 301 }
264 302
265 void resource_add_property(DavResource *res, const char *ns, const char *name, xmlNode *val) { 303 void resource_add_property(DavResource *res, const char *ns, const char *name, xmlNode *val) {
266 if(!val) { 304 if(!val) {
267 return; 305 return;
276 } 314 }
277 315
278 resource_add_prop(res, ns, name, dav_text_node(res->session, val)); 316 resource_add_prop(res, ns, name, dav_text_node(res->session, val));
279 } 317 }
280 318
281 void resource_set_crypto_properties(DavResource *res, UcxMap *cprops) { 319 void resource_set_crypto_properties(DavResource *res, CxMap *cprops) {
282 DavResourceData *data = res->data; 320 DavResourceData *data = res->data;
283 resource_free_properties(res->session, data->crypto_properties); 321 resource_free_properties(res->session, data->crypto_properties);
284 data->crypto_properties = cprops; 322 data->crypto_properties = cprops;
285 } 323 }
286 324
287 DavXmlNode* resource_get_property(DavResource *res, const char *ns, const char *name) { 325 DavXmlNode* resource_get_property(DavResource *res, const char *ns, const char *name) {
288 sstr_t keystr = dav_property_key(ns, name); 326 cxmutstr keystr = dav_property_key(ns, name);
289 UcxKey key = ucx_key(keystr.ptr, keystr.length); 327 CxHashKey key = cx_hash_key(keystr.ptr, keystr.length);
290 DavXmlNode *ret = resource_get_property_k(res, key); 328 DavXmlNode *ret = resource_get_property_k(res, key);
291 free(keystr.ptr); 329 free(keystr.ptr);
292 330
293 return ret; 331 return ret;
294 } 332 }
295 333
296 DavXmlNode* resource_get_encrypted_property(DavResource *res, const char *ns, const char *name) { 334 DavXmlNode* resource_get_encrypted_property(DavResource *res, const char *ns, const char *name) {
297 sstr_t keystr = dav_property_key(ns, name); 335 cxmutstr keystr = dav_property_key(ns, name);
298 UcxKey key = ucx_key(keystr.ptr, keystr.length); 336 CxHashKey key = cx_hash_key(keystr.ptr, keystr.length);
299 DavXmlNode *ret = resource_get_encrypted_property_k(res, key); 337 DavXmlNode *ret = resource_get_encrypted_property_k(res, key);
300 free(keystr.ptr); 338 free(keystr.ptr);
301 339
302 return ret; 340 return ret;
303 } 341 }
304 342
305 DavXmlNode* resource_get_property_k(DavResource *res, UcxKey key) { 343 DavXmlNode* resource_get_property_k(DavResource *res, CxHashKey key) {
306 DavResourceData *data = (DavResourceData*)res->data; 344 DavResourceData *data = (DavResourceData*)res->data;
307 DavProperty *property = ucx_map_get(data->properties, key); 345 DavProperty *property = cxMapGet(data->properties, key);
308 346
309 return property ? property->value : NULL; 347 return property ? property->value : NULL;
310 } 348 }
311 349
312 DavXmlNode* resource_get_encrypted_property_k(DavResource *res, UcxKey key) { 350 DavXmlNode* resource_get_encrypted_property_k(DavResource *res, CxHashKey key) {
313 DavResourceData *data = (DavResourceData*)res->data; 351 DavResourceData *data = (DavResourceData*)res->data;
314 DavProperty *property = ucx_map_get(data->crypto_properties, key); 352 DavProperty *property = cxMapGet(data->crypto_properties, key);
315 353
316 return property ? property->value : NULL; 354 return property ? property->value : NULL;
317 } 355 }
318 356
319 sstr_t dav_property_key(const char *ns, const char *name) { 357 cxmutstr dav_property_key(const char *ns, const char *name) {
320 return dav_property_key_a(ucx_default_allocator(), ns, name); 358 return dav_property_key_a(cxDefaultAllocator, ns, name);
321 } 359 }
322 360
323 sstr_t dav_property_key_a(UcxAllocator *a, const char *ns, const char *name) { 361 cxmutstr dav_property_key_a(const CxAllocator *a, const char *ns, const char *name) {
324 scstr_t ns_str = scstr(ns); 362 cxstring ns_str = cx_str(ns);
325 scstr_t name_str = scstr(name); 363 cxstring name_str = cx_str(name);
326 364
327 return sstrcat_a(a, 4, ns_str, S("\0"), name_str, S("\0")); 365 return cx_strcat_a(a, 4, ns_str, CX_STR("\0"), name_str, CX_STR("\0"));
328 } 366 }
329 367
330 368
331 369
332 370
409 } 447 }
410 448
411 return cr->descending ? -ret : ret; 449 return cr->descending ? -ret : ret;
412 } 450 }
413 451
414 void resource_add_ordered_child(DavResource *parent, DavResource *child, UcxList *ordercr) { 452 void resource_add_ordered_child(DavResource *parent, DavResource *child, CxList *ordercr) {
415 if(!ordercr) { 453 if(!ordercr) {
416 resource_add_child(parent, child); 454 resource_add_child(parent, child);
417 return; 455 return;
418 } 456 }
419 457
425 parent->children = child; 463 parent->children = child;
426 } else { 464 } else {
427 DavResource *resource = parent->children; 465 DavResource *resource = parent->children;
428 while(resource) { 466 while(resource) {
429 int r = 0; 467 int r = 0;
430 UCX_FOREACH(elm, ordercr) { 468 CxIterator i = cxListIterator(ordercr);
431 DavOrderCriterion *cr = elm->data; 469 cx_foreach(DavOrderCriterion*, cr, i) {
432 r = resource_cmp(child, resource, cr); 470 r = resource_cmp(child, resource, cr);
433 if(r != 0) { 471 if(r != 0) {
434 break; 472 break;
435 } 473 }
436 } 474 }
493 } 531 }
494 532
495 DavResourceData *data = res->data; 533 DavResourceData *data = res->data;
496 534
497 DavXmlNode *property = NULL; 535 DavXmlNode *property = NULL;
498 UcxList *remove_list = NULL; 536 CxList *remove_list = NULL;
499 UcxList *set_list = NULL; 537 CxList *set_list = NULL;
500 538
501 if(encrypted) { 539 if(encrypted) {
502 // check if crypto_properties because it will only be created 540 // check if crypto_properties because it will only be created
503 // if the resource has encrypted properties 541 // if the resource has encrypted properties
504 if(!data->crypto_properties) { 542 if(!data->crypto_properties) {
513 set_list = data->set; 551 set_list = data->set;
514 } 552 }
515 553
516 // resource_get_property only returns persistent properties 554 // resource_get_property only returns persistent properties
517 // check the remove and set list 555 // check the remove and set list
518 if(property) { 556 if(property && remove_list) {
519 // if the property is in the remove list, we return NULL 557 // if the property is in the remove list, we return NULL
520 UCX_FOREACH(elm, remove_list) { 558 CxIterator i = cxListIterator(remove_list);
521 DavProperty *p = elm->data; 559 cx_foreach(DavProperty*, p, i) {
522 if(!strcmp(p->name, name) && !strcmp(p->ns->name, ns)) { 560 if(!strcmp(p->name, name) && !strcmp(p->ns->name, ns)) {
523 return NULL; 561 return NULL;
524 } 562 }
525 } 563 }
526 } 564 }
565
527 // the set list contains property updates 566 // the set list contains property updates
528 // we return an updated property if possible 567 // we return an updated property if possible
529 UCX_FOREACH(elm, set_list) { 568 if(set_list) {
530 DavProperty *p = elm->data; 569 CxIterator i = cxListIterator(set_list);
531 if(!strcmp(p->name, name) && !strcmp(p->ns->name, ns)) { 570 cx_foreach(DavProperty*, p, i) {
532 return p->value; // TODO: fix 571 if(!strcmp(p->name, name) && !strcmp(p->ns->name, ns)) {
533 } 572 return p->value; // TODO: fix
534 } 573 }
574 }
575 }
576
535 // no property update 577 // no property update
536 578
537 return property; 579 return property;
538 } 580 }
539 581
570 char *pname; 612 char *pname;
571 dav_get_property_namespace_str(res->session->context, name, &pns, &pname); 613 dav_get_property_namespace_str(res->session->context, name, &pns, &pname);
572 dav_set_string_property_ns(res, pns, pname, value); 614 dav_set_string_property_ns(res, pns, pname, value);
573 } 615 }
574 616
617 static int add2propertylist(const CxAllocator *a, CxList **list, DavProperty *property) {
618 if(!*list) {
619 CxList *newlist = cxLinkedListCreate(a, NULL, CX_STORE_POINTERS);
620 if(!newlist) {
621 return 1;
622 }
623 *list = newlist;
624 }
625 cxListAdd(*list, property);
626 return 0;
627 }
628
575 void dav_set_string_property_ns(DavResource *res, char *ns, char *name, char *value) { 629 void dav_set_string_property_ns(DavResource *res, char *ns, char *name, char *value) {
576 DavSession *sn = res->session; 630 DavSession *sn = res->session;
577 UcxAllocator *a = res->session->mp->allocator; 631 const CxAllocator *a = res->session->mp->allocator;
578 DavResourceData *data = res->data; 632 DavResourceData *data = res->data;
579 633
580 DavProperty *property = createprop(res->session, ns, name); 634 DavProperty *property = createprop(res->session, ns, name);
581 property->value = dav_text_node(res->session, value); 635 property->value = dav_text_node(res->session, value);
582 636
583 if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) { 637 if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) {
584 data->crypto_set = ucx_list_append_a(a, data->crypto_set, property); 638 add2propertylist(a, &data->crypto_set, property);
585 } else { 639 } else {
586 data->set = ucx_list_append_a(a, data->set, property); 640 add2propertylist(a, &data->set, property);
587 } 641 }
588 } 642 }
589 643
590 void dav_set_property(DavResource *res, char *name, DavXmlNode *value) { 644 void dav_set_property(DavResource *res, char *name, DavXmlNode *value) {
591 char *pns; 645 char *pns;
594 dav_set_property_ns(res, pns, pname, value); 648 dav_set_property_ns(res, pns, pname, value);
595 } 649 }
596 650
597 void dav_set_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value) { 651 void dav_set_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value) {
598 DavSession *sn = res->session; 652 DavSession *sn = res->session;
599 UcxAllocator *a = sn->mp->allocator; 653 const CxAllocator *a = sn->mp->allocator;
600 DavResourceData *data = res->data; 654 DavResourceData *data = res->data;
601 655
602 DavProperty *property = createprop(sn, ns, name); 656 DavProperty *property = createprop(sn, ns, name);
603 // TODO: this function should copy the value 657 // TODO: this function should copy the value
604 // but we also need a function, that doesn't create a copy 658 // but we also need a function, that doesn't create a copy
605 property->value = value; 659 property->value = value;
606 660
607 if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) { 661 if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) {
608 data->crypto_set = ucx_list_append_a(a, data->crypto_set, property); 662 add2propertylist(a, &data->crypto_set, property);
609 } else { 663 } else {
610 data->set = ucx_list_append_a(a, data->set, property); 664 add2propertylist(a, &data->set, property);
611 } 665 }
612 } 666 }
613 667
614 void dav_remove_property(DavResource *res, char *name) { 668 void dav_remove_property(DavResource *res, char *name) {
615 char *pns; 669 char *pns;
619 } 673 }
620 674
621 void dav_remove_property_ns(DavResource *res, char *ns, char *name) { 675 void dav_remove_property_ns(DavResource *res, char *ns, char *name) {
622 DavSession *sn = res->session; 676 DavSession *sn = res->session;
623 DavResourceData *data = res->data; 677 DavResourceData *data = res->data;
624 UcxAllocator *a = res->session->mp->allocator; 678 const CxAllocator *a = res->session->mp->allocator;
625 679
626 DavProperty *property = createprop(res->session, ns, name); 680 DavProperty *property = createprop(res->session, ns, name);
627 681
628 if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) { 682 if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) {
629 data->crypto_remove = ucx_list_append_a(a, data->crypto_remove, property); 683 add2propertylist(a, &data->crypto_remove, property);
630 } else { 684 } else {
631 data->remove = ucx_list_append_a(a, data->remove, property); 685 add2propertylist(a, &data->remove, property);
632 } 686 }
633 } 687 }
634 688
635 void dav_set_encrypted_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value) { 689 void dav_set_encrypted_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value) {
636 UcxAllocator *a = res->session->mp->allocator; 690 const CxAllocator *a = res->session->mp->allocator;
637 DavResourceData *data = res->data; 691 DavResourceData *data = res->data;
638 692
639 DavProperty *property = createprop(res->session, ns, name); 693 DavProperty *property = createprop(res->session, ns, name);
640 property->value = value; // TODO: copy node? 694 property->value = value; // TODO: copy node?
641 695
642 data->crypto_set = ucx_list_append_a(a, data->crypto_set, property); 696 add2propertylist(a, &data->crypto_set, property);
643 } 697 }
644 698
645 void dav_set_encrypted_string_property_ns(DavResource *res, char *ns, char *name, char *value) { 699 void dav_set_encrypted_string_property_ns(DavResource *res, char *ns, char *name, char *value) {
646 UcxAllocator *a = res->session->mp->allocator; 700 const CxAllocator *a = res->session->mp->allocator;
647 DavResourceData *data = res->data; 701 DavResourceData *data = res->data;
648 702
649 DavProperty *property = createprop(res->session, ns, name); 703 DavProperty *property = createprop(res->session, ns, name);
650 property->value = dav_text_node(res->session, value); 704 property->value = dav_text_node(res->session, value);
651 705
652 data->crypto_set = ucx_list_append_a(a, data->crypto_set, property); 706 add2propertylist(a, &data->crypto_set, property);
653 } 707 }
654 708
655 void dav_remove_encrypted_property_ns(DavResource *res, char *ns, char *name) { 709 void dav_remove_encrypted_property_ns(DavResource *res, char *ns, char *name) {
656 DavResourceData *data = res->data; 710 DavResourceData *data = res->data;
657 UcxAllocator *a = res->session->mp->allocator; 711 const CxAllocator *a = res->session->mp->allocator;
658 712
659 DavProperty *property = createprop(res->session, ns, name); 713 DavProperty *property = createprop(res->session, ns, name);
660 714
661 data->crypto_remove = ucx_list_append_a(a, data->crypto_remove, property); 715 add2propertylist(a, &data->crypto_remove, property);
662 } 716 }
663 717
664 static int compare_propname(const void *a, const void *b) { 718 static int compare_propname(const void *a, const void *b) {
665 const DavPropName *p1 = a; 719 const DavPropName *p1 = a;
666 const DavPropName *p2 = b; 720 const DavPropName *p2 = b;
674 } 728 }
675 729
676 DavPropName* dav_get_property_names(DavResource *res, size_t *count) { 730 DavPropName* dav_get_property_names(DavResource *res, size_t *count) {
677 DavResourceData *data = res->data; 731 DavResourceData *data = res->data;
678 732
679 *count = data->properties->count; 733 *count = data->properties->size;
680 DavPropName *names = dav_session_calloc( 734 DavPropName *names = dav_session_calloc(
681 res->session, 735 res->session,
682 *count, 736 *count,
683 sizeof(DavPropName)); 737 sizeof(DavPropName));
684 738
685 739
686 UcxMapIterator i = ucx_map_iterator(data->properties); 740 CxIterator i = cxMapIteratorValues(data->properties);
687 DavProperty *value; 741 DavProperty *value;
688 int j = 0; 742 int j = 0;
689 UCX_MAP_FOREACH(key, value, i) { 743 cx_foreach(DavProperty*, value, i) {
690 DavPropName *name = &names[j]; 744 DavPropName *name = &names[j];
691 745
692 name->ns = value->ns->name; 746 name->ns = value->ns->name;
693 name->name = value->name; 747 name->name = value->name;
694 748
724 data->length = length; 778 data->length = length;
725 } 779 }
726 780
727 781
728 int dav_load(DavResource *res) { 782 int dav_load(DavResource *res) {
729 UcxBuffer *rqbuf = create_allprop_propfind_request(); 783 CxBuffer *rqbuf = create_allprop_propfind_request();
730 int ret = dav_propfind(res->session, res, rqbuf); 784 int ret = dav_propfind(res->session, res, rqbuf);
731 ucx_buffer_free(rqbuf); 785 cxBufferFree(rqbuf);
732 return ret; 786 return ret;
733 } 787 }
734 788
735 int dav_load_prop(DavResource *res, DavPropName *properties, size_t numprop) { 789 int dav_load_prop(DavResource *res, DavPropName *properties, size_t numprop) {
736 UcxMempool *mp = ucx_mempool_new(64); 790 CxMempool *mp = cxBasicMempoolCreate(64);
737 791 const CxAllocator *a = mp->allocator;
738 UcxList *proplist = NULL; 792
793 CxList *proplist = cxArrayListCreate(a, NULL, sizeof(DavProperty), numprop);
739 for(size_t i=0;i<numprop;i++) { 794 for(size_t i=0;i<numprop;i++) {
740 DavProperty *p = ucx_mempool_malloc(mp, sizeof(DavProperty)); 795 DavProperty p;
741 p->name = properties[i].name; 796 p.name = properties[i].name;
742 p->ns = ucx_mempool_malloc(mp, sizeof(DavNamespace)); 797 p.ns = cxMalloc(a, sizeof(DavNamespace));
743 p->ns->name = properties[i].ns; 798 p.ns->name = properties[i].ns;
744 if(!strcmp(properties[i].ns, "DAV:")) { 799 if(!strcmp(properties[i].ns, "DAV:")) {
745 p->ns->prefix = "D"; 800 p.ns->prefix = "D";
746 } else { 801 } else {
747 p->ns->prefix = ucx_asprintf(mp->allocator, "x%d", i).ptr; 802 p.ns->prefix = cx_asprintf_a(a, "x%d", (int)i).ptr;
748 } 803 }
749 p->value = NULL; 804 p.value = NULL;
750 proplist = ucx_list_append_a(mp->allocator, proplist, p); 805 cxListAdd(proplist, &p);
751 } 806 }
752 807
753 UcxBuffer *rqbuf = create_propfind_request(res->session, proplist, "propfind", 0); 808 CxBuffer *rqbuf = create_propfind_request(res->session, proplist, "propfind", 0);
754 int ret = dav_propfind(res->session, res, rqbuf); 809 int ret = dav_propfind(res->session, res, rqbuf);
755 ucx_buffer_free(rqbuf); 810 cxBufferFree(rqbuf);
756 ucx_mempool_destroy(mp); 811 cxMempoolDestroy(mp);
757 return ret; 812 return ret;
758 } 813 }
759 814
760 815
761 static void init_hash_stream(HashStream *hstr, void *stream, dav_read_func readfn, dav_seek_func seekfn) { 816 static void init_hash_stream(HashStream *hstr, void *stream, dav_read_func readfn, dav_seek_func seekfn) {
803 if(data->content) { 858 if(data->content) {
804 int encryption = DAV_ENCRYPT_CONTENT(sn) && sn->key; 859 int encryption = DAV_ENCRYPT_CONTENT(sn) && sn->key;
805 CURLcode ret; 860 CURLcode ret;
806 if(encryption) { 861 if(encryption) {
807 AESEncrypter *enc = NULL; 862 AESEncrypter *enc = NULL;
808 UcxBuffer *buf = NULL; 863 CxBuffer *buf = NULL;
809 if(data->read) { 864 if(data->read) {
810 enc = aes_encrypter_new( 865 enc = aes_encrypter_new(
811 sn->key, 866 sn->key,
812 data->content, 867 data->content,
813 data->read, 868 data->read,
814 data->seek); 869 data->seek);
815 } else { 870 } else {
816 buf = ucx_buffer_new(data->content, data->length, 0); 871 buf = cxBufferCreate(data->content, data->length, cxDefaultAllocator, 0);
817 buf->size = data->length; 872 buf->size = data->length;
818 enc = aes_encrypter_new( 873 enc = aes_encrypter_new(
819 sn->key, 874 sn->key,
820 buf, 875 buf,
821 (dav_read_func)ucx_buffer_read, 876 (dav_read_func)cxBufferRead,
822 (dav_seek_func)dav_buffer_seek); 877 (dav_seek_func)cxBufferSeek);
823 } 878 }
824 879
825 // put resource 880 // put resource
826 ret = do_put_request( 881 ret = do_put_request(
827 sn, 882 sn,
836 dav_get_hash(&enc->sha256, (unsigned char*)data->hash); 891 dav_get_hash(&enc->sha256, (unsigned char*)data->hash);
837 char *enc_hash = aes_encrypt(data->hash, DAV_SHA256_DIGEST_LENGTH, sn->key); 892 char *enc_hash = aes_encrypt(data->hash, DAV_SHA256_DIGEST_LENGTH, sn->key);
838 893
839 aes_encrypter_close(enc); 894 aes_encrypter_close(enc);
840 if(buf) { 895 if(buf) {
841 ucx_buffer_free(buf); 896 cxBufferFree(buf);
842 } 897 }
843 898
844 // add crypto properties 899 // add crypto properties
845 // TODO: store the properties later 900 // TODO: store the properties later
846 if(resource_add_crypto_info(sn, res->href, res->name, enc_hash)) { 901 if(resource_add_crypto_info(sn, res->href, res->name, enc_hash)) {
849 } 904 }
850 resource_add_string_property(res, DAV_NS, "crypto-hash", enc_hash); 905 resource_add_string_property(res, DAV_NS, "crypto-hash", enc_hash);
851 free(enc_hash); 906 free(enc_hash);
852 } else if((sn->flags & DAV_SESSION_STORE_HASH) == DAV_SESSION_STORE_HASH) { 907 } else if((sn->flags & DAV_SESSION_STORE_HASH) == DAV_SESSION_STORE_HASH) {
853 HashStream hstr; 908 HashStream hstr;
854 UcxBuffer *iobuf = NULL; 909 CxBuffer *iobuf = NULL;
855 if(!data->read) { 910 if(!data->read) {
856 iobuf = ucx_buffer_new(data->content, data->length, 0); 911 iobuf = cxBufferCreate(data->content, data->length, cxDefaultAllocator, 0);
857 iobuf->size = data->length; 912 iobuf->size = data->length;
858 init_hash_stream( 913 init_hash_stream(
859 &hstr, 914 &hstr,
860 iobuf, 915 iobuf,
861 (dav_read_func)ucx_buffer_read, 916 (dav_read_func)cxBufferRead,
862 (dav_seek_func)ucx_buffer_seek); 917 (dav_seek_func)cxBufferSeek);
863 } else { 918 } else {
864 init_hash_stream( 919 init_hash_stream(
865 &hstr, 920 &hstr,
866 data->content, 921 data->content,
867 data->read, 922 data->read,
898 curl_easy_getinfo(sn->handle, CURLINFO_RESPONSE_CODE, &status); 953 curl_easy_getinfo(sn->handle, CURLINFO_RESPONSE_CODE, &status);
899 if(ret == CURLE_OK && (status >= 200 && status < 300)) { 954 if(ret == CURLE_OK && (status >= 200 && status < 300)) {
900 res->session->error = 0; 955 res->session->error = 0;
901 // cleanup node data 956 // cleanup node data
902 if(!data->read) { 957 if(!data->read) {
903 ucx_mempool_free(sn->mp, data->content); 958 cxFree(sn->mp->allocator, data->content);
904 } 959 }
905 data->content = NULL; 960 data->content = NULL;
906 data->read = NULL; 961 data->read = NULL;
907 data->length = 0; 962 data->length = 0;
908 } else { 963 } else {
915 if(DAV_ENCRYPT_PROPERTIES(sn) && sn->key && (data->crypto_set || data->crypto_remove)) { 970 if(DAV_ENCRYPT_PROPERTIES(sn) && sn->key && (data->crypto_set || data->crypto_remove)) {
916 DavResource *crypto_res = dav_resource_new_href(sn, res->href); 971 DavResource *crypto_res = dav_resource_new_href(sn, res->href);
917 int ret = 1; 972 int ret = 1;
918 973
919 if(crypto_res) { 974 if(crypto_res) {
920 UcxBuffer *rqbuf = create_cryptoprop_propfind_request(); 975 CxBuffer *rqbuf = create_cryptoprop_propfind_request();
921 ret = dav_propfind(res->session, res, rqbuf); 976 ret = dav_propfind(res->session, res, rqbuf);
922 ucx_buffer_free(rqbuf); 977 cxBufferFree(rqbuf);
923 } 978 }
924 979
925 if(!ret) { 980 if(!ret) {
926 DavXmlNode *crypto_prop_node = dav_get_property_ns(crypto_res, DAV_NS, "crypto-prop"); 981 DavXmlNode *crypto_prop_node = dav_get_property_ns(crypto_res, DAV_NS, "crypto-prop");
927 UcxMap *crypto_props = parse_crypto_prop(sn, sn->key, crypto_prop_node); 982 CxMap *crypto_props = parse_crypto_prop(sn, sn->key, crypto_prop_node);
928 if(!crypto_props) { 983 if(!crypto_props) {
929 // resource hasn't encrypted properties yet 984 // resource hasn't encrypted properties yet
930 crypto_props = ucx_map_new(32); // create new map 985 crypto_props = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 32); // create new map
931 } 986 }
932 987
933 // remove all properties 988 // remove all properties
934 UCX_FOREACH(elm, data->crypto_remove) { 989 if(data->crypto_remove) {
935 if(crypto_props->count == 0) { 990 CxIterator i = cxListIterator(data->crypto_remove);
936 break; // map already empty, can't remove any more 991 cx_foreach(DavProperty *, property, i) {
992 if(crypto_props->size == 0) {
993 break; // map already empty, can't remove any more
994 }
995
996 cxmutstr key = dav_property_key(property->ns->name, property->name);
997 DavProperty *existing_prop = cxMapGet(crypto_props, cx_hash_key(key.ptr, key.length));
998 if(existing_prop) {
999 // TODO: free existing_prop
1000 }
1001 free(key.ptr);
937 } 1002 }
938
939 DavProperty *property = elm->data;
940 sstr_t key = dav_property_key(property->ns->name, property->name);
941 DavProperty *existing_prop = ucx_map_sstr_remove(crypto_props, key);
942 if(existing_prop) {
943 // TODO: free existing_prop
944 }
945 free(key.ptr);
946 } 1003 }
947 1004
948 // set properties 1005 // set properties
949 UCX_FOREACH(elm, data->crypto_set) { 1006 if(data->crypto_set) {
950 DavProperty *property = elm->data; 1007 CxIterator i = cxListIterator(data->crypto_set);
951 sstr_t key = dav_property_key(property->ns->name, property->name); 1008 cx_foreach(DavProperty *, property, i) {
952 DavProperty *existing_prop = ucx_map_sstr_remove(crypto_props, key); 1009 cxmutstr keystr = dav_property_key(property->ns->name, property->name);
953 ucx_map_sstr_put(crypto_props, key, property); 1010 CxHashKey key = cx_hash_key(keystr.ptr, keystr.length);
954 if(existing_prop) { 1011 DavProperty *existing_prop = cxMapRemoveAndGet(crypto_props, key);
955 // TODO: free existing_prop 1012 cxMapPut(crypto_props, key, property);
956 } 1013 if(existing_prop) {
957 free(key.ptr); 1014 // TODO: free existing_prop
1015 }
1016 free(keystr.ptr);
1017 }
958 } 1018 }
959 1019
960 DavXmlNode *crypto_prop_value = create_crypto_prop(sn, crypto_props); 1020 DavXmlNode *crypto_prop_value = create_crypto_prop(sn, crypto_props);
961 if(crypto_prop_value) { 1021 if(crypto_prop_value) {
962 DavProperty *new_crypto_prop = createprop(sn, DAV_NS, "crypto-prop"); 1022 DavProperty *new_crypto_prop = createprop(sn, DAV_NS, "crypto-prop");
963 new_crypto_prop->value = crypto_prop_value; 1023 new_crypto_prop->value = crypto_prop_value;
964 data->set = ucx_list_prepend_a(sn->mp->allocator, data->set, new_crypto_prop); 1024 add2propertylist(sn->mp->allocator, &data->set, new_crypto_prop);
965 } 1025 }
966 1026
967 dav_resource_free(crypto_res); 1027 dav_resource_free(crypto_res);
968 } 1028 }
969 1029
974 1034
975 // store properties 1035 // store properties
976 int r = 0; 1036 int r = 0;
977 sn->error = DAV_OK; 1037 sn->error = DAV_OK;
978 if(data->set || data->remove) { 1038 if(data->set || data->remove) {
979 UcxBuffer *request = create_proppatch_request(data); 1039 CxBuffer *request = create_proppatch_request(data);
980 UcxBuffer *response = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND); 1040 CxBuffer *response = cxBufferCreate(NULL, 1024, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
981 //printf("request:\n%.*s\n\n", request->pos, request->space); 1041 //printf("request:\n%.*s\n\n", request->pos, request->space);
982 1042
983 CURLcode ret = do_proppatch_request(sn, locktoken, request, response); 1043 CURLcode ret = do_proppatch_request(sn, locktoken, request, response);
984 long status = 0; 1044 long status = 0;
985 curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status); 1045 curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status);
992 } else { 1052 } else {
993 dav_session_set_error(sn, ret, status); 1053 dav_session_set_error(sn, ret, status);
994 r = -1; 1054 r = -1;
995 } 1055 }
996 1056
997 ucx_buffer_free(request); 1057 cxBufferFree(request);
998 ucx_buffer_free(response); 1058 cxBufferFree(response);
999 } 1059 }
1000 1060
1001 return r; 1061 return r;
1002 } 1062 }
1003 1063
1127 util_set_url(res->session, dav_resource_get_href(res)); 1187 util_set_url(res->session, dav_resource_get_href(res));
1128 1188
1129 DavLock *lock = dav_get_lock(res->session, res->path); 1189 DavLock *lock = dav_get_lock(res->session, res->path);
1130 char *locktoken = lock ? lock->token : NULL; 1190 char *locktoken = lock ? lock->token : NULL;
1131 1191
1132 UcxBuffer *response = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND); 1192 CxBuffer *response = cxBufferCreate(NULL, 4096, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
1133 CURLcode ret = do_delete_request(res->session, locktoken, response); 1193 CURLcode ret = do_delete_request(res->session, locktoken, response);
1134 long status = 0; 1194 long status = 0;
1135 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); 1195 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
1136 int r = 0; 1196 int r = 0;
1137 if(ret == CURLE_OK && (status >= 200 && status < 300)) { 1197 if(ret == CURLE_OK && (status >= 200 && status < 300)) {
1143 } else { 1203 } else {
1144 dav_session_set_error(res->session, ret, status); 1204 dav_session_set_error(res->session, ret, status);
1145 r = 1; 1205 r = 1;
1146 } 1206 }
1147 1207
1148 ucx_buffer_free(response); 1208 cxBufferFree(response);
1149 return r; 1209 return r;
1150 } 1210 }
1151 1211
1152 static int create_ancestors(DavSession *sn, char *href, char *path) { 1212 static int create_ancestors(DavSession *sn, char *href, char *path) {
1153 CURL *handle = sn->handle; 1213 CURL *handle = sn->handle;
1170 util_set_url(sn, h); 1230 util_set_url(sn, h);
1171 code = do_mkcol_request(sn, locktoken); 1231 code = do_mkcol_request(sn, locktoken);
1172 curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &status); 1232 curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &status);
1173 if(status == 201) { 1233 if(status == 201) {
1174 // resource successfully created 1234 // resource successfully created
1175 char *name = util_resource_name(p); 1235 char *name = (char*)util_resource_name(p);
1176 int len = strlen(name); 1236 int len = strlen(name);
1177 if(name[len - 1] == '/') { 1237 if(name[len - 1] == '/') {
1178 name[len - 1] = '\0'; 1238 name[len - 1] = '\0';
1179 } 1239 }
1180 if(resource_add_crypto_info(sn, h, name, NULL)) { 1240 if(resource_add_crypto_info(sn, h, name, NULL)) {
1223 if(code == CURLE_OK && (s >= 200 && s < 300)) { 1283 if(code == CURLE_OK && (s >= 200 && s < 300)) {
1224 sn->error = DAV_OK; 1284 sn->error = DAV_OK;
1225 // if the session has encrypted file names, add crypto infos 1285 // if the session has encrypted file names, add crypto infos
1226 if(!resource_add_crypto_info(sn, res->href, res->name, NULL)) { 1286 if(!resource_add_crypto_info(sn, res->href, res->name, NULL)) {
1227 // do a minimal propfind request 1287 // do a minimal propfind request
1228 UcxBuffer *rqbuf = create_propfind_request(sn, NULL, "propfind", 0); 1288 CxBuffer *rqbuf = create_propfind_request(sn, NULL, "propfind", 0);
1229 int ret = dav_propfind(sn, res, rqbuf); 1289 int ret = dav_propfind(sn, res, rqbuf);
1230 ucx_buffer_free(rqbuf); 1290 cxBufferFree(rqbuf);
1231 return ret; 1291 return ret;
1232 } else { 1292 } else {
1233 return 1; 1293 return 1;
1234 } 1294 }
1235 } else { 1295 } else {
1329 int dav_lock_t(DavResource *res, time_t timeout) { 1389 int dav_lock_t(DavResource *res, time_t timeout) {
1330 DavSession *sn = res->session; 1390 DavSession *sn = res->session;
1331 CURL *handle = sn->handle; 1391 CURL *handle = sn->handle;
1332 util_set_url(sn, dav_resource_get_href(res)); 1392 util_set_url(sn, dav_resource_get_href(res));
1333 1393
1334 UcxBuffer *request = create_lock_request(); 1394 CxBuffer *request = create_lock_request();
1335 UcxBuffer *response = ucx_buffer_new(NULL, 512, UCX_BUFFER_AUTOEXTEND); 1395 CxBuffer *response = cxBufferCreate(NULL, 512, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
1336 CURLcode ret = do_lock_request(sn, request, response, timeout); 1396 CURLcode ret = do_lock_request(sn, request, response, timeout);
1337 1397
1338 //printf("\nlock\n"); 1398 //printf("\nlock\n");
1339 //printf("%.*s\n\n", request->size, request->space); 1399 //printf("%.*s\n\n", request->size, request->space);
1340 //printf("%.*s\n\n", response->size, response->space); 1400 //printf("%.*s\n\n", response->size, response->space);
1341 1401
1342 ucx_buffer_free(request); 1402 cxBufferFree(request);
1343 1403
1344 long status = 0; 1404 long status = 0;
1345 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); 1405 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
1346 if(ret == CURLE_OK && (status >= 200 && status < 300)) { 1406 if(ret == CURLE_OK && (status >= 200 && status < 300)) {
1347 LockDiscovery lock; 1407 LockDiscovery lock;
1348 if(parse_lock_response(sn, response, &lock)) { 1408 int parse_error = parse_lock_response(sn, response, &lock);
1409 cxBufferFree(response);
1410 if(parse_error) {
1349 sn->error = DAV_ERROR; 1411 sn->error = DAV_ERROR;
1350 ucx_buffer_free(response);
1351 return -1; 1412 return -1;
1352 } 1413 }
1353 ucx_buffer_free(response);
1354 1414
1355 DavLock *l = dav_create_lock(sn, lock.locktoken, lock.timeout); 1415 DavLock *l = dav_create_lock(sn, lock.locktoken, lock.timeout);
1356 free(lock.locktoken); 1416 free(lock.locktoken);
1357 free(lock.timeout); 1417 free(lock.timeout);
1358 1418
1371 dav_destroy_lock(sn, l); 1431 dav_destroy_lock(sn, l);
1372 return -1; 1432 return -1;
1373 } 1433 }
1374 } else { 1434 } else {
1375 dav_session_set_error(sn, ret, status); 1435 dav_session_set_error(sn, ret, status);
1376 ucx_buffer_free(response); 1436 cxBufferFree(response);
1377 return -1; 1437 return -1;
1378 } 1438 }
1379 } 1439 }
1380 1440
1381 int dav_unlock(DavResource *res) { 1441 int dav_unlock(DavResource *res) {
1406 int resource_add_crypto_info(DavSession *sn, const char *href, const char *name, const char *hash) { 1466 int resource_add_crypto_info(DavSession *sn, const char *href, const char *name, const char *hash) {
1407 if(!DAV_IS_ENCRYPTED(sn)) { 1467 if(!DAV_IS_ENCRYPTED(sn)) {
1408 return 0; 1468 return 0;
1409 } 1469 }
1410 1470
1411 UcxBuffer *request = create_crypto_proppatch_request(sn, sn->key, name, hash); 1471 CxBuffer *request = create_crypto_proppatch_request(sn, sn->key, name, hash);
1412 UcxBuffer *response = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND); 1472 CxBuffer *response = cxBufferCreate(NULL, 1024, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
1413 1473
1414 util_set_url(sn, href); 1474 util_set_url(sn, href);
1415 // TODO: lock 1475 // TODO: lock
1416 CURLcode ret = do_proppatch_request(sn, NULL, request, response); 1476 CURLcode ret = do_proppatch_request(sn, NULL, request, response);
1417 ucx_buffer_free(request); 1477 cxBufferFree(request);
1418 long status = 0; 1478 long status = 0;
1419 curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status); 1479 curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status);
1420 if(ret == CURLE_OK && status == 207) { 1480 if(ret == CURLE_OK && status == 207) {
1421 // TODO: parse response 1481 // TODO: parse response
1422 sn->error = DAV_OK; 1482 sn->error = DAV_OK;
1423 ucx_buffer_free(response); 1483 cxBufferFree(response);
1424 return 0; 1484 return 0;
1425 } else { 1485 } else {
1426 dav_session_set_error(sn, ret, status); 1486 dav_session_set_error(sn, ret, status);
1427 ucx_buffer_free(response); 1487 cxBufferFree(response);
1428 return 1; 1488 return 1;
1429 } 1489 }
1430 } 1490 }
1431 1491
1432 /* ----------------------------- crypto-prop ----------------------------- */ 1492 /* ----------------------------- crypto-prop ----------------------------- */
1433 1493
1434 DavXmlNode* create_crypto_prop(DavSession *sn, UcxMap *properties) { 1494 DavXmlNode* create_crypto_prop(DavSession *sn, CxMap *properties) {
1435 if(!sn->key) { 1495 if(!sn->key) {
1436 return NULL; 1496 return NULL;
1437 } 1497 }
1438 1498
1439 UcxBuffer *content = ucx_buffer_new(NULL, 2048, UCX_BUFFER_AUTOEXTEND); 1499 CxBuffer *content = cxBufferCreate(NULL, 2048, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
1440 1500
1441 // create an xml document containing all properties 1501 // create an xml document containing all properties
1442 UcxMap *nsmap = ucx_map_new(8); 1502 CxMap *nsmap = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 8);
1443 ucx_map_cstr_put(nsmap, "DAV:", strdup("D")); 1503 nsmap->simple_destructor = free;
1444 1504 cxMapPut(nsmap, cx_hash_key_str("DAV:"), strdup("D"));
1445 ucx_buffer_puts(content, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 1505
1446 ucx_buffer_puts(content, "<D:prop xmlns:D=\"DAV:\">\n"); 1506 cxBufferPutString(content, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1447 1507 cxBufferPutString(content, "<D:prop xmlns:D=\"DAV:\">\n");
1448 UcxMapIterator i = ucx_map_iterator(properties); 1508
1509 CxIterator i = cxMapIteratorValues(properties);
1449 DavProperty *prop; 1510 DavProperty *prop;
1450 UCX_MAP_FOREACH(key, prop, i) { 1511 cx_foreach(DavProperty*, prop, i) {
1451 DavXmlNode pnode; 1512 DavXmlNode pnode;
1452 pnode.type = DAV_XML_ELEMENT; 1513 pnode.type = DAV_XML_ELEMENT;
1453 pnode.namespace = prop->ns->name; 1514 pnode.namespace = prop->ns->name;
1454 pnode.name = prop->name; 1515 pnode.name = prop->name;
1455 pnode.prev = NULL; 1516 pnode.prev = NULL;
1458 pnode.parent = NULL; 1519 pnode.parent = NULL;
1459 pnode.attributes = NULL; 1520 pnode.attributes = NULL;
1460 pnode.content = NULL; 1521 pnode.content = NULL;
1461 pnode.contentlength = 0; 1522 pnode.contentlength = 0;
1462 1523
1463 dav_print_node(content, (write_func)ucx_buffer_write, nsmap, &pnode); 1524 dav_print_node(content, (cx_write_func)cxBufferWrite, nsmap, &pnode);
1464 ucx_buffer_putc(content, '\n'); 1525 cxBufferPut(content, '\n');
1465 } 1526 }
1466 1527
1467 ucx_buffer_puts(content, "</D:prop>"); 1528 cxBufferPutString(content, "</D:prop>");
1468 1529
1469 ucx_map_free_content(nsmap, (ucx_destructor)free); 1530 cxMapDestroy(nsmap);
1470 ucx_map_free(nsmap);
1471 1531
1472 // encrypt xml document 1532 // encrypt xml document
1473 char *crypto_prop_content = aes_encrypt(content->space, content->size, sn->key); 1533 char *crypto_prop_content = aes_encrypt(content->space, content->size, sn->key);
1474 ucx_buffer_free(content); 1534 cxBufferDestroy(content);
1475 1535
1476 DavXmlNode *ret = NULL; 1536 DavXmlNode *ret = NULL;
1477 if(crypto_prop_content) { 1537 if(crypto_prop_content) {
1478 ret = dav_text_node(sn, crypto_prop_content); 1538 ret = dav_text_node(sn, crypto_prop_content);
1479 free(crypto_prop_content); 1539 free(crypto_prop_content);
1480 } 1540 }
1481 return ret; 1541 return ret;
1482 } 1542 }
1483 1543
1484 UcxMap* parse_crypto_prop(DavSession *sn, DavKey *key, DavXmlNode *node) { 1544 CxMap* parse_crypto_prop(DavSession *sn, DavKey *key, DavXmlNode *node) {
1485 if(!node || node->type != DAV_XML_TEXT || node->contentlength == 0) { 1545 if(!node || node->type != DAV_XML_TEXT || node->contentlength == 0) {
1486 return NULL; 1546 return NULL;
1487 } 1547 }
1488 1548
1489 return parse_crypto_prop_str(sn, key, node->content); 1549 return parse_crypto_prop_str(sn, key, node->content);
1490 } 1550 }
1491 1551
1492 UcxMap* parse_crypto_prop_str(DavSession *sn, DavKey *key, const char *content) { 1552 CxMap* parse_crypto_prop_str(DavSession *sn, DavKey *key, const char *content) {
1493 size_t len = 0; 1553 size_t len = 0;
1494 char *dec_str = aes_decrypt(content, &len, key); 1554 char *dec_str = aes_decrypt(content, &len, key);
1495 1555
1496 xmlDoc *doc = xmlReadMemory(dec_str, len, NULL, NULL, 0); 1556 xmlDoc *doc = xmlReadMemory(dec_str, len, NULL, NULL, 0);
1497 free(dec_str); 1557 free(dec_str);
1517 xmlFreeDoc(doc); 1577 xmlFreeDoc(doc);
1518 return NULL; 1578 return NULL;
1519 } 1579 }
1520 1580
1521 // ready to get the properties 1581 // ready to get the properties
1522 UcxMap *map = ucx_map_new(32); 1582 CxMap *map = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 32);
1523 xmlNode *n = xml_root->children; 1583 xmlNode *n = xml_root->children;
1524 while(n) { 1584 while(n) {
1525 if(n->type == XML_ELEMENT_NODE && n->ns && n->ns->href) { 1585 if(n->type == XML_ELEMENT_NODE && n->ns && n->ns->href) {
1526 DavProperty *property = dav_session_malloc(sn, sizeof(DavProperty)); 1586 DavProperty *property = dav_session_malloc(sn, sizeof(DavProperty));
1527 property->name = dav_session_strdup(sn, (const char*)n->name); 1587 property->name = dav_session_strdup(sn, (const char*)n->name);
1529 property->ns->name = dav_session_strdup(sn, (const char*)n->ns->href); 1589 property->ns->name = dav_session_strdup(sn, (const char*)n->ns->href);
1530 property->ns->prefix = n->ns->prefix ? 1590 property->ns->prefix = n->ns->prefix ?
1531 dav_session_strdup(sn, (const char*)n->ns->prefix) : NULL; 1591 dav_session_strdup(sn, (const char*)n->ns->prefix) : NULL;
1532 property->value = n->children ? dav_convert_xml(sn, n->children) : NULL; 1592 property->value = n->children ? dav_convert_xml(sn, n->children) : NULL;
1533 1593
1534 sstr_t key = dav_property_key(property->ns->name, property->name); 1594 cxmutstr key = dav_property_key(property->ns->name, property->name);
1535 ucx_map_sstr_put(map, key, property); 1595 cxMapPut(map, cx_hash_key(key.ptr, key.length), property);
1536 free(key.ptr); 1596 free(key.ptr);
1537 } 1597 }
1538 n = n->next; 1598 n = n->next;
1539 } 1599 }
1540 1600
1541 xmlFreeDoc(doc); 1601 xmlFreeDoc(doc);
1542 if(map->count == 0) { 1602 if(map->size == 0) {
1543 ucx_map_free(map); 1603 cxMapDestroy(map);
1544 return NULL; 1604 return NULL;
1545 } 1605 }
1546 return map; 1606 return map;
1547 } 1607 }
1548 1608

mercurial