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

📄 locks.c

📁 linux网络服务器工具
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* ### does this allocation have a proper lifetime? need to check */    /* ### can we use a buffer for this? */    /* size is TYPE + pathname + null */    key.dsize = strlen(pathname) + 2;    key.dptr = apr_palloc(p, key.dsize);    *key.dptr = DAV_TYPE_FNAME;    memcpy(key.dptr + 1, pathname, key.dsize - 1);    if (key.dptr[key.dsize - 2] == '/')        key.dptr[--key.dsize - 1] = '\0';    return key;}/* * dav_generic_lock_expired:  return 1 (true) if the given timeout is in the *    past or present (the lock has expired), or 0 (false) if in the future *    (the lock has not yet expired). */static int dav_generic_lock_expired(time_t expires){    return expires != DAV_TIMEOUT_INFINITE && time(NULL) >= expires;}/* * dav_generic_save_lock_record:  Saves the lock information specified in the *    direct and indirect lock lists about path into the lock database. *    If direct and indirect == NULL, the key is removed. */static dav_error * dav_generic_save_lock_record(dav_lockdb *lockdb,                                                apr_datum_t key,                                                dav_lock_discovery *direct,                                                dav_lock_indirect *indirect){    dav_error *err;    apr_status_t status;    apr_datum_t val = { 0 };    char *ptr;    dav_lock_discovery *dp = direct;    dav_lock_indirect *ip = indirect;#if DAV_DEBUG    if (lockdb->ro) {        return dav_new_error(lockdb->info->pool,                             HTTP_INTERNAL_SERVER_ERROR, 0,                             "INTERNAL DESIGN ERROR: the lockdb was opened "                             "readonly, but an attempt to save locks was "                             "performed.");    }#endif    if ((err = dav_generic_really_open_lockdb(lockdb)) != NULL) {        /* ### add a higher-level error? */        return err;    }    /* If nothing to save, delete key */    if (dp == NULL && ip == NULL) {        /* don't fail if the key is not present */        /* ### but what about other errors? */        apr_dbm_delete(lockdb->info->db, key);        return NULL;    }    while(dp) {        val.dsize += dav_size_direct(dp);        dp = dp->next;    }    while(ip) {        val.dsize += dav_size_indirect(ip);        ip = ip->next;    }    /* ### can this be apr_palloc() ? */    /* ### hmmm.... investigate the use of a buffer here */    ptr = val.dptr = apr_pcalloc(lockdb->info->pool, val.dsize);    dp  = direct;    ip  = indirect;    while(dp) {        /* Direct lock - lock_discovery struct follows */        *ptr++ = DAV_LOCK_DIRECT;        memcpy(ptr, dp, sizeof(dp->f));        /* Fixed portion of struct */        ptr += sizeof(dp->f);        memcpy(ptr, dp->locktoken, sizeof(*dp->locktoken));        ptr += sizeof(*dp->locktoken);        if (dp->owner == NULL) {            *ptr++ = '\0';        }        else {            memcpy(ptr, dp->owner, strlen(dp->owner) + 1);            ptr += strlen(dp->owner) + 1;        }        if (dp->auth_user == NULL) {            *ptr++ = '\0';        }        else {            memcpy(ptr, dp->auth_user, strlen(dp->auth_user) + 1);            ptr += strlen(dp->auth_user) + 1;        }        dp = dp->next;    }    while(ip) {        /* Indirect lock prefix */        *ptr++ = DAV_LOCK_INDIRECT;        memcpy(ptr, ip->locktoken, sizeof(*ip->locktoken));        ptr += sizeof(*ip->locktoken);        memcpy(ptr, &ip->timeout, sizeof(ip->timeout));        ptr += sizeof(ip->timeout);        memcpy(ptr, &ip->key.dsize, sizeof(ip->key.dsize));        ptr += sizeof(ip->key.dsize);        memcpy(ptr, ip->key.dptr, ip->key.dsize);        ptr += ip->key.dsize;        ip = ip->next;    }    if ((status = apr_dbm_store(lockdb->info->db, key, val)) != APR_SUCCESS) {        /* ### more details? add an error_id? */        err = dav_generic_dbm_new_error(lockdb->info->db, lockdb->info->pool,                                        status);        return dav_push_error(lockdb->info->pool,                              HTTP_INTERNAL_SERVER_ERROR,                              DAV_ERR_LOCK_SAVE_LOCK,                              "Could not save lock information.",                              err);    }    return NULL;}/* * dav_load_lock_record:  Reads lock information about key from lock db; *    creates linked lists of the direct and indirect locks. * *    If add_method = DAV_APPEND_LIST, the result will be appended to the *    head of the direct and indirect lists supplied. * *    Passive lock removal:  If lock has timed out, it will not be returned. *    ### How much "logging" does RFC 2518 require? */static dav_error * dav_generic_load_lock_record(dav_lockdb *lockdb,                                                apr_datum_t key,                                                int add_method,                                                dav_lock_discovery **direct,                                                dav_lock_indirect **indirect){    apr_pool_t *p = lockdb->info->pool;    dav_error *err;    apr_status_t status;    apr_size_t offset = 0;    int need_save = DAV_FALSE;    apr_datum_t val = { 0 };    dav_lock_discovery *dp;    dav_lock_indirect *ip;    if (add_method != DAV_APPEND_LIST) {        *direct = NULL;        *indirect = NULL;    }    if ((err = dav_generic_really_open_lockdb(lockdb)) != NULL) {        /* ### add a higher-level error? */        return err;    }    /*     * If we opened readonly and the db wasn't there, then there are no     * locks for this resource. Just exit.     */    if (lockdb->info->db == NULL) {        return NULL;    }    if ((status = apr_dbm_fetch(lockdb->info->db, key, &val)) != APR_SUCCESS) {        return dav_generic_dbm_new_error(lockdb->info->db, p, status);    }    if (!val.dsize) {        return NULL;    }    while (offset < val.dsize) {        switch (*(val.dptr + offset++)) {        case DAV_LOCK_DIRECT:            /* Create and fill a dav_lock_discovery structure */            dp = apr_pcalloc(p, sizeof(*dp));            /* Copy the dav_lock_discovery_fixed portion */            memcpy(dp, val.dptr + offset, sizeof(dp->f));            offset += sizeof(dp->f);            /* Copy the lock token. */            dp->locktoken = apr_pmemdup(p, val.dptr + offset, sizeof(*dp->locktoken));            offset += sizeof(*dp->locktoken);            /* Do we have an owner field? */            if (*(val.dptr + offset) == '\0') {                ++offset;            }            else {                apr_size_t len = strlen(val.dptr + offset);                dp->owner = apr_pstrmemdup(p, val.dptr + offset, len);                offset += len + 1;            }            if (*(val.dptr + offset) == '\0') {                ++offset;            }            else {                apr_size_t len = strlen(val.dptr + offset);                dp->auth_user = apr_pstrmemdup(p, val.dptr + offset, len);                offset += len + 1;            }            if (!dav_generic_lock_expired(dp->f.timeout)) {                dp->next = *direct;                *direct = dp;            }            else {                need_save = DAV_TRUE;            }            break;        case DAV_LOCK_INDIRECT:            /* Create and fill a dav_lock_indirect structure */            ip = apr_pcalloc(p, sizeof(*ip));            ip->locktoken = apr_pmemdup(p, val.dptr + offset, sizeof(*ip->locktoken));            offset += sizeof(*ip->locktoken);            memcpy(&ip->timeout, val.dptr + offset, sizeof(ip->timeout));            offset += sizeof(ip->timeout);            /* length of datum */            ip->key.dsize = *((int *) (val.dptr + offset));            offset += sizeof(ip->key.dsize);            ip->key.dptr = apr_pmemdup(p, val.dptr + offset, ip->key.dsize);            offset += ip->key.dsize;            if (!dav_generic_lock_expired(ip->timeout)) {                ip->next = *indirect;                *indirect = ip;            }            else {                need_save = DAV_TRUE;            }            break;        default:            apr_dbm_freedatum(lockdb->info->db, val);            /* ### should use a computed_desc and insert corrupt token data */            --offset;            return dav_new_error(p,                                 HTTP_INTERNAL_SERVER_ERROR,                                 DAV_ERR_LOCK_CORRUPT_DB,                                 apr_psprintf(p,                                             "The lock database was found to "                                             "be corrupt. offset %"                                             APR_SIZE_T_FMT ", c=%02x",                                             offset, val.dptr[offset]));        }    }    apr_dbm_freedatum(lockdb->info->db, val);    /* Clean up this record if we found expired locks */    /*     * ### shouldn't do this if we've been opened READONLY. elide the     * ### timed-out locks from the response, but don't save that info back     */    if (need_save == DAV_TRUE) {        return dav_generic_save_lock_record(lockdb, key, *direct, *indirect);    }    return NULL;}/* resolve <indirect>, returning <*direct> */static dav_error * dav_generic_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_generic_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,                         "The lock database was found to be corrupt. "                         "An indirect lock's direct lock could not "                         "be found.");}/* --------------------------------------------------------------- * * Property-related lock functions * *//* * dav_generic_get_supportedlock:  Returns a static string for all *    supportedlock properties. I think we save more returning a static string *    than constructing it every time, though it might look cleaner. */static const char *dav_generic_get_supportedlock(const dav_resource *resource){    static const char supported[] = DEBUG_CR        "<D:lockentry>" DEBUG_CR        "<D:lockscope><D:exclusive/></D:lockscope>" DEBUG_CR        "<D:locktype><D:write/></D:locktype>" DEBUG_CR        "</D:lockentry>" DEBUG_CR        "<D:lockentry>" DEBUG_CR        "<D:lockscope><D:shared/></D:lockscope>" DEBUG_CR        "<D:locktype><D:write/></D:locktype>" DEBUG_CR        "</D:lockentry>" DEBUG_CR;    return supported;}/* --------------------------------------------------------------- * * General lock functions * */static dav_error * dav_generic_remove_locknull_state(dav_lockdb *lockdb,                                                 const dav_resource *resource){    /* We don't need to do anything. */    return NULL;}static dav_error * dav_generic_create_lock(dav_lockdb *lockdb,                                      const dav_resource *resource,                                      dav_lock **lock){    apr_datum_t key;    key = dav_generic_build_key(lockdb->info->pool, resource);    *lock = dav_generic_alloc_lock(lockdb, key, NULL);    (*lock)->is_locknull = !resource->exists;    return NULL;}static dav_error * dav_generic_get_locks(dav_lockdb *lockdb,                                         const dav_resource *resource,                                         int calltype,                                         dav_lock **locks){    apr_pool_t *p = lockdb->info->pool;    apr_datum_t key;    dav_error *err;    dav_lock *lock = NULL;    dav_lock *newlock;    dav_lock_discovery *dp;    dav_lock_indirect *ip;#if DAV_DEBUG    if (calltype == DAV_GETLOCKS_COMPLETE) {        return dav_new_error(lockdb->info->pool,                             HTTP_INTERNAL_SERVER_ERROR, 0,                             "INTERNAL DESIGN ERROR: DAV_GETLOCKS_COMPLETE "                             "is not yet supported");    }#endif    key = dav_generic_build_key(p, resource);    if ((err = dav_generic_load_lock_record(lockdb, key, DAV_CREATE_LIST,                                            &dp, &ip)) != NULL) {        /* ### push a higher-level desc? */

⌨️ 快捷键说明

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