⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util_lock.c

📁 Apache V2.0.15 Alpha For Linuxhttpd-2_0_15-alpha.tar.Z
💻 C
📖 第 1 页 / 共 2 页
字号:
{    dav_walker_ctx *ctx = wres->walk_ctx;    dav_error *err;    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;    }    return NULL;}/*** dav_get_direct_resource:**** Find a lock on the specified resource, then return the resource the** lock was applied to (in other words, given a (possibly) indirect lock,** return the direct lock's corresponding resource).**** If the lock is an indirect lock, this usually means traversing up the** namespace [repository] hierarchy. Note that some lock providers may be** able to return this information with a traversal.*/static dav_error * dav_get_direct_resource(apr_pool_t *p,					   dav_lockdb *lockdb,					   const dav_locktoken *locktoken,					   const dav_resource *resource,					   const dav_resource **direct_resource){    if (lockdb->hooks->lookup_resource != NULL) {	return (*lockdb->hooks->lookup_resource)(lockdb, locktoken,						 resource, direct_resource);    }    *direct_resource = NULL;    /* Find the top of this lock-     * If r->filename's direct   locks include locktoken, use r->filename.     * If r->filename's indirect locks include locktoken, retry r->filename/..     * Else fail.     */    while (resource != NULL) {	dav_error *err;	dav_lock *lock;        dav_resource *parent;	/*	** Find the lock specified by <locktoken> on <resource>. If it is	** an indirect lock, then partial results are okay. We're just	** trying to find the thing and know whether it is a direct or	** an indirect lock.	*/	if ((err = (*lockdb->hooks->find_lock)(lockdb, resource, locktoken,					       1, &lock)) != NULL) {	    /* ### add a higher-level desc? */	    return err;	}	/* not found! that's an error. */	if (lock == NULL) {	    return dav_new_error(p, HTTP_BAD_REQUEST, 0,				 "The specified locktoken does not correspond "				 "to an existing lock on this resource.");	}	if (lock->rectype == DAV_LOCKREC_DIRECT) {	    /* we found the direct lock. return this resource. */	    *direct_resource = resource;	    return NULL;	}	/* the lock was indirect. move up a level in the URL namespace */	if ((err = (*resource->hooks->get_parent_resource)(resource,                                                           &parent)) != NULL) {            /* ### add a higher-level desc? */            return err;        }        resource = parent;    }    return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,			 "The lock database is corrupt. A direct lock could "			 "not be found for the corresponding indirect lock "			 "on this resource.");}/*** dav_unlock:  Removes all direct and indirect locks for r->filename,**    with given locktoken.  If locktoken == null_locktoken, all locks**    are removed.  If r->filename represents an indirect lock,**    we must unlock the appropriate direct lock.**    Returns OK or appropriate HTTP_* response and logs any errors.**** ### We've already crawled the tree to ensure everything was locked**     by us; there should be no need to incorporate a rollback.*/int dav_unlock(request_rec *r, const dav_resource *resource,	       const dav_locktoken *locktoken){    int result;    dav_lockdb *lockdb;    const dav_resource *lock_resource = resource;    const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r);    const dav_hooks_repository *repos_hooks = resource->hooks;    dav_error *err;    /* If no locks provider, then there is nothing to unlock. */    if (hooks == NULL) {        return OK;    }    /* 2518 requires the entire lock to be removed if resource/locktoken     * point to an indirect lock.  We need resource of the _direct_     * lock in order to walk down the tree and remove the locks.  So,     * If locktoken != null_locktoken,      *    Walk up the resource hierarchy until we see a direct lock.     *    Or, we could get the direct lock's db/key, pick out the URL     *    and do a subrequest.  I think walking up is faster and will work     *    all the time.     * Else     *    Just start removing all locks at and below resource.     */    if ((err = (*hooks->open_lockdb)(r, 0, 1, &lockdb)) != NULL) {	/* ### return err! maybe add a higher-level desc */	/* ### map result to something nice; log an error */	return HTTP_INTERNAL_SERVER_ERROR;    }    if (locktoken != NULL	&& (err = dav_get_direct_resource(r->pool, lockdb,					  locktoken, resource,					  &lock_resource)) != NULL) {	/* ### add a higher-level desc? */	/* ### should return err! */	return err->status;    }    /* At this point, lock_resource/locktoken refers to a direct lock (key), ie     * the root of a depth > 0 lock, or locktoken is null.     */    if ((err = (*hooks->remove_lock)(lockdb, lock_resource,				     locktoken)) != NULL) {	/* ### add a higher-level desc? */	/* ### return err! */	return HTTP_INTERNAL_SERVER_ERROR;    }    if (lock_resource->collection) {        dav_walker_ctx ctx = { { 0 } };        dav_response *multi_status;	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.r = r;	ctx.locktoken = locktoken;	err = (*repos_hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status);	/* ### fix this! */        /* ### do something with multi_status */	result = err == NULL ? OK : err->status;    }    else	result = OK;    (*hooks->close_lockdb)(lockdb);    return result;}/* dav_inherit_walker:  Walker callback function to inherit locks */static dav_error * dav_inherit_walker(dav_walk_resource *wres, int calltype){    dav_walker_ctx *ctx = wres->walk_ctx;    if (ctx->skip_root	&& (*wres->resource->hooks->is_same_resource)(wres->resource,                                                      ctx->w.root)) {	return NULL;    }    /* ### maybe add a higher-level desc */    return (*ctx->w.lockdb->hooks->append_locks)(ctx->w.lockdb,                                                 wres->resource, 1,                                                 ctx->lock);}/*** dav_inherit_locks:  When a resource or collection is added to a collection,**    locks on the collection should be inherited to the resource/collection.**    (MOVE, MKCOL, etc) Here we propagate any direct or indirect locks from**    parent of resource to resource and below.*/static dav_error * dav_inherit_locks(request_rec *r, dav_lockdb *lockdb,				     const dav_resource *resource,				     int use_parent){    dav_error *err;    const dav_resource *which_resource;    dav_lock *locks;    dav_lock *scan;    dav_lock *prev;    dav_walker_ctx ctx = { { 0 } };    const dav_hooks_repository *repos_hooks = resource->hooks;    dav_response *multi_status;    if (use_parent) {        dav_resource *parent;	if ((err = (*repos_hooks->get_parent_resource)(resource,                                                       &parent)) != NULL) {            /* ### add a higher-level desc? */            return err;        }	if (parent == NULL) {	    /* ### map result to something nice; log an error */	    return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,				 "Could not fetch parent resource. Unable to "				 "inherit locks from the parent and apply "				 "them to this resource.");	}        which_resource = parent;    }    else {	which_resource = resource;    }    if ((err = (*lockdb->hooks->get_locks)(lockdb, which_resource,					   DAV_GETLOCKS_PARTIAL,					   &locks)) != NULL) {	/* ### maybe add a higher-level desc */	return err;    }    if (locks == NULL) {	/* No locks to propagate, just return */	return NULL;    }    /*    ** (1) Copy all indirect locks from our parent;    ** (2) Create indirect locks for the depth infinity, direct locks    **     in our parent.    **    ** The append_locks call in the walker callback will do the indirect    ** conversion, but we need to remove any direct locks that are NOT    ** depth "infinity".    */    for (scan = locks, prev = NULL;	 scan != NULL;	 prev = scan, scan = scan->next) {	if (scan->rectype == DAV_LOCKREC_DIRECT	    && scan->depth != DAV_INFINITY) {	    if (prev == NULL)		locks = scan->next;	    else		prev->next = scan->next;	}    }    /* <locks> has all our new locks.  Walk down and propagate them. */    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.lock = locks;    ctx.skip_root = !use_parent;    /* ### do something with multi_status */    return (*repos_hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status);}/* ---------------------------------------------------------------**** Functions dealing with lock-null resources***//*** dav_get_resource_state:  Returns the state of the resource**    r->filename:  DAV_RESOURCE_NULL, DAV_RESOURCE_LOCK_NULL,**    or DAV_RESOURCE_EXIST.****    Returns DAV_RESOURCE_ERROR if an error occurs.*/int dav_get_resource_state(request_rec *r, const dav_resource *resource){    const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r);    if (resource->exists)	return DAV_RESOURCE_EXISTS;    if (hooks != NULL) {	dav_error *err;	dav_lockdb *lockdb;	int locks_present;	/*	** A locknull resource has the form:	**	**   known-dir "/" locknull-file	**	** It would be nice to look into <resource> to verify this form,	** but it does not have enough information for us. Instead, we	** can look at the path_info. If the form does not match, then	** there is no way we could have a locknull resource -- it must	** be a plain, null resource.	**	** Apache sets r->filename to known-dir/unknown-file and r->path_info	** to "" for the "proper" case. If anything is in path_info, then	** it can't be a locknull resource.	**	** ### I bet this path_info hack doesn't work for repositories.	** ### Need input from repository implementors! What kind of	** ### restructure do we need? New provider APIs?	*/	if (r->path_info != NULL && *r->path_info != '\0') {	    return DAV_RESOURCE_NULL;	}	        if ((err = (*hooks->open_lockdb)(r, 1, 1, &lockdb)) == NULL) {	    /* note that we might see some expired locks... *shrug* */	    err = (*hooks->has_locks)(lockdb, resource, &locks_present);	    (*hooks->close_lockdb)(lockdb);        }        if (err != NULL) {	    /* ### don't log an error. return err. add higher-level desc. */	    ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r,		          "Failed to query lock-null status for %s",			  r->filename);	    return DAV_RESOURCE_ERROR;        }	if (locks_present)	    return DAV_RESOURCE_LOCK_NULL;    }    return DAV_RESOURCE_NULL;}dav_error * dav_notify_created(request_rec *r,			       dav_lockdb *lockdb,			       const dav_resource *resource,			       int resource_state,			       int depth){    dav_error *err;    if (resource_state == DAV_RESOURCE_LOCK_NULL) {	/*	** The resource is no longer a locknull resource. This will remove	** the special marker.	**	** Note that a locknull resource has already inherited all of the	** locks from the parent. We do not need to call dav_inherit_locks.	**	** NOTE: some lock providers record locks for locknull resources using	**       a different key than for regular resources. this will shift	**       the lock information between the two key types.	*/	(void)(*lockdb->hooks->remove_locknull_state)(lockdb, resource);	/*	** There are resources under this one, which are new. We must	** propagate the locks down to the new resources.	*/	if (depth > 0 &&	    (err = dav_inherit_locks(r, lockdb, resource, 0)) != NULL) {	    /* ### add a higher level desc? */	    return err;	}    }    else if (resource_state == DAV_RESOURCE_NULL) {	/* ### should pass depth to dav_inherit_locks so that it can	** ### optimize for the depth==0 case.	*/	/* this resource should inherit locks from its parent */	if ((err = dav_inherit_locks(r, lockdb, resource, 1)) != NULL) {	    err = dav_push_error(r->pool, err->status, 0,				 "The resource was created successfully, but "				 "there was a problem inheriting locks from "				 "the parent resource.",				 err);	    return err;	}    }    /* else the resource already exists and its locks are correct. */    return NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -