Index: src/daemon/common/commonFile.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/daemon/common/commonFile.ml,v
retrieving revision 1.46
diff -u -r1.46 commonFile.ml
--- src/daemon/common/commonFile.ml	14 Dec 2005 21:17:46 -0000	1.46
+++ src/daemon/common/commonFile.ml	2 Jan 2006 22:01:42 -0000
@@ -252,8 +252,20 @@
   
 let set_file_best_name file name =
   let file = as_file_impl file in
-  let name = String2.replace name '/' "::" in
-  file.impl_file_best_name <- name
+  let old_name = file.impl_file_best_name in
+  let real_name = Filename2.filesystem_compliant name "" in
+  if real_name = "" then
+    lprintf_nl () "can not rename file \"%s\" to \"%s\""
+      file.impl_file_best_name real_name
+  else begin
+    file.impl_file_best_name <- real_name;
+    if name <> real_name then
+      lprintf_nl () "wanted new name \"%s\" changed to \"%s\" due to system limitations"
+        (String.escaped name) (String.escaped file.impl_file_best_name);
+    if !verbose && old_name <> file.impl_file_best_name then
+      lprintf_nl () "best_name of \"%s\" changed to \"%s\""
+        (String.escaped old_name) (String.escaped file.impl_file_best_name)
+  end
 
 let set_file_format (file : file) format =
   let file = as_file_impl file in
Index: src/daemon/driver/driverCommands.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/daemon/driver/driverCommands.ml,v
retrieving revision 1.108
diff -u -r1.108 driverCommands.ml
--- src/daemon/driver/driverCommands.ml	1 Jan 2006 19:25:42 -0000	1.108
+++ src/daemon/driver/driverCommands.ml	2 Jan 2006 22:01:44 -0000
@@ -1992,9 +1992,7 @@
 \\<td class=downloaded width=100%%\\>\\</td\\>
 \\<td nowrap class=\\\"fbig pr\\\"\\>\\<a onclick=\\\"javascript: {
                    var getdir = prompt('Input: <priority#> <directory> (surround dir with quotes if necessary)','0 /home/mldonkey/share')
-                   var reg = new RegExp (' ', 'gi') ;
-                   var outstr = getdir.replace(reg, '+');
-                   parent.fstatus.location.href='submit?q=share+' + encodeURI(outstr);
+                   parent.fstatus.location.href='submit?q=share+' + encodeURIComponent(getdir);
                    setTimeout('window.location.reload()',1000);
                     }\\\"\\>Add Share\\</a\\>
 \\</td\\>
@@ -2662,8 +2660,8 @@
         try
           let file = file_find num in
           set_file_best_name file new_name;
-          Printf.sprintf (_b "Download %d renamed to %s") num new_name
-        with _ -> Printf.sprintf (_b "No file number %d") num
+          Printf.sprintf (_b "Download %d renamed to %s") num (file_best_name file)
+        with e -> Printf.sprintf (_b "No file number %d, error %s") num (Printexc2.to_string e)
     ), "<num> \"<new name>\" :\t\tchange name of download <num> to <new name>";
 
     "dllink", Arg_multiple (fun args o ->
Index: src/networks/donkey/donkeyGlobals.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/networks/donkey/donkeyGlobals.ml,v
retrieving revision 1.65
diff -u -r1.65 donkeyGlobals.ml
--- src/networks/donkey/donkeyGlobals.ml	1 Jan 2006 19:27:07 -0000	1.65
+++ src/networks/donkey/donkeyGlobals.ml	2 Jan 2006 22:01:45 -0000
@@ -277,9 +277,7 @@
       match impl.impl_file_probable_name with
         None -> ()
       | Some best_name ->
-          let best_name = String2.replace best_name '/' "::" in
-          set_file_best_name file best_name;
-          if !verbose then lprintf_nl () "BEST NAME now IS %s" best_name;
+          set_file_best_name file best_name
     with Not_found -> ()
 
 let new_file file_diskname file_state md4 file_size filenames writable =
Index: src/networks/donkey/donkeyInteractive.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/networks/donkey/donkeyInteractive.ml,v
retrieving revision 1.78
diff -u -r1.78 donkeyInteractive.ml
--- src/networks/donkey/donkeyInteractive.ml	1 Jan 2006 19:27:07 -0000	1.78
+++ src/networks/donkey/donkeyInteractive.ml	2 Jan 2006 22:01:46 -0000
@@ -547,6 +547,13 @@
       else
         let md4 = if String.length md4 > 32 then
           String.sub md4 0 32 else md4 in
+	let name =
+	  let name2 = Filename2.filesystem_compliant name "" in
+	    if name2 = "" then
+	      Printf.sprintf "urn_ed2k_%s" md4
+	    else
+	      name2
+	in
           begin try
             let file = query_download [name] (Int64.of_string size)
               (Md4.of_string md4) None None None false;
@@ -790,9 +797,7 @@
 \\<!--
 function submitRenameForm(i) {
 var formID = document.getElementById(\\\"renameForm\\\" + i)
-var regExp = new RegExp (' ', 'gi') ;
-var renameTextOut = formID.newName.value.replace(regExp, '+');
-parent.fstatus.location.href='submit?q=rename+'+i+'+\\\"'+encodeURI(renameTextOut)+'\\\"';
+parent.fstatus.location.href='submit?q=rename+'+i+'+\\\"'+encodeURIComponent(formID.newName.value)+'\\\"';
 }
 //--\\>
 \\</script\\>";
@@ -1279,9 +1284,7 @@
 \\<!--
 function submitRenameForm(i) {
 var formID = document.getElementById(\\\"renameForm\\\" + i)
-var regExp = new RegExp (' ', 'gi') ;
-var renameTextOut = formID.newName.value.replace(regExp, '+');
-parent.fstatus.location.href='submit?q=rename+%d+\\\"'+encodeURI(renameTextOut)+'\\\"';
+parent.fstatus.location.href='submit?q=rename+%d+\\\"'+encodeURIComponent(formID.newName.value)+'\\\"';
 }
 //--\\>
 \\</script\\>" (file_num file)
Index: src/utils/cdk/filename2.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/utils/cdk/filename2.ml,v
retrieving revision 1.3
diff -u -r1.3 filename2.ml
--- src/utils/cdk/filename2.ml	17 Oct 2005 15:25:46 -0000	1.3
+++ src/utils/cdk/filename2.ml	2 Jan 2006 22:01:46 -0000
@@ -141,14 +141,73 @@
   in
   iter (path_of_filename filename) filename
 
-let escaped filename =
-  let s = String.copy filename in
-  for i = 0 to String.length filename - 1 do
-    match filename.[i] with
-    | '\\' | '/' | ':' -> s.[i] <- '_'
-    | _ -> ()
-  done;
-  s
+let filesystem_compliant name fs =
+  (* replace all illegal characters with a valid one.
+     assumes all filesystems accept '_'s in filenames *)
+  let escape_chars p filename =
+    let s = String.copy filename in
+    for i = 0 to String.length filename - 1 do
+      if p s.[i] then s.[i] <- '_'
+    done;
+    s in
+
+  (* remove all illegal characters at the beginning of filename *)
+  let trim_left p filename =
+    let len = String.length filename in
+    let left =
+      let rec aux i =
+	if i < len && p filename.[i] then aux (i+1) else i in
+      aux 0 in
+    if left = 0 then filename
+    else
+      String.sub filename left (len - left) in
+
+  (* remove all illegal characters at the end of filename *)
+  let trim_right p filename =
+    let len = String.length filename in
+    let right =
+      let rec aux i =
+	if i > 0 && p filename.[i-1] then aux (i-1) else i in
+      aux len in
+    if right = len then filename
+    else
+      String.sub filename 0 right in
+
+  let minimal_filter c =
+    match c with
+      | '/' | '\\' | '<' | '>' | '"' -> true
+      | _ -> false in
+
+  let posix_compliant name =
+    escape_chars minimal_filter name in
+
+  let windows_compliant name =
+    (* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/creating__deleting__and_maintaining_files.asp *)
+    let windows_filter c = 
+      minimal_filter c ||
+	match c with
+	  | '*' | '?' | '|' | ':' | '"' -> true
+	  | _ -> false in
+
+    (* Windows has additional restrictions:
+       - filenames cannot start with a '.' 
+       - filenames cannot end with '.' or space *)
+    let name = trim_left (fun c -> c = '.') name in
+    let name = trim_right (fun c -> c = '.' || c = ' ') name in
+    escape_chars windows_filter name in
+
+  let macosx_compliant name =
+  (* ':' is directory seperator on Mac OS X: http://www.comentum.com/File-Systems-HFS-FAT-UFS.html *)
+    let macosx_filter c = 
+      minimal_filter c || c = ':' in
+    escape_chars macosx_filter name in
+
+  if Autoconf.windows then 
+    windows_compliant name
+  else if Autoconf.system = "macosx" then 
+    macosx_compliant name
+  else 
+    posix_compliant name
 
 let temp_directory () =
   match Sys.os_type with
Index: src/utils/cdk/filename2.mli
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/utils/cdk/filename2.mli,v
retrieving revision 1.3
diff -u -r1.3 filename2.mli
--- src/utils/cdk/filename2.mli	17 Oct 2005 15:25:46 -0000	1.3
+++ src/utils/cdk/filename2.mli	2 Jan 2006 22:01:47 -0000
@@ -61,7 +61,8 @@
   
 val basename : string -> string
   
-val escaped : string -> string
+(* remove invalid chars in a filename, depending on the filesystem *)
+val filesystem_compliant : string -> string -> string
 
 val temp_directory : unit -> string
-  
\ No newline at end of file
+  
Index: src/utils/cdk/string2.mli
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/utils/cdk/string2.mli,v
retrieving revision 1.7
diff -u -r1.7 string2.mli
--- src/utils/cdk/string2.mli	19 Aug 2004 07:56:55 -0000	1.7
+++ src/utils/cdk/string2.mli	2 Jan 2006 22:01:47 -0000
@@ -103,7 +103,3 @@
   
 val map : (char -> 'a) -> string -> 'a array
 val iteri: (int -> char -> unit) -> string -> unit
-  
-
-val init : int -> (int -> char) -> string
-  
\ No newline at end of file
