/* ** 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_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, i.e. ** remove it from the list in the appropriate .DAV/locknull file. */ 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; } 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; pool *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; } #ifndef WIN32 { dav_lock_discovery *ld; dav_lock_indirect *id; dav_datum 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; } } #endif return NULL; }
/* ** dav_fs_build_key: Given a resource, return a apr_datum_t key ** to look up lock information for this file. */ static apr_datum_t dav_fs_build_key(apr_pool_t *p, const dav_resource *resource) { const char *pathname = dav_fs_pathname(resource); 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 dav_datum key ** to look up lock information for this file. ** ** (Win32 or file is lock-null): ** dav_datum->dvalue = full path ** ** (non-Win32 and file exists ): ** dav_datum->dvalue = inode, dev_major, dev_minor */ static dav_datum dav_fs_build_key(pool *p, const dav_resource *resource) { const char *file = dav_fs_pathname(resource); #ifndef WIN32 dav_datum key; struct stat finfo; /* ### use lstat() ?? */ if (stat(file, &finfo) == 0) { /* ### can we use a buffer for this? */ key.dsize = 1 + sizeof(finfo.st_ino) + sizeof(finfo.st_dev); key.dptr = ap_palloc(p, key.dsize); *key.dptr = DAV_TYPE_INODE; memcpy(key.dptr + 1, &finfo.st_ino, sizeof(finfo.st_ino)); memcpy(key.dptr + 1 + sizeof(finfo.st_ino), &finfo.st_dev, sizeof(finfo.st_dev)); return key; } #endif return dav_fs_build_fname_key(p, file); }
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; }