commit 74eaf99b83297bf6b9cd9a650e0a3fb8002693ce
Author: ygrek <ygrek@autistici.org>
Date:   Sat Nov 13 22:14:06 2010 +0200

    DC: fix sharing on Windows
    
    factor out CommonFile.concat_file for safe path construction

diff --git src/daemon/common/commonFile.ml src/daemon/common/commonFile.ml
index 4aed6ea..956c5d3 100644
--- src/daemon/common/commonFile.ml
+++ src/daemon/common/commonFile.ml
@@ -1267,3 +1267,13 @@ let lprintf_file_nl file fmt =
   lprintf_nl2 ("[" ^ (file_network file).network_shortname ^
 	       "] [file_num " ^ (string_of_int (file_num file)) ^ "]" ^
 	       "[temp " ^ (file_disk_name file) ^ "]") fmt
+
+let concat_file dir filename =
+  let fs = Unix32.filesystem dir in
+  let namemax =
+    match Unix32.fnamelen dir with
+    | None -> 0
+    | Some v -> v
+  in
+  Filename.concat dir (Filename2.filesystem_compliant filename fs namemax)
+
diff --git src/daemon/common/commonFile.mli src/daemon/common/commonFile.mli
index b06d60a..e542233 100644
--- src/daemon/common/commonFile.mli
+++ src/daemon/common/commonFile.mli
@@ -157,3 +157,7 @@ val file_owner : CommonTypes.file -> CommonTypes.userdb
 val set_file_group : CommonTypes.file -> CommonTypes.groupdb option -> unit
 val file_group : CommonTypes.file -> CommonTypes.groupdb option
 val lprintf_file_nl : CommonTypes.file -> ('a, unit, unit) Pervasives.format -> 'a
+
+(** [concat_file dir filename] sanitizes [filename] and appends it to [dir] *)
+val concat_file : string -> string -> string
+
diff --git src/daemon/common/commonInteractive.ml src/daemon/common/commonInteractive.ml
index 7c52568..3a14857 100644
--- src/daemon/common/commonInteractive.ml
+++ src/daemon/common/commonInteractive.ml
@@ -151,7 +151,7 @@ let file_committed_name incoming_dir file =
       in
       iter 1
     else new_name in
-  set_file_best_name file (file_best_name file) "" 0;
+  set_file_best_name file (file_best_name file) fs namemax;
   Filename.concat incoming_dir new_name
 
 let script_for_file file incoming new_name =
diff --git src/networks/bittorrent/bTInteractive.ml src/networks/bittorrent/bTInteractive.ml
index bf0a809..eba8f63 100644
--- src/networks/bittorrent/bTInteractive.ml
+++ src/networks/bittorrent/bTInteractive.ml
@@ -703,16 +703,7 @@ let load_torrent_string s user group =
     (if torrent.torrent_announce_list <> [] then torrent.torrent_announce_list else [torrent.torrent_announce]);
   if not !torrent_is_usable then raise (Torrent_can_not_be_used torrent.torrent_name);
 
-  let torrent_diskname =
-    let fs = Unix32.filesystem downloads_directory in
-    let namemax =
-      match Unix32.fnamelen downloads_directory with
-      | None -> 0
-      | Some v -> v
-    in
-    Filename.concat downloads_directory
-    (Filename2.filesystem_compliant torrent.torrent_name fs namemax) ^ ".torrent"
-    in
+  let torrent_diskname = CommonFile.concat_file downloads_directory (torrent.torrent_name ^ ".torrent") in
   if Sys.file_exists torrent_diskname then
     begin
       if !verbose then lprintf_nl "load_torrent_string: %s already exists, ignoring" torrent_diskname;
diff --git src/networks/direct_connect/dcClients.ml src/networks/direct_connect/dcClients.ml
index 7a90515..7829e64 100644
--- src/networks/direct_connect/dcClients.ml
+++ src/networks/direct_connect/dcClients.ml
@@ -944,8 +944,8 @@ let rec client_reader c t sock =
           let mylist = try DcShared.make_xml_mylist (DcShared.find_dir_exn dir) 
             with exn -> failwith (Printf.sprintf "PartialList %s : %s" dir (Printexc2.to_string exn))
           in 
-          let filename = Filename.concat directconnect_directory
-            (Printf.sprintf "mylist.%s.partial.xml.bz2" (DcGlobals.safe_filename (clients_username c)))
+          let filename = CommonFile.concat_file directconnect_directory
+            (Printf.sprintf "mylist.%s.partial.xml.bz2" (clients_username c))
           in
           DcShared.buffer_to_bz2_to_file mylist filename;
           c.client_state <- DcUploadListStarting filename;
diff --git src/networks/direct_connect/dcGlobals.ml src/networks/direct_connect/dcGlobals.ml
index e79aaf4..e30c2fc 100644
--- src/networks/direct_connect/dcGlobals.ml
+++ src/networks/direct_connect/dcGlobals.ml
@@ -502,18 +502,7 @@ let new_upfile dcsh fd =
   } in
   file
 
-(* FIXME review *)
-let safe_filename s =
-  let s = String.copy s in
-  for i = 0 to String.length s - 1 do
-    match s.[i] with
-    | c when Char.code c < 32 -> s.[i] <- '_'
-    | '.' | '/' | '\\' | ':' -> s.[i] <- '_'
-    | _ -> ()
-  done;
-  s
-
-(* Return existing file or create new one *)     
+(* Return existing file or create new one *)
 let new_file tiger_root (directory:string) (filename:string) (file_size:int64) =
   (try
     let f = Hashtbl.find dc_files_by_unchecked_hash tiger_root in
@@ -527,12 +516,12 @@ let new_file tiger_root (directory:string) (filename:string) (file_size:int64) =
       if !verbose_download then lprintf_nl "File exists: (%s) (%s)" f.file_directory f.file_name;
       f 
   with _ ->
-      let temp_filename = safe_filename
+      let temp_filename =
         (match tiger_root with
         | "" -> Printf.sprintf "DC_%s_%s" directory filename
         | _ -> Printf.sprintf "DC_%s" tiger_root)
       in 
-      let fullname = Filename.concat !!temp_directory temp_filename in
+      let fullname = CommonFile.concat_file !!temp_directory temp_filename in
       let temp_file = Unix32.create_rw fullname in
       let current_size = 
         (try
diff --git src/networks/direct_connect/dcShared.ml src/networks/direct_connect/dcShared.ml
index c0c3dec..1a1c29a 100644
--- src/networks/direct_connect/dcShared.ml
+++ src/networks/direct_connect/dcShared.ml
@@ -322,6 +322,12 @@ let dc_updatesharesize () =
 
 let _ = 
   network.op_network_share <- (fun fullname codedname size -> (* this is called once/60s with all shared files *)
+    (* file path in DC network should use '/' as separator, convert local path accordingly *)
+    let codedname =
+      match Filename2.slash with 
+      | '/' -> codedname
+      | c -> let s = String.copy codedname in String2.replace_char s c '/'; s
+    in
     (try
       let dcsh = Hashtbl.find dc_shared_files_by_fullname fullname in
       if (dcsh.dc_shared_size = size) then begin            (* if size is correct... *)
diff --git src/utils/cdk/filename2.mli src/utils/cdk/filename2.mli
index fc190dd..28f2094 100644
--- src/utils/cdk/filename2.mli
+++ src/utils/cdk/filename2.mli
@@ -17,6 +17,9 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *)
 
+val slash : char
+(** character used as a directory separator in file paths *)
+
 val dirname : string -> string 
 (*d [dirname filename] returns the dirname of [filename] after normalization *)
 
