Roxen.git / server / base_server / module.pike

version» Context lines:

Roxen.git/server/base_server/module.pike:821:    foreach (prefix_locks; PATH; LOCKS) {CODE;} \    } while (0)      //! Find some or all locks that apply to @[path].   //!   //! @param path   //! Normalized path below the filesystem location.   //!   //! @param recursive   //! If @expr{1@} also return locks anywhere below @[path]. + //! If @expr{-1} return locks anywhere below @[path], but not + //! any above @[path]. (This is appropriate to use to get the + //! list of locks that need to be unlocked on DELETE.)   //!   //! @param exclude_shared   //! If @expr{1@} do not return shared locks that are held by users   //! other than the one the request is authenticated as. (This is   //! appropriate to get the list of locks that would conflict if the   //! current user were to make a shared lock.)   //!   //! @returns   //! Returns a multiset containing all applicable locks in   //! this location module, or @expr{0@} (zero) if there are none.   //!   //! @note   //! @[DAVLock] objects may be created if the filesystem has some   //! persistent storage of them. The default implementation does not   //! store locks persistently.   //!   //! @note   //! The default implementation only handles the @expr{"DAV:write"@}   //! lock type.   multiset(DAVLock) find_locks(string path, -  int(0..1) recursive, +  int(-1..1) recursive,    int(0..1) exclude_shared,    RequestID id)   {    // Common case.    if (!sizeof(file_locks) && !sizeof(prefix_locks)) return 0;       TRACE_ENTER(sprintf("find_locks(%O, %O, %O, X)",    path, recursive, exclude_shared), this);       string rsc = resource_id (path, id);
Roxen.git/server/base_server/module.pike:874:    }    else    add_locks = lambda (mapping(mixed:DAVLock) sub_locks) {    locks |= mkmultiset (values (sub_locks));    };       if (file_locks[rsc]) {    add_locks (file_locks[rsc]);    }    +  if (recursive >= 0) {    foreach(prefix_locks;    string prefix; mapping(mixed:DAVLock) sub_locks) {    if (has_prefix(rsc, prefix)) {    add_locks (sub_locks);    break;    }    } -  +  }       if (recursive) {    LOOP_OVER_BOTH (string prefix, mapping(mixed:DAVLock) sub_locks, {    if (has_prefix(prefix, rsc)) {    add_locks (sub_locks);    }    });    }       add_locks = 0;
Roxen.git/server/base_server/module.pike:1112:   {    TRACE_ENTER(sprintf("unregister_lock(%O, lock(%O), X).", path, lock->locktoken),    this);    mixed auth_user = id && authenticated_user_id (path, id);    path = resource_id (path, id);    DAVLock removed_lock;    if (lock->recursive) {    if (id) {    removed_lock = m_delete(prefix_locks[path], auth_user);    } else { -  foreach(prefix_locks[path]; mixed user; DAVLock l) { +  foreach(prefix_locks[path]||([]); mixed user; DAVLock l) {    if (l == lock) {    removed_lock = m_delete(prefix_locks[path], user);    }    }    }    if (!sizeof (prefix_locks[path])) m_delete (prefix_locks, path);    }    else if (file_locks[path]) {    if (id) {    removed_lock = m_delete (file_locks[path], auth_user);    } else { -  foreach(file_locks[path]; mixed user; DAVLock l) { +  foreach(file_locks[path]||([]); mixed user; DAVLock l) {    if (l == lock) {    removed_lock = m_delete(file_locks[path], user);    }    }    }    if (!sizeof (file_locks[path])) m_delete (file_locks, path);    } -  ASSERT_IF_DEBUG (lock /*%O*/ == removed_lock /*%O*/, lock, removed_lock); +  // NB: The lock may have already been removed in the !id case. +  ASSERT_IF_DEBUG (!(id || removed_lock) || +  (lock /*%O*/ == removed_lock /*%O*/), +  lock, removed_lock);    TRACE_LEAVE("Ok.");    return 0;   }      //! Register @[lock] on the path @[path] under the assumption that   //! there is no other lock already that conflicts with this one, i.e.   //! that @expr{check_locks(path,lock->recursive,id)@} would return   //! @expr{LOCK_NONE@} if @expr{lock->lockscope@} is   //! @expr{"DAV:exclusive"@}, or @expr{<= LOCK_SHARED_AT@} if   //! @expr{lock->lockscope@} is @expr{"DAV:shared"@}.
Roxen.git/server/base_server/module.pike:1365:   //! write access to @[path]. It should at least call   //! @[check_if_header] to check DAV locks. It takes the same arguments   //! and has the same return value as that function.   //!   //! WARNING: This function has some design issues and will very likely   //! get a different interface. Compatibility is NOT guaranteed.   //!   //! A filesystem module should typically put all needed write access   //! checks here and then use this from @[find_file()],   //! @[delete_file()] etc. + //! + //! @returns + //! Returns @expr{0@} (zero) on success, a status mapping on + //! failure, or @expr{1@} if @[recursive] is set and write access is + //! allowed on this level but maybe not somewhere below. The caller + //! should in the last case do the operation on this level if + //! possible and then handle each member in the directory + //! recursively with @[write_access] etc.   protected mapping(string:mixed)|int(0..1) write_access(string relative_path,    int(0..1) recursive,    RequestID id)   {    return check_if_header (relative_path, recursive, id);   }    -  + //! + protected variant mapping(string:mixed)|int(0..1) write_access(array(string) paths, +  int(0..1) recursive, +  RequestID id) + { +  mapping(string:mixed)|int(0..1) ret; +  int got_ok; +  foreach(paths, string path) { +  ret = write_access(path, recursive, id); +  if (!ret) { +  got_ok = 1; +  continue; +  } +  if (ret == 1) { +  continue; +  } +  if (ret->error == Protocols.HTTP.HTTP_PRECOND_FAILED) { +  continue; +  } +  return ret; +  } +  +  if (got_ok) { +  // The if headers are valid for at least one of the paths, +  // and none of the other paths are locked. +  return 0; +  } +  +  // HTTP_PRECOND_FAILED for all of the paths. +  return ret; + } +    mapping(string:mixed)|int(-1..0)|Stdio.File find_file(string path,    RequestID id);      //! Used by the default @[recurse_delete_files] implementation to   //! delete a file or an empty directory.   //!   //! @returns   //! Returns a 2xx series status mapping on success (typically 204 No   //! Content). Returns 0 if the file doesn't exist. Returns an   //! appropriate status mapping for any other error.