summaryrefslogtreecommitdiffstats
path: root/src/files.ml
diff options
context:
space:
mode:
Diffstat (limited to 'src/files.ml')
-rw-r--r--src/files.ml45
1 files changed, 44 insertions, 1 deletions
diff --git a/src/files.ml b/src/files.ml
index ee27b4e..a034400 100644
--- a/src/files.ml
+++ b/src/files.ml
@@ -319,6 +319,36 @@ let setupTargetPathsLocal (fspath, path) =
let setupTargetPaths =
Remote.registerRootCmd "setupTargetPaths" setupTargetPathsLocal
+let rec createDirectories fspath localPath props =
+ match props with
+ [] ->
+ ()
+ | desc :: rem ->
+ match Path.deconstructRev localPath with
+ None ->
+ assert false
+ | Some (_, parentPath) ->
+ createDirectories fspath parentPath rem;
+ try
+ let absolutePath = Fspath.concat fspath parentPath in
+ Fs.mkdir absolutePath (Props.perms desc)
+ (* The directory may have already been created
+ if there are several paths with the same prefix *)
+ with Unix.Unix_error (Unix.EEXIST, _, _) -> ()
+
+let setupTargetPathsAndCreateParentDirectoryLocal (fspath, (path, props)) =
+ let localPath = Update.translatePathLocal fspath path in
+ Util.convertUnixErrorsToTransient
+ "creating parent directories"
+ (fun () -> createDirectories fspath localPath props);
+ let (workingDir,realPath) = Fspath.findWorkingDir fspath localPath in
+ let tempPath = Os.tempPath ~fresh:false workingDir realPath in
+ Lwt.return (workingDir, realPath, tempPath, localPath)
+
+let setupTargetPathsAndCreateParentDirectory =
+ Remote.registerRootCmd "setupTargetPathsAndCreateParentDirectory"
+ setupTargetPathsAndCreateParentDirectoryLocal
+
(* ------------------------------------------------------------ *)
let updateSourceArchiveLocal (fspathFrom, (localPathFrom, uiFrom, errPaths)) =
@@ -376,6 +406,15 @@ let deleteSpuriousChildrenLocal (_, (fspathTo, pathTo, archChildren)) =
let deleteSpuriousChildren =
Remote.registerRootCmd "deleteSpuriousChildren" deleteSpuriousChildrenLocal
+let rec normalizePropsRec propsFrom propsTo =
+ match propsFrom, propsTo with
+ d :: r, d' :: r' -> normalizePropsRec r r'
+ | _, [] -> propsFrom
+ | [], _ :: _ -> assert false
+
+let normalizeProps propsFrom propsTo =
+ normalizePropsRec (Safelist.rev propsFrom) (Safelist.rev propsTo)
+
(* ------------------------------------------------------------ *)
let copyReg = Lwt_util.make_region 50
@@ -385,10 +424,13 @@ let copy
rootFrom pathFrom (* copy from here... *)
uiFrom (* (and then check that this updateItem still
describes the current state of the src replica) *)
+ propsFrom (* the properties of the parent directories, in
+ case we need to propagate them *)
rootTo pathTo (* ...to here *)
uiTo (* (but, before committing the copy, check that
this updateItem still describes the current
state of the target replica) *)
+ propsTo (* the properties of the parent directories *)
id = (* for progress display *)
debug (fun() ->
Util.msg
@@ -396,7 +438,8 @@ let copy
(root2string rootFrom) (Path.toString pathFrom)
(root2string rootTo) (Path.toString pathTo));
(* Calculate target paths *)
- setupTargetPaths rootTo pathTo
+ setupTargetPathsAndCreateParentDirectory rootTo
+ (pathTo, normalizeProps propsFrom propsTo)
>>= fun (workingDir, realPathTo, tempPathTo, localPathTo) ->
(* When in Unicode case-insensitive mode, we want to create files
with NFC normal-form filenames. *)