static csync_vio_file_stat_t *owncloud_readdir(csync_vio_method_handle_t *dhandle) { struct listdir_context *fetchCtx = dhandle; if( fetchCtx == NULL) { /* DEBUG_WEBDAV("An empty dir or at end"); */ return NULL; } while( fetchCtx->currResource ) { resource* currResource = fetchCtx->currResource; char *escaped_path = NULL; /* set pointer to next element */ fetchCtx->currResource = fetchCtx->currResource->next; /* It seems strange: first uri->path is unescaped to escape it in the next step again. * The reason is that uri->path is not completely escaped (ie. it seems only to have * spaces escaped), while the fetchCtx->target is fully escaped. * See http://bugs.owncloud.org/thebuggenie/owncloud/issues/oc-613 */ escaped_path = ne_path_escape( currResource->uri ); if (ne_path_compare(fetchCtx->target, escaped_path) != 0) { csync_vio_file_stat_t* lfs = resourceToFileStat(currResource); fill_stat_cache(lfs); SAFE_FREE( escaped_path ); return lfs; } /* This is the target URI */ SAFE_FREE( escaped_path ); } return NULL; }
/* Give it a path segment, it returns non-zero if child is * a child of parent. */ int ne_path_childof(const char *parent, const char *child) { char *root = ne_strdup(child); int ret; if (strlen(parent) >= strlen(child)) { ret = 0; } else { /* root is the first of child, equal to length of parent */ root[strlen(parent)] = '\0'; ret = (ne_path_compare(parent, root) == 0); } ne_free(root); return ret; }
void ne_lock_using_resource(ne_request *req, const char *uri, int depth) { NE_DEBUG_WINSCP_CONTEXT(ne_get_session(req)); struct lh_req_cookie *lrc = ne_get_request_private(req, HOOK_ID); struct lock_list *item; int match; if (lrc == NULL) return; /* Iterate over the list of stored locks to see if any of them * apply to this resource */ for (item = lrc->store->locks; item != NULL; item = item->next) { match = 0; if (depth == NE_DEPTH_INFINITE && ne_path_childof(uri, item->lock->uri.path)) { /* Case 1: this is a depth-infinity request which will * modify a lock somewhere inside the collection. */ NE_DEBUG(NE_DBG_LOCKS, "Has child: %s\n", item->lock->token); match = 1; } else if (ne_path_compare(uri, item->lock->uri.path) == 0) { /* Case 2: this request is directly on a locked resource */ NE_DEBUG(NE_DBG_LOCKS, "Has direct lock: %s\n", item->lock->token); match = 1; } else if (item->lock->depth == NE_DEPTH_INFINITE && ne_path_childof(item->lock->uri.path, uri)) { /* Case 3: there is a higher-up infinite-depth lock which * covers the resource that this request will modify. */ NE_DEBUG(NE_DBG_LOCKS, "Is child of: %s\n", item->lock->token); match = 1; } if (match) { submit_lock(lrc, item->lock); } } }
void ne_lock_using_parent(ne_request *req, const char *path) { NE_DEBUG_WINSCP_CONTEXT(ne_get_session(req)); struct lh_req_cookie *lrc = ne_get_request_private(req, HOOK_ID); ne_uri u = {0}; struct lock_list *item; char *parent; if (lrc == NULL) return; parent = ne_path_parent(path); if (parent == NULL) return; ne_fill_server_uri(ne_get_session(req), &u); for (item = lrc->store->locks; item != NULL; item = item->next) { /* Only care about locks which are on this server. */ u.path = item->lock->uri.path; if (ne_uri_cmp(&u, &item->lock->uri)) continue; /* This lock is needed if it is an infinite depth lock which * covers the parent, or a lock on the parent itself. */ if ((item->lock->depth == NE_DEPTH_INFINITE && ne_path_childof(item->lock->uri.path, parent)) || ne_path_compare(item->lock->uri.path, parent) == 0) { NE_DEBUG(NE_DBG_LOCKS, "Locked parent, %s on %s\n", item->lock->token, item->lock->uri.path); submit_lock(lrc, item->lock); } } u.path = parent; /* handy: makes u.path valid and ne_free(parent). */ ne_uri_free(&u); }
/* * result parsing list. * This function is called to parse the result of the propfind request * to list directories on the WebDAV server. I takes a single resource * and fills a resource struct and stores it to the result list which * is stored in the listdir_context. */ static void results(void *userdata, const ne_uri *uri, const ne_prop_result_set *set) { struct listdir_context *fetchCtx = userdata; struct resource *newres = 0; const char *clength, *modtime = NULL; const char *resourcetype = NULL; const ne_status *status = NULL; char *path = ne_path_unescape( uri->path ); (void) status; if( ! fetchCtx ) { DEBUG_WEBDAV("No valid fetchContext"); return; } DEBUG_WEBDAV("** propfind result found: %s", path ); if( ! fetchCtx->target ) { DEBUG_WEBDAV("error: target must not be zero!" ); return; } if (ne_path_compare(fetchCtx->target, uri->path) == 0 && !fetchCtx->include_target) { /* This is the target URI */ DEBUG_WEBDAV( "Skipping target resource."); /* Free the private structure. */ SAFE_FREE( path ); return; } /* Fill the resource structure with the data about the file */ newres = c_malloc(sizeof(struct resource)); newres->uri = path; /* no need to strdup because ne_path_unescape already allocates */ newres->name = c_basename( path ); modtime = ne_propset_value( set, &ls_props[0] ); clength = ne_propset_value( set, &ls_props[1] ); resourcetype = ne_propset_value( set, &ls_props[2] ); newres->type = resr_normal; if( clength == NULL && resourcetype && strncmp( resourcetype, "<DAV:collection>", 16 ) == 0) { newres->type = resr_collection; } if (modtime) newres->modtime = ne_httpdate_parse(modtime); if (clength) { char *p; newres->size = DAV_STRTOL(clength, &p, 10); if (*p) { newres->size = 0; } } /* prepend the new resource to the result list */ newres->next = fetchCtx->list; fetchCtx->list = newres; fetchCtx->result_count = fetchCtx->result_count + 1; DEBUG_WEBDAV( "results for URI %s: %d %d", newres->name, (int)newres->size, (int)newres->type ); }
static int _data_cmp(const void *a, const void *b) { const propfind_recursive_element_t *elementA = a; const propfind_recursive_element_t *elementB = b; return ne_path_compare(elementA->self->uri, elementB->self->uri); }
static int _key_cmp(const void *key, const void *b) { const char *elementAUri = (char*)key; const propfind_recursive_element_t *elementB = b; return ne_path_compare(elementAUri, elementB->self->uri); }