src/server/webdav/operation.c

changeset 415
d938228c382e
parent 413
6afaebf003ea
child 503
aeaf7db26fac
equal deleted inserted replaced
414:99a34860c105 415:d938228c382e
28 28
29 #include <stdio.h> 29 #include <stdio.h>
30 #include <stdlib.h> 30 #include <stdlib.h>
31 #include <errno.h> 31 #include <errno.h>
32 32
33 #include <ucx/list.h> 33 #include <cx/list.h>
34 34
35 #include "../daemon/session.h" 35 #include "../daemon/session.h"
36 #include "../util/pblock.h" 36 #include "../util/pblock.h"
37 37
38 #include "operation.h" 38 #include "operation.h"
58 WebdavOperation* webdav_create_propfind_operation( 58 WebdavOperation* webdav_create_propfind_operation(
59 Session *sn, 59 Session *sn,
60 Request *rq, 60 Request *rq,
61 WebdavBackend *dav, 61 WebdavBackend *dav,
62 WebdavPList *reqprops, 62 WebdavPList *reqprops,
63 UcxList *requests, 63 WebdavPropfindRequestList *requests,
64 WebdavResponse *response) 64 WebdavResponse *response)
65 { 65 {
66 WebdavOperation *op = pool_malloc(sn->pool, sizeof(WebdavOperation)); 66 WebdavOperation *op = pool_malloc(sn->pool, sizeof(WebdavOperation));
67 ZERO(op, sizeof(WebdavOperation)); 67 ZERO(op, sizeof(WebdavOperation));
68 op->dav = dav; 68 op->dav = dav;
92 // store data that we need when the resource will be closed 92 // store data that we need when the resource will be closed
93 op->stat = s; 93 op->stat = s;
94 op->parent = parent; 94 op->parent = parent;
95 95
96 // get first propfind object 96 // get first propfind object
97 WebdavPropfindRequest *propfind = op->requests->data; 97 WebdavPropfindRequest *propfind = op->requests->propfind;
98 98
99 // execute propfind_do of the first backend for the first resource 99 // execute propfind_do of the first backend for the first resource
100 int ret = REQ_PROCEED; 100 int ret = REQ_PROCEED;
101 if(op->dav->propfind_do(propfind, op->response, NULL, resource, s)) { 101 if(op->dav->propfind_do(propfind, op->response, NULL, resource, s)) {
102 ret = REQ_ABORTED; 102 ret = REQ_ABORTED;
115 typedef struct PathSearchElm { 115 typedef struct PathSearchElm {
116 char *href; 116 char *href;
117 char *path; 117 char *path;
118 size_t hreflen; 118 size_t hreflen;
119 size_t pathlen; 119 size_t pathlen;
120 struct PathSearchElm *next;
120 } PathSearchElm; 121 } PathSearchElm;
121 122
122 /* 123 /*
123 * concats base + / + elm 124 * concats base + / + elm
124 * if baseinit is true, only elm is copied 125 * if baseinit is true, only elm is copied
185 WebdavOperation *op, 186 WebdavOperation *op,
186 VFSContext *vfs, 187 VFSContext *vfs,
187 const char *href, 188 const char *href,
188 const char *path) 189 const char *path)
189 { 190 {
190 WebdavPropfindRequest *request = op->requests->data; 191 WebdavPropfindRequest *request = op->requests->propfind;
191 return webdav_op_iterate_children( 192 return webdav_op_iterate_children(
192 vfs, request->depth, href, path, propfind_child_cb, op); 193 vfs, request->depth, href, path, propfind_child_cb, op);
193 } 194 }
194 195
195 int webdav_op_propfiond_close_resource( 196 int webdav_op_propfiond_close_resource(
197 WebdavResource *resource) 198 WebdavResource *resource)
198 { 199 {
199 // start with second backend and request, because 200 // start with second backend and request, because
200 // the first one was already called by webdav_op_propfind_begin 201 // the first one was already called by webdav_op_propfind_begin
201 WebdavBackend *dav = op->dav->next; 202 WebdavBackend *dav = op->dav->next;
202 UcxList *request = op->requests->next; 203 WebdavPropfindRequestList *request = op->requests->next;
203 204
204 // call propfind_do of all remaining backends 205 // call propfind_do of all remaining backends
205 int ret = REQ_PROCEED; 206 int ret = REQ_PROCEED;
206 while(dav && request) { 207 while(dav && request) {
207 if(dav->propfind_do( 208 if(dav->propfind_do(
208 request->data, 209 request->propfind,
209 op->response, 210 op->response,
210 op->parent, 211 op->parent,
211 resource, 212 resource,
212 op->stat)) 213 op->stat))
213 { 214 {
223 /* 224 /*
224 * Executes propfind_finish for each Backend 225 * Executes propfind_finish for each Backend
225 */ 226 */
226 int webdav_op_propfind_finish(WebdavOperation *op) { 227 int webdav_op_propfind_finish(WebdavOperation *op) {
227 WebdavBackend *dav = op->dav; 228 WebdavBackend *dav = op->dav;
228 UcxList *requests = op->requests; 229 WebdavPropfindRequestList *requests = op->requests;
229 230
230 int ret = REQ_PROCEED; 231 int ret = REQ_PROCEED;
231 while(dav && requests) { 232 while(dav && requests) {
232 if(dav->propfind_finish(requests->data)) { 233 if(dav->propfind_finish(requests->propfind)) {
233 ret = REQ_ABORTED; 234 ret = REQ_ABORTED;
234 } 235 }
235 236
236 dav = dav->next; 237 dav = dav->next;
237 requests = requests->next; 238 requests = requests->next;
272 WebdavOperation *op, 273 WebdavOperation *op,
273 const char *href, 274 const char *href,
274 const char *path) 275 const char *path)
275 { 276 {
276 WebdavProppatchRequest *orig_request = op->proppatch; 277 WebdavProppatchRequest *orig_request = op->proppatch;
277 UcxAllocator *a = session_get_allocator(op->sn); 278 CxAllocator *a = pool_allocator(op->sn->pool);
278 279
279 // create WebdavResource object for the requested resource 280 // create WebdavResource object for the requested resource
280 WebdavResource *resource = op->response->addresource(op->response, href); 281 WebdavResource *resource = op->response->addresource(op->response, href);
281 if(!resource) { 282 if(!resource) {
282 return REQ_ABORTED; 283 return REQ_ABORTED;
497 const char *href, 498 const char *href,
498 const char *path, 499 const char *path,
499 vfs_op_child_func func, 500 vfs_op_child_func func,
500 void *userdata) 501 void *userdata)
501 { 502 {
502 UcxAllocator *a = session_get_allocator(vfs->sn);
503 pool_handle_t *pool = vfs->sn->pool; 503 pool_handle_t *pool = vfs->sn->pool;
504 504
505 PathSearchElm *start_elm = pool_malloc(pool, sizeof(PathSearchElm)); 505 PathSearchElm *start_elm = pool_malloc(pool, sizeof(PathSearchElm));
506 start_elm->href = pool_strdup(pool, href ? href : ""); 506 start_elm->href = pool_strdup(pool, href ? href : "");
507 start_elm->path = pool_strdup(pool, path ? path : ""); 507 start_elm->path = pool_strdup(pool, path ? path : "");
508 start_elm->hreflen = href ? strlen(href) : 0; 508 start_elm->hreflen = href ? strlen(href) : 0;
509 start_elm->pathlen = path ? strlen(path) : 0; 509 start_elm->pathlen = path ? strlen(path) : 0;
510 510 start_elm->next = NULL;
511 UcxList *stack = ucx_list_prepend_a(a, NULL, start_elm); 511
512 UcxList *stack_end = stack; 512 PathSearchElm *stack = start_elm;
513 if(!stack) { 513 PathSearchElm *stack_end = start_elm;
514 return 1;
515 }
516 514
517 // reusable buffer for full child path and href 515 // reusable buffer for full child path and href
518 char *newpath = pool_malloc(pool, 256); 516 char *newpath = pool_malloc(pool, 256);
519 size_t newpathlen = 256; 517 size_t newpathlen = 256;
520 518
521 char *newhref = pool_malloc(pool, 256); 519 char *newhref = pool_malloc(pool, 256);
522 size_t newhreflen = 256; 520 size_t newhreflen = 256;
523 521
524 int err = 0; 522 int err = 0;
525 while(stack && !err) { 523 while(stack && !err) {
526 PathSearchElm *cur_elm = stack->data; 524 PathSearchElm *cur_elm = stack;
527 525
528 // when newpath is initialized with the parent path 526 // when newpath is initialized with the parent path
529 // set path_buf_init to TRUE 527 // set path_buf_init to TRUE
530 WSBool href_buf_init = FALSE; 528 WSBool href_buf_init = FALSE;
531 WSBool path_buf_init = FALSE; 529 WSBool path_buf_init = FALSE;
594 memcpy(pathcp, newpath, childpathlen + 1); 592 memcpy(pathcp, newpath, childpathlen + 1);
595 pathcp[childpathlen] = '\0'; 593 pathcp[childpathlen] = '\0';
596 594
597 PathSearchElm *new_elm = pool_malloc(pool, 595 PathSearchElm *new_elm = pool_malloc(pool,
598 sizeof(PathSearchElm)); 596 sizeof(PathSearchElm));
597 if(!new_elm) {
598 err = 1;
599 break;
600 }
599 new_elm->href = hrefcp; 601 new_elm->href = hrefcp;
600 new_elm->path = pathcp; 602 new_elm->path = pathcp;
601 new_elm->hreflen = childhreflen; 603 new_elm->hreflen = childhreflen;
602 new_elm->pathlen = childpathlen; 604 new_elm->pathlen = childpathlen;
605 new_elm->next = NULL;
603 606
604 // add the new_elm to the stack 607 // add the new_elm to the stack
605 // stack_end is always not NULL here, because we remove 608 // stack_end is always not NULL here, because the loop is
609 // running as long as we have a stack and we remove
606 // the first stack element at the end of the loop 610 // the first stack element at the end of the loop
607 UcxList *newlistelm = ucx_list_append_a(a, stack_end, new_elm); 611 stack_end->next = new_elm;
608 if(!newlistelm) { 612 stack_end = new_elm;
609 err = 1;
610 break;
611 }
612 stack_end = newlistelm;
613 } 613 }
614 } 614 }
615 615
616 vfs_closedir(dir); 616 vfs_closedir(dir);
617
618 stack = stack->next;
617 619
618 pool_free(pool, cur_elm->path); 620 pool_free(pool, cur_elm->path);
619 pool_free(pool, cur_elm->href); 621 pool_free(pool, cur_elm->href);
620 pool_free(pool, cur_elm); 622 pool_free(pool, cur_elm);
621
622 stack = ucx_list_remove_a(a, stack, stack);
623 } 623 }
624 624
625 // in case of an error, we have to free all remaining stack elements 625 // in case of an error, we have to free all remaining stack elements
626 UCX_FOREACH(elm, stack) { 626 for(PathSearchElm *elm=stack;elm;) {
627 char *data = elm->data; 627 PathSearchElm *next_elm = elm->next;
628 if(data != path) { 628 pool_free(pool, elm->path);
629 pool_free(pool, data); 629 pool_free(pool, elm->href);
630 } 630 pool_free(pool, elm);
631 elm = next_elm;
631 } 632 }
632 633
633 return err; 634 return err;
634 } 635 }
635 636

mercurial