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

📄 lock.c

📁 linux网络服务器工具
💻 C
📖 第 1 页 / 共 4 页
字号:
{    apr_datum_t key;    /* ### 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_fs_build_key:  Given a resource, return a apr_datum_t key**    to look up lock information for this file.****    (inode/dev not supported or file is lock-null):**       apr_datum_t->dvalue = full path****    (inode/dev supported and file exists ):**       apr_datum_t->dvalue = inode, dev*/static apr_datum_t dav_fs_build_key(apr_pool_t *p,                                    const dav_resource *resource){    const char *file = dav_fs_pathname(resource);    apr_datum_t key;    apr_finfo_t finfo;    apr_status_t rv;    /* ### use lstat() ?? */    /*     * XXX: What for platforms with no IDENT (dev/inode)?     */    rv = apr_stat(&finfo, file, APR_FINFO_IDENT, p);    if ((rv == APR_SUCCESS || rv == APR_INCOMPLETE)        && ((finfo.valid & APR_FINFO_IDENT) == APR_FINFO_IDENT))    {        /* ### can we use a buffer for this? */        key.dsize = 1 + sizeof(finfo.inode) + sizeof(finfo.device);        key.dptr = apr_palloc(p, key.dsize);        *key.dptr = DAV_TYPE_INODE;        memcpy(key.dptr + 1, &finfo.inode, sizeof(finfo.inode));        memcpy(key.dptr + 1 + sizeof(finfo.inode), &finfo.device,               sizeof(finfo.device));        return key;    }    return dav_fs_build_fname_key(p, file);}/*** dav_fs_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_fs_lock_expired(time_t expires){    return expires != DAV_TIMEOUT_INFINITE && time(NULL) >= expires;}/*** dav_fs_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_fs_save_lock_record(dav_lockdb *lockdb, apr_datum_t key,                                           dav_lock_discovery *direct,                                           dav_lock_indirect *indirect){    dav_error *err;    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_fs_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? */        (void) dav_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) {        *ptr++ = DAV_LOCK_DIRECT;   /* Direct lock - lock_discovery struct follows */        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) {        *ptr++ = DAV_LOCK_INDIRECT;   /* Indirect lock prefix */        memcpy(ptr, ip->locktoken, sizeof(*ip->locktoken));   /* Locktoken */        ptr += sizeof(*ip->locktoken);        memcpy(ptr, &ip->timeout, sizeof(ip->timeout));   /* Expire time */        ptr += sizeof(ip->timeout);        memcpy(ptr, &ip->key.dsize, sizeof(ip->key.dsize));   /* Size of key */        ptr += sizeof(ip->key.dsize);        memcpy(ptr, ip->key.dptr, ip->key.dsize);   /* Key data */        ptr += ip->key.dsize;        ip = ip->next;    }    if ((err = dav_dbm_store(lockdb->info->db, key, val)) != NULL) {        /* ### more details? add an error_id? */        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_fs_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_size_t offset = 0;    int need_save = DAV_FALSE;    apr_datum_t val = { 0 };    dav_lock_discovery *dp;    dav_lock_indirect *ip;    dav_buffer buf = { 0 };    if (add_method != DAV_APPEND_LIST) {        *direct = NULL;        *indirect = NULL;    }    if ((err = dav_fs_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 ((err = dav_dbm_fetch(lockdb->info->db, key, &val)) != NULL)        return err;    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));            memcpy(dp, val.dptr + offset, sizeof(dp->f));            offset += sizeof(dp->f);            dp->locktoken = apr_pmemdup(p, val.dptr + offset, sizeof(*dp->locktoken));            offset += sizeof(*dp->locktoken);            if (*(val.dptr + offset) == '\0') {                ++offset;            }            else {                dp->owner = apr_pstrdup(p, val.dptr + offset);                offset += strlen(dp->owner) + 1;            }            if (*(val.dptr + offset) == '\0') {                ++offset;            }            else {                dp->auth_user = apr_pstrdup(p, val.dptr + offset);                offset += strlen(dp->auth_user) + 1;            }            if (!dav_fs_lock_expired(dp->f.timeout)) {                dp->next = *direct;                *direct = dp;            }            else {                need_save = DAV_TRUE;                /* Remove timed-out locknull fm .locknull list */                if (*key.dptr == DAV_TYPE_FNAME) {                    const char *fname = key.dptr + 1;                    apr_finfo_t finfo;                    apr_status_t rv;                    /* if we don't see the file, then it's a locknull */                    rv = apr_stat(&finfo, fname, APR_FINFO_MIN | APR_FINFO_LINK, p);                    if (rv != APR_SUCCESS && rv != APR_INCOMPLETE) {                        if ((err = dav_fs_remove_locknull_member(p, fname, &buf)) != NULL) {                            /* ### push a higher-level description? */                            return err;                        }                    }                }            }            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);            memcpy(&ip->key.dsize, val.dptr + offset, sizeof(ip->key.dsize)); /* length of datum */            offset += sizeof(ip->key.dsize);            ip->key.dptr = apr_pmemdup(p, val.dptr + offset, ip->key.dsize);            offset += ip->key.dsize;            if (!dav_fs_lock_expired(ip->timeout)) {                ip->next = *indirect;                *indirect = ip;            }            else {                need_save = DAV_TRUE;                /* A locknull resource will never be locked indirectly */            }            break;        default:            dav_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]));        }    }    dav_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_fs_save_lock_record(lockdb, key, *direct, *indirect);    }    return NULL;}/* 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,                         "The lock database was found to be corrupt. "                         "An indirect lock's direct lock could not "                         "be found.");}/* ---------------------------------------------------------------**** Property-related lock functions***//*** dav_fs_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_fs_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

⌨️ 快捷键说明

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