/* Discover all locks on URI */ int ne_lock_discover(ne_session *sess, const char *uri, ne_lock_result callback, void *userdata) { ne_propfind_handler *handler; struct discover_ctx ctx = {0}; int ret; ctx.results = callback; ctx.userdata = userdata; ctx.session = sess; ctx.cdata = ne_buffer_create(); handler = ne_propfind_create(sess, uri, NE_DEPTH_ZERO,"PROPFIND"); ne_propfind_set_private(handler, ld_create, &ctx); ne_xml_push_handler(ne_propfind_get_parser(handler), ld_startelm, ld_cdata, end_element_ldisc, handler); ret = ne_propfind_named(handler, lock_props, discover_results, &ctx); ne_buffer_destroy(ctx.cdata); ne_propfind_destroy(handler); return ret; }
static int fetch_resource_list( const char *uri, int depth, struct listdir_context *fetchCtx ) { int ret = 0; ne_propfind_handler *hdl = NULL; ne_request *request = NULL; const char *content_type = NULL; char *curi = NULL; const ne_status *req_status = NULL; curi = _cleanPath( uri ); if (!fetchCtx) { errno = ENOMEM; SAFE_FREE(curi); return -1; } fetchCtx->list = NULL; fetchCtx->target = curi; fetchCtx->currResource = NULL; /* do a propfind request and parse the results in the results function, set as callback */ hdl = ne_propfind_create(dav_session.ctx, curi, depth); if(hdl) { ret = ne_propfind_named(hdl, ls_props, results, fetchCtx); request = ne_propfind_get_request( hdl ); req_status = ne_get_status( request ); } if( ret == NE_OK ) { fetchCtx->currResource = fetchCtx->list; /* Check the request status. */ if( req_status && req_status->klass != 2 ) { set_errno_from_http_errcode(req_status->code); DEBUG_WEBDAV("ERROR: Request failed: status %d (%s)", req_status->code, req_status->reason_phrase); ret = NE_CONNECT; set_error_message(req_status->reason_phrase); } DEBUG_WEBDAV("Simple propfind result code %d.", req_status ? req_status->code : -1); } else { if( ret == NE_ERROR && req_status->code == 404) { errno = ENOENT; } else { set_errno_from_neon_errcode(ret); } } if( ret == NE_OK ) { /* Check the content type. If the server has a problem, ie. database is gone or such, * the content type is not xml but a html error message. Stop on processing if it's * not XML. * FIXME: Generate user error message from the reply content. */ content_type = ne_get_response_header( request, "Content-Type" ); if( !(content_type && c_streq(content_type, "application/xml; charset=utf-8") ) ) { DEBUG_WEBDAV("ERROR: Content type of propfind request not XML: %s.", content_type ? content_type: "<empty>"); errno = ERRNO_WRONG_CONTENT; set_error_message("Server error: PROPFIND reply is not XML formatted!"); ret = NE_CONNECT; } } #ifndef NDEBUG if( ret != NE_OK ) { const char *err = ne_get_error(dav_session.ctx); DEBUG_WEBDAV("WRN: propfind named failed with %d, request error: %s", ret, err ? err : "<nil>"); } #endif /* NDEBUG */ if (hdl != NULL) { ne_propfind_destroy(hdl); } #ifndef NDEBUG if (ret == NE_REDIRECT) { const ne_uri *redir_ne_uri = ne_redirect_location(dav_session.ctx); if (redir_ne_uri) { char *redir_uri = ne_uri_unparse(redir_ne_uri); DEBUG_WEBDAV("Permanently moved to %s", redir_uri); } } #endif /* NDEBUG */ if( ret != NE_OK ) { free_fetchCtx(fetchCtx); return -1; } return 0; }
void fetch_resource_list_recursive(const char *uri, const char *curi) { int ret = 0; ne_propfind_handler *hdl = NULL; ne_request *request = NULL; const char *content_type = NULL; const ne_status *req_status = NULL; int depth = NE_DEPTH_INFINITE; DEBUG_WEBDAV("fetch_resource_list_recursive Starting recursive propfind %s %s", uri, curi); /* do a propfind request and parse the results in the results function, set as callback */ hdl = ne_propfind_create(dav_session.ctx, curi, depth); if(hdl) { ret = ne_propfind_named(hdl, ls_props, propfind_results_recursive, (void*)curi); request = ne_propfind_get_request( hdl ); req_status = ne_get_status( request ); } if( ret == NE_OK ) { /* Check the request status. */ if( req_status && req_status->klass != 2 ) { set_errno_from_http_errcode(req_status->code); DEBUG_WEBDAV("ERROR: Request failed: status %d (%s)", req_status->code, req_status->reason_phrase); ret = NE_CONNECT; set_error_message(req_status->reason_phrase); } DEBUG_WEBDAV("Recursive propfind result code %d.", req_status ? req_status->code : 0); } else { if( ret == NE_ERROR && req_status->code == 404) { errno = ENOENT; } else { set_errno_from_neon_errcode(ret); } } if( ret == NE_OK ) { /* Check the content type. If the server has a problem, ie. database is gone or such, * the content type is not xml but a html error message. Stop on processing if it's * not XML. * FIXME: Generate user error message from the reply content. */ content_type = ne_get_response_header( request, "Content-Type" ); if( !(content_type && c_streq(content_type, "application/xml; charset=utf-8") ) ) { DEBUG_WEBDAV("ERROR: Content type of propfind request not XML: %s.", content_type ? content_type: "<empty>"); errno = ERRNO_WRONG_CONTENT; set_error_message("Server error: PROPFIND reply is not XML formatted!"); ret = NE_CONNECT; } } if( ret != NE_OK ) { const char *err = NULL; err = ne_get_error( dav_session.ctx ); DEBUG_WEBDAV("WRN: propfind named failed with %d, request error: %s", ret, err ? err : "<nil>"); } if( hdl ) ne_propfind_destroy(hdl); if( ret != NE_OK ) { return; } return; }
/* * fetches a resource list from the WebDAV server. This is equivalent to list dir. */ static struct listdir_context *fetch_resource_list(const char *uri, int depth) { struct listdir_context *fetchCtx; int ret = 0; ne_propfind_handler *hdl = NULL; ne_request *request = NULL; const char *content_type = NULL; char *curi = NULL; const ne_status *req_status = NULL; curi = _cleanPath( uri ); /* The old legacy one-level PROPFIND cache. Also gets filled by the recursive cache if 'infinity' did not suceed. */ if (propfind_cache) { if (c_streq(curi, propfind_cache->target)) { DEBUG_WEBDAV("fetch_resource_list Using simple PROPFIND cache %s", curi); propfind_cache->ref++; SAFE_FREE(curi); return propfind_cache; } } fetchCtx = c_malloc( sizeof( struct listdir_context )); if (!fetchCtx) { errno = ENOMEM; SAFE_FREE(curi); return NULL; } fetchCtx->list = NULL; fetchCtx->target = curi; fetchCtx->currResource = NULL; fetchCtx->ref = 1; /* do a propfind request and parse the results in the results function, set as callback */ hdl = ne_propfind_create(dav_session.ctx, curi, depth); if(hdl) { ret = ne_propfind_named(hdl, ls_props, results, fetchCtx); request = ne_propfind_get_request( hdl ); req_status = ne_get_status( request ); } if( ret == NE_OK ) { fetchCtx->currResource = fetchCtx->list; /* Check the request status. */ if( req_status && req_status->klass != 2 ) { set_errno_from_http_errcode(req_status->code); DEBUG_WEBDAV("ERROR: Request failed: status %d (%s)", req_status->code, req_status->reason_phrase); ret = NE_CONNECT; set_error_message(req_status->reason_phrase); oc_notify_progress( uri, CSYNC_NOTIFY_ERROR, req_status->code, (intptr_t)(req_status->reason_phrase) ); } DEBUG_WEBDAV("Simple propfind result code %d.", req_status->code); } else { if( ret == NE_ERROR && req_status->code == 404) { errno = ENOENT; } else { set_errno_from_neon_errcode(ret); } } if( ret == NE_OK ) { /* Check the content type. If the server has a problem, ie. database is gone or such, * the content type is not xml but a html error message. Stop on processing if it's * not XML. * FIXME: Generate user error message from the reply content. */ content_type = ne_get_response_header( request, "Content-Type" ); if( !(content_type && c_streq(content_type, "application/xml; charset=utf-8") ) ) { DEBUG_WEBDAV("ERROR: Content type of propfind request not XML: %s.", content_type ? content_type: "<empty>"); errno = ERRNO_WRONG_CONTENT; set_error_message("Server error: PROPFIND reply is not XML formatted!"); ret = NE_CONNECT; } } if( ret != NE_OK ) { const char *err = NULL; set_errno_from_neon_errcode(ret); err = ne_get_error( dav_session.ctx ); if(err) { set_error_message(err); } DEBUG_WEBDAV("WRN: propfind named failed with %d, request error: %s", ret, err ? err : "<nil>"); } if( hdl ) ne_propfind_destroy(hdl); if( ret != NE_OK ) { free_fetchCtx(fetchCtx); return NULL; } free_fetchCtx(propfind_cache); propfind_cache = fetchCtx; propfind_cache->ref++; return fetchCtx; }