diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/daemon/common/commonComplexOptions.ml ./src/daemon/common/commonComplexOptions.ml
--- ./src/daemon/common/commonComplexOptions.ml	2006-07-14 15:24:23.000000000 +0200
+++ ./src/daemon/common/commonComplexOptions.ml	2006-07-20 13:35:29.000000000 +0200
@@ -104,7 +104,7 @@
 
           (try
               set_file_best_name file
-              (get_value "file_filename" value_to_string)
+              (get_value "file_filename" value_to_string) "" 0
             with _ -> ());
           set_file_priority file priority;
 
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/daemon/common/commonFile.ml ./src/daemon/common/commonFile.ml
--- ./src/daemon/common/commonFile.ml	2006-06-11 19:37:38.000000000 +0200
+++ ./src/daemon/common/commonFile.ml	2006-07-20 13:35:29.000000000 +0200
@@ -251,10 +251,10 @@
   let file = as_file_impl file in
   file.impl_file_best_name
   
-let set_file_best_name file name =
+let set_file_best_name file name fs namemax =
   let file = as_file_impl file in
   let old_name = file.impl_file_best_name in
-  let real_name = Filename2.filesystem_compliant name "" in
+  let real_name = Filename2.filesystem_compliant name fs namemax in
   if real_name = "" then
     lprintf_nl "can not rename file \"%s\" to \"%s\""
       (String.escaped file.impl_file_best_name) (String.escaped real_name)
@@ -661,7 +661,7 @@
       Printf.bprintf buf "[%-s %5d]\n%s\n%s%s\nTotal   %10s\nPartial %10s\npriority %d\n"
         n.network_name
         (file_num file)
-        (String2.shorten 80 (file_best_name file))
+        (shorten (file_best_name file) 80)
 	(match file_magic file with
 	   Some magic -> Printf.sprintf "%s\n" magic
 	 | None -> "")
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/daemon/common/commonFile.mli ./src/daemon/common/commonFile.mli
--- ./src/daemon/common/commonFile.mli	2006-06-11 19:37:38.000000000 +0200
+++ ./src/daemon/common/commonFile.mli	2006-07-20 13:35:29.000000000 +0200
@@ -82,7 +82,7 @@
 val file_resume : CommonTypes.file -> unit
 val set_file_state : CommonTypes.file -> CommonTypes.file_state -> unit
 val file_best_name : CommonTypes.file -> string
-val set_file_best_name : CommonTypes.file -> string -> unit
+val set_file_best_name : CommonTypes.file -> string -> string -> int -> unit
 val set_file_format : CommonTypes.file -> CommonTypes.format -> unit
 val file_check : CommonTypes.file -> unit
 val file_recover : CommonTypes.file -> unit
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/daemon/common/commonInteractive.ml ./src/daemon/common/commonInteractive.ml
--- ./src/daemon/common/commonInteractive.ml	2006-07-14 16:23:37.000000000 +0200
+++ ./src/daemon/common/commonInteractive.ml	2006-07-20 13:35:29.000000000 +0200
@@ -128,22 +128,31 @@
     end
 
 let file_commited_name incoming_dir file =
-  let best_name = file_best_name file in
   (try Unix2.safe_mkdir incoming_dir with _ -> ());
+  let fs = Unix32.filesystem incoming_dir in
+  let namemax =
+    match Unix32.fnamelen incoming_dir with
+      None -> 0
+    | Some v -> Int64.to_int v in
+
   let new_name =
-    Filename.concat incoming_dir (canonize_basename best_name)
-  in
+    Filename2.filesystem_compliant 
+      (canonize_basename (file_best_name file)) fs namemax in
+
   let new_name =
-    if Sys.file_exists new_name then
+    if Sys.file_exists (Filename.concat incoming_dir new_name) then
       let rec iter num =
-        let new_name = Printf.sprintf "%s.%d" new_name num in
-        if Sys.file_exists new_name then
-          iter (num+1)
-        else new_name
+        let new_name =
+	  Filename2.filesystem_compliant
+            (Printf.sprintf "%s_%d" new_name num) fs namemax in
+          if Sys.file_exists (Filename.concat incoming_dir new_name) then
+            iter (num+1)
+          else new_name
       in
       iter 1
     else new_name in
-  new_name
+  set_file_best_name file (file_best_name file) "" 0;
+  Filename.concat incoming_dir new_name
 
 let script_for_file file incoming new_name =
   let info = file_info file in
@@ -227,8 +236,7 @@
 	      | _ -> ()
 	    end;
 
-	  let new_name = file_commited_name
-            incoming.shdir_dirname file in
+	  let new_name = file_commited_name incoming.shdir_dirname file in
 	    if Unix2.is_directory file_name then begin
 	      Unix2.safe_mkdir new_name;
 	      Unix2.chmod new_name (Misc.int_of_octal_string !!create_dir_mask)
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/daemon/driver/driverCommands.ml ./src/daemon/driver/driverCommands.ml
--- ./src/daemon/driver/driverCommands.ml	2006-07-14 16:23:37.000000000 +0200
+++ ./src/daemon/driver/driverCommands.ml	2006-07-20 13:35:29.000000000 +0200
@@ -2719,7 +2719,7 @@
         let num = int_of_string arg in
         try
           let file = file_find num in
-          set_file_best_name file new_name;
+          set_file_best_name file new_name "" 0;
           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>";
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/daemon/driver/driverInterface.ml ./src/daemon/driver/driverInterface.ml
--- ./src/daemon/driver/driverInterface.ml	2006-06-27 22:25:51.000000000 +0200
+++ ./src/daemon/driver/driverInterface.ml	2006-07-20 13:35:29.000000000 +0200
@@ -831,7 +831,7 @@
           
           | P.SaveFile (num, name) ->
               let file = file_find num in
-              set_file_best_name file name;
+              set_file_best_name file name "" 0;
               (match file_state file with
                   FileDownloaded ->
                     file_save_as file name;
@@ -888,7 +888,7 @@
           
           | P.RenameFile (num, new_name) ->
               let file = file_find num in
-              set_file_best_name file new_name;
+              set_file_best_name file new_name "" 0;
               addevent gui.gui_events.gui_files num true
           
           | P.ConnectFriend num 
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/networks/donkey/donkeyComplexOptions.ml ./src/networks/donkey/donkeyComplexOptions.ml
--- ./src/networks/donkey/donkeyComplexOptions.ml	2006-06-27 23:20:28.000000000 +0200
+++ ./src/networks/donkey/donkeyComplexOptions.ml	2006-07-20 13:35:29.000000000 +0200
@@ -282,7 +282,7 @@
 
   (try
       set_file_best_name (as_file file)
-      (get_value "file_filename" value_to_string)
+      (get_value "file_filename" value_to_string) "" 0
     with _ -> update_best_name file);
   
   let md4s = try get_value "file_md4s" (value_to_array value_to_md4) 
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/networks/donkey/donkeyGlobals.ml ./src/networks/donkey/donkeyGlobals.ml
--- ./src/networks/donkey/donkeyGlobals.ml	2006-06-27 23:20:28.000000000 +0200
+++ ./src/networks/donkey/donkeyGlobals.ml	2006-07-20 13:35:29.000000000 +0200
@@ -303,7 +303,7 @@
       match impl.impl_file_probable_name with
         None -> ()
       | Some best_name ->
-          set_file_best_name file best_name
+          set_file_best_name file best_name "" 0
     with Not_found -> ()
 
 let new_file file_diskname file_state md4 file_size filenames writable =
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/networks/donkey/donkeyInteractive.ml ./src/networks/donkey/donkeyInteractive.ml
--- ./src/networks/donkey/donkeyInteractive.ml	2006-07-20 13:05:42.000000000 +0200
+++ ./src/networks/donkey/donkeyInteractive.ml	2006-07-20 13:35:29.000000000 +0200
@@ -563,7 +563,7 @@
         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
+	  let name2 = Filename2.filesystem_compliant name "" 0 in
 	    if name2 = "" then
 	      Printf.sprintf "urn_ed2k_%s" md4
 	    else
@@ -1188,7 +1188,7 @@
 let _ =
   file_ops.op_file_save_as <- (fun file name ->
       file.file_filenames <- [name, noips()];
-      set_file_best_name (as_file file) name
+      set_file_best_name (as_file file) name "" 0
   );
   file_ops.op_file_set_format <- (fun file format ->
       file.file_format <- format);
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/utils/cdk/filename2.ml ./src/utils/cdk/filename2.ml
--- ./src/utils/cdk/filename2.ml	2006-01-04 15:11:55.000000000 +0100
+++ ./src/utils/cdk/filename2.ml	2006-07-20 13:38:15.000000000 +0200
@@ -109,15 +109,6 @@
 let to_string filename =
   List.fold_left (fun file f -> f file) filename !to_strings
 
-  
-let shorten max s =
-  let len = String.length s in
-  if len > max then 
-    Printf.sprintf "%s...%s" (String.sub s 0 (max - 7))
-    (String.sub s (len-4) 4)
-  else s
-    
-    
 let path_of_filename filename =
   let filename = String.copy filename in
   let len = String.length filename in
@@ -141,7 +132,7 @@
   in
   iter (path_of_filename filename) filename
 
-let filesystem_compliant name fs =
+let filesystem_compliant name fs namemax =
   (* replace all illegal characters with a valid one.
      assumes all filesystems accept '_'s in filenames *)
   let escape_chars p filename =
@@ -202,12 +193,43 @@
       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 sys_checked_name =
+    if Autoconf.windows then 
+      windows_compliant name
+    else if Autoconf.system = "macosx" then 
+      macosx_compliant name
+    else 
+      posix_compliant name in
+
+  let fs_checked_name =
+    let remove_last_spaces s =
+      let len = String.length s in
+      let rec aux n =
+        if n = 0 then n
+        else
+          let n1 = n - 1 in
+          if s.[n1] = ' ' then aux n1
+          else n in
+      let last_space = aux len in
+      if last_space = len then s
+      else String.sub s 0 last_space
+    in
+(* FAT filesystems do not allow files with space as last char *)
+    match fs with
+      "msdos" -> remove_last_spaces sys_checked_name
+    | _ -> sys_checked_name in
+
+  let length_checked_name =
+    if namemax = 0 || String.length sys_checked_name < namemax then
+      fs_checked_name
+    else
+      let ext = extension fs_checked_name in
+        if String.length ext > namemax then
+          String.sub fs_checked_name 0 namemax
+        else
+	  String.sub fs_checked_name 0 (namemax - (String.length ext)) ^ ext
+  in
+  length_checked_name
 
 let temp_directory () =
   match Sys.os_type with
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/utils/cdk/filename2.mli ./src/utils/cdk/filename2.mli
--- ./src/utils/cdk/filename2.mli	2006-01-04 15:11:55.000000000 +0100
+++ ./src/utils/cdk/filename2.mli	2006-07-20 13:35:29.000000000 +0200
@@ -54,15 +54,13 @@
 (*d [to_string filename] converts [filename] to a string using registered
 conversion functions. *)
   
-val shorten : int -> string -> string
-  
 (* transform a filename in a list of dirname *)
 val path_of_filename : string -> string list
   
 val basename : string -> string
   
-(* remove invalid chars in a filename, depending on the filesystem *)
-val filesystem_compliant : string -> string -> string
+(* remove invalid chars in a filename, depending on the filesystem, 
+   trim filename length to allowed limit on filesystem *)
+val filesystem_compliant : string -> string -> int -> string
 
 val temp_directory : unit -> string
-  
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/utils/cdk/string2.ml ./src/utils/cdk/string2.ml
--- ./src/utils/cdk/string2.ml	2006-06-12 12:02:59.000000000 +0200
+++ ./src/utils/cdk/string2.ml	2006-07-20 13:35:29.000000000 +0200
@@ -271,12 +271,6 @@
     if s.[i] == c1 then s.[i] <- c2
   done
 
-let shorten max s =
-  let len = String.length s in
-  if len > max then 
-    String.sub s 0 max
-  else s
-
 let stem s =
   let s = String.lowercase (String.copy s) in
   for i = 0 to String.length s - 1 do
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/utils/cdk/string2.mli ./src/utils/cdk/string2.mli
--- ./src/utils/cdk/string2.mli	2006-06-12 12:02:59.000000000 +0200
+++ ./src/utils/cdk/string2.mli	2006-07-20 13:35:29.000000000 +0200
@@ -95,9 +95,6 @@
 (* [replace_char s c1 c2] replaces char [c1] by char [c2] in [s] *)
 val replace_char : string -> char -> char -> unit
 
-(* [shorten max s] cuts [s] to [max] chars if [s] is longer than [max] *)
-val shorten : int -> string -> string
-  
 (* [stem s] cuts the string [s] in small words, for indexation eg *)
 val stem : string -> string list
   
