$OpenBSD: patch-update_ml,v 1.1 2005/05/30 19:27:45 sturm Exp $
Post-release developer patch.
o Fix the file open in text mode instead of binary.
  See http://groups.yahoo.com/group/unison-users/message/3184
  and http://lists.seas.upenn.edu/pipermail/unison-hackers/2005-May/000089.html
o Better error message for non-existing paths.
  See http://lists.seas.upenn.edu/pipermail/unison-hackers/2005-May/000092.html
o Update archive timestamps to avoid defeating fastcheck on Windows.
  See http://groups.yahoo.com/group/unison-users/message/3821
--- update.ml.orig	Mon Sep  6 15:15:46 2004
+++ update.ml	Fri May 27 16:33:58 2005
@@ -347,13 +347,25 @@ let postCommitArchiveLocal (fspath,())
      let fto = Fspath.toString (Os.fileInUnisonDir toname) in
      debug (fun() -> Util.msg "Copying archive %s to %s\n" ffrom fto);
      Util.convertUnixErrorsToFatal "copying archive" (fun () ->
-       let outFd = Unix.openfile fto
-         [Unix.O_RDWR;Unix.O_CREAT;Unix.O_TRUNC] 0o600 in
+       let outFd = 
+         open_out_gen [Open_wronly; Open_creat; Open_trunc; Open_binary] 
+              0o600 fto
+       in
        Unix.chmod fto 0o600; (* In case the file already existed *)
-       let inFd = Unix.openfile ffrom [Unix.O_RDONLY] 0o444 in
-       Uutil.readWrite inFd outFd (fun _ -> ());
-       Unix.close inFd;
-       Unix.close outFd;
+       let inFd = open_in_bin ffrom in
+       let bufsize = 10000 in
+       let buf = String.create bufsize in
+
+       let rec read () =
+         let n = input inFd buf 0 bufsize in
+         if n>0 then begin
+           output outFd buf 0 n;
+         read()
+         end
+       in
+       read ();
+       close_in inFd;
+       close_out outFd;
        let arcFspath = Os.fileInUnisonDir toname in
        let info = Fileinfo.get false arcFspath Path.empty in
        Hashtbl.replace archiveInfoCache thisRoot info))
@@ -1578,7 +1590,6 @@ and buildUpdateRec archive currfspath pa
 let rec buildUpdate archive fspath fullpath here path =
   match Path.deconstruct path with
     None ->
-      Os.checkThatParentPathIsADir fspath here;
       showStatus path;
       let (arch, ui) =
         buildUpdateRec archive fspath here (useFastChecking()) in
@@ -1588,6 +1599,12 @@ let rec buildUpdate archive fspath fullp
        end,
        ui)
   | Some(name, path') ->
+      if not (isDir fspath here) then
+        (archive,
+         Error (Printf.sprintf
+                  "path %s is not valid because %s is not a directory"
+                  (Path.toString fullpath) (Path.toString here)))
+      else
       let children = getChildren fspath here in
       let (name', status) =
         try
@@ -1625,7 +1642,7 @@ let rec buildUpdate archive fspath fullp
              Note that we may also put NoArchive deep inside an
              archive...
           *)
-          (ArchiveDir (desc, NameMap.add name' child otherChildren),
+          (ArchiveDir (desc, NameMap.add name' arch otherChildren),
            updates)
 
 (* for the given path, find the archive and compute the list of update
