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; |
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; |
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 |