/* private context for doing a filesystem walk */
typedef struct {
- dav_walker_ctx *wctx;
+ /* the input walk parameters */
+ const dav_walk_params *params;
+
+ /* reused as we walk */
+ dav_walk_resource wres;
dav_resource res1;
dav_resource res2;
dav_buffer path1;
dav_buffer path2;
+ dav_buffer uri_buf; /* URI for res1 */
+
dav_buffer locknull_buf;
} dav_fs_walker_context;
return NULL;
}
-static dav_error * dav_fs_copymove_walker(dav_walker_ctx *ctx, int calltype)
+static dav_error * dav_fs_copymove_walker(dav_walk_resource *wres,
+ int calltype)
{
- dav_resource_private *srcinfo = ctx->resource->info;
- dav_resource_private *dstinfo = ctx->res2->info;
+ dav_walker_ctx *ctx = wres->walk_ctx;
+ dav_resource_private *srcinfo = wres->resource->info;
+ dav_resource_private *dstinfo = wres->res_dst->info;
dav_error *err = NULL;
- if (ctx->resource->collection) {
+ if (wres->resource->collection) {
if (calltype == DAV_CALLTYPE_POSTFIX) {
/* Postfix call for MOVE. delete the source dir.
* Note: when copying, we do not enable the postfix-traversal.
}
else {
/* copy/move of a collection. Create the new, target collection */
- if (apr_make_dir(dstinfo->pathname, APR_OS_DEFAULT, ctx->pool)
- != APR_SUCCESS) {
+ if (apr_make_dir(dstinfo->pathname, APR_OS_DEFAULT,
+ ctx->w.pool) != APR_SUCCESS) {
/* ### assume it was a permissions problem */
/* ### need a description here */
- err = dav_new_error(ctx->pool, HTTP_FORBIDDEN, 0, NULL);
+ err = dav_new_error(ctx->w.pool, HTTP_FORBIDDEN, 0, NULL);
}
}
}
else {
- err = dav_fs_copymove_file(ctx->is_move, ctx->pool,
+ err = dav_fs_copymove_file(ctx->is_move, ctx->w.pool,
srcinfo->pathname, dstinfo->pathname,
&ctx->work_buf);
/* ### push a higher-level description? */
if (err != NULL
&& !ap_is_HTTP_SERVER_ERROR(err->status)
&& (ctx->is_move
- || !dav_fs_is_same_resource(ctx->resource, ctx->root))) {
+ || !dav_fs_is_same_resource(wres->resource, ctx->w.root))) {
/* ### use errno to generate DAV:responsedescription? */
- dav_add_response(ctx, ctx->resource->uri, err->status, NULL);
+ dav_add_response(wres, err->status, NULL);
/* the error is in the multistatus now. do not stop the traversal. */
return NULL;
* including the state dirs
*/
if (src->collection) {
- dav_walker_ctx ctx = { 0 };
+ dav_walker_ctx ctx = { { 0 } };
+
+ ctx.w.walk_type = DAV_WALKTYPE_ALL | DAV_WALKTYPE_HIDDEN;
+ ctx.w.func = dav_fs_copymove_walker;
+ ctx.w.walk_ctx = &ctx;
+ ctx.w.pool = src->info->pool;
+ ctx.w.root = src;
+ ctx.w.root_dst = dst;
- ctx.walk_type = DAV_WALKTYPE_ALL | DAV_WALKTYPE_HIDDEN;
- ctx.func = dav_fs_copymove_walker;
- ctx.pool = src->info->pool;
- ctx.resource = src;
- ctx.res2 = dst;
ctx.is_move = is_move;
- ctx.postfix = is_move; /* needed for MOVE to delete source dirs */
- /* copy over the source URI */
- dav_buffer_init(ctx.pool, &ctx.uri, src->uri);
+ /* postfix is needed for MOVE to delete source dirs */
+ if (is_move)
+ ctx.w.walk_type |= DAV_WALKTYPE_POSTFIX;
if ((err = dav_fs_walk(&ctx, depth)) != NULL) {
/* on a "real" error, then just punt. nothing else to do. */
err);
}
-static dav_error * dav_fs_delete_walker(dav_walker_ctx *ctx, int calltype)
+static dav_error * dav_fs_delete_walker(dav_walk_resource *wres, int calltype)
{
- dav_resource_private *info = ctx->resource->info;
+ dav_resource_private *info = wres->resource->info;
/* do not attempt to remove a null resource,
* or a collection with children
*/
- if (ctx->resource->exists &&
- (!ctx->resource->collection || calltype == DAV_CALLTYPE_POSTFIX)) {
+ if (wres->resource->exists &&
+ (!wres->resource->collection || calltype == DAV_CALLTYPE_POSTFIX)) {
/* try to remove the resource */
int result;
- result = ctx->resource->collection
+ result = wres->resource->collection
? rmdir(info->pathname)
: remove(info->pathname);
/* ### assume there is a permissions problem */
/* ### use errno to generate DAV:responsedescription? */
- dav_add_response(ctx, ctx->resource->uri, HTTP_FORBIDDEN, NULL);
+ dav_add_response(wres, HTTP_FORBIDDEN, NULL);
}
}
* including the state dirs
*/
if (resource->collection) {
- dav_walker_ctx ctx = { 0 };
+ dav_walker_ctx ctx = { { 0 } };
dav_error *err = NULL;
- ctx.walk_type = DAV_WALKTYPE_ALL | DAV_WALKTYPE_HIDDEN;
- ctx.postfix = 1;
- ctx.func = dav_fs_delete_walker;
- ctx.pool = info->pool;
- ctx.resource = resource;
-
- dav_buffer_init(info->pool, &ctx.uri, resource->uri);
+ ctx.w.walk_type = (DAV_WALKTYPE_ALL
+ | DAV_WALKTYPE_HIDDEN
+ | DAV_WALKTYPE_POSTFIX);
+ ctx.w.func = dav_fs_delete_walker;
+ ctx.w.walk_ctx = &ctx;
+ ctx.w.pool = info->pool;
+ ctx.w.root = resource;
if ((err = dav_fs_walk(&ctx, DAV_INFINITY)) != NULL) {
/* on a "real" error, then just punt. nothing else to do. */
* including lock-null resources as we go. */
static dav_error * dav_fs_walker(dav_fs_walker_context *fsctx, int depth)
{
+ const dav_walk_params *params = fsctx->params;
+ apr_pool_t *pool = params->pool;
dav_error *err = NULL;
- dav_walker_ctx *wctx = fsctx->wctx;
- int isdir = wctx->resource->collection;
+ int isdir = fsctx->res1.collection;
apr_dir_t *dirp;
/* ensure the context is prepared properly, then call the func */
- err = (*wctx->func)(wctx,
- isdir
- ? DAV_CALLTYPE_COLLECTION
- : DAV_CALLTYPE_MEMBER);
+ err = (*params->func)(&fsctx->wres,
+ isdir
+ ? DAV_CALLTYPE_COLLECTION
+ : DAV_CALLTYPE_MEMBER);
if (err != NULL) {
return err;
}
/* put a trailing slash onto the directory, in preparation for appending
* files to it as we discovery them within the directory */
- dav_check_bufsize(wctx->pool, &fsctx->path1, DAV_BUFFER_PAD);
+ dav_check_bufsize(pool, &fsctx->path1, DAV_BUFFER_PAD);
fsctx->path1.buf[fsctx->path1.cur_len++] = '/';
fsctx->path1.buf[fsctx->path1.cur_len] = '\0'; /* in pad area */
/* if a secondary path is present, then do that, too */
if (fsctx->path2.buf != NULL) {
- dav_check_bufsize(wctx->pool, &fsctx->path2, DAV_BUFFER_PAD);
+ dav_check_bufsize(pool, &fsctx->path2, DAV_BUFFER_PAD);
fsctx->path2.buf[fsctx->path2.cur_len++] = '/';
fsctx->path2.buf[fsctx->path2.cur_len] = '\0'; /* in pad area */
}
fsctx->res2.collection = 0;
/* open and scan the directory */
- if ((apr_opendir(&dirp, fsctx->path1.buf, wctx->pool)) != APR_SUCCESS) {
+ if ((apr_opendir(&dirp, fsctx->path1.buf, pool)) != APR_SUCCESS) {
/* ### need a better error */
- return dav_new_error(wctx->pool, HTTP_NOT_FOUND, 0, NULL);
+ return dav_new_error(pool, HTTP_NOT_FOUND, 0, NULL);
}
while ((apr_readdir(dirp)) == APR_SUCCESS) {
char *name;
continue;
}
- if (wctx->walk_type & DAV_WALKTYPE_AUTH) {
+ if (params->walk_type & DAV_WALKTYPE_AUTH) {
/* ### need to authorize each file */
/* ### example: .htaccess is normally configured to fail auth */
}
}
/* skip the state dir unless a HIDDEN is performed */
- if (!(wctx->walk_type & DAV_WALKTYPE_HIDDEN)
+ if (!(params->walk_type & DAV_WALKTYPE_HIDDEN)
&& !strcmp(name, DAV_FS_STATE_DIR)) {
continue;
}
/* append this file onto the path buffer (copy null term) */
- dav_buffer_place_mem(wctx->pool, &fsctx->path1, name, len + 1, 0);
+ dav_buffer_place_mem(pool, &fsctx->path1, name, len + 1, 0);
- if (apr_lstat(&fsctx->info1.finfo, fsctx->path1.buf, wctx->pool) != 0) {
+ if (apr_lstat(&fsctx->info1.finfo, fsctx->path1.buf, pool) != 0) {
/* woah! where'd it go? */
/* ### should have a better error here */
- err = dav_new_error(wctx->pool, HTTP_NOT_FOUND, 0, NULL);
+ err = dav_new_error(pool, HTTP_NOT_FOUND, 0, NULL);
break;
}
/* copy the file to the URI, too. NOTE: we will pad an extra byte
for the trailing slash later. */
- dav_buffer_place_mem(wctx->pool, &wctx->uri, name, len + 1, 1);
+ dav_buffer_place_mem(pool, &fsctx->uri_buf, name, len + 1, 1);
/* if there is a secondary path, then do that, too */
if (fsctx->path2.buf != NULL) {
- dav_buffer_place_mem(wctx->pool, &fsctx->path2, name, len + 1, 0);
+ dav_buffer_place_mem(pool, &fsctx->path2, name, len + 1, 0);
}
/* set up the (internal) pathnames for the two resources */
fsctx->info2.pathname = fsctx->path2.buf;
/* set up the URI for the current resource */
- fsctx->res1.uri = wctx->uri.buf;
+ fsctx->res1.uri = fsctx->uri_buf.buf;
/* ### for now, only process regular files (e.g. skip symlinks) */
if (fsctx->info1.finfo.filetype == APR_REG) {
/* call the function for the specified dir + file */
- if ((err = (*wctx->func)(wctx, DAV_CALLTYPE_MEMBER)) != NULL) {
+ if ((err = (*params->func)(&fsctx->wres,
+ DAV_CALLTYPE_MEMBER)) != NULL) {
/* ### maybe add a higher-level description? */
break;
}
}
else if (fsctx->info1.finfo.filetype == APR_DIR) {
size_t save_path_len = fsctx->path1.cur_len;
- size_t save_uri_len = wctx->uri.cur_len;
+ size_t save_uri_len = fsctx->uri_buf.cur_len;
size_t save_path2_len = fsctx->path2.cur_len;
/* adjust length to incorporate the subdir name */
fsctx->path2.cur_len += len;
/* adjust URI length to incorporate subdir and a slash */
- wctx->uri.cur_len += len + 1;
- wctx->uri.buf[wctx->uri.cur_len - 1] = '/';
- wctx->uri.buf[wctx->uri.cur_len] = '\0';
+ fsctx->uri_buf.cur_len += len + 1;
+ fsctx->uri_buf.buf[fsctx->uri_buf.cur_len - 1] = '/';
+ fsctx->uri_buf.buf[fsctx->uri_buf.cur_len] = '\0';
/* switch over to a collection */
fsctx->res1.collection = 1;
/* put the various information back */
fsctx->path1.cur_len = save_path_len;
fsctx->path2.cur_len = save_path2_len;
- wctx->uri.cur_len = save_uri_len;
+ fsctx->uri_buf.cur_len = save_uri_len;
fsctx->res1.collection = 0;
fsctx->res2.collection = 0;
if (err != NULL)
return err;
- if (wctx->walk_type & DAV_WALKTYPE_LOCKNULL) {
+ if (params->walk_type & DAV_WALKTYPE_LOCKNULL) {
size_t offset = 0;
/* null terminate the directory name */
** we don't have to pad the URI for a slash since a locknull
** resource is not a collection.
*/
- dav_buffer_place_mem(wctx->pool, &fsctx->path1,
+ dav_buffer_place_mem(pool, &fsctx->path1,
fsctx->locknull_buf.buf + offset, len + 1, 0);
- dav_buffer_place_mem(wctx->pool, &wctx->uri,
+ dav_buffer_place_mem(pool, &fsctx->uri_buf,
fsctx->locknull_buf.buf + offset, len + 1, 0);
if (fsctx->path2.buf != NULL) {
- dav_buffer_place_mem(wctx->pool, &fsctx->path2,
+ dav_buffer_place_mem(pool, &fsctx->path2,
fsctx->locknull_buf.buf + offset,
len + 1, 0);
}
fsctx->info2.pathname = fsctx->path2.buf;
/* set up the URI for the current resource */
- fsctx->res1.uri = wctx->uri.buf;
+ fsctx->res1.uri = fsctx->uri_buf.buf;
/*
** To prevent a PROPFIND showing an expired locknull
### even the resolve func would probably fail when it
### tried to find a timed-out direct lock).
*/
- if ((err = dav_lock_query(wctx->lockdb, wctx->resource, &locks)) != NULL) {
+ if ((err = dav_lock_query(params->lockdb, &fsctx->res1,
+ &locks)) != NULL) {
/* ### maybe add a higher-level description? */
return err;
}
/* call the function for the specified dir + file */
if (locks != NULL &&
- (err = (*wctx->func)(wctx, DAV_CALLTYPE_LOCKNULL)) != NULL) {
+ (err = (*params->func)(&fsctx->wres,
+ DAV_CALLTYPE_LOCKNULL)) != NULL) {
/* ### maybe add a higher-level description? */
return err;
}
fsctx->res1.exists = 1;
}
- if (wctx->postfix) {
+ if (params->walk_type & DAV_WALKTYPE_POSTFIX) {
/* replace the dirs' trailing slashes with null terms */
fsctx->path1.buf[--fsctx->path1.cur_len] = '\0';
- wctx->uri.buf[--wctx->uri.cur_len] = '\0';
+ fsctx->uri_buf.buf[--fsctx->uri_buf.cur_len] = '\0';
if (fsctx->path2.buf != NULL) {
fsctx->path2.buf[--fsctx->path2.cur_len] = '\0';
}
/* this is a collection which exists */
fsctx->res1.collection = 1;
- return (*wctx->func)(wctx, DAV_CALLTYPE_POSTFIX);
+ return (*params->func)(&fsctx->wres, DAV_CALLTYPE_POSTFIX);
}
return NULL;
static dav_error * dav_fs_walk(dav_walker_ctx *wctx, int depth)
{
+ const dav_walk_params *params = &wctx->w;
dav_fs_walker_context fsctx = { 0 };
+ dav_error *err;
#if DAV_DEBUG
- if ((wctx->walk_type & DAV_WALKTYPE_LOCKNULL) != 0
- && wctx->lockdb == NULL) {
- return dav_new_error(wctx->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+ if ((params->walk_type & DAV_WALKTYPE_LOCKNULL) != 0
+ && params->lockdb == NULL) {
+ return dav_new_error(params->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
"DESIGN ERROR: walker called to walk locknull "
"resources, but a lockdb was not provided.");
}
-
- /* ### an assertion that we have space for a trailing slash */
- if (wctx->uri.cur_len + 1 > wctx->uri.alloc_len) {
- return dav_new_error(wctx->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
- "DESIGN ERROR: walker should have been called "
- "with padding in the URI buffer.");
- }
#endif
- fsctx.wctx = wctx;
-
- wctx->root = wctx->resource;
+ fsctx.params = params;
+ fsctx.wres.walk_ctx = params->walk_ctx;
/* ### zero out versioned, working, baselined? */
- fsctx.res1 = *wctx->resource;
+ fsctx.res1 = *params->root;
fsctx.res1.info = &fsctx.info1;
- fsctx.info1 = *wctx->resource->info;
+ fsctx.info1 = *params->root->info;
- dav_buffer_init(wctx->pool, &fsctx.path1, fsctx.info1.pathname);
+ dav_buffer_init(params->pool, &fsctx.path1, fsctx.info1.pathname);
fsctx.info1.pathname = fsctx.path1.buf;
- if (wctx->res2 != NULL) {
- fsctx.res2 = *wctx->res2;
+ if (params->root_dst != NULL) {
+ fsctx.res2 = *params->root_dst;
fsctx.res2.exists = 0;
fsctx.res2.collection = 0;
fsctx.res2.info = &fsctx.info2;
- fsctx.info2 = *wctx->res2->info;
+ fsctx.info2 = *params->root_dst->info;
/* res2 does not exist -- clear its finfo structure */
memset(&fsctx.info2.finfo, 0, sizeof(fsctx.info2.finfo));
- dav_buffer_init(wctx->pool, &fsctx.path2, fsctx.info2.pathname);
+ dav_buffer_init(params->pool, &fsctx.path2, fsctx.info2.pathname);
fsctx.info2.pathname = fsctx.path2.buf;
}
+ /* prep the URI buffer */
+ dav_buffer_init(params->pool, &fsctx.uri_buf, params->root->uri);
+
/* if we have a directory, then ensure the URI has a trailing "/" */
if (fsctx.res1.collection
- && wctx->uri.buf[wctx->uri.cur_len - 1] != '/') {
+ && fsctx.uri_buf.buf[fsctx.uri_buf.cur_len - 1] != '/') {
/* this will fall into the pad area */
- wctx->uri.buf[wctx->uri.cur_len++] = '/';
- wctx->uri.buf[wctx->uri.cur_len] = '\0';
+ fsctx.uri_buf.buf[fsctx.uri_buf.cur_len++] = '/';
+ fsctx.uri_buf.buf[fsctx.uri_buf.cur_len] = '\0';
}
/*
** to fetch it from res2. We will ensure that res1 and uri will remain
** synchronized.
*/
- fsctx.res1.uri = wctx->uri.buf;
+ fsctx.res1.uri = fsctx.uri_buf.buf;
fsctx.res2.uri = NULL;
/* use our resource structures */
- wctx->resource = &fsctx.res1;
- wctx->res2 = &fsctx.res2;
+ fsctx.wres.resource = &fsctx.res1;
+ fsctx.wres.res_dst = &fsctx.res2;
- return dav_fs_walker(&fsctx, depth);
+ err = dav_fs_walker(&fsctx, depth);
+ wctx->response = fsctx.wres.response;
+ return err;
}
/* dav_fs_etag: Stolen from ap_make_etag. Creates a strong etag
}
/* ### move this to dav_util? */
-DAV_DECLARE(void) dav_add_response(dav_walker_ctx *ctx, const char *href,
+DAV_DECLARE(void) dav_add_response(dav_walk_resource *wres,
int status, dav_get_props_result *propstats)
{
+ dav_walker_ctx *ctx = wres->walk_ctx;
dav_response *resp;
/* just drop some data into an dav_response */
- resp = apr_pcalloc(ctx->pool, sizeof(*resp));
- resp->href = apr_pstrdup(ctx->pool, href);
+ resp = apr_pcalloc(ctx->w.pool, sizeof(*resp));
+ resp->href = apr_pstrdup(ctx->w.pool, wres->resource->uri);
resp->status = status;
if (propstats) {
resp->propresult = *propstats;
}
- resp->next = ctx->response;
- ctx->response = resp;
+ resp->next = wres->response;
+ wres->response = resp;
}
/* handle the DELETE method */
return;
}
- ap_text_append(ctx->pool, &hdr,
+ ap_text_append(ctx->w.pool, &hdr,
"<D:propstat>" DEBUG_CR
"<D:prop>" DEBUG_CR);
elem = dav_find_child(ctx->doc->root, "prop");
for (elem = elem->first_child; elem; elem = elem->next) {
- ap_text_append(ctx->pool, &hdr, ap_xml_empty_elem(ctx->pool, elem));
+ ap_text_append(ctx->w.pool, &hdr,
+ ap_xml_empty_elem(ctx->w.pool, elem));
}
- ap_text_append(ctx->pool, &hdr,
+ ap_text_append(ctx->w.pool, &hdr,
"</D:prop>" DEBUG_CR
"<D:status>HTTP/1.1 404 Not Found</D:status>" DEBUG_CR
"</D:propstat>" DEBUG_CR);
ctx->propstat_404 = hdr.first;
}
-static dav_error * dav_propfind_walker(dav_walker_ctx *ctx, int calltype)
+static dav_error * dav_propfind_walker(dav_walk_resource *wres, int calltype)
{
+ dav_walker_ctx *ctx = wres->walk_ctx;
dav_error *err;
dav_propdb *propdb;
dav_get_props_result propstats = { 0 };
** Note: we cast to lose the "const". The propdb won't try to change
** the resource, however, since we are opening readonly.
*/
- err = dav_open_propdb(ctx->r, ctx->lockdb,
- (dav_resource *)ctx->resource, 1,
+ err = dav_open_propdb(ctx->r, ctx->w.lockdb,
+ (dav_resource *)wres->resource, 1,
ctx->doc ? ctx->doc->namespaces : NULL, &propdb);
if (err != NULL) {
/* ### do something with err! */
/* some props were expected on this collection/resource */
dav_cache_badprops(ctx);
badprops.propstats = ctx->propstat_404;
- dav_add_response(ctx, ctx->uri.buf, 0, &badprops);
+ dav_add_response(wres, 0, &badprops);
}
else {
/* no props on this collection/resource */
- dav_add_response(ctx, ctx->uri.buf, HTTP_OK, NULL);
+ dav_add_response(wres, HTTP_OK, NULL);
}
return NULL;
}
}
dav_close_propdb(propdb);
- dav_add_response(ctx, ctx->uri.buf, 0, &propstats);
+ dav_add_response(wres, 0, &propstats);
return NULL;
}
int result;
ap_xml_doc *doc;
const ap_xml_elem *child;
- dav_walker_ctx ctx = { 0 };
+ dav_walker_ctx ctx = { { 0 } };
/* Ask repository module to resolve the resource */
result = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource);
return HTTP_BAD_REQUEST;
}
- ctx.walk_type = DAV_WALKTYPE_ALL | DAV_WALKTYPE_AUTH;
- ctx.func = dav_propfind_walker;
- ctx.pool = r->pool;
+ ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_AUTH;
+ ctx.w.func = dav_propfind_walker;
+ ctx.w.walk_ctx = &ctx;
+ ctx.w.pool = r->pool;
+ ctx.w.root = resource;
+
ctx.doc = doc;
ctx.r = r;
- ctx.resource = resource;
-
- dav_buffer_init(r->pool, &ctx.uri, r->uri);
/* ### should open read-only */
- if ((err = dav_open_lockdb(r, 0, &ctx.lockdb)) != NULL) {
+ if ((err = dav_open_lockdb(r, 0, &ctx.w.lockdb)) != NULL) {
err = dav_push_error(r->pool, err->status, 0,
"The lock database could not be opened, "
"preventing access to the various lock "
err);
return dav_handle_err(r, err, NULL);
}
- if (ctx.lockdb != NULL) {
+ if (ctx.w.lockdb != NULL) {
/* if we have a lock database, then we can walk locknull resources */
- ctx.walk_type |= DAV_WALKTYPE_LOCKNULL;
+ ctx.w.walk_type |= DAV_WALKTYPE_LOCKNULL;
}
err = (*resource->hooks->walk)(&ctx, depth);
- if (ctx.lockdb != NULL) {
- (*ctx.lockdb->hooks->close_lockdb)(ctx.lockdb);
+ if (ctx.w.lockdb != NULL) {
+ (*ctx.w.lockdb->hooks->close_lockdb)(ctx.w.lockdb);
}
if (err != NULL) {
*/
/* dav_lock_walker: Walker callback function to record indirect locks */
-static dav_error * dav_lock_walker(dav_walker_ctx *ctx, int calltype)
+static dav_error * dav_lock_walker(dav_walk_resource *wres, int calltype)
{
+ dav_walker_ctx *ctx = wres->walk_ctx;
dav_error *err;
/* We don't want to set indirects on the target */
- if ((*ctx->resource->hooks->is_same_resource)(ctx->resource, ctx->root))
+ if ((*wres->resource->hooks->is_same_resource)(wres->resource,
+ ctx->w.root))
return NULL;
- if ((err = (*ctx->lockdb->hooks->append_locks)(ctx->lockdb, ctx->resource,
- 1,
- ctx->lock)) != NULL) {
+ if ((err = (*ctx->w.lockdb->hooks->append_locks)(ctx->w.lockdb,
+ wres->resource, 1,
+ ctx->lock)) != NULL) {
if (ap_is_HTTP_SERVER_ERROR(err->status)) {
/* ### add a higher-level description? */
return err;
}
/* add to the multistatus response */
- dav_add_response(ctx, ctx->resource->uri, err->status, NULL);
+ dav_add_response(wres, err->status, NULL);
/*
** ### actually, this is probably wrong: we want to fail the whole
if (depth > 0) {
/* Walk existing collection and set indirect locks */
- dav_walker_ctx ctx = { 0 };
+ dav_walker_ctx ctx = { { 0 } };
+
+ ctx.w.walk_type = DAV_WALKTYPE_ALL | DAV_WALKTYPE_AUTH;
+ ctx.w.func = dav_lock_walker;
+ ctx.w.walk_ctx = &ctx;
+ ctx.w.pool = r->pool;
+ ctx.w.root = resource;
+ ctx.w.lockdb = lockdb;
- ctx.walk_type = DAV_WALKTYPE_ALL | DAV_WALKTYPE_AUTH;
- ctx.postfix = 0;
- ctx.func = dav_lock_walker;
- ctx.pool = r->pool;
ctx.r = r;
- ctx.resource = resource;
- ctx.lockdb = lockdb;
ctx.lock = lock;
- dav_buffer_init(r->pool, &ctx.uri, resource->uri);
-
err = (*resource->hooks->walk)(&ctx, DAV_INFINITY);
if (err != NULL) {
/* implies a 5xx status code occurred. screw the multistatus */
}
/* dav_unlock_walker: Walker callback function to remove indirect locks */
-static dav_error * dav_unlock_walker(dav_walker_ctx *ctx, int calltype)
+static dav_error * dav_unlock_walker(dav_walk_resource *wres, int calltype)
{
+ dav_walker_ctx *ctx = wres->walk_ctx;
dav_error *err;
- if ((err = (*ctx->lockdb->hooks->remove_lock)(ctx->lockdb, ctx->resource,
- ctx->locktoken)) != NULL) {
+ if ((err = (*ctx->w.lockdb->hooks->remove_lock)(ctx->w.lockdb,
+ wres->resource,
+ ctx->locktoken)) != NULL) {
/* ### should we stop or return a multistatus? looks like STOP */
/* ### add a higher-level description? */
return err;
}
if (lock_resource->collection) {
- dav_walker_ctx ctx = { 0 };
+ dav_walker_ctx ctx = { { 0 } };
+
+ ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_LOCKNULL;
+ ctx.w.func = dav_unlock_walker;
+ ctx.w.walk_ctx = &ctx;
+ ctx.w.pool = r->pool;
+ ctx.w.root = lock_resource;
+ ctx.w.lockdb = lockdb;
- ctx.walk_type = DAV_WALKTYPE_ALL | DAV_WALKTYPE_LOCKNULL;
- ctx.postfix = 0;
- ctx.func = dav_unlock_walker;
- ctx.pool = r->pool;
- ctx.resource = lock_resource;
ctx.r = r;
- ctx.lockdb = lockdb;
ctx.locktoken = locktoken;
- dav_buffer_init(r->pool, &ctx.uri, lock_resource->uri);
-
err = (*repos_hooks->walk)(&ctx, DAV_INFINITY);
/* ### fix this! */
}
/* dav_inherit_walker: Walker callback function to inherit locks */
-static dav_error * dav_inherit_walker(dav_walker_ctx *ctx, int calltype)
+static dav_error * dav_inherit_walker(dav_walk_resource *wres, int calltype)
{
+ dav_walker_ctx *ctx = wres->walk_ctx;
+
if (ctx->skip_root
- && (*ctx->resource->hooks->is_same_resource)(ctx->resource,
- ctx->root)) {
+ && (*wres->resource->hooks->is_same_resource)(wres->resource,
+ ctx->w.root)) {
return NULL;
}
/* ### maybe add a higher-level desc */
- return (*ctx->lockdb->hooks->append_locks)(ctx->lockdb, ctx->resource, 1,
- ctx->lock);
+ return (*ctx->w.lockdb->hooks->append_locks)(ctx->w.lockdb,
+ wres->resource, 1,
+ ctx->lock);
}
/*
dav_lock *locks;
dav_lock *scan;
dav_lock *prev;
- dav_walker_ctx ctx = { 0 };
+ dav_walker_ctx ctx = { { 0 } };
const dav_hooks_repository *repos_hooks = resource->hooks;
if (use_parent) {
/* <locks> has all our new locks. Walk down and propagate them. */
- ctx.walk_type = DAV_WALKTYPE_ALL | DAV_WALKTYPE_LOCKNULL;
- ctx.postfix = 0;
- ctx.func = dav_inherit_walker;
- ctx.pool = r->pool;
- ctx.resource = resource;
+ ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_LOCKNULL;
+ ctx.w.func = dav_inherit_walker;
+ ctx.w.walk_ctx = &ctx;
+ ctx.w.pool = r->pool;
+ ctx.w.root = resource;
+ ctx.w.lockdb = lockdb;
+
ctx.r = r;
- ctx.lockdb = lockdb;
ctx.lock = locks;
ctx.skip_root = !use_parent;
- dav_buffer_init(r->pool, &ctx.uri, resource->uri);
-
return (*repos_hooks->walk)(&ctx, DAV_INFINITY);
}