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

📄 lock.c

📁 最新apache的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	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_palloc(p, sizeof(*dp->locktoken));            memcpy(dp->locktoken, 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_lstat(&finfo, fname, APR_FINFO_MIN, 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_palloc(p, sizeof(*ip->locktoken));	    memcpy(ip->locktoken, 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_palloc(p, ip->key.dsize); 	    memcpy(ip->key.dptr, 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	"<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***//* ---------------------------------------------------------------**** Functions dealing with lock-null resources***//*** dav_fs_load_locknull_list:  Returns a dav_buffer dump of the locknull file**    for the given directory.*/static dav_error * dav_fs_load_locknull_list(apr_pool_t *p, const char *dirpath,					     dav_buffer *pbuf) {    apr_finfo_t finfo;    apr_file_t *file = NULL;    dav_error *err = NULL;    apr_size_t amt;    apr_status_t rv;    dav_buffer_init(p, pbuf, dirpath);    if (pbuf->buf[pbuf->cur_len - 1] == '/')	pbuf->buf[--pbuf->cur_len] = '\0';    dav_buffer_place(p, pbuf, "/" DAV_FS_STATE_DIR "/" DAV_FS_LOCK_NULL_FILE);    /* reset this in case we leave w/o reading into the buffer */    pbuf->cur_len = 0;    if (apr_file_open(&file, pbuf->buf, APR_READ | APR_BINARY, APR_OS_DEFAULT,                p) != APR_SUCCESS) {	return NULL;    }    rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, file);    if (rv != APR_SUCCESS) {	err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,			    apr_psprintf(p,					"Opened but could not stat file %s",					pbuf->buf));	goto loaderror;    }    if (finfo.size != (apr_size_t)finfo.size) {	err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,			    apr_psprintf(p,					"Opened but rejected huge file %s",					pbuf->buf));	goto loaderror;    }    amt = (apr_size_t)finfo.size;    dav_set_bufsize(p, pbuf, amt);    if (apr_file_read(file, pbuf->buf, &amt) != APR_SUCCESS        || amt != finfo.size) {	err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,			    apr_psprintf(p,					"Failure reading locknull file "					"for %s", dirpath));	/* just in case the caller disregards the returned error */	pbuf->cur_len = 0;	goto loaderror;    }  loaderror:    apr_file_close(file);    return err;}/*** dav_fs_save_locknull_list:  Saves contents of pbuf into the**    locknull file for dirpath.*/static dav_error * dav_fs_save_locknull_list(apr_pool_t *p, const char *dirpath,					     dav_buffer *pbuf){    const char *pathname;    apr_file_t *file = NULL;    dav_error *err = NULL;    apr_size_t amt;    if (pbuf->buf == NULL)	return NULL;    dav_fs_ensure_state_dir(p, dirpath);    pathname = apr_pstrcat(p,			  dirpath,			  dirpath[strlen(dirpath) - 1] == '/' ? "" : "/",			  DAV_FS_STATE_DIR "/" DAV_FS_LOCK_NULL_FILE,			  NULL);    if (pbuf->cur_len == 0) {	/* delete the file if cur_len == 0 */	if (apr_file_remove(pathname, p) != 0) {	    return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,				 apr_psprintf(p,					     "Error removing %s", pathname));	}	return NULL;    }    if (apr_file_open(&file, pathname,                APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BINARY,                APR_OS_DEFAULT, p) != APR_SUCCESS) {	return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,			     apr_psprintf(p,					 "Error opening %s for writing",					 pathname));    }    amt = pbuf->cur_len;    if (apr_file_write(file, pbuf->buf, &amt) != APR_SUCCESS        || amt != pbuf->cur_len) {	err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,			    apr_psprintf(p,					"Error writing %" APR_SIZE_T_FMT                                         " bytes to %s",					pbuf->cur_len, pathname));    }    apr_file_close(file);    return err;}/*** dav_fs_remove_locknull_member:  Removes filename from the locknull list**    for directory path.*/static dav_error * dav_fs_remove_locknull_member(apr_pool_t *p,                                                 const char *filename,						 dav_buffer *pbuf){    dav_error *err;    apr_size_t len;    apr_size_t scanlen;    char *scan;    const char *scanend;    char *dirpath = apr_pstrdup(p, filename);    char *fname = strrchr(dirpath, '/');    int dirty = 0;    if (fname != NULL)	*fname++ = '\0';    else	fname = dirpath;    len = strlen(fname) + 1;    if ((err = dav_fs_load_locknull_list(p, dirpath, pbuf)) != NULL) {	/* ### add a higher level description? */	return err;    }    for (scan = pbuf->buf, scanend = scan + pbuf->cur_len;	 scan < scanend;	 scan += scanlen) {	scanlen = strlen(scan) + 1;	if (len == scanlen && memcmp(fname, scan, scanlen) == 0) {	    pbuf->cur_len -= scanlen;	    memmove(scan, scan + scanlen, scanend - (scan + scanlen));	    dirty = 1;	    break;	}    }    if (dirty) {	if ((err = dav_fs_save_locknull_list(p, dirpath, pbuf)) != NULL) {	    /* ### add a higher level description? */	    return err;	}    }    return NULL;}/* Note: used by dav_fs_repos.c */dav_error * dav_fs_get_locknull_members(    const dav_resource *resource,    dav_buffer *pbuf){    const char *dirpath;    /* ### should test this result value... */    (void) dav_fs_dir_file_name(resource, &dirpath, NULL);    return dav_fs_load_locknull_list(dav_fs_pool(resource), dirpath, pbuf);}/* ### fold into append_lock? *//* ### take an optional buf parameter? */static dav_error * dav_fs_add_locknull_state(    dav_lockdb *lockdb,    const dav_resource *resource){    dav_buffer buf = { 0 };    apr_pool_t *p = lockdb->info->pool;    const char *dirpath;    const char *fname;    dav_error *err;    /* ### should test this result value... */    (void) dav_fs_dir_file_name(resource, &dirpath, &fname);    if ((err = dav_fs_load_locknull_list(p, dirpath, &buf)) != NULL) {        return dav_push_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,			      "Could not load .locknull file.", err);    }    dav_buffer_append(p, &buf, fname);    buf.cur_len++;	/* we want the null-term here */    if ((err = dav_fs_save_locknull_list(p, dirpath, &buf)) != NULL) {        return dav_push_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,			      "Could not save .locknull file.", err);    }    return NULL;}/*** dav_fs_remove_locknull_state:  Given a request, check to see if r->filename**    is/was a lock-null resource.  If so, return it to an existant state.****    ### this function is broken... it doesn't check!****    In this implementation, this involves two things:**    (a) remove it from the list in the appropriate .DAV/locknull file**    (b) on *nix, convert the key from a filename to an inode.*/static dav_error * dav_fs_remove_locknull_state(    dav_lockdb *lockdb,    const dav_resource *resource){    dav_buffer buf = { 0 };    dav_error *err;    apr_pool_t *p = lockdb->info->pool;    const char *pathname = dav_fs_pathname(resource);    if ((err = dav_fs_remove_locknull_member(p, pathname, &buf)) != NULL) {

⌨️ 快捷键说明

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