Index: src/config/unix/os_stubs_c.c
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/config/unix/os_stubs_c.c,v
retrieving revision 1.12
diff -u -r1.12 os_stubs_c.c
--- src/config/unix/os_stubs_c.c	6 Oct 2005 10:50:31 -0000	1.12
+++ src/config/unix/os_stubs_c.c	20 Nov 2005 15:29:59 -0000
@@ -131,7 +131,7 @@
 void os_uname(char buf[]) {
 	struct utsname uts;
   uname(&uts);
-	sprintf(buf, "%s %s %s %s %s\0", 
+	sprintf(buf, "%s %s %s %s %s", 
    uts.sysname, uts.nodename, uts.release, uts.version, uts.machine);
 }
 #else
Index: src/daemon/common/commonFile.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/daemon/common/commonFile.ml,v
retrieving revision 1.43
diff -u -r1.43 commonFile.ml
--- src/daemon/common/commonFile.ml	12 Nov 2005 11:30:05 -0000	1.43
+++ src/daemon/common/commonFile.ml	20 Nov 2005 15:30:00 -0000
@@ -52,7 +52,7 @@
     mutable impl_file_ops : 'a file_ops;
     mutable impl_file_size : int64;
     mutable impl_file_age : int;
-    mutable impl_file_fd : Unix32.t;
+    mutable impl_file_fd : Unix32.t option;
     mutable impl_file_downloaded : int64;
     mutable impl_file_received : int64;
     mutable impl_file_last_received : (int64 * int) list;
@@ -121,7 +121,7 @@
     impl_file_ops = Obj.magic 0;
     impl_file_size = Int64.zero;
     impl_file_age = 0;
-    impl_file_fd = Unix32.create_diskfile "" [Unix.O_RDONLY] 0o666;
+    impl_file_fd = None;
     impl_file_downloaded = Int64.zero;
     impl_file_received = Int64.zero;
     impl_file_last_received = [];
@@ -398,19 +398,20 @@
 let file_size file = 
   (as_file_impl file).impl_file_size
 
-let file_disk_name file =
-  Unix32.filename (as_file_impl file).impl_file_fd
-
 let file_fd file =
-  (as_file_impl file).impl_file_fd
+  match (as_file_impl file).impl_file_fd with
+    | Some fd -> fd
+    | None -> raise Not_found
+
+let file_disk_name file =
+  Unix32.filename (file_fd file)
 
 let set_file_fd file fd =
-  (as_file_impl file).impl_file_fd <- fd
+  (as_file_impl file).impl_file_fd <- Some fd
 
 let set_file_disk_name file filename =
   let orig_fd = file_fd file in
-  if orig_fd != Unix32.bad_fd then
-    Unix32.rename orig_fd filename
+  Unix32.rename orig_fd filename
 
 let file_downloaded file = (as_file_impl file).impl_file_downloaded
 
Index: src/daemon/common/commonFile.mli
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/daemon/common/commonFile.mli,v
retrieving revision 1.10
diff -u -r1.10 commonFile.mli
--- src/daemon/common/commonFile.mli	20 Jun 2005 18:47:01 -0000	1.10
+++ src/daemon/common/commonFile.mli	20 Nov 2005 15:30:00 -0000
@@ -27,7 +27,7 @@
   mutable impl_file_ops : 'a file_ops;
   mutable impl_file_size : int64;
   mutable impl_file_age : int;
-  mutable impl_file_fd : Unix32.t;
+  mutable impl_file_fd : Unix32.t option;
   mutable impl_file_downloaded : int64;
   mutable impl_file_received : int64;
   mutable impl_file_last_received : (int64 * int) list;
@@ -126,4 +126,4 @@
   CommonTypes.file -> CommonTypes.file -> int64 -> int64 -> int64 -> unit
 val file_files : CommonTypes.file -> CommonTypes.file list
 val propose_filenames : unit -> unit
-val propose_filename : CommonTypes.file -> unit
\ No newline at end of file
+val propose_filename : CommonTypes.file -> unit
Index: src/daemon/common/commonHasher_c.c
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/daemon/common/commonHasher_c.c,v
retrieving revision 1.8
diff -u -r1.8 commonHasher_c.c
--- src/daemon/common/commonHasher_c.c	28 Aug 2005 10:49:49 -0000	1.8
+++ src/daemon/common/commonHasher_c.c	20 Nov 2005 15:30:01 -0000
@@ -325,28 +325,35 @@
 /*    fprintf(stderr,"waiting for next job\n");  */
     pthread_cond_timedwait(&cond, &mutex, &timeout);
     
-    if(!job_done){
+    if(!job_done) {
 
 /*      fprintf(stderr,"job started\n");   */
       
-      if(job_method == METHOD_MD4)
+      long bsize;
+      switch(job_method) {
+      case METHOD_MD4:
         md4_unsafe64_fd_direct(job_fd, job_begin_pos, job_len, job_result);
-      else
-        if( job_method == METHOD_MD5)
-          md5_unsafe64_fd_direct(job_fd, job_begin_pos, job_len, job_result);
-        else
-          if( job_method == METHOD_SHA1)
-            sha1_unsafe64_fd_direct(job_fd, job_begin_pos, job_len, job_result);
-          else 
-            if( job_method == METHOD_TIGER){
-              long bsize = tiger_block_size(job_len);
-              tiger_tree_fd(job_fd, job_len, 0, bsize, job_result);
-            } else {
-              printf("commonHasher_c.c: method sha1 not implemented\n");
-              exit(2);
-            }
-            /*        fprintf(stderr,"job finished\n");  */
-            job_done = 1;
+	break;
+
+      case METHOD_MD5:
+	md5_unsafe64_fd_direct(job_fd, job_begin_pos, job_len, job_result);
+	break;
+
+      case METHOD_SHA1:
+	sha1_unsafe64_fd_direct(job_fd, job_begin_pos, job_len, job_result);
+	break;
+
+      case METHOD_TIGER:
+	bsize = tiger_block_size(job_len);
+	tiger_tree_fd(job_fd, job_len, 0, bsize, job_result);
+	break;
+
+      default:
+	printf("commonHasher_c.c: method not implemented\n");
+	exit(2);
+      }
+      /*        fprintf(stderr,"job finished\n");  */
+      job_done = 1;
     }
   }
   
Index: src/daemon/common/commonInteractive.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/daemon/common/commonInteractive.ml,v
retrieving revision 1.51
diff -u -r1.51 commonInteractive.ml
--- src/daemon/common/commonInteractive.ml	16 Oct 2005 20:42:50 -0000	1.51
+++ src/daemon/common/commonInteractive.ml	20 Nov 2005 15:30:02 -0000
@@ -184,14 +184,16 @@
           with e ->
               lprintf_nl "[cInt] Exception %s in file_cancel" (Printexc2.to_string e);
       ) subfiles;
-      (try
-          let fd = file_fd file in
-          if fd != Unix32.bad_fd then Unix32.remove (file_fd file)
-        with e ->
-            lprintf_nl "[cInt]Sys.remove %s exception %s"
-              (file_disk_name file)
-            (Printexc2.to_string e); );
-      Unix32.destroy (file_fd file);
+      try
+	let fd = file_fd file in
+	(try
+           Unix32.remove fd
+         with e ->
+           lprintf_nl "[cInt]Sys.remove %s exception %s"
+             (file_disk_name file)
+             (Printexc2.to_string e));
+	Unix32.destroy fd
+      with Not_found -> ()
   with e ->
       lprintf_nl "[cInt] Exception in file_cancel: %s" (Printexc2.to_string e)
 
Index: src/daemon/common/commonOptions.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/daemon/common/commonOptions.ml,v
retrieving revision 1.100
diff -u -r1.100 commonOptions.ml
--- src/daemon/common/commonOptions.ml	12 Nov 2005 11:30:06 -0000	1.100
+++ src/daemon/common/commonOptions.ml	20 Nov 2005 15:30:06 -0000
@@ -1530,7 +1530,7 @@
       if !!log_file <> "" then
         try
 	  if Sys.file_exists !!log_file then
-	    if (Unix32.getsize !!log_file false)
+	    if (Unix32.getsize !!log_file)
 	     > (Int64ops.megabytes !!log_file_size) then begin
 	      Sys.remove !!log_file;
               lprintf_nl "Logfile %s resetted, bigger than %d MB" !!log_file !!log_file_size
Index: src/daemon/common/commonShared.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/daemon/common/commonShared.ml,v
retrieving revision 1.26
diff -u -r1.26 commonShared.ml
--- src/daemon/common/commonShared.ml	16 Oct 2005 20:42:50 -0000	1.26
+++ src/daemon/common/commonShared.ml	20 Nov 2005 15:30:07 -0000
@@ -145,7 +145,7 @@
   let codedname = Filename.concat dirname filename in
   if !verbose_share then
     lprintf_nl () "sharing %s" fullname;
-  let size = Unix32.getsize fullname false in
+  let size = Unix32.getsize fullname in
   incr files_scanned;
   files_scanned_size := !files_scanned_size ++ size;
   if Unix2.is_directory fullname then begin
@@ -277,7 +277,7 @@
 		end
               else
               try
-                let size = (Unix32.getsize full_name) false in
+                let size = Unix32.getsize full_name in
                 if size > strategy.sharing_minsize && 
                   size < strategy.sharing_maxsize &&
                   (strategy.sharing_extensions = [] ||
Index: src/daemon/common/commonSwarming2.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/daemon/common/commonSwarming2.ml,v
retrieving revision 1.22
diff -u -r1.22 commonSwarming2.ml
--- src/daemon/common/commonSwarming2.ml	12 Nov 2005 11:20:20 -0000	1.22
+++ src/daemon/common/commonSwarming2.ml	20 Nov 2005 15:30:12 -0000
@@ -3223,7 +3223,7 @@
     let block_sizes = [| 1000; 400; 299 |]
     let block_sizes = Array.map Int64.of_int block_sizes
 
-    let file_check_fd = Unix32.create_diskfile file Unix32.rw_flag 0o444
+    let file_check_fd = Unix32.create_diskfile file true
 
     module S = Make(struct
 
@@ -3318,7 +3318,7 @@
                 let nchunks = Int64.to_int (Int64.pred file_size // block_size) + 1 in
 
                 let file = {
-                    file_fd = Unix32.create_diskfile temp_filename Unix32.rw_flag 0o666;
+                    file_fd = Unix32.create_diskfile temp_filename true;
                     file_num = i;
                     file_name = "toto";
                     file_size = file_size;
Index: src/daemon/common/commonUploads.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/daemon/common/commonUploads.ml,v
retrieving revision 1.36
diff -u -r1.36 commonUploads.ml
--- src/daemon/common/commonUploads.ml	5 Nov 2005 16:23:40 -0000	1.36
+++ src/daemon/common/commonUploads.ml	20 Nov 2005 15:30:12 -0000
@@ -501,8 +501,8 @@
     | MD5EXT ->
         let md5ext =
           try
-            let fd = Unix32.create_rw info.shared_fullname in
-            let file_size = Unix32.getsize64 fd false in
+            let fd = Unix32.create_ro info.shared_fullname in
+            let file_size = Unix32.getsize64 fd in
             let len64 = min 307200L file_size in
             let len = Int64.to_int len64 in
             let s = String.create len in
Index: src/daemon/driver/driverLink.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/daemon/driver/driverLink.ml,v
retrieving revision 1.7
diff -u -r1.7 driverLink.ml
--- src/daemon/driver/driverLink.ml	28 May 2005 11:19:42 -0000	1.7
+++ src/daemon/driver/driverLink.ml	20 Nov 2005 15:30:15 -0000
@@ -374,7 +374,7 @@
       let file = correct_file file in
       if !verbose_dp500 then lprintf "Size of [%s]\n" file;
       let fd = Unix32.create_ro file in
-      let size = Unix32.getsize64 fd false in
+      let size = Unix32.getsize64 fd in
       write_string sock (Printf.sprintf "%015Ld" size)
     else
     if command = "GET" then
@@ -395,7 +395,7 @@
             end;
           let pclink_buf, len_read = 
             if len_read = 0 then
-              let size = Unix32.getsize64 fd false in
+              let size = Unix32.getsize64 fd in
               let size = Int64.to_int size in
               String.create size, size
             else
Index: src/networks/bittorrent/bTGlobals.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/networks/bittorrent/bTGlobals.ml,v
retrieving revision 1.43
diff -u -r1.43 bTGlobals.ml
--- src/networks/bittorrent/bTGlobals.ml	12 Nov 2005 11:20:20 -0000	1.43
+++ src/networks/bittorrent/bTGlobals.ml	20 Nov 2005 15:30:16 -0000
@@ -55,7 +55,7 @@
 let file_size file = file.file_file.impl_file_size
 let file_downloaded file = file_downloaded (as_file file)
 let file_age file = file.file_file.impl_file_age
-let file_fd file = file.file_file.impl_file_fd
+let file_fd file = file_fd (as_file file)
 let file_disk_name file = file_disk_name (as_file file)
 let file_state file = file_state (as_file file)
 let file_num file = file_num (as_file file)
@@ -171,7 +171,7 @@
   let file_fd =
     if file_files <> [] then
       Unix32.create_multifile file_temp
-        [Unix.O_RDWR; Unix.O_CREAT] 0o666 file_files
+        true file_files
     else
       Unix32.create_rw file_temp
   in
@@ -227,7 +227,7 @@
           file_shared = None;
         } and file_impl =  {
           dummy_file_impl with
-          impl_file_fd = file_fd;
+          impl_file_fd = Some file_fd;
           impl_file_size = t.torrent_length;
           impl_file_downloaded = Int64.zero;
           impl_file_val = file;
@@ -292,7 +292,7 @@
       ft_retry = (fun _ -> ());
     } and file_impl =  {
       dummy_file_impl with
-      impl_file_fd = Unix32.bad_fd;
+      impl_file_fd = None;
       impl_file_size = zero;
       impl_file_downloaded = Int64.zero;
       impl_file_val = ft;
Index: src/networks/bittorrent/bTTorrent.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/networks/bittorrent/bTTorrent.ml,v
retrieving revision 1.7
diff -u -r1.7 bTTorrent.ml
--- src/networks/bittorrent/bTTorrent.ml	4 Aug 2005 22:00:23 -0000	1.7
+++ src/networks/bittorrent/bTTorrent.ml	20 Nov 2005 15:30:17 -0000
@@ -378,19 +378,19 @@
               if Unix2.is_directory fullname then
                 iter_directory list basename
               else
-                (basename, Unix32.getsize fullname false) :: list
+                (basename, Unix32.getsize fullname) :: list
             in
             iter_files left dirname tail
       in
       let files = iter_directory [] "" in
-      let t = Unix32.create_multifile filename Unix32.ro_flag 0o666 files in
+      let t = Unix32.create_multifile filename false files in
       files, t
     else
       [], Unix32.create_ro filename
   in
 
   Unix32.flush_fd t;
-  let length = Unix32.getsize64 t false in
+  let length = Unix32.getsize64 t in
   let npieces = 1+ Int64.to_int ((length -- one) // chunk_size) in
   let pieces = Array.create npieces Sha1.null in
   for i = 0 to npieces - 1 do
Index: src/networks/direct_connect/dcGlobals.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/networks/direct_connect/dcGlobals.ml,v
retrieving revision 1.11
diff -u -r1.11 dcGlobals.ml
--- src/networks/direct_connect/dcGlobals.ml	5 Jul 2005 12:28:57 -0000	1.11
+++ src/networks/direct_connect/dcGlobals.ml	20 Nov 2005 15:30:17 -0000
@@ -278,7 +278,7 @@
           file_clients = [];
         } and impl = {
           dummy_file_impl with
-          impl_file_fd = t;
+          impl_file_fd = Some t;
           impl_file_size = file_size;
           impl_file_downloaded = current_size;
           impl_file_val = file;
@@ -458,5 +458,5 @@
 let file_size file = file.file_file.impl_file_size
 let file_downloaded file = file_downloaded (as_file file.file_file)
 let file_age file = file.file_file.impl_file_age
-let file_fd file = file.file_file.impl_file_fd
-  
\ No newline at end of file
+let file_fd file = file_fd (as_file file.file_file)
+  
Index: src/networks/donkey/donkeyGlobals.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/networks/donkey/donkeyGlobals.ml,v
retrieving revision 1.58
diff -u -r1.58 donkeyGlobals.ml
--- src/networks/donkey/donkeyGlobals.ml	12 Nov 2005 11:20:21 -0000	1.58
+++ src/networks/donkey/donkeyGlobals.ml	20 Nov 2005 15:30:17 -0000
@@ -100,7 +100,7 @@
 let file_size file = file.file_file.impl_file_size
 let file_downloaded file = file_downloaded (as_file file)
 let file_age file = file.file_file.impl_file_age
-let file_fd file = file.file_file.impl_file_fd
+let file_fd file = file_fd (as_file file)
 let file_disk_name file = file_disk_name (as_file file)
 let file_best_name file = file_best_name (as_file file)
 
@@ -312,7 +312,7 @@
           && file.file_diskname = file_diskname
         then
           file.file_file.impl_file_fd <-
-            Unix32.create_diskfile file.file_diskname Unix32.rw_flag 0o666;
+            Some (Unix32.create_diskfile file.file_diskname true);
       if Unix32.destroyed (file_fd file) then
           lprintf_nl () "New Edonkey file with %b && %b remaining destroyed fd %s"
             (not writable) (file.file_diskname = file_diskname) file.file_diskname;
@@ -331,14 +331,14 @@
 (* Only if the file does not already exists *)
           not (Sys.file_exists file_diskname)
         then
-          Unix32.create_sparsefile file_diskname
+          Unix32.create_sparsefile file_diskname writable
         else
-          Unix32.create_diskfile file_diskname Unix32.rw_flag 0o666
+          Unix32.create_diskfile file_diskname writable
       in
       let file_size =
         if file_size = Int64.zero then
           try
-            Unix32.getsize file_diskname writable
+            Unix32.getsize file_diskname
           with _ ->
               failwith "Zero length file ?"
         else file_size
@@ -370,7 +370,7 @@
           impl_file_ops = file_ops;
           impl_file_age = last_time ();
           impl_file_size = file_size;
-          impl_file_fd = t;
+          impl_file_fd = Some t;
           impl_file_best_name = Filename.basename file_diskname;
           impl_file_last_seen = last_time () - 100 * 24 * 3600;
         }
Index: src/networks/donkey/donkeyInteractive.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/networks/donkey/donkeyInteractive.ml,v
retrieving revision 1.70
diff -u -r1.70 donkeyInteractive.ml
--- src/networks/donkey/donkeyInteractive.ml	12 Nov 2005 22:53:52 -0000	1.70
+++ src/networks/donkey/donkeyInteractive.ml	20 Nov 2005 15:30:21 -0000
@@ -1450,7 +1450,7 @@
     ignore (Hashtbl.find files_by_md4 md4)
   with Not_found ->
       let file_diskname = Filename.concat !!temp_directory filename in
-      let size = Unix32.getsize file_diskname true in
+      let size = Unix32.getsize file_diskname in
       if size <> zero then
         let names =
             (* TODO RESULT
Index: src/networks/donkey/donkeyMain.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/networks/donkey/donkeyMain.ml,v
retrieving revision 1.39
diff -u -r1.39 donkeyMain.ml
--- src/networks/donkey/donkeyMain.ml	5 Nov 2005 16:23:40 -0000	1.39
+++ src/networks/donkey/donkeyMain.ml	20 Nov 2005 15:30:23 -0000
@@ -179,7 +179,9 @@
     let enabler = ref true in
     is_enabled := true;
     network.op_network_disable <- disable enabler;
-    client_public_key := Unix32.load_key (!!client_private_key);
+    (try
+      client_public_key := Unix32.load_key (!!client_private_key)
+    with _ -> ());
     if not !!enable_donkey then enable_donkey =:= true;
     
     try
@@ -212,7 +214,7 @@
                 try
                   let file_disk_name = file_disk_name file in
                   if Unix32.file_exists file_disk_name &&
-                    Unix32.getsize file_disk_name false <> Int64.zero then begin
+                    Unix32.getsize file_disk_name <> Int64.zero then begin
                     (* getsize writable=false is ok because file has state FileDownloaded *)
                       lprintf_nl () "FILE DOWNLOADED"; 
                       
Index: src/networks/donkey/donkeyShare.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/networks/donkey/donkeyShare.ml,v
retrieving revision 1.30
diff -u -r1.30 donkeyShare.ml
--- src/networks/donkey/donkeyShare.ml	16 Oct 2005 20:42:54 -0000	1.30
+++ src/networks/donkey/donkeyShare.ml	20 Nov 2005 15:30:23 -0000
@@ -217,7 +217,7 @@
                 lprintf_nl () "Shared file doesn't exist";
                 raise Not_found;
               end;
-            if Unix32.getsize sh.shared_name false <> sh.shared_size then begin
+            if Unix32.getsize sh.shared_name <> sh.shared_size then begin
                 lprintf_nl () "Bad shared file size";
                 raise Not_found;
               end;
Index: src/networks/fasttrack/fasttrackGlobals.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/networks/fasttrack/fasttrackGlobals.ml,v
retrieving revision 1.27
diff -u -r1.27 fasttrackGlobals.ml
--- src/networks/fasttrack/fasttrackGlobals.ml	16 Oct 2005 20:42:54 -0000	1.27
+++ src/networks/fasttrack/fasttrackGlobals.ml	20 Nov 2005 15:30:23 -0000
@@ -78,7 +78,7 @@
 let file_size file = file.file_file.impl_file_size
 let file_downloaded file = file_downloaded (as_file file)
 let file_age file = file.file_file.impl_file_age
-let file_fd file = file.file_file.impl_file_fd
+let file_fd file = file_fd (as_file file)
 let file_disk_name file = file_disk_name (as_file file)
 let file_state file =
   file_state (as_file file)
@@ -276,7 +276,7 @@
       file_ttr = None;
     } and file_impl =  {
       dummy_file_impl with
-      impl_file_fd = t;
+      impl_file_fd = Some t;
       impl_file_size = file_size;
       impl_file_downloaded = Int64.zero;
       impl_file_val = file;
Index: src/networks/fileTP/fileTPGlobals.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/networks/fileTP/fileTPGlobals.ml,v
retrieving revision 1.16
diff -u -r1.16 fileTPGlobals.ml
--- src/networks/fileTP/fileTPGlobals.ml	16 Oct 2005 20:42:54 -0000	1.16
+++ src/networks/fileTP/fileTPGlobals.ml	20 Nov 2005 15:30:23 -0000
@@ -71,7 +71,7 @@
 let file_size file = file.file_file.impl_file_size
 let file_downloaded file = file_downloaded (as_file file)
 let file_age file = file.file_file.impl_file_age
-let file_fd file = file.file_file.impl_file_fd
+let file_fd file = file_fd (as_file file)
 let file_disk_name file = file_disk_name (as_file file)
 let file_best_name file = file_best_name (as_file file)
 
@@ -150,7 +150,7 @@
       file_nconnected_clients = 0;
     } and file_impl =  {
       dummy_file_impl with
-      impl_file_fd = t;
+      impl_file_fd = Some t;
       impl_file_size = zero;
       impl_file_downloaded = zero;
       impl_file_val = file;
Index: src/networks/gnutella/gnutellaGlobals.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/networks/gnutella/gnutellaGlobals.ml,v
retrieving revision 1.31
diff -u -r1.31 gnutellaGlobals.ml
--- src/networks/gnutella/gnutellaGlobals.ml	2 Sep 2005 23:48:54 -0000	1.31
+++ src/networks/gnutella/gnutellaGlobals.ml	20 Nov 2005 15:30:23 -0000
@@ -78,7 +78,7 @@
 let file_size file = file.file_file.impl_file_size
 let file_downloaded file = file_downloaded (as_file file)
 let file_age file = file.file_file.impl_file_age
-let file_fd file = file.file_file.impl_file_fd
+let file_fd file = file_fd (as_file file)
 let file_disk_name file = file_disk_name (as_file file)
 let file_state file =  file_state (as_file file)
 let file_num file =  file_num (as_file file)
@@ -307,7 +307,7 @@
       file_ttr = None;
     } and file_impl =  {
       dummy_file_impl with
-      impl_file_fd = t;
+      impl_file_fd = Some t;
       impl_file_size = file_size;
       impl_file_downloaded = Int64.zero;
       impl_file_val = file;
Index: src/networks/gnutella/gnutellaProtocol.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/networks/gnutella/gnutellaProtocol.ml,v
retrieving revision 1.17
diff -u -r1.17 gnutellaProtocol.ml
--- src/networks/gnutella/gnutellaProtocol.ml	16 Oct 2005 20:42:54 -0000	1.17
+++ src/networks/gnutella/gnutellaProtocol.ml	20 Nov 2005 15:30:26 -0000
@@ -511,7 +511,7 @@
           
           (fun pos upload_buffer spos rlen ->
               Unix32.read fd pos upload_buffer spos rlen),
-          Unix32.getsize64 fd false, []
+          Unix32.getsize64 fd, []
         else
           failwith (Printf.sprintf "Cannot find TigerTree [%s]" urn)
     | _ -> failwith "Cannot parse /uri-res/N2T request"
Index: src/networks/openFT/openFTGlobals.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/networks/openFT/openFTGlobals.ml,v
retrieving revision 1.4
diff -u -r1.4 openFTGlobals.ml
--- src/networks/openFT/openFTGlobals.ml	1 Nov 2004 11:23:02 -0000	1.4
+++ src/networks/openFT/openFTGlobals.ml	20 Nov 2005 15:30:26 -0000
@@ -61,7 +61,7 @@
 let file_size file = file.file_file.impl_file_size
 let file_downloaded file = file.file_file.impl_file_downloaded
 let file_age file = file.file_file.impl_file_age
-let file_fd file = file.file_file.impl_file_fd
+let file_fd file = file_fd (as_file file.file_file)
 let file_disk_name file = file_disk_name (as_file file.file_file)
 let set_file_disk_name file = set_file_disk_name (as_file file.file_file)
 
@@ -187,7 +187,7 @@
           file_clients = [];
         } and file_impl =  {
           dummy_file_impl with
-          impl_file_fd = Unix32.create file_temp [Unix.O_RDWR; Unix.O_CREAT] 0o666;
+          impl_file_fd = Some (Unix32.create_rw file_temp);
           impl_file_size = file_size;
           impl_file_downloaded = current_size;
           impl_file_val = file;
Index: src/networks/opennap/opennapGlobals.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/networks/opennap/opennapGlobals.ml,v
retrieving revision 1.10
diff -u -r1.10 opennapGlobals.ml
--- src/networks/opennap/opennapGlobals.ml	28 Jun 2005 23:17:07 -0000	1.10
+++ src/networks/opennap/opennapGlobals.ml	20 Nov 2005 15:30:26 -0000
@@ -203,7 +203,7 @@
           dummy_file_impl with
           impl_file_ops = file_ops;
           impl_file_val = file; 
-          impl_file_fd = t;
+          impl_file_fd = Some t;
           impl_file_size = file_size;
           impl_file_downloaded = current_size;
           impl_file_age = last_time ();          
@@ -327,7 +327,7 @@
 let file_size file = file.file_file.impl_file_size
 let file_downloaded file = file_downloaded (as_file file.file_file)
 let file_age file = file.file_file.impl_file_age
-let file_fd file = file.file_file.impl_file_fd
+let file_fd file = file_fd (as_file file.file_file)
   
   
 let shared_counter = ref (Int64.zero)
Index: src/networks/soulseek/slskGlobals.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/networks/soulseek/slskGlobals.ml,v
retrieving revision 1.11
diff -u -r1.11 slskGlobals.ml
--- src/networks/soulseek/slskGlobals.ml	28 May 2005 11:19:42 -0000	1.11
+++ src/networks/soulseek/slskGlobals.ml	20 Nov 2005 15:30:26 -0000
@@ -93,7 +93,7 @@
 let file_size file = file.file_file.impl_file_size
 let file_downloaded file = file_downloaded (as_file file.file_file)
 let file_age file = file.file_file.impl_file_age
-let file_fd file = file.file_file.impl_file_fd
+let file_fd file = file_fd (as_file file.file_file)
   
 let client_type c =
   client_type (as_client c.client_client)
@@ -268,7 +268,7 @@
           file_clients = [];
         } and impl = {
           dummy_file_impl with
-          impl_file_fd = Unix32.create_rw file_temp;
+          impl_file_fd = Some (Unix32.create_rw file_temp);
           impl_file_size = file_size;
           impl_file_downloaded = current_size;
           impl_file_val = file;
Index: src/utils/cdk/unix2.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/utils/cdk/unix2.ml,v
retrieving revision 1.17
diff -u -r1.17 unix2.ml
--- src/utils/cdk/unix2.ml	17 Oct 2005 15:25:46 -0000	1.17
+++ src/utils/cdk/unix2.ml	20 Nov 2005 15:30:26 -0000
@@ -128,6 +128,7 @@
   "unix_lseek_64" 
 external c_getsize64 : string -> int64 = "ml_getsize64"
 external c_getfdsize64 : Unix.file_descr -> int64 = "ml_getfdsize64"
+(* c_ftruncate64 sets size, optionally using a sparse file *)
 external c_ftruncate64 : Unix.file_descr -> int64 -> bool -> unit =
   "mld_ftruncate_64"
 external c_getdtablesize : unit -> int = "ml_getdtablesize"
Index: src/utils/lib/md4.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/utils/lib/md4.ml,v
retrieving revision 1.15
diff -u -r1.15 md4.ml
--- src/utils/lib/md4.ml	16 Oct 2005 20:42:55 -0000	1.15
+++ src/utils/lib/md4.ml	20 Nov 2005 15:30:28 -0000
@@ -341,7 +341,7 @@
     
     let file s =
       let digest = String.create hash_length in
-      let file_size = Unix32.getsize s false in
+      let file_size = Unix32.getsize s in
       unsafe_file digest s file_size;
       digest
     
@@ -489,7 +489,7 @@
         "tigertree_unsafe64_fd"
       
       let unsafe_file digest filename file_size = 
-        let fd = Unix32.create_diskfile filename [Unix.O_RDONLY] 0o444 in
+        let fd = Unix32.create_diskfile filename false in
         Unix32.apply_on_chunk fd Int64.zero file_size 
           (fun fd pos ->
             digest_subfile digest fd pos file_size)
Index: src/utils/lib/unix32.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/utils/lib/unix32.ml,v
retrieving revision 1.50
diff -u -r1.50 unix32.ml
--- src/utils/lib/unix32.ml	23 Oct 2005 16:05:41 -0000	1.50
+++ src/utils/lib/unix32.ml	20 Nov 2005 15:30:28 -0000
@@ -22,114 +22,143 @@
 open Int64ops
 open Printf2
 
+let lprintf_nl =
+  (fun format ->
+     lprintf "%s[Ux32] " (log_time ()); 
+     lprintf_nl2 format)
+  
 let chunk_min_size = ref 65000L
-
+  
 let max_buffered = ref (Int64.of_int (1024 * 1024))
-
+  
 let create_dir_mask = ref "755"
 let verbose = false
 let max_cache_size = ref 50
-
+  
 let mini (x: int) (y: int) =
   if x > y then y else x
-
+    
 let rights = 0o664
-
+  
 let ro_flag =  [Unix.O_RDONLY]
-let rw_flag =  [Unix.O_CREAT; Unix.O_RDWR]
-
+let rw_flag =  [Unix.O_RDWR]
+let rw_creat_flag =  [Unix.O_CREAT; Unix.O_RDWR]
+  
 external external_start : string -> unit = "external_start"
 external external_exit : unit -> unit = "external_exit"
 external uname : unit -> string = "ml_uname"
-
+  
 (* CryptoPP *)
 external create_key : unit -> string = "ml_createKey"
 external load_key : string -> string = "ml_loadKey"
 external create_signature : string -> int -> int64 -> int -> int64 -> string = "ml_createSignature"
 external verify_signature : string -> int -> string -> int -> int64 -> int -> int64 -> bool = "ml_verifySignature_bytecode" "ml_verifySignature"
-
-let really_write fd s pos len =
+  
+(* let really_write fd s pos len =
   try
     Unix2.really_write fd s pos len
-  with e -> raise e
+  with e -> raise e *)
+let really_write = Unix2.really_write
 
 module FDCache = struct
     
     type t = {
         mutable fd : Unix.file_descr option;
         mutable filename : string;
-        mutable destroyed : bool;
-(*        mutable exist : bool; *)
-      }
-    
+	mutable writable : bool;
+        mutable destroyed : bool; (* could we get rid of this ? *)
+    }
+
     let cache_size = ref 0
     let cache = Fifo.create ()
-    
-    let create f =
-(*      let exist = Sys.file_exists f in *)
-      {
-        filename = f;
-        fd = None;
-        destroyed = false;
-(*        exist = exist; *)
-      }
       
     let close t =
-      if not t.destroyed then begin
-          match t.fd with
+      if not t.destroyed then
+        match t.fd with
           | Some fd ->
-(*          lprintf "close_one: closing %d\n" (Obj.magic fd); *)
-              (try Unix.close fd with _ -> ());
-              t.fd <- None;
-              decr cache_size
+(*          lprintf "close: closing %d\n" (Obj.magic fd); *)
+	      (try Unix.close fd with e -> 
+		 lprintf_nl "Exception in FDCache.close %s: %s" 
+		   t.filename
+		   (Printexc2.to_string e);
+		 raise e);
+	      t.fd <- None;
+	      decr cache_size
           | None -> ()
-        end
 
-    let check_destroyed t =
+    let is_closed t =
       if t.destroyed then
-        failwith "Unix32: Cannot use destroyed FD"
-        
-    let destroy t =
-      if not t.destroyed then begin
-          close t;
-          t.destroyed <- true
-        end
-        
+	true
+      else match t.fd with
+	| Some fd -> false
+	| None -> true
+
     let rec close_one () =
       if not (Fifo.empty cache) then
         let t = Fifo.take cache in
         match t.fd with
-          None ->
-            close_one ()
-        | Some fd ->
-            close t
-
+          | None ->
+	      close_one ()
+          | Some fd ->
+	      try
+		close t
+	      with _ -> close_one ()
 
-    let local_force_fd t writable =
+    let check_destroyed t =
+      if t.destroyed then
+        failwith "Unix32.check_destroyed %s: Cannot use destroyed FD"
+	  t.filename
+        
+    let destroy t =
+      if not t.destroyed then begin
+        (try close t with _ -> ());
+        t.destroyed <- true
+      end
+        
+    let _local_force_fd creat t =
       check_destroyed t;
       let fd =
         match t.fd with
-          None ->
-            if !cache_size >= !max_cache_size then close_one ();
-            let fd =
-              if writable then begin
-                try
-                  Unix.openfile t.filename rw_flag rights
-                with Unix.Unix_error( (Unix.EACCES | Unix.EROFS) ,_,_) ->
-                  Unix.openfile t.filename ro_flag 0o400
-                end
-              else
-                Unix.openfile t.filename ro_flag 0o400
-            in
-            incr cache_size;
-(*            lprintf "local_force: opening %d\n" (Obj.magic fd);  *)
-            Fifo.put cache t;
-            t.fd <- Some fd;
-            fd
-        | Some fd -> fd
+          | Some fd -> fd
+          | None ->
+	      if !cache_size >= !max_cache_size then close_one ();
+	      let fd =
+		try
+		  if t.writable then
+                    Unix.openfile t.filename 
+		      (if creat then rw_creat_flag else rw_flag) rights
+		  else
+		    Unix.openfile t.filename ro_flag 0o400
+		with e ->
+		  lprintf_nl "Exception in FDCache._local_force_fd %s (%s): %s" 
+		    t.filename 
+		    (if t.writable then "rw" else "ro") 
+                    (Printexc2.to_string e);
+		  raise e
+	      in
+		incr cache_size;
+(*              lprintf "local_force: opening %d\n" (Obj.magic fd_rw);  *)
+		Fifo.put cache t;
+		t.fd <- Some fd;
+		fd
       in
 (*      lprintf "local_force_fd %d\n" (Obj.magic fd); *)
-      fd
+	fd
+
+    let create f writable =
+      lprintf "Open %s (%s)\n" f (if writable then "rw" else "ro");
+      let t =
+	{
+         filename = f;
+	 writable = writable;
+         fd = None;
+         destroyed = false;
+        }
+      in
+      let _fd = _local_force_fd true t in
+      t
+      
+    let local_force_fd t = _local_force_fd false t
 
     let close_all () =
       while not (Fifo.empty cache) do
@@ -137,68 +166,126 @@
       done
 
     let rename t f =
-      check_destroyed t;
-      close t;
-      Unix2.rename t.filename f;
-      destroy t
+      try
+	check_destroyed t;
+	close t;
+	Unix2.rename t.filename f;
+	destroy t
+      with e ->
+	lprintf_nl "Exception in FDCache.rename %s %s: %s" 
+	  t.filename 
+	  f
+          (Printexc2.to_string e);
+	raise e
 
     let multi_rename t f file =
-      check_destroyed t;
-      close t;
-      (let d = (Filename.dirname (Filename.concat f file)) in
-        Unix2.safe_mkdir d;
-  Unix2.chmod d (Misc.int_of_octal_string !create_dir_mask);
-	Unix2.can_write_to_directory d);
-      Unix2.rename t.filename (Filename.concat f file);
-      destroy t
+      try
+	check_destroyed t;
+	close t;
+	(let d = (Filename.dirname (Filename.concat f file)) in
+           Unix2.safe_mkdir d;
+           Unix2.chmod d (Misc.int_of_octal_string !create_dir_mask);
+	   Unix2.can_write_to_directory d);
+	Unix2.rename t.filename (Filename.concat f file);
+	destroy t
+      with e ->
+	lprintf_nl "Exception in FDCache.multi_rename %s %s: %s" 
+	  t.filename 
+	  (Filename.concat f file)
+          (Printexc2.to_string e);
+	raise e
 
     let ftruncate64 t len sparse =
-      check_destroyed t;
-      Unix2.c_ftruncate64 (local_force_fd t true) len sparse
+      try
+	check_destroyed t;
+	Unix2.c_ftruncate64 (local_force_fd t) len sparse
+      with e ->
+	lprintf_nl "Exception in FDCache.ftruncate64 %s %Ld (%s): %s" 
+	  t.filename 
+	  len
+	  (if sparse then "sparse" else "not sparse")
+          (Printexc2.to_string e);
+	raise e
 
-    let getsize64 t writable =
-      check_destroyed t;
-      let s = Unix2.c_getfdsize64 (local_force_fd t writable) in
-      if not writable then close t;
-      s
+    let getsize64 t =
+      try
+	check_destroyed t;
+	let was_closed = is_closed t in
+	let s = Unix2.c_getfdsize64 (local_force_fd t) in
+	if was_closed then
+	  close t;
+	s
+      with e ->
+	lprintf_nl "Exception in FDCache.getsize64 %s: %s" 
+	  t.filename 
+          (Printexc2.to_string e);
+	raise e
 
     let mtime64 t =
-      check_destroyed t;
-      let st = Unix.LargeFile.stat t.filename in
-      st.Unix.LargeFile.st_mtime
+      try
+	check_destroyed t;
+	let st = Unix.LargeFile.stat t.filename in
+	st.Unix.LargeFile.st_mtime
+      with e ->
+	lprintf_nl "Exception in FDCache.mtime64 %s: %s" 
+	  t.filename 
+          (Printexc2.to_string e);
+	raise e
 
     let exists t =
-      check_destroyed t;
-      Sys.file_exists t.filename
+      try
+	check_destroyed t;
+	Sys.file_exists t.filename
+      with e ->
+	lprintf_nl "Exception in FDCache.exists %s: %s" 
+	  t.filename 
+          (Printexc2.to_string e);
+	raise e
 
     let remove t =
-      check_destroyed t;
-      if exists t then Sys.remove t.filename;
-      destroy t
+      try
+	check_destroyed t;
+	if exists t then 
+	  Sys.remove t.filename;
+	destroy t
+      with e ->
+	lprintf_nl "Exception in FDCache.remove %s: %s" 
+	  t.filename 
+          (Printexc2.to_string e);
+	raise e
 
     let read file file_pos string string_pos len =
-      let fd = local_force_fd file true in
-      (*
-        I know I am calling local_force_fd with writable = true
-        although we are reading here, but I had problems with
-        it like exceptions in really_write
-      *)
-      let final_pos = Unix2.c_seek64 fd file_pos Unix.SEEK_SET in
-      if verbose then lprintf "really_read %d\n" len;
-      Unix2.really_read fd string string_pos len
+      try
+	let fd = local_force_fd file in
+	let final_pos = Unix2.c_seek64 fd file_pos Unix.SEEK_SET in
+	if verbose then 
+	  lprintf_nl "really_read %d" len;
+	Unix2.really_read fd string string_pos len
+      with e ->
+	lprintf_nl "Exception in FDCache.read %s %Ld %d: %s" 
+	  file.filename 
+	  file_pos
+	  len
+          (Printexc2.to_string e);
+	raise e
 
     let write file file_pos string string_pos len =
-      let fd = local_force_fd file true in
-      let final_pos = Unix2.c_seek64 fd file_pos Unix.SEEK_SET in
-      if verbose then lprintf "really_write %d\n" len;
-      begin
-        try
+      try
+	assert (file.writable);
+	let fd = local_force_fd file in
+	let final_pos = Unix2.c_seek64 fd file_pos Unix.SEEK_SET in
+	  if verbose then 
+	    lprintf_nl "really_write %d" len;
 	  really_write fd string string_pos len
-	with e ->
-	    lprintf_nl "[Unix32] Exception %s in write: file %s file_pos=%Ld len=%d string_pos=%d, string length=%d"
-	      (Printexc2.to_string e) file.filename file_pos len string_pos (String.length string);
-	    raise e
-      end
+      with e ->
+	lprintf_nl "Exception in FDCache.write file %s file_pos=%Ld len=%d string_pos=%d, string length=%d: %s"
+	  file.filename 
+	  file_pos 
+	  len 
+	  string_pos 
+	  (String.length string) 
+	  (Printexc2.to_string e);
+	raise e
 
     let copy_chunk t1 t2 pos1 pos2 len64 =
       check_destroyed t1;
@@ -215,19 +302,29 @@
             iter (remaining -- len64) (pos1 ++ len64) (pos2 ++ len64)
           end
       in
-      iter len64 pos1 pos2
+      try
+	iter len64 pos1 pos2
+      with e ->
+	lprintf_nl "Exception in FDCache.copy_chunk %s %Ld to %s %Ld (%Ld): %s"
+	  t1.filename 
+	  pos1
+	  t2.filename
+	  pos2
+	  len64
+          (Printexc2.to_string e);
+	raise e
 
   end
 
 module type File =   sig
     type t
-    val create : string -> t
+    val create : string -> bool -> t
     val apply_on_chunk : t -> int64 -> int64 ->
       (Unix.file_descr -> int64 -> 'a) -> 'a
     val close : t -> unit
     val rename : t -> string -> unit
     val ftruncate64 : t -> int64 -> bool -> unit
-    val getsize64 : t -> bool -> int64
+    val getsize64 : t -> int64
     val mtime64 : t -> float
     val exists : t -> bool
     val remove : t -> unit
@@ -245,7 +342,7 @@
     let create = FDCache.create
 
     let apply_on_chunk t pos_s len_s f =
-      let fd = FDCache.local_force_fd t true in
+      let fd = FDCache.local_force_fd t in
       f fd pos_s
 
     let close = FDCache.close
@@ -270,7 +367,7 @@
   match !zero_chunk_fd_option with
     Some fd -> fd
   | None ->
-      let fd = FDCache.create zero_chunk_name in
+      let fd = FDCache.create zero_chunk_name true in
       FDCache.ftruncate64 fd zero_chunk_len false;
       zero_chunk_fd_option := Some fd;
       fd
@@ -322,17 +419,14 @@
 
     let rec print_tree indent tree =
       match tree with
-        Leaf file -> lprintf "%s  - %s (%Ld,%Ld)\n"
+        Leaf file -> lprintf_nl "%s  - %s (%Ld,%Ld)"
             indent file.filename file.pos file.len
       | Node (pos, tree1, tree2) ->
-          lprintf "%scut at %Ld\n" indent pos;
+          lprintf_nl "%scut at %Ld" indent pos;
           print_tree (indent ^ "  ") tree1;
           print_tree (indent ^ "  ") tree2
 
-    let rights = 0o664
-    let access = [Unix.O_CREAT; Unix.O_RDWR]
-
-    let create dirname files =
+    let create dirname writable files =
       Unix2.safe_mkdir dirname;
       let rec iter files pos files2 =
         match files with
@@ -354,19 +448,19 @@
         | (filename, size) :: tail ->
             let temp_filename = Filename.concat dirname filename in
             Unix2.safe_mkdir (Filename.dirname temp_filename);
-            let fd = FDCache.create temp_filename in
-            let cur_len = ref Int64.zero in
-            if not (Unix2.is_directory temp_filename) then
-            begin
-              ignore(FDCache.local_force_fd fd true);
-              cur_len := FDCache.getsize64 fd true;
-            end;
+            let fd = FDCache.create temp_filename writable in
+            let cur_len = 
+	      if Unix2.is_directory temp_filename then 0L
+	      else begin
+		ignore(FDCache.local_force_fd fd);
+		FDCache.getsize64 fd
+	      end in
             iter tail (pos ++ size)
             ({
                 filename = filename;
                 pos = pos;
                 len = size;
-                current_len = !cur_len;
+                current_len = cur_len;
                 fd = fd;
                 tail = [];
               } :: files2)
@@ -399,7 +493,7 @@
     let rec fill_zeros file_out file_pos max_len =
       if max_len > zero then
         let max_possible_write = min max_len zero_chunk_len in
-        FDCache.copy_chunk (zero_chunk_fd()) file_out
+        FDCache.copy_chunk (zero_chunk_fd ()) file_out
           zero file_pos max_possible_write;
         fill_zeros file_out (file_pos ++ max_possible_write)
         (max_len -- max_possible_write)
@@ -411,45 +505,49 @@
       let file_begin = file.pos in
       let max_current_pos = file_begin ++ file.current_len in
       if max_current_pos >= chunk_end then
-        let fd = FDCache.local_force_fd file.fd true in
+        let fd = FDCache.local_force_fd file.fd in
         f fd (chunk_begin -- file_begin)
       else
-      let temp_file = Filename.temp_file "chunk" ".tmp" in
-      let file_out = FDCache.create temp_file in
+	let temp_file = Filename.temp_file "chunk" ".tmp" in
+	let file_out = FDCache.create temp_file true in
 
+	try
 (* first file *)
-      let in_pos = chunk_begin -- file_begin in
-      let in_len = max_current_pos -- chunk_begin in
-      FDCache.copy_chunk file.fd file_out
-        in_pos  zero in_len;
-      let zeros =
-        min (chunk_len -- in_len) (file.len -- file.current_len)
-      in
-      fill_zeros file_out in_len zeros;
-      let in_len = in_len ++ zeros in
+	  let in_pos = chunk_begin -- file_begin in
+	  let in_len = max_current_pos -- chunk_begin in
+	  FDCache.copy_chunk file.fd file_out
+            in_pos  zero in_len;
+	  let zeros =
+            min (chunk_len -- in_len) (file.len -- file.current_len) in
+	  fill_zeros file_out in_len zeros;
+	  let in_len = in_len ++ zeros in
 
 (* other files *)
-      do_on_remaining tail in_len  (chunk_len -- in_len)
-      (fun file file_pos len ->
-          let max_current_pos = min len file.current_len in
-          FDCache.copy_chunk file.fd file_out
-            zero file_pos max_current_pos;
-          let file_pos = file_pos ++ max_current_pos in
-          let zeros = len -- max_current_pos in
-          fill_zeros file_out file_pos zeros;
-          file_pos ++ zeros
-      );
-      FDCache.close file_out;
-      let fd = FDCache.local_force_fd file_out true in
-      try 
-        let v = f fd zero in
-        FDCache.close file_out;
-        Sys.remove temp_file;
-        v
-      with e -> 
+	  do_on_remaining tail in_len  (chunk_len -- in_len)
+	    (fun file file_pos len ->
+               let max_current_pos = min len file.current_len in
+	       FDCache.copy_chunk file.fd file_out
+		 zero file_pos max_current_pos;
+	       let file_pos = file_pos ++ max_current_pos in
+               let zeros = len -- max_current_pos in
+	       fill_zeros file_out file_pos zeros;
+	       file_pos ++ zeros
+	    );
+	  FDCache.close file_out;
+	  let fd = FDCache.local_force_fd file_out in
+          let v = f fd zero in
           FDCache.close file_out;
           Sys.remove temp_file;
-          raise e
+          v
+	with e ->
+	  lprintf_nl "Exception in MultiFile.apply_on_chunk %s %Ld %Ld: %s"
+	    t.dirname
+	    chunk_begin
+	    chunk_len
+            (Printexc2.to_string e);
+	  (try FDCache.close file_out with _ -> ());
+	  (try Sys.remove temp_file with _ -> ());
+	  raise e
 
     let close t =
       List.iter (fun file -> FDCache.close file.fd) t.files
@@ -459,7 +557,8 @@
 
     let rename t f =
       close t;
-      List.iter (fun file -> FDCache.multi_rename file.fd f file.filename) t.files
+      List.iter (fun file -> FDCache.multi_rename file.fd f file.filename) 
+	t.files
 
     let ftruncate64 t size sparse =
       t.size <- size
@@ -467,16 +566,28 @@
     let getsize64 t = t.size
 
     let mtime64 t =
-      let st = Unix.LargeFile.stat t.dirname in
-      st.Unix.LargeFile.st_mtime
+      try
+	let st = Unix.LargeFile.stat t.dirname in
+	st.Unix.LargeFile.st_mtime
+      with e ->
+	lprintf_nl "Exception in MultiFile.mtime64 %s: %s" 
+	  t.dirname
+          (Printexc2.to_string e);
+	raise e
 
     let exists t =
       Sys.file_exists t.dirname
 
     let remove t =
-      close t;
-      if Sys.file_exists t.dirname then
-        Unix2.remove_all_directory t.dirname
+      try
+	close t;
+	if Sys.file_exists t.dirname then
+          Unix2.remove_all_directory t.dirname
+      with e ->
+	lprintf_nl "Exception in MultiFile.remove %s: %s" 
+	  t.dirname
+          (Printexc2.to_string e);
+	raise e
 
     let file_write file in_file_pos s in_string_pos len =
       (* prevent write to zero-byte files so BT downloads finish *)
@@ -520,12 +631,12 @@
 
 (* other files *)
       do_on_remaining tail (string_pos + in_len)
-      (chunk_len -- first_read)
-      (fun file string_pos len64 ->
-          let len = Int64.to_int len64 in
-          f file zero string string_pos len;
-          string_pos + len
-      )
+	(chunk_len -- first_read)
+	(fun file string_pos len64 ->
+           let len = Int64.to_int len64 in
+           f file zero string string_pos len;
+           string_pos + len
+	)
 
     let read t chunk_begin string string_pos len =
       io file_read t chunk_begin string string_pos len
@@ -557,11 +668,9 @@
         mutable dirname : string;
         mutable size : int64;
         mutable chunks : chunk array;
+	mutable writable : bool;
       }
     
-    let rights = 0o664
-    let access = [Unix.O_CREAT; Unix.O_RDWR]
-    
     let zero_chunk () =
       {
         chunkname = zero_chunk_name;
@@ -570,10 +679,10 @@
         fd = zero_chunk_fd ();
       }
     
-    let create filename =
-(*      lprintf "SparseFile.create %s\n" filename; *)
+    let create filename writable =
+(*      lprintf_nl "SparseFile.create %s" filename; *)
       let dirname = filename ^ ".chunks" in
-(*      lprintf "Creating directory %s\n" dirname; *)
+(*      lprintf_nl "Creating directory %s" dirname; *)
       Unix2.safe_mkdir dirname;
       Unix2.can_write_to_directory dirname;
       {
@@ -581,60 +690,71 @@
         dirname = dirname;
         chunks = [||];
         size = zero;
+        writable = writable;
       }
     
     let find_read_pos t pos =
       let nchunks = Array.length t.chunks in
       let rec iter t start len =
         if len <= 0 then start else
-        let milen = len/2 in
-        let med = start + milen in
-        let chunk = t.chunks.(med) in
-        if chunk.pos <= pos && pos -- chunk.pos < chunk.len then med else
-        if chunk.pos > pos then
-          if med = start then start else
-            iter t start milen
-        else
-        let next = med+1 in
-        iter t next (start+len-next)
+          let milen = len/2 in
+          let med = start + milen in
+          let chunk = t.chunks.(med) in
+          if chunk.pos <= pos && pos -- chunk.pos < chunk.len then med 
+	  else
+            if chunk.pos > pos then
+              if med = start then start 
+	      else
+		iter t start milen
+            else
+              let next = med+1 in
+	      iter t next (start+len-next)
       in
-      iter t 0 nchunks
+	iter t 0 nchunks
     
     let find_write_pos t pos =
       let nchunks = Array.length t.chunks in
       let rec iter t start len =
-        if len <= 0 then start else
-        let milen = len/2 in
-        let med = start + milen in
-        let chunk = t.chunks.(med) in
-        if chunk.pos <= pos && pos -- chunk.pos <= chunk.len then med else
-        if chunk.pos > pos then
-          if med = start then start else
-            iter t start milen
-        else
-        let next = med+1 in
-        iter t next (start+len-next)
+        if len <= 0 then start 
+	else
+          let milen = len/2 in
+          let med = start + milen in
+          let chunk = t.chunks.(med) in
+          if chunk.pos <= pos && pos -- chunk.pos <= chunk.len then med 
+	  else
+            if chunk.pos > pos then
+              if med = start then start 
+	      else
+		iter t start milen
+            else
+              let next = med+1 in
+	      iter t next (start+len-next)
       in
-      iter t 0 nchunks
+	iter t 0 nchunks
+
+(*  (*** debugging code ***)
 
-(*
     let find_read_pos2 t pos =
       let rec iter t i len =
-        if i = len then i else
-        let chunk = t.chunks.(i) in
-        if chunk.pos ++ chunk.len > pos then i else
-          iter t (i+1) len
+        if i = len then i 
+        else
+          let chunk = t.chunks.(i) in
+          if chunk.pos ++ chunk.len > pos then i 
+          else
+            iter t (i+1) len
       in
-      iter t 0 (Array.length t.chunks)
+        iter t 0 (Array.length t.chunks)
 
     let find_write_pos2 t pos =
       let rec iter t i len =
-        if i = len then i else
-        let chunk = t.chunks.(i) in
-        if chunk.pos ++ chunk.len >= pos then i else
-          iter t (i+1) len
+        if i = len then i 
+        else
+          let chunk = t.chunks.(i) in
+          if chunk.pos ++ chunk.len >= pos then i 
+          else
+            iter t (i+1) len
       in
-      iter t 0 (Array.length t.chunks)
+        iter t 0 (Array.length t.chunks)
 
     let _ =
       let one = 1L in
@@ -642,24 +762,24 @@
       let three = 3L in
       for i = 0 to 3 do
         let chunks = Array.init i (fun i ->
-              let name = string_of_int i in
-              let pos = 3 * i + 1 in
-              let fd = FDCache.create name access rights in
-              lprintf " %d [%d - %d]" i pos (pos+2);
-              {
-                chunkname = name;
-                pos = Int64.of_int pos;
-                len = two;
-                fd = fd;
-              }
-          ) in
-        lprintf "\n";
+          let name = string_of_int i in
+          let pos = 3 * i + 1 in
+          let fd = FDCache.create name writable in
+          lprintf " %d [%d - %d]" i pos (pos+2);
+          {
+            chunkname = name;
+            pos = Int64.of_int pos;
+            len = two;
+            fd = fd;
+          }
+        ) in
+        lprintf_nl "";
         let t = {
-            filename = "";
-            dirname = "";
-            size = zero;
-            chunks = chunks;
-          } in
+          filename = "";
+          dirname = "";
+          size = zero;
+          chunks = chunks;
+        } in
         for j = 0 to 3 * i + 3 do
           let pos = (Int64.of_int j) in
           let i1 = find_write_pos t pos in
@@ -667,7 +787,7 @@
           let i2 = find_write_pos2 t pos in
           assert (i1 = i2)
         done;
-        lprintf "\n";
+        lprintf_nl "";
       done;
       exit 0
 *)
@@ -687,54 +807,59 @@
         
         let chunk = t.chunks.(index) in
         let in_chunk_pos = chunk_begin -- chunk.pos in
-        let fd = FDCache.local_force_fd chunk.fd true in
+        let fd = FDCache.local_force_fd chunk.fd in
         f fd in_chunk_pos
       
       else
       
-      let temp_file = Filename.temp_file "chunk" ".tmp" in
-      let file_out = FDCache.create temp_file in
+	let temp_file = Filename.temp_file "chunk" ".tmp" in
+	let file_out = FDCache.create temp_file t.writable in
       
-      let rec iter pos index chunk_begin chunk_len =
-        
-        if chunk_len > zero then
-          let chunk =
-            if index >= nchunks then 
-              let z = zero_chunk () in
-              z.pos <- chunk_begin;
-              z
-            else
-            let chunk = t.chunks.(index) in
-            let next_pos = chunk.pos in
-            if next_pos > chunk_begin then 
-              let z = zero_chunk () in
-              z.pos <- chunk_begin;
-              z.len <- min zero_chunk_len (next_pos -- chunk_begin);
-              z
-            else
-              chunk
-          in
+	let rec iter pos index chunk_begin chunk_len =
+          if chunk_len > zero then
+            let chunk =
+              if index >= nchunks then 
+		let z = zero_chunk () in
+		z.pos <- chunk_begin;
+		z
+              else
+		let chunk = t.chunks.(index) in
+		let next_pos = chunk.pos in
+		if next_pos > chunk_begin then 
+		  let z = zero_chunk () in
+		  z.pos <- chunk_begin;
+		  z.len <- min zero_chunk_len (next_pos -- chunk_begin);
+		  z
+		else
+		  chunk
+            in
           
-          let in_chunk_pos = chunk_begin -- chunk.pos in
-          let max_len = min chunk_len (chunk.len -- in_chunk_pos) in
+            let in_chunk_pos = chunk_begin -- chunk.pos in
+            let max_len = min chunk_len (chunk.len -- in_chunk_pos) in
           
-          FDCache.copy_chunk chunk.fd file_out
-            in_chunk_pos pos max_len;
-          iter (pos ++ max_len) (index+1) (chunk_begin ++ max_len)
-          (chunk_len -- max_len)
-      
-      in
-      iter zero (find_read_pos t chunk_begin) chunk_begin chunk_len;
-      
-      FDCache.close file_out;
-      let fd = FDCache.local_force_fd file_out true in
-      try
-        let v = f fd zero in
-        Sys.remove temp_file;
-        v
-      with e -> 
-          Sys.remove temp_file;
-          raise e
+            FDCache.copy_chunk chunk.fd file_out
+              in_chunk_pos pos max_len;
+            iter (pos ++ max_len) (index+1) (chunk_begin ++ max_len)
+              (chunk_len -- max_len)
+      
+	in
+	  try
+	    iter zero (find_read_pos t chunk_begin) chunk_begin chunk_len;
+      
+	    FDCache.close file_out;
+	    let fd = FDCache.local_force_fd file_out in
+            let v = f fd zero in
+            Sys.remove temp_file;
+            v
+	  with e -> 
+	    lprintf_nl "Exception in SparseFile.apply_on_chunk %s %Ld %Ld: %s"
+	      t.dirname
+	      chunk_begin
+	      chunk_len
+              (Printexc2.to_string e);
+	    (try FDCache.close file_out with _ -> ());
+	    (try Sys.remove temp_file with _ -> ());
+	    raise e
     
     let close t =
       Array.iter (fun file -> FDCache.close file.fd) t.chunks
@@ -750,10 +875,9 @@
       let index = 0 in
       let nchunks = Array.length t.chunks in
       
-      let file_out = FDCache.create f in
+      let file_out = FDCache.create f true in
       
       let rec iter pos index chunk_begin chunk_len =
-        
         if chunk_len > zero then
           let chunk =
             if index >= nchunks then 
@@ -761,15 +885,15 @@
               z.pos <- chunk_begin;
               z
             else
-            let chunk = t.chunks.(index) in
-            let next_pos = chunk.pos in
-            if next_pos > chunk_begin then 
-              let z = zero_chunk () in
-              z.pos <- chunk_begin;
-              z.len <- min zero_chunk_len (next_pos -- chunk_begin);
-              z
+              let chunk = t.chunks.(index) in
+              let next_pos = chunk.pos in
+	      if next_pos > chunk_begin then 
+		let z = zero_chunk () in
+		z.pos <- chunk_begin;
+		z.len <- min zero_chunk_len (next_pos -- chunk_begin);
+		z
               else
-              chunk
+		chunk
           in
 
           let in_chunk_pos = chunk_begin -- chunk.pos in
@@ -781,35 +905,47 @@
           if chunk.fd != zero_chunk_fd () then FDCache.remove chunk.fd;
 
           iter (pos ++ max_len) (index+1) (chunk_begin ++ max_len)
-          (chunk_len -- max_len)
+            (chunk_len -- max_len)
 
       in
-      iter zero 0 chunk_begin chunk_len;
-      FDCache.close file_out;
-      ()
-(*
-      Sys.rename t.dirname f;
-      List.iter (fun file ->
-          file.fd.FDCache.filename <- Filename.concat t.dirname file.filename
-      ) t.files
+	iter zero 0 chunk_begin chunk_len;
+	FDCache.close file_out;
+	()
+(* (* why is that commented off ? Does SparseFile.rename actually work ? *)
+        Sys.rename t.dirname f;
+        List.iter (fun file ->
+            file.fd.FDCache.filename <- Filename.concat t.dirname file.filename
+        ) t.files
 *)
 
     let ftruncate64 t size sparse =
       t.size <- size
 
-    let getsize64 t writable = t.size
+    let getsize64 t = t.size
 
     let mtime64 t =
-      let st = Unix.LargeFile.stat t.dirname in
-      st.Unix.LargeFile.st_mtime
+      try
+	let st = Unix.LargeFile.stat t.dirname in
+	st.Unix.LargeFile.st_mtime
+      with e ->
+	lprintf_nl "Exception in SparseFile.mtime64 %s: %s"
+	  t.dirname
+          (Printexc2.to_string e);
+	raise e
 
     let exists t =
       Sys.file_exists t.dirname
 
     let remove t =
-      close t;
+      try
+	close t;
 (*      lprintf "Removing %s\n" t.dirname; *)
-      Unix2.remove_all_directory t.dirname
+	Unix2.remove_all_directory t.dirname
+      with e ->
+	lprintf_nl "Exception in SparseFile.remove %s: %s" 
+	  t.dirname
+          (Printexc2.to_string e);
+	raise e
 
     let read t chunk_begin string string_pos chunk_len =
       let chunk_len64 = Int64.of_int chunk_len in
@@ -824,15 +960,15 @@
               z.pos <- chunk_begin;
               z
             else
-            let chunk = t.chunks.(index) in
-            let next_pos = chunk.pos in
-            if next_pos > chunk_begin then 
-              let z = zero_chunk () in
-              z.pos <- chunk_begin;
-              z.len <- min zero_chunk_len (next_pos -- chunk_begin);
-              z
-            else
-              chunk
+              let chunk = t.chunks.(index) in
+              let next_pos = chunk.pos in
+	      if next_pos > chunk_begin then 
+		let z = zero_chunk () in
+		z.pos <- chunk_begin;
+		z.len <- min zero_chunk_len (next_pos -- chunk_begin);
+		z
+              else
+		chunk
           in
 
           let in_chunk_pos = chunk_begin -- chunk.pos in
@@ -841,46 +977,43 @@
 
           FDCache.read chunk.fd in_chunk_pos string string_pos max_len;
           iter (string_pos + max_len) (index+1) (chunk_begin ++ max_len64)
-          (chunk_len64 -- max_len64)
-
+            (chunk_len64 -- max_len64)
 
       in
-      iter string_pos (find_read_pos t chunk_begin) chunk_begin chunk_len64
+	iter string_pos (find_read_pos t chunk_begin) chunk_begin chunk_len64
 
     let write t chunk_begin string string_pos len =
       let index = find_write_pos t chunk_begin in
-
       let len64 = Int64.of_int len in
-
       let nchunks = Array.length t.chunks in
 
       if index = Array.length t.chunks then begin
 (*          lprintf "Adding chunk at end\n"; *)
-          let chunk_name = Int64.to_string chunk_begin in
-          let chunk_name = Filename.concat t.dirname chunk_name in
-          let fd = FDCache.create chunk_name in
-          let chunk = {
-              chunkname = chunk_name;
-              pos = chunk_begin;
-              len = zero;
-              fd = fd;
-            } in
-          let new_array = Array.create (nchunks+1) chunk in
-          Array.blit t.chunks 0 new_array 0 nchunks;
-          t.chunks <- new_array
+        let chunk_name = Int64.to_string chunk_begin in
+        let chunk_name = Filename.concat t.dirname chunk_name in
+        let fd = FDCache.create chunk_name t.writable in
+        let chunk = {
+          chunkname = chunk_name;
+          pos = chunk_begin;
+          len = zero;
+          fd = fd;
+        } in
+        let new_array = Array.create (nchunks+1) chunk in
+        Array.blit t.chunks 0 new_array 0 nchunks;
+        t.chunks <- new_array
 
-        end else
-      if t.chunks.(index).pos > chunk_begin then begin
+      end else
+	if t.chunks.(index).pos > chunk_begin then begin
 (*          lprintf "Inserting chunk\n"; *)
           let chunk_name = Int64.to_string chunk_begin in
           let chunk_name = Filename.concat t.dirname chunk_name in
-          let fd = FDCache.create chunk_name in
+          let fd = FDCache.create chunk_name t.writable in
           let chunk = {
-              chunkname = chunk_name;
-              pos = chunk_begin;
-              len = zero;
-              fd = fd;
-            } in
+            chunkname = chunk_name;
+            pos = chunk_begin;
+            len = zero;
+            fd = fd;
+          } in
           let new_array = Array.create (nchunks+1) chunk in
           Array.blit t.chunks 0 new_array 0 index;
           Array.blit t.chunks index new_array (index+1) (nchunks-index);
@@ -894,15 +1027,15 @@
             if index = nchunks-1 then
               index, len, Int64.of_int len
             else
-            let max_pos = t.chunks.(index+1).pos in
-            let max_possible_len64 = max_pos -- chunk_begin in
-            let len64 = Int64.of_int len in
-            let max_len64 = min max_possible_len64 len64 in
-            let max_len = Int64.to_int max_len64 in
-            if max_len64 = max_possible_len64 then
-              index+1, max_len, max_len64
-            else
-              index, max_len, max_len64
+              let max_pos = t.chunks.(index+1).pos in
+              let max_possible_len64 = max_pos -- chunk_begin in
+              let len64 = Int64.of_int len in
+              let max_len64 = min max_possible_len64 len64 in
+              let max_len = Int64.to_int max_len64 in
+	      if max_len64 = max_possible_len64 then
+		index+1, max_len, max_len64
+              else
+		index, max_len, max_len64
           in
 
           let chunk = t.chunks.(index) in
@@ -911,9 +1044,9 @@
           chunk.len <- chunk.len ++ max_len64;
 
           iter next_index (chunk_begin ++ max_len64)
-          (string_pos + max_len) (len - max_len)
+            (string_pos + max_len) (len - max_len)
       in
-      iter index chunk_begin string_pos len;
+	iter index chunk_begin string_pos len;
 
       t.size <- max t.size (chunk_begin ++ len64);
 
@@ -934,6 +1067,7 @@
 type file = {
     mutable file_kind : file_kind;
     mutable filename : string;
+    mutable writable : bool;
     mutable error : exn option;
     mutable buffers : (string * int * int * int64 * int64) list;
   }
@@ -941,47 +1075,55 @@
 module H = Weak.Make(struct
       type old_t = file
       type t = old_t
-      let hash t = Hashtbl.hash t.filename
+      let hash t = Hashtbl.hash (t.filename, t.writable)
 
-      let equal x y  = x.filename = y.filename
+      let equal x y  = x.filename = y.filename && x.writable = y.writable
     end)
 
 let dummy =  {
-    file_kind = DiskFile (DiskFile.create "");
+    file_kind = Destroyed;
     filename = "";
+    writable = false;
     error = None;
     buffers = [];
   }
 
 let table = H.create 100
 
-let create f creator =
+let create f writable creator =
   try
-    let fd = H.find table { dummy with filename = f } in
+    let fd = H.find table { dummy with filename = f; writable = writable } in
 (*    lprintf "%s already exists\n" f; *)
     fd
-  with _ ->
-      let t =  {
-          file_kind = creator f;
-          filename = f;
-          error = None;
-          buffers = [];
-        } in
-      H.add table t;
-      t
-    
-    
-      
-let create_diskfile filename _ _ =
-  create filename (fun f -> DiskFile (DiskFile.create f))
-
-let create_multifile filename _ _ files =
-  create filename (fun f ->
-      MultiFile (MultiFile.create f files))
-
-let create_sparsefile filename =
-  create filename (fun f ->
-      SparseFile (SparseFile.create f))
+  with Not_found ->
+    let t = {
+      file_kind = creator f;
+      filename = f;
+      writable = writable;
+      error = None;
+      buffers = [];
+    } in
+    H.add table t;
+    t
+
+(* check if a writable descriptor on the same file exists *)
+let find_writable fd =
+  if fd.writable then Some fd
+  else
+    try
+      Some (H.find table { fd with writable = true })
+    with Not_found -> None
+      
+let create_diskfile filename writable =
+  create filename writable (fun f -> DiskFile (DiskFile.create f writable))
+
+let create_multifile filename writable files =
+  create filename writable (fun f ->
+    MultiFile (MultiFile.create f writable files))
+
+let create_sparsefile filename writable =
+  create filename writable (fun f ->
+    SparseFile (SparseFile.create f writable))
 
 let ftruncate64 t len sparse =
   match t.file_kind with
@@ -997,12 +1139,12 @@
   | SparseFile t -> SparseFile.mtime64 t
   | Destroyed -> failwith "Unix32.mtime64 on destroyed FD"
       
-let getsize64 t writable =
+let getsize64 t =
   match t.file_kind with
-  | DiskFile t -> DiskFile.getsize64 t writable
+  | DiskFile t -> DiskFile.getsize64 t
     (* only avoid opening rw on shared files, shared files can only be DiskFile *)
   | MultiFile t -> MultiFile.getsize64 t
-  | SparseFile t -> SparseFile.getsize64 t writable
+  | SparseFile t -> SparseFile.getsize64 t
   | Destroyed -> failwith "Unix32.getsize64 on destroyed FD"
 
 let fds_size = Unix2.c_getdtablesize ()
@@ -1010,105 +1152,92 @@
 let buffered_bytes = ref Int64.zero
 let modified_files = ref []
 
-(*
-let _ =
-
-  lprintf "Your system supports %d file descriptors\n" fds_size;
-  lprintf "You can download files up to %s\n\n"
-    ( match Unix2.c_sizeofoff_t () with
-	|  4 -> "2GB"
-	|  _ -> Printf.sprintf "2^%d-1 bits (do the maths ;-p)"
-	     ((Unix2.c_sizeofoff_t () *8)-1)			
-    )
-*)
-
-(* at most 50 files can be opened simultaneously *)
-
-
 let filename t = t.filename
 
 let write file file_pos string string_pos len =
   if len > 0 then
-  match file.file_kind with
-  | DiskFile t -> DiskFile.write t file_pos string string_pos len
-  | MultiFile t -> MultiFile.write t file_pos string string_pos len
-  | SparseFile t -> SparseFile.write t file_pos string string_pos len
-  | Destroyed -> failwith "Unix32.write on destroyed FD"
+    match file.file_kind with
+      | DiskFile t -> DiskFile.write t file_pos string string_pos len
+      | MultiFile t -> MultiFile.write t file_pos string string_pos len
+      | SparseFile t -> SparseFile.write t file_pos string string_pos len
+      | Destroyed -> failwith "Unix32.write on destroyed FD"
   else
-    lprintf "Unix32.write: error, invalid argument len = 0\n"
+    lprintf_nl "Unix32.write: error, invalid argument len = 0"
         
 let buffer = Buffer.create 65000
 
-
 let flush_buffer t offset =
-  if verbose then lprintf "flush_buffer\n";
+  if verbose then lprintf_nl "flush_buffer";
   let s = Buffer.contents buffer in
   Buffer.reset buffer;
   let len = String.length s in
   try
-    if verbose then lprintf "seek64 %Ld\n" offset;
+    if verbose then lprintf_nl "seek64 %Ld" offset;
     if len > 0 then write t offset s 0 len;
 (*
     let fd, offset =  fd_of_chunk t offset (Int64.of_int len) in
     let final_pos = Unix2.c_seek64 fd offset Unix.SEEK_SET in
-    if verbose then lprintf "really_write %d\n" len;
+    if verbose then lprintf_nl "really_write %d" len;
     Unix2.really_write fd s 0 len;
 *)
     buffered_bytes := !buffered_bytes -- (Int64.of_int len);
-    if verbose then lprintf "written %d bytes (%Ld)\n" len !buffered_bytes;
+    if verbose then lprintf_nl "written %d bytes (%Ld)" len !buffered_bytes;
   with e ->
-      lprintf "exception %s in flush_buffer\n" (Printexc2.to_string e);
-      t.buffers <- (s, 0, len, offset, Int64.of_int len) :: t.buffers;
-      raise e
+    lprintf_nl "exception %s in flush_buffer" (Printexc2.to_string e);
+    t.buffers <- (s, 0, len, offset, Int64.of_int len) :: t.buffers;
+    raise e
 
 let flush_fd t =
-  if t.buffers = [] then () else
-  let list =
-    List.sort (fun (_, _, _, o1, l1) (_, _, _, o2, l2) ->
-        let c = compare o1 o2 in
-        if c = 0 then compare l2 l1 else c)
-    t.buffers
-  in
-  if verbose then lprintf "flush_fd\n";
-  t.buffers <- list;
-  let rec iter_out () =
-    match t.buffers with
-      [] -> ()
-    | (s, pos_s, len_s, offset, len) :: tail ->
-        Buffer.reset buffer;
-        Buffer.add_substring buffer s pos_s len_s;
-        t.buffers <- tail;
-        iter_in offset len
-
-  and iter_in offset len =
-    match t.buffers with
-      [] -> flush_buffer t offset
-    | (s, pos_s, len_s, offset2, len2) :: tail ->
-        let in_offset = offset ++ len -- offset2 in
-        if in_offset = Int64.zero then begin
-            Buffer.add_substring buffer s pos_s len_s;
-            t.buffers <- tail;
-            iter_in offset (len ++ len2);
-          end else
-        if in_offset < Int64.zero then begin
-            flush_buffer t offset;
-            iter_out ()
-          end else
-        let keep_len = len2 -- in_offset in
-        if verbose then lprintf "overlap %Ld\n" keep_len;
-        t.buffers <- tail;
-        if keep_len <= Int64.zero then begin
-            buffered_bytes := !buffered_bytes -- len2;
-            iter_in offset len
-          end else begin
-            let new_pos = len2 -- keep_len in
-            Buffer.add_substring buffer s
-              (pos_s + Int64.to_int new_pos) (Int64.to_int keep_len);
-            buffered_bytes := !buffered_bytes -- new_pos;
-            iter_in offset (len ++ keep_len)
-          end
-  in
-  iter_out ()
+  match find_writable t with
+  | None -> ()
+  | Some t ->
+      if t.buffers = [] then () else
+	let list =
+	  List.sort (fun (_, _, _, o1, l1) (_, _, _, o2, l2) ->
+	    let c = compare o1 o2 in
+            if c = 0 then compare l2 l1 else c)
+	    t.buffers
+	in
+	if verbose then lprintf_nl "flush_fd";
+	t.buffers <- list;
+	let rec iter_out () =
+	  match t.buffers with
+	  | [] -> ()
+	  | (s, pos_s, len_s, offset, len) :: tail ->
+              Buffer.reset buffer;
+              Buffer.add_substring buffer s pos_s len_s;
+              t.buffers <- tail;
+              iter_in offset len
+
+	and iter_in offset len =
+	  match t.buffers with
+	  | [] -> flush_buffer t offset
+	  | (s, pos_s, len_s, offset2, len2) :: tail ->
+              let in_offset = offset ++ len -- offset2 in
+              if in_offset = Int64.zero then begin
+		Buffer.add_substring buffer s pos_s len_s;
+		t.buffers <- tail;
+		iter_in offset (len ++ len2);
+              end else
+		if in_offset < Int64.zero then begin
+		  flush_buffer t offset;
+		  iter_out ()
+		end else
+		  let keep_len = len2 -- in_offset in
+		  if verbose then lprintf_nl "overlap %Ld" keep_len;
+		  t.buffers <- tail;
+		  if keep_len <= 0L then begin
+		    buffered_bytes := !buffered_bytes -- len2;
+		    iter_in offset len
+		  end else begin
+		    let new_pos = len2 -- keep_len in
+		    Buffer.add_substring buffer s
+		      (pos_s + Int64.to_int new_pos) (Int64.to_int keep_len);
+		    buffered_bytes := !buffered_bytes -- new_pos;
+		    iter_in offset (len ++ keep_len)
+		  end
+	in
+	iter_out ()
 
 let read t file_pos string string_pos len =
   flush_fd t;
@@ -1122,41 +1251,41 @@
       
 let flush _ =
   try
-    if verbose then lprintf "flush all\n";
+    if verbose then lprintf_nl "flush all";
     let rec iter list =
       match list with
-        [] -> []
+      | [] -> []
       | t :: tail ->
           try
             flush_fd t;
             t.error <- None;
             iter tail
           with e ->
-              t.error <- Some e;
-              t :: (iter tail)
+            t.error <- Some e;
+            t :: (iter tail)
     in
-    modified_files := iter !modified_files;
-    if !buffered_bytes <> Int64.zero then
-      lprintf "[ERROR] remaining bytes after flush\n"
+      modified_files := iter !modified_files;
+      if !buffered_bytes <> 0L then
+	lprintf_nl "[ERROR] remaining bytes after flush"
   with e ->
-      lprintf "[ERROR] Exception %s in Unix32.flush\n"
+      lprintf_nl "[ERROR] Exception %s in Unix32.flush"
         (Printexc2.to_string e)
 
 let buffered_write t offset s pos_s len_s =
   let len = Int64.of_int len_s in
   match t.error with
-    None ->
+  | None ->
       if len > Int64.zero then begin
-          if not (List.memq t !modified_files) then
-            modified_files := t:: !modified_files;
-          t.buffers <- (s, pos_s, len_s, offset, len) :: t.buffers;
-          buffered_bytes := !buffered_bytes ++ len;
-          if verbose then
-            lprintf "buffering %Ld bytes (%Ld)\n" len !buffered_bytes;
+        if not (List.memq t !modified_files) then
+          modified_files := t :: !modified_files;
+        t.buffers <- (s, pos_s, len_s, offset, len) :: t.buffers;
+        buffered_bytes := !buffered_bytes ++ len;
+        if verbose then
+          lprintf_nl "buffering %Ld bytes (%Ld)" len !buffered_bytes;
 
 (* Don't buffer more than 1 Mo *)
-          if !buffered_bytes > !max_buffered then flush ()
-        end
+        if !buffered_bytes > !max_buffered then flush ()
+      end
   | Some e ->
       raise e
 
@@ -1177,18 +1306,19 @@
       iter (remaining - len) (pos1 ++ len64) (pos2 ++ len64)
     end
   in
-  iter len pos1 pos2
+    iter len pos1 pos2
 
 let mega = megabytes 1
+
 let rec copy t1 t2 pos1 pos2 len64 = 
   if len64 > mega then begin
-      copy_chunk t1 t2 pos1 pos2 (Int64.to_int mega);
-      copy t1 t2 (pos1 ++ mega) (pos2 ++ mega) (len64 -- mega)
-    end else
+    copy_chunk t1 t2 pos1 pos2 (Int64.to_int mega);
+    copy t1 t2 (pos1 ++ mega) (pos2 ++ mega) (len64 -- mega)
+  end else
     copy_chunk t1 t2 pos1 pos2 (Int64.to_int len64)
 
-
 let close_all = FDCache.close_all
+
 let close t =
   flush_fd t;
   match t.file_kind with
@@ -1199,18 +1329,17 @@
 
 let destroy t =
   if t.file_kind <> Destroyed then begin
-      H.remove table t;
-      (match t.file_kind with
-        | DiskFile t -> DiskFile.destroy t
-        | MultiFile t -> MultiFile.destroy t
-        | SparseFile t -> SparseFile.destroy t
-        | Destroyed -> ());
-      t.file_kind <- Destroyed
-    end
+    H.remove table t;
+    (match t.file_kind with
+     | DiskFile t -> DiskFile.destroy t
+     | MultiFile t -> MultiFile.destroy t
+     | SparseFile t -> SparseFile.destroy t
+     | Destroyed -> ());
+    t.file_kind <- Destroyed
+  end
     
-(* let create_ro filename = create_diskfile filename ro_flag 0o666 *)
-let create_rw filename = create_diskfile filename rw_flag 0o666
-let create_ro = create_rw
+let create_rw filename = create_diskfile filename true
+let create_ro filename = create_diskfile filename false
 
 let apply_on_chunk t pos len f =
   match t.file_kind with
@@ -1238,10 +1367,15 @@
   | SparseFile t -> SparseFile.remove t
   | Destroyed -> failwith "Unix32.remove on destroyed FD"
       
-let getsize s writable =  getsize64 (create_ro s) writable
+let getsize s =  getsize64 (create_ro s)
 let mtime s =  mtime64 (create_ro s)
 
-let file_exists s = exists (create_ro s)
+let file_exists s = 
+  (* We use this instead of Sys.file_exists, in case exists has side
+     effects ? *)
+  try 
+    exists (create_ro s)
+  with Unix.Unix_error (Unix.ENOENT, _, _) -> false
 
 let rename t f =
   flush_fd t;
@@ -1272,121 +1406,122 @@
 * copy_chunk: remove this
 *)
     
-    type t = {
-        file : file;
-        mutable file_parts : part list;
-      }
-    
-    and part = {
-        mutable part_file : file;
-        mutable part_begin : int64;
-        mutable part_len : int64;
-        mutable part_end : int64;
-        mutable part_shared : t list;
-      }
-    
-    let copy_shared_parts_out file parts =
-      List2.tail_map (fun part ->
-          if part.part_file == file then 
-            match part.part_shared with
-              [] -> part
-            | t :: tail ->
-                lprintf "Copy shared part to another file\n";
-                copy part.part_file t.file part.part_begin part.part_begin
-                  part.part_len;
-                lprintf "   Copy done.\n";
-                part.part_file <- t.file;
-                part.part_shared <- tail;
-                { part with part_file = file; part_shared = [] }
-          else part
-      ) parts
-    
-    let copy_shared_parts_in file parts =
-      List2.tail_map (fun part ->
-          if part.part_file != file then begin
-              lprintf "Copy shared part to another file\n";
-              copy part.part_file file part.part_begin part.part_begin
-                part.part_len;
-              lprintf "   Copy done.\n";
-              part.part_shared <- List.filter (fun t -> t.file != file) 
-              part.part_shared;
-              { part with part_file = file; part_shared = [] }
-            end else part
-      ) parts
-    
-    let remove t =
-      t.file_parts <- copy_shared_parts_out t.file t.file_parts;
-      remove t.file
-    
-    let destroy t = 
-      t.file_parts <- copy_shared_parts_out t.file t.file_parts;
-      destroy t.file
-    
-    let old_close = close
-    
-    let close t = close t.file
-    let getsize64 t  = getsize64 t.file
-    let filename t = filename t.file
-    
-    let rename t file_name = 
-      t.file_parts <- copy_shared_parts_in t.file t.file_parts;
-      t.file_parts <- copy_shared_parts_out t.file t.file_parts;
-      rename t.file file_name
-    
-    let mtime64 t = mtime64 t.file
-    let flush_fd t = flush_fd t.file
+  type t = {
+    file : file;
+    mutable file_parts : part list;
+  }
     
-    let apply_on_parts f t file_pos s pos len =
-      List.iter (fun part ->
-          f part.part_file file_pos s pos len) t.file_parts
+  and part = {
+    mutable part_file : file;
+    mutable part_begin : int64;
+    mutable part_len : int64;
+    mutable part_end : int64;
+    mutable part_shared : t list;
+  }
     
-    let buffered_write t file_pos s pos len =
-      apply_on_parts buffered_write t file_pos s pos len
+  let copy_shared_parts_out file parts =
+    List2.tail_map (fun part ->
+      if part.part_file == file then 
+        match part.part_shared with
+        | [] -> part
+        | t :: tail ->
+            lprintf_nl "Copy shared part to another file";
+            copy part.part_file t.file part.part_begin part.part_begin
+              part.part_len;
+            lprintf_nl "   Copy done.";
+            part.part_file <- t.file;
+            part.part_shared <- tail;
+            { part with part_file = file; part_shared = [] }
+      else part
+    ) parts
+    
+  let copy_shared_parts_in file parts =
+    List2.tail_map (fun part ->
+      if part.part_file != file then begin
+        lprintf_nl "Copy shared part to another file";
+        copy part.part_file file part.part_begin part.part_begin
+          part.part_len;
+        lprintf_nl "   Copy done.";
+        part.part_shared <- List.filter (fun t -> t.file != file) 
+          part.part_shared;
+        { part with part_file = file; part_shared = [] }
+      end else 
+	part
+    ) parts
+    
+  let remove t =
+    t.file_parts <- copy_shared_parts_out t.file t.file_parts;
+    remove t.file
+    
+  let destroy t = 
+    t.file_parts <- copy_shared_parts_out t.file t.file_parts;
+    destroy t.file
+    
+  let old_close = close
+    
+  let close t = close t.file
+  let getsize64 t  = getsize64 t.file
+  let filename t = filename t.file
+    
+  let rename t file_name = 
+    t.file_parts <- copy_shared_parts_in t.file t.file_parts;
+    t.file_parts <- copy_shared_parts_out t.file t.file_parts;
+    rename t.file file_name
+    
+  let mtime64 t = mtime64 t.file
+  let flush_fd t = flush_fd t.file
+    
+  let apply_on_parts f t file_pos s pos len =
+    List.iter (fun part ->
+      f part.part_file file_pos s pos len) t.file_parts
+    
+  let buffered_write t file_pos s pos len =
+    apply_on_parts buffered_write t file_pos s pos len
     
-    let buffered_write_copy t file_pos s pos len =
-      apply_on_parts buffered_write_copy t file_pos s pos len
+  let buffered_write_copy t file_pos s pos len =
+    apply_on_parts buffered_write_copy t file_pos s pos len
     
-    let write t file_pos s pos len =
-      apply_on_parts write t file_pos s pos len
+  let write t file_pos s pos len =
+    apply_on_parts write t file_pos s pos len
     
-    let read t file_pos s pos len =
-      apply_on_parts read t file_pos s pos len
+  let read t file_pos s pos len =
+    apply_on_parts read t file_pos s pos len
 
 
 
 (* TODO: there is no need to create a temporary file when the wanted chunk
-overlaps different parts, but these parts are on the same physical file. *)
-    let apply_on_chunk t chunk_begin chunk_len f =
-      let chunk_end = chunk_begin ++ chunk_len in
-      let rec iter list =
-        match list with 
-          [] -> assert false
-        | part :: tail ->
-            if part.part_begin <= chunk_begin &&
-              part.part_end >= chunk_end then
+ * overlaps different parts, but these parts are on the same physical file. *)
+  let apply_on_chunk t chunk_begin chunk_len f =
+    let chunk_end = chunk_begin ++ chunk_len in
+    let rec iter list =
+      match list with 
+      | [] -> assert false
+      | part :: tail ->
+          if part.part_begin <= chunk_begin &&
+            part.part_end >= chunk_end then
               apply_on_chunk part.part_file chunk_begin chunk_len f
-            else
+          else
             if part.part_end > chunk_begin then
               make_temp_file list
             else
               iter tail
       
-      and make_temp_file list = 
-        let temp_file = Filename.temp_file "chunk" ".tmp" in
-        let file_out = create_rw temp_file in
+    and make_temp_file list = 
+      let temp_file = Filename.temp_file "chunk" ".tmp" in
+      let file_out = create_rw temp_file in
         
-        let rec fill pos chunk_begin chunk_len list =
-          if chunk_len > zero then
-            match list with
-              [] -> ()
-            | part :: tail ->
+      let rec fill pos chunk_begin chunk_len list =
+        if chunk_len > zero then
+          match list with
+          | [] -> ()
+          | part :: tail ->
                 
-                let tocopy = min chunk_len (part.part_end -- chunk_begin) in
-                copy_chunk part.part_file file_out chunk_begin pos 
-                  (Int64.to_int tocopy);
-                fill (pos ++ tocopy) (chunk_begin ++ tocopy)
+              let tocopy = min chunk_len (part.part_end -- chunk_begin) in
+              copy_chunk part.part_file file_out chunk_begin pos 
+                (Int64.to_int tocopy);
+              fill (pos ++ tocopy) (chunk_begin ++ tocopy)
                 (chunk_len -- tocopy) tail
-        in
+      in
         fill zero chunk_begin chunk_len list;
         old_close file_out;
         try
@@ -1394,61 +1529,56 @@
           Sys.remove temp_file;
           v
         with e ->
-            Sys.remove temp_file;
-            raise e
+          (try Sys.remove temp_file with _ -> ());
+          raise e
       
       in
-      
-      iter t.file_parts
+        iter t.file_parts
     
-    let ftruncate64 t len sparse = 
-      ftruncate64 t.file len sparse
+  let ftruncate64 t len sparse = 
+    ftruncate64 t.file len sparse
     
-    let maxint64 = megabytes 1000000
+  let maxint64 = megabytes 1000000
     
-    let create file =
-      let part = { 
-          part_file = file;
-          part_begin = zero;
-          part_end = maxint64;
-          part_len = maxint64;
-          part_shared = []
-        } in
+  let create file =
+    let part = { 
+      part_file = file;
+      part_begin = zero;
+      part_end = maxint64;
+      part_len = maxint64;
+      part_shared = []
+    } in
       { file = file; file_parts = [part] }
     
-    let create_diskfile file_name flags rights =
-      create (create_diskfile file_name flags rights)
+  let create_diskfile file_name writable =
+    create (create_diskfile file_name writable)
     
-    let create_multifile file_name flags rights files =
-      create (create_multifile file_name flags rights files)
+  let create_multifile file_name writable files =
+    create (create_multifile file_name writable files)
     
-    let create_sparsefile file_name =
-      create (create_sparsefile file_name)
+  let create_sparsefile file_name writable =
+    create (create_sparsefile file_name writable)
     
-    let create_ro filename = 
-      create (create_ro filename)
+  let create_ro filename = 
+    create (create_ro filename)
     
-    let create_rw filename = 
-      create (create_rw filename)
+  let create_rw filename = 
+    create (create_rw filename)
 
 (* the new part (shared_begin, shared_len) is shared between t1 and t2.
 It will be kept inside t1, and used by t2. The problem is what happens
 when these two files have already been partially downloaded ? This 
   problem has to be solved at a upper level. *)
-    let shared_part t1 t2 shared_begin shared_len = 
-      let shared_end = shared_begin ++ shared_len in
-      ()
+  let shared_part t1 t2 shared_begin shared_len = 
+    let shared_end = shared_begin ++ shared_len in
+    ()
       
-  end
+end
+
 let destroyed t = t.file_kind = Destroyed
   
 type t = file
 
-let bad_fd = 
-  let t = create_rw "/dev/null" in
-  t.file_kind <- Destroyed;
-  t
-
 type statfs = {
   f_type : int64;   (* type of filesystem *)
   f_bsize : int64;  (* optimal transfer block size *)
@@ -1617,8 +1747,8 @@
 
 let _ =
   Heap.add_memstat "Unix32" (fun level buf ->
-      let counter = ref 0 in
-      H.iter (fun _ -> incr counter) table;
-      Printf.bprintf buf "  table: %d\n" !counter;
-      Printf.bprintf buf "  modified_files: %d\n" (List.length !modified_files);
+    let counter = ref 0 in
+    H.iter (fun _ -> incr counter) table;
+    Printf.bprintf buf "  table: %d\n" !counter;
+    Printf.bprintf buf "  modified_files: %d\n" (List.length !modified_files);
   )
Index: src/utils/lib/unix32.mli
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/src/utils/lib/unix32.mli,v
retrieving revision 1.18
diff -u -r1.18 unix32.mli
--- src/utils/lib/unix32.mli	23 Oct 2005 16:05:42 -0000	1.18
+++ src/utils/lib/unix32.mli	20 Nov 2005 15:30:28 -0000
@@ -34,8 +34,9 @@
 (* val force_fd : t -> Unix.file_descr *)
   
 (* val seek64 : t -> int64 -> Unix.seek_command -> int64  *)
-val getsize : string -> bool -> int64
-val getsize64 : t -> bool -> int64
+val getsize : string -> int64
+val getsize64 : t -> int64
+(* size, sparse flag *)
 val ftruncate64 : t -> int64 -> bool -> unit
 
 val close_all : unit -> unit
@@ -66,29 +67,29 @@
   (Unix.file_descr -> int64 -> 'a) -> 'a
   
 
-val create_diskfile : string -> Unix.open_flag list -> int -> t
+val create_diskfile : string -> bool -> t
 val create_ro : string -> t
 val create_rw : string -> t
   
 (* 
-[create_multifile dirname access rights files]: create a directory
+[create_multifile dirname writable files]: create a directory
 [dirname] containing the files in [files]. [files] is a list of tuples
 [(filename, size)] where [filename] is relative inside the directory
 [dirname] and [size] is the size of the files. 
   *)
   
 val create_multifile :     
-  string -> Unix.open_flag list -> int -> (string * int64) list -> t
+  string -> bool -> (string * int64) list -> t
 
-val create_sparsefile :  string -> t
+val create_sparsefile :  string -> bool -> t
 
 val ro_flag :  Unix.open_flag list
 val rw_flag :  Unix.open_flag list
   
 val destroy : t -> unit
   
-val bad_fd : t
-  
+val dummy : t
+
 val destroyed : t -> bool
 
 val bsize : string -> int64 option
Index: tools/get_range.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/tools/get_range.ml,v
retrieving revision 1.4
diff -u -r1.4 get_range.ml
--- tools/get_range.ml	28 May 2005 11:19:43 -0000	1.4
+++ tools/get_range.ml	20 Nov 2005 15:30:28 -0000
@@ -53,7 +53,7 @@
       "size" -> 
         if Array.length Sys.argv <> 3 then usage ();
         let filename = argv.(2) in
-        Printf.printf "[SIZE %Ld]\n" (Unix32.getsize filename false)
+        Printf.printf "[SIZE %Ld]\n" (Unix32.getsize filename)
         
     | "range" ->
         if Array.length Sys.argv <> 6 then usage ();
@@ -111,4 +111,4 @@
   with e ->
       lprintf "Exception %s\n" (Printexc2.to_string e);
       exit 2
-      
\ No newline at end of file
+      
Index: tools/make_torrent.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/tools/make_torrent.ml,v
retrieving revision 1.7
diff -u -r1.7 make_torrent.ml
--- tools/make_torrent.ml	19 Oct 2005 13:02:28 -0000	1.7
+++ tools/make_torrent.ml	20 Nov 2005 15:30:28 -0000
@@ -150,12 +150,12 @@
               torrent.torrent_name (Filename.basename filename);
           end;
         let t = if torrent.torrent_files <> [] then
-            Unix32.create_multifile filename Unix32.ro_flag 0o666
+            Unix32.create_multifile filename false
               torrent.torrent_files
           else  Unix32.create_ro filename
         in
 
-        let length = Unix32.getsize64 t false in
+        let length = Unix32.getsize64 t in
 
         if torrent.torrent_length <> length then begin
             Printf.printf "ERROR: computed size %Ld <> torrent size %Ld\n"
Index: tools/mld_hash.ml
===================================================================
RCS file: /cvsroot/mldonkey/mldonkey/tools/mld_hash.ml,v
retrieving revision 1.5
diff -u -r1.5 mld_hash.ml
--- tools/mld_hash.ml	19 Oct 2005 12:43:27 -0000	1.5
+++ tools/mld_hash.ml	20 Nov 2005 15:30:28 -0000
@@ -90,7 +90,7 @@
   let sha1 = Sha1.digest_subfile fd zero file_size in
   let tiger = TigerTree.digest_subfile fd zero file_size in
   lprintf "urn:bitprint:%s.%s\n" (Sha1.to_string sha1) (TigerTree.to_string tiger);
-  let file_size = Unix32.getsize64 fd false in
+  let file_size = Unix32.getsize64 fd in
   let nchunks = Int64.to_int (Int64.pred file_size // tiger_block_size) + 1 in
   let chunks = 
     let chunks = Array.create nchunks tiger in
@@ -115,8 +115,8 @@
 (*************************************************************************)
   
 let bitprint_filename filename partial =
-  let fd = Unix32.create_rw filename in
-  let file_size = Unix32.getsize64 fd false in
+  let fd = Unix32.create_ro filename in
+  let file_size = Unix32.getsize64 fd in
   let (sha1, tiger2) = bitprint_file fd file_size partial in
   lprintf "urn:bitprint:%s.%s\n" (Sha1.to_string sha1) (TigerTree.to_string tiger2);
   ()
@@ -155,8 +155,8 @@
 (*************************************************************************)
 
 let sha1_hash_filename block_size filename =
-  let fd = Unix32.create_rw filename in
-  let file_size = Unix32.getsize64 fd false in
+  let fd = Unix32.create_ro filename in
+  let file_size = Unix32.getsize64 fd in
   let nchunks = Int64.to_int (Int64.pred file_size // block_size) + 1 in
   for i = 0 to nchunks - 1 do
     let begin_pos = block_size ** (Int64.of_int i) in
@@ -175,8 +175,8 @@
 (*************************************************************************)
   
 let ed2k_hash_filename filename partial = 
-  let fd = Unix32.create_rw filename in
-  let file_size = Unix32.getsize64 fd false in
+  let fd = Unix32.create_ro filename in
+  let file_size = Unix32.getsize64 fd in
   let md4 = ed2k_hash_file fd file_size partial in
   lprintf "ed2k://|file|%s|%Ld|%s|/\n" 
     (Url.encode (Filename.basename filename))
@@ -190,8 +190,8 @@
 (*************************************************************************)
   
 let sig2dat_hash_filename filename partial =
-  let fd = Unix32.create_rw filename in
-  let file_size = Unix32.getsize64 fd false in
+  let fd = Unix32.create_ro filename in
+  let file_size = Unix32.getsize64 fd in
   let len64 = min 307200L file_size in
   let len = Int64.to_int len64 in
   let s = String.create len in
@@ -222,10 +222,10 @@
   let dummy_string = "bonjourhello1" in
   
   let create_diskfile filename size =
-    Unix32.create_diskfile filename Unix32.rw_flag 0o066
+    Unix32.create_diskfile filename true
   in
   let create_sparsefile filename size =
-    Unix32.create_sparsefile filename
+    Unix32.create_sparsefile filename true
   in
   let create_multifile filename size =    
     let rec iter pos size list =
@@ -242,7 +242,7 @@
         lprintf "    %-50s %Ld\n" name size;
     ) files;
     Unix32.create_multifile filename 
-      Unix32.rw_flag 0o066  files
+      true  files
   in    
   
   let (file_types : (string * (string -> int64 -> Unix32.t)
@@ -351,8 +351,8 @@
   let len = Int64.to_int (end_pos -- begin_pos) in
   let s1 = String.create len in
   let s2 = String.create len in
-  let fd1 = Unix32.create_rw filename1 in
-  let fd2 = Unix32.create_rw filename2 in
+  let fd1 = Unix32.create_ro filename1 in
+  let fd2 = Unix32.create_ro filename2 in
   Unix32.read fd1 begin_pos s1 0 len;
   Unix32.read fd2 begin_pos s2 0 len;
   
