Roxen.git
/
server
/
base_server
/
module.pike
version
»
Context lines:
10
20
40
80
file
none
3
Roxen.git/server/base_server/module.pike:1702:
//! 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].