diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x '*.cmi' -x '*.cmx' -x '*.cma' -x '*.cmo' -x '*.o' -x '*.a' -x '*.cmxa' -x output.0 -x requests -x traces.0 -x confdefs.h -x config.h -x config.log -x config.status -x configure -x Makefile.config -x .depend -x mlnet -x Makefile -x mldonkey.rc -x ocamlpp.byte -x packages -x cddb_lexer.ml -x autoconf.ml.new -x autoconf.ml -x .cvsignore -N -r -u ./src/daemon/common/commonComplexOptions.ml ./src/daemon/common/commonComplexOptions.ml
--- ./src/daemon/common/commonComplexOptions.ml	2006-07-20 17:32:28.000000000 +0200
+++ ./src/daemon/common/commonComplexOptions.ml	2006-07-20 17:32:39.000000000 +0200
@@ -912,7 +912,7 @@
 
 let search_incoming_files () =
   try
-    List.find (fun s -> s.shdir_strategy = "incoming_files") 
+    List.find_all (fun s -> s.shdir_strategy = "incoming_files") 
     !!shared_directories
   with Not_found ->
         let dirname = Filename.concat "incoming" "files" in
@@ -924,17 +924,11 @@
           }
         in
         shared_directories =:= s :: !!shared_directories;
-        s
-
-let incoming_files () =
-  let dir = search_incoming_files () in
-    Unix2.safe_mkdir dir.shdir_dirname;
-    Unix2.can_write_to_directory dir.shdir_dirname;
-    dir
+        [s]
 
 let search_incoming_directories () =
   try
-    List.find (fun s -> s.shdir_strategy = "incoming_directories") 
+    List.find_all (fun s -> s.shdir_strategy = "incoming_directories") 
     !!shared_directories
   with Not_found ->
       let dirname = Filename.concat "incoming" "directories" in
@@ -946,13 +940,71 @@
         }
       in
       shared_directories =:= s :: !!shared_directories;
-      s
+      [s]
+
+exception Incoming_full
+
+let incoming_dir usedir ?user ?needed_space ?network () =
+
+  let directories =
+    if usedir then
+      search_incoming_directories ()
+    else
+      search_incoming_files ()
+  in
+
+  let dirname_user =
+    match user with
+    | None -> ""
+    | Some user -> (user2_user_find user).user_commit_dir
+  in
+
+(*
+  let dirname_network =
+    match network with
+    | None -> ""
+    | Some network -> network
+  in
+*)
+(* todo: make the dir naming order user configurable *)
+  let compute_dir_name dir =
+    let dirname = Filename.concat dir dirname_user in
+(*    let dirname = Filename.concat dirname dirname_network in *)
+    dirname
+  in
+
+  let checkdir =
+    try
+      List.find (fun d ->
+	let dirname = compute_dir_name d.shdir_dirname in
+(* check if temp_directory and incoming are on different partitions *)
+	try
+          if (Unix.stat dirname).Unix.st_dev <> (Unix.stat !!temp_directory).Unix.st_dev then
+            begin
+              match needed_space with
+              | None -> true
+              | Some needed_space ->
+                  match Unix32.diskfree dirname with
+                    Some v -> v >= needed_space
+	          | _ -> true
+            end
+          else true
+	with _ -> true
+        ) directories
+    with Not_found -> raise Incoming_full;
+  in
+
+  let newdir = {
+      shdir_dirname = (compute_dir_name checkdir.shdir_dirname);
+      shdir_priority = checkdir.shdir_priority;
+      shdir_networks = checkdir.shdir_networks;
+      shdir_strategy = checkdir.shdir_strategy;
+    }
+  in
+  Unix2.safe_mkdir newdir.shdir_dirname;
+  Unix2.can_write_to_directory newdir.shdir_dirname;
+  newdir
 
-let incoming_directories () =
-  let dir = search_incoming_directories () in
-    Unix2.safe_mkdir dir.shdir_dirname;
-    Unix2.can_write_to_directory dir.shdir_dirname;
-    dir
 
 let _ =
 (* Check the definition of the incoming_files and incoming_directories in
@@ -961,8 +1013,8 @@
   option_hook shared_directories (fun _ ->
       if not !verification then begin
           verification := true;
-          ignore (incoming_files ());
-          ignore (incoming_directories ());
+          ignore (incoming_dir false ());
+          ignore (incoming_dir true ());
           verification := false
         end
   )
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x '*.cmi' -x '*.cmx' -x '*.cma' -x '*.cmo' -x '*.o' -x '*.a' -x '*.cmxa' -x output.0 -x requests -x traces.0 -x confdefs.h -x config.h -x config.log -x config.status -x configure -x Makefile.config -x .depend -x mlnet -x Makefile -x mldonkey.rc -x ocamlpp.byte -x packages -x cddb_lexer.ml -x autoconf.ml.new -x autoconf.ml -x .cvsignore -N -r -u ./src/daemon/common/commonComplexOptions.mli ./src/daemon/common/commonComplexOptions.mli
--- ./src/daemon/common/commonComplexOptions.mli	2006-03-19 18:38:08.000000000 +0100
+++ ./src/daemon/common/commonComplexOptions.mli	2006-07-20 17:32:39.000000000 +0200
@@ -39,10 +39,9 @@
 val shared_directories : 
   CommonTypes.shared_directory list Options.option_record
   
-val incoming_files : unit -> CommonTypes.shared_directory
-val incoming_directories : unit -> CommonTypes.shared_directory
-val search_incoming_files : unit -> CommonTypes.shared_directory
-val search_incoming_directories : unit -> CommonTypes.shared_directory
+val incoming_dir : bool -> ?user:string -> ?needed_space:int64 -> ?network:string -> unit -> CommonTypes.shared_directory
+val search_incoming_files : unit -> CommonTypes.shared_directory list
+val search_incoming_directories : unit -> CommonTypes.shared_directory list
   
 val sharing_only_directory : CommonTypes.sharing_strategy
 
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x '*.cmi' -x '*.cmx' -x '*.cma' -x '*.cmo' -x '*.o' -x '*.a' -x '*.cmxa' -x output.0 -x requests -x traces.0 -x confdefs.h -x config.h -x config.log -x config.status -x configure -x Makefile.config -x .depend -x mlnet -x Makefile -x mldonkey.rc -x ocamlpp.byte -x packages -x cddb_lexer.ml -x autoconf.ml.new -x autoconf.ml -x .cvsignore -N -r -u ./src/daemon/common/commonInteractive.ml ./src/daemon/common/commonInteractive.ml
--- ./src/daemon/common/commonInteractive.ml	2006-07-20 17:32:28.000000000 +0200
+++ ./src/daemon/common/commonInteractive.ml	2006-07-20 17:34:07.000000000 +0200
@@ -219,27 +219,15 @@
 	if primary == file then
        (try
 	  let file_name = file_disk_name file in
+(* Multiuser ToDo: commit to several dirs if file is also owned by a group *)
 	  let incoming =
-            if Unix2.is_directory file_name then
-              incoming_directories ()
-            else
-              incoming_files ()
+            incoming_dir
+            (Unix2.is_directory file_name)
+            ~needed_space:(file_size file)
+            ~user:(file_owner file)
+            ()
           in
 
-(* check if temp_directory and incoming are on different partitions *)
-	  if (Unix.stat incoming.shdir_dirname).Unix.st_dev <>
-	     (Unix.stat !!temp_directory).Unix.st_dev
-	  then
-	    begin
-	      match Unix32.diskfree incoming.shdir_dirname with
-	        Some v -> if v < (file_size file) then begin
-		    send_dirfull_warning incoming.shdir_dirname true
-		      (Printf.sprintf "can not commit %s" (file_best_name file));
-		    raise Incoming_full
-		  end
-	      | _ -> ()
-	    end;
-
 	  let new_name = file_commited_name incoming.shdir_dirname file in
 	    if Unix2.is_directory file_name then begin
 	      Unix2.safe_mkdir new_name;
@@ -288,8 +276,11 @@
                 with e ->
                     lprintf_nl "Exception %s in file_commit secondaries" (Printexc2.to_string e);
             ) secondary_files
-        with e ->
-              lprintf_nl "Exception in file_commit: %s" (Printexc2.to_string e))
+	with
+	  Incoming_full ->
+	    send_dirfull_warning "" true
+	      (Printf.sprintf "all incoming dirs are full, can not commit %s" (file_best_name file))
+	| e -> lprintf_nl "Exception in file_commit: %s" (Printexc2.to_string e))
     | _ -> assert false
 
 let file_cancel file user =
@@ -345,12 +336,8 @@
         Printf.sprintf "mldonkey@%s, file received" (Unix.gethostname ())
     in
 
-    let incoming =
-      if Unix2.is_directory (file_disk_name file) then
-        incoming_directories ()
-      else
-        incoming_files ()
-    in
+(* TODO: This information can be wrong *)
+    let incoming = incoming_dir (Unix2.is_directory (file_disk_name file)) () in
 
     let line4 = if !!url_in_mail = "" then "" else
       Printf.sprintf "\r\n<%s/%s/%s>\r\n" !!url_in_mail incoming.shdir_dirname (Url.encode (file_best_name file))
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x '*.cmi' -x '*.cmx' -x '*.cma' -x '*.cmo' -x '*.o' -x '*.a' -x '*.cmxa' -x output.0 -x requests -x traces.0 -x confdefs.h -x config.h -x config.log -x config.status -x configure -x Makefile.config -x .depend -x mlnet -x Makefile -x mldonkey.rc -x ocamlpp.byte -x packages -x cddb_lexer.ml -x autoconf.ml.new -x autoconf.ml -x .cvsignore -N -r -u ./src/daemon/common/commonShared.ml ./src/daemon/common/commonShared.ml
--- ./src/daemon/common/commonShared.ml	2006-06-12 22:47:21.000000000 +0200
+++ ./src/daemon/common/commonShared.ml	2006-07-20 17:32:39.000000000 +0200
@@ -235,10 +235,10 @@
   
 let shared_scan_directory shared_dir local_dir =
   let incoming_files_inode = 
-    ((Unix.stat ((CommonComplexOptions.incoming_files ()).shdir_dirname)).Unix.st_ino)
+    ((Unix.stat ((CommonComplexOptions.incoming_dir false ()).shdir_dirname)).Unix.st_ino)
   in
   let incoming_directories_inode = 
-    ((Unix.stat ((CommonComplexOptions.incoming_directories ()).shdir_dirname)).Unix.st_ino)
+    ((Unix.stat ((CommonComplexOptions.incoming_dir true ()).shdir_dirname)).Unix.st_ino)
   in
   let temp_directory_inode =
     ((Unix.stat !!temp_directory).Unix.st_ino)
