📄 lock.c
字号:
"<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) { /* ### add a higher-level description? */ return err; } { dav_lock_discovery *ld; dav_lock_indirect *id; apr_datum_t key; /* ** Fetch the lock(s) that made the resource lock-null. Remove ** them under the filename key. Obtain the new inode key, and ** save the same lock information under it. */ key = dav_fs_build_fname_key(p, pathname); if ((err = dav_fs_load_lock_record(lockdb, key, DAV_CREATE_LIST, &ld, &id)) != NULL) { /* ### insert a higher-level error description */ return err; } if ((err = dav_fs_save_lock_record(lockdb, key, NULL, NULL)) != NULL) { /* ### insert a higher-level error description */ return err; } key = dav_fs_build_key(p, resource); if ((err = dav_fs_save_lock_record(lockdb, key, ld, id)) != NULL) { /* ### insert a higher-level error description */ return err; } } return NULL;}static dav_error * dav_fs_create_lock(dav_lockdb *lockdb, const dav_resource *resource, dav_lock **lock){ apr_datum_t key; key = dav_fs_build_key(lockdb->info->pool, resource); *lock = dav_fs_alloc_lock(lockdb, key, NULL); (*lock)->is_locknull = !resource->exists; return NULL;}static dav_error * dav_fs_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_fs_build_key(p, resource); if ((err = dav_fs_load_lock_record(lockdb, key, DAV_CREATE_LIST, &dp, &ip)) != NULL) { /* ### push a higher-level desc? */ return err; } /* copy all direct locks to the result list */ for (; dp != NULL; dp = dp->next) { newlock = dav_fs_alloc_lock(lockdb, key, dp->locktoken); newlock->is_locknull = !resource->exists; newlock->scope = dp->f.scope; newlock->type = dp->f.type; newlock->depth = dp->f.depth; newlock->timeout = dp->f.timeout; newlock->owner = dp->owner; newlock->auth_user = dp->auth_user; /* hook into the result list */ newlock->next = lock; lock = newlock; } /* copy all the indirect locks to the result list. resolve as needed. */ for (; ip != NULL; ip = ip->next) { newlock = dav_fs_alloc_lock(lockdb, ip->key, ip->locktoken); newlock->is_locknull = !resource->exists; if (calltype == DAV_GETLOCKS_RESOLVED) { if ((err = dav_fs_resolve(lockdb, ip, &dp, NULL, NULL)) != NULL) { /* ### push a higher-level desc? */ return err; } newlock->scope = dp->f.scope; newlock->type = dp->f.type; newlock->depth = dp->f.depth; newlock->timeout = dp->f.timeout; newlock->owner = dp->owner; newlock->auth_user = dp->auth_user; } else { /* DAV_GETLOCKS_PARTIAL */ newlock->rectype = DAV_LOCKREC_INDIRECT_PARTIAL; } /* hook into the result list */ newlock->next = lock; lock = newlock; } *locks = lock; return NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -