예제 #1
0
파일: locks.c 프로젝트: CHINAANSHE/apache
static dav_error * dav_generic_remove_lock(dav_lockdb *lockdb,
                                           const dav_resource *resource,
                                           const dav_locktoken *locktoken)
{
    dav_error *err;
    dav_lock_discovery *dh = NULL;
    dav_lock_indirect *ih = NULL;
    apr_datum_t key;

    key = dav_generic_build_key(lockdb->info->pool, resource);

    if (locktoken != NULL) {
        dav_lock_discovery *dp;
        dav_lock_discovery *dprev = NULL;
        dav_lock_indirect *ip;
        dav_lock_indirect *iprev = NULL;

        if ((err = dav_generic_load_lock_record(lockdb, key, DAV_CREATE_LIST,
                                           &dh, &ih)) != NULL) {
            /* ### maybe add a higher-level description */
            return err;
        }

        for (dp = dh; dp != NULL; dp = dp->next) {
            if (dav_compare_locktoken(locktoken, dp->locktoken) == 0) {
                if (dprev)
                    dprev->next = dp->next;
                else
                    dh = dh->next;
            }
            dprev = dp;
        }

        for (ip = ih; ip != NULL; ip = ip->next) {
            if (dav_compare_locktoken(locktoken, ip->locktoken) == 0) {
                if (iprev)
                    iprev->next = ip->next;
                else
                    ih = ih->next;
            }
            iprev = ip;
        }

    }

    /* save the modified locks, or remove all locks (dh=ih=NULL). */
    if ((err = dav_generic_save_lock_record(lockdb, key, dh, ih)) != NULL) {
        /* ### maybe add a higher-level description */
        return err;
    }

    return NULL;
}
예제 #2
0
static int dav_fs_do_refresh(dav_lock_discovery *dp,
			     const dav_locktoken_list *ltl,
			     time_t new_time)
{
    int dirty = 0;

    for (; ltl != NULL; ltl = ltl->next) {
	if (dav_compare_locktoken(dp->locktoken, ltl->locktoken) == 0)
	{
	    dp->f.timeout = new_time;
	    dirty = 1;
	}
    }

    return dirty;
}
/* resolve <indirect>, returning <*direct> */
static dav_error * dav_fs_resolve(dav_lockdb *lockdb,
                                  dav_lock_indirect *indirect,
                                  dav_lock_discovery **direct,
                                  dav_lock_discovery **ref_dp,
                                  dav_lock_indirect **ref_ip)
{
    dav_error *err;
    dav_lock_discovery *dir;
    dav_lock_indirect *ind;

    if ((err = dav_fs_load_lock_record(lockdb, indirect->key,
                                       DAV_CREATE_LIST,
                                       &dir, &ind)) != NULL) {
        /* ### insert a higher-level description? */
        return err;
    }
    if (ref_dp != NULL) {
        *ref_dp = dir;
        *ref_ip = ind;
    }

    for (; dir != NULL; dir = dir->next) {
        if (!dav_compare_locktoken(indirect->locktoken, dir->locktoken)) {
            *direct = dir;
            return NULL;
        }
    }

    /* No match found (but we should have found one!) */

    /* ### use a different description and/or error ID? */
    return dav_new_error(lockdb->info->pool,
                         HTTP_INTERNAL_SERVER_ERROR,
                         DAV_ERR_LOCK_CORRUPT_DB, 0,
                         "The lock database was found to be corrupt. "
                         "An indirect lock's direct lock could not "
                         "be found.");
}
/*
** dav_fs_compare_locktoken
**
** Determine whether two locktokens are the same
*/
static int dav_fs_compare_locktoken(
    const dav_locktoken *lt1,
    const dav_locktoken *lt2)
{
    return dav_compare_locktoken(lt1, lt2);
}
static dav_error * dav_fs_remove_lock(dav_lockdb *lockdb,
                                      const dav_resource *resource,
                                      const dav_locktoken *locktoken)
{
    dav_error *err;
    dav_buffer buf = { 0 };
    dav_lock_discovery *dh = NULL;
    dav_lock_indirect *ih = NULL;
    apr_datum_t key;

    key = dav_fs_build_key(lockdb->info->pool, resource);

    if (locktoken != NULL) {
        dav_lock_discovery *dp;
        dav_lock_discovery *dprev = NULL;
        dav_lock_indirect *ip;
        dav_lock_indirect *iprev = NULL;

        if ((err = dav_fs_load_lock_record(lockdb, key, DAV_CREATE_LIST,
                                           &dh, &ih)) != NULL) {
            /* ### maybe add a higher-level description */
            return err;
        }

        for (dp = dh; dp != NULL; dp = dp->next) {
            if (dav_compare_locktoken(locktoken, dp->locktoken) == 0) {
                if (dprev)
                    dprev->next = dp->next;
                else
                    dh = dh->next;
            }
            dprev = dp;
        }

        for (ip = ih; ip != NULL; ip = ip->next) {
            if (dav_compare_locktoken(locktoken, ip->locktoken) == 0) {
                if (iprev)
                    iprev->next = ip->next;
                else
                    ih = ih->next;
            }
            iprev = ip;
        }

    }

    /* save the modified locks, or remove all locks (dh=ih=NULL). */
    if ((err = dav_fs_save_lock_record(lockdb, key, dh, ih)) != NULL) {
        /* ### maybe add a higher-level description */
        return err;
    }

    /*
    ** If this resource is a locknull resource AND no more locks exist,
    ** then remove the locknull member.
    **
    ** Note: remove_locknull_state() attempts to convert a locknull member
    **       to a real member. In this case, all locks are gone, so the
    **       locknull resource returns to the null state (ie. doesn't exist),
    **       so there is no need to update the lockdb (and it won't find
    **       any because a precondition is that none exist).
    */
    if (!resource->exists && dh == NULL && ih == NULL
        && (err = dav_fs_remove_locknull_member(lockdb->info->pool,
                                                dav_fs_pathname(resource),
                                                &buf)) != NULL) {
        /* ### maybe add a higher-level description */
        return err;
    }

    return NULL;
}
static dav_error * dav_fs_find_lock(dav_lockdb *lockdb,
                                    const dav_resource *resource,
                                    const dav_locktoken *locktoken,
                                    int partial_ok,
                                    dav_lock **lock)
{
    dav_error *err;
    apr_datum_t key;
    dav_lock_discovery *dp;
    dav_lock_indirect *ip;

    *lock = NULL;

    key = dav_fs_build_key(lockdb->info->pool, resource);
    if ((err = dav_fs_load_lock_record(lockdb, key, DAV_CREATE_LIST,
                                       &dp, &ip)) != NULL) {
        /* ### push a higher-level desc? */
        return err;
    }

    for (; dp != NULL; dp = dp->next) {
        if (!dav_compare_locktoken(locktoken, dp->locktoken)) {
            *lock = dav_fs_alloc_lock(lockdb, key, locktoken);
            (*lock)->is_locknull = !resource->exists;
            (*lock)->scope = dp->f.scope;
            (*lock)->type = dp->f.type;
            (*lock)->depth = dp->f.depth;
            (*lock)->timeout = dp->f.timeout;
            (*lock)->owner = dp->owner;
            (*lock)->auth_user = dp->auth_user;
            return NULL;
        }
    }

    for (; ip != NULL; ip = ip->next) {
        if (!dav_compare_locktoken(locktoken, ip->locktoken)) {
            *lock = dav_fs_alloc_lock(lockdb, ip->key, locktoken);
            (*lock)->is_locknull = !resource->exists;

            /* ### nobody uses the resolving right now! */
            if (partial_ok) {
                (*lock)->rectype = DAV_LOCKREC_INDIRECT_PARTIAL;
            }
            else {
                (*lock)->rectype = DAV_LOCKREC_INDIRECT;
                if ((err = dav_fs_resolve(lockdb, ip, &dp,
                                          NULL, NULL)) != NULL) {
                    /* ### push a higher-level desc? */
                    return err;
                }
                (*lock)->scope = dp->f.scope;
                (*lock)->type = dp->f.type;
                (*lock)->depth = dp->f.depth;
                (*lock)->timeout = dp->f.timeout;
                (*lock)->owner = dp->owner;
                (*lock)->auth_user = dp->auth_user;
            }
            return NULL;
        }
    }

    return NULL;
}