Roxen.git / server / base_server / module.pike

version» Context lines:

Roxen.git/server/base_server/module.pike:1807:   //! Destination path below the filesystem location.   //!   //! @param behavior   //! Specifies how to copy properties. See the @[PropertyBehavior]   //! type for details.   //!   //! @param overwrite   //! Specifies how to handle the situation if the destination already   //! exists. See the @[Overwrite] type for details.   //! + //! @param one_level + //! Indicates whether recursion is to be inhibited. + //!   //! @returns   //! Returns a 2xx series status mapping on success (typically 201   //! Created if the destination didn't exist before, or 204 No   //! Content otherwise). Returns 0 if the source doesn't exist.   //! Returns an appropriate status mapping for any other error. That   //! includes an empty mapping in case there's a failure on some   //! subpart or at the destination, to signify a 207 Multi-Status   //! response using the info in @[id->get_multi_status()].   mapping(string:mixed) recurse_copy_files(string source, string destination,    PropertyBehavior behavior, -  Overwrite overwrite, RequestID id) +  Overwrite overwrite, RequestID id, +  int|void one_level)   {    SIMPLE_TRACE_ENTER(this, "Recursive copy from %O to %O (%s)",    source, destination,    overwrite == DO_OVERWRITE ? "replace" :    overwrite == NEVER_OVERWRITE ? "no overwrite" :    "overlay");    string src_tmp = has_suffix(source, "/")?source:(source+"/");    string dst_tmp = has_suffix(destination, "/")?destination:(destination+"/");    if ((src_tmp == dst_tmp) ||    has_prefix(src_tmp, dst_tmp) ||    has_prefix(dst_tmp, src_tmp)) {    TRACE_LEAVE("Source and destination overlap.");    return Roxen.http_status(403, "Source and destination overlap.");    }       string prefix = map(query_location()[1..]/"/", Roxen.http_encode_url)*"/";    MultiStatus.Prefixed result =    id->get_multi_status()->prefix (id->url_base() + prefix);    -  mapping(string:mixed) recurse(string source, string destination) { +  mapping(string:mixed) recurse(string source, string destination, +  int|void one_level) {    // Note: Already got an extra TRACE_ENTER level on entry here.       Stat st = stat_file(source, id);    if (!st) {    TRACE_LEAVE("Source not found.");    return 0;    } -  // FIXME: Check destination? +  // NB: No need to check the destination here, as it is done by +  // copy_collection() and copy_file().    if (st->isdir) {    mapping(string:mixed) res =    copy_collection(source, destination, behavior, overwrite, result, id);    if (res && (!sizeof (res) || res->error >= 300)) {    // RFC 2518 8.8.3 and 8.8.8 (error minimization).    TRACE_LEAVE("Copy of collection failed.");    return res;    } -  +  if (!one_level) {    foreach(find_dir(source, id), string filename) {    string subsrc = combine_path_unix(source, filename);    string subdst = combine_path_unix(destination, filename);    SIMPLE_TRACE_ENTER(this, "Copy from %O to %O\n", subsrc, subdst);    mapping(string:mixed) sub_res = recurse(subsrc, subdst);    if (sub_res && !(<0, 201, 204>)[sub_res->error]) {    result->add_status(subdst, sub_res->error, sub_res->rettext);    }    } -  +  }    TRACE_LEAVE("");    return res;    } else {    TRACE_LEAVE("");    return copy_file(source, destination, behavior, overwrite, id);    }    };       int start_ms_size = id->multi_status_size(); -  mapping(string:mixed) res = recurse (source, destination); +  mapping(string:mixed) res = recurse (source, destination, one_level);    if (res && res->error != 204 && res->error != 201)    return res;    else if (id->multi_status_size() != start_ms_size)    return ([]);    else    return res;   }      //! Used by the default @[recurse_move_files] to move a file (and not   //! a directory) from @[source] to @[destination].