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-10-01 19:47:11.000000000 +0200
+++ ./src/daemon/common/commonFile.ml	2006-10-08 00:34:12.000000000 +0200
@@ -78,6 +78,7 @@
 has been changed. The method should not perform the move, just know that
 it will happen soon. *)
     mutable op_file_save_as : ('a -> string -> unit);
+    mutable op_file_shared : ('a -> CommonTypes.shared option);
     mutable op_file_to_option : ('a -> (string * option_value) list);
     mutable op_file_cancel : ('a -> unit);
     mutable op_file_pause : ('a -> unit);
@@ -209,6 +210,10 @@
   let file = as_file_impl file in
   file.impl_file_ops.op_file_save_as file.impl_file_val name
 
+let file_shared (file : file) =
+  let file = as_file_impl file in
+  file.impl_file_ops.op_file_shared file.impl_file_val
+
 let file_comment (file : file) =
   let file = as_file_impl file in
   file.impl_file_ops.op_file_comment file.impl_file_val
@@ -997,6 +1002,7 @@
       op_file_commit = (fun _ _ -> ni_ok network "file_commit");
       op_file_save_as = (fun _ _ -> ni_ok network "file_save_as");
 (*    op_file_print = (fun _ _ -> ni_ok network "file_print"); *)
+      op_file_shared = (fun _ -> None);
       op_file_to_option = (fun _ -> fni network "file_to_option");
       op_file_cancel = (fun _ -> ni_ok network "file_cancel");
       op_file_info = (fun _ -> fni network "file_info");
@@ -1036,6 +1042,8 @@
         lprintf_nl "op_file_commit";
       if c.op_file_save_as == cc.op_file_save_as then
         lprintf_nl "op_file_save_as";
+      if c.op_file_shared == cc.op_file_shared then
+        lprintf_nl "op_file_shared";
       if c.op_file_cancel == cc.op_file_cancel then
         lprintf_nl "op_file_cancel";
       if c.op_file_pause == cc.op_file_pause then
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-10-03 17:23:08.000000000 +0200
+++ ./src/daemon/common/commonFile.mli	2006-10-08 00:34:12.000000000 +0200
@@ -45,6 +45,7 @@
   mutable op_file_network : CommonTypes.network;
   mutable op_file_commit : 'a -> string -> unit;
   mutable op_file_save_as : 'a -> string -> unit;
+  mutable op_file_shared : 'a -> CommonTypes.shared option;
   mutable op_file_to_option : 'a -> (string * Options.option_value) list;
   mutable op_file_cancel : 'a -> unit;
   mutable op_file_pause : 'a -> unit;
@@ -79,6 +80,7 @@
 val update_file_state : 'a file_impl -> CommonTypes.file_state -> unit
 val file_to_option : CommonTypes.file -> (string * Options.option_value) list
 val file_save_as : CommonTypes.file -> string -> unit
+val file_shared : CommonTypes.file -> CommonTypes.shared option
 val file_comment : CommonTypes.file -> string
 val file_network : CommonTypes.file -> CommonTypes.network
 val file_info : CommonTypes.file -> GuiTypes.file_info
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/commonServer.ml ./src/daemon/common/commonServer.ml
--- ./src/daemon/common/commonServer.ml	2006-09-23 22:29:46.000000000 +0200
+++ ./src/daemon/common/commonServer.ml	2006-10-08 00:34:12.000000000 +0200
@@ -53,6 +53,7 @@
     mutable op_server_connect : ('a -> unit);
     mutable op_server_disconnect : ('a -> unit);
     mutable op_server_users : ('a -> user list);
+    mutable op_server_published : ('a -> file list);
     mutable op_server_query_users : ('a -> unit);
     mutable op_server_find_user : ('a -> string -> unit);
     mutable op_server_cid : ('a -> Ip.t);
@@ -108,12 +109,14 @@
     T.server_users = None;
     T.server_banner = "";
     T.server_preferred = false;
+    T.server_master = false;
     T.server_version = "";
     T.server_max_users = 0L;
     T.server_soft_limit = 0L;
     T.server_hard_limit = 0L;
     T.server_lowid_users = 0L;
     T.server_ping = 0;
+    T.server_published_files = 0;
   }
 
 let server_num s =
@@ -183,6 +186,10 @@
   let s = as_server_impl s in
   s.impl_server_ops.op_server_users s.impl_server_val
 
+let server_published s =
+  let s = as_server_impl s in
+  s.impl_server_ops.op_server_published s.impl_server_val
+
 let server_cid s =
   let s = as_server_impl s in
   s.impl_server_ops.op_server_cid s.impl_server_val
@@ -212,6 +219,7 @@
       op_server_disconnect = (fun _ -> ni_ok network "server_disconnect");
       op_server_find_user = (fun _ -> fni network "find_user");
       op_server_query_users = (fun _ -> ni_ok network "query_users");
+      op_server_published = (fun _ -> fni network "published");
       op_server_users = (fun _ -> fni network "users");
       op_server_cid = (fun _ -> fni network "cid");
       op_server_low_id = (fun _ -> fni network "low_id");
@@ -367,6 +375,7 @@
     ( "0", "srh", "Connect|Disconnect", "C/D" ) ;
     ( "0", "srh", "Remove", "Rem" ) ;
     ( "0", "srh", "Preferred", "P" ) ;
+    ( "0", "srh", "Master servers", "M" ) ;
     ( "0", "srh", "[Hi]gh or [Lo]w ID", "ID" ) ;
     ( "0", "srh", "Network name", "Network" ) ;
     ( "0", "srh", "Connection status", "Status" ) ;
@@ -375,11 +384,12 @@
     ( "1", "srh ar", "Number of connected users", "Users" ) ;
     ( "1", "srh ar br", "Max number of users", "MaxUsers" ) ;
     ( "1", "srh ar br", "LowID users", "LowID" ) ;
-    ( "1", "srh ar br", "Number of files indexed on server", "Files" ) ;
+    ( "1", "srh ar", "Number of files indexed on server", "Files" );
+    ( "1", "srh ar br", "Number of published files on server", "Publ" );
     ( "1", "srh ar", "Soft file limit", "Soft" ) ;
     ( "1", "srh ar br", "Hard file limit", "Hard" ) ;
     ( "0", "srh ar br", "Ping (ms)", "Ping" ) ;
-    ( "0", "srh", "Server version", "Version" ) ;
+    ( "0", "srh br", "Server version", "Version" ) ;
     ( "0", "srh", "Server name", "Name" ) ;
     ( "0", "srh", "Server details", "Details" ) ])
 
@@ -496,6 +506,7 @@
 
     let cc,cn = Geoip.get_country (Ip.ip_of_addr info.G.server_addr) in
     html_mods_td buf ([
+      ("", "srb", if info.G.server_master then "T" else "F");
       (id_title, "sr", id_text);
       ("", "sr", n.network_name);
       ("", "sr", server_state_string);
@@ -504,7 +515,18 @@
       ("", "sr ar", Printf.sprintf "%Ld" info.G.server_nusers);
       ("", "sr ar br", Printf.sprintf "%Ld" info.G.server_max_users);
       ("", "sr ar br", Printf.sprintf "%Ld" info.G.server_lowid_users);
-      ("", "sr ar br", Printf.sprintf "%Ld" info.G.server_nfiles);
+      ("", "sr ar", Printf.sprintf "%Ld" info.G.server_nfiles)]);
+
+    if info.G.server_published_files = 0 then
+      html_mods_td buf ([("", "sr br", "")])
+    else
+      Printf.bprintf buf
+"\\<TD class=\\\"sr br\\\" onMouseOver=\\\"mOvr(this);\\\"
+onMouseOut=\\\"mOut(this);\\\" title=\\\"Show published files\\\"
+onClick=\\\"location.href='submit?q=server_shares+%d'\\\"\\>%d\\</TD\\>"
+	snum info.G.server_published_files;
+
+    html_mods_td buf ([
       ("", "sr ar", Printf.sprintf "%Ld" info.G.server_soft_limit);
       ("", "sr ar br", Printf.sprintf "%Ld" info.G.server_hard_limit);
       ("", "sr ar br", Printf.sprintf "%d" info.G.server_ping);
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/commonShared.ml ./src/daemon/common/commonShared.ml
--- ./src/daemon/common/commonShared.ml	2006-09-23 22:29:46.000000000 +0200
+++ ./src/daemon/common/commonShared.ml	2006-10-08 00:34:12.000000000 +0200
@@ -43,7 +43,8 @@
     mutable impl_shared_size : int64;
     mutable impl_shared_id : Md4.t;
     mutable impl_shared_requests : int;
-    mutable impl_shared_magic : string option
+    mutable impl_shared_magic : string option;
+    mutable impl_shared_servers : CommonTypes.server list;
   }
   
 and 'a shared_ops = {
@@ -214,6 +215,7 @@
     impl_shared_id = Md4.null;
     impl_shared_requests = 0;
     impl_shared_magic = None;
+    impl_shared_servers = []
   }
   
   
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/commonShared.mli ./src/daemon/common/commonShared.mli
--- ./src/daemon/common/commonShared.mli	2006-06-12 22:47:21.000000000 +0200
+++ ./src/daemon/common/commonShared.mli	2006-10-08 00:34:12.000000000 +0200
@@ -9,7 +9,8 @@
   mutable impl_shared_size : int64;
   mutable impl_shared_id : Md4.Md4.t;
   mutable impl_shared_requests : int;
-  mutable impl_shared_magic : string option
+  mutable impl_shared_magic : string option;
+  mutable impl_shared_servers : CommonTypes.server list;
 } 
 and 'a shared_ops = {
   mutable op_shared_info : 'a -> GuiTypes.shared_info;
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/commonUploads.ml ./src/daemon/common/commonUploads.ml
--- ./src/daemon/common/commonUploads.ml	2006-09-22 19:39:51.000000000 +0200
+++ ./src/daemon/common/commonUploads.ml	2006-10-08 00:34:12.000000000 +0200
@@ -695,7 +695,8 @@
           impl_shared_ops = shared_ops;
           impl_shared_val = sh;
           impl_shared_requests = 0;
-          impl_shared_magic = None
+          impl_shared_magic = None;
+          impl_shared_servers = [];
         }
       and sh = {
           shared_info = index;
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/guiDecoding.ml ./src/daemon/common/guiDecoding.ml
--- ./src/daemon/common/guiDecoding.ml	2006-09-23 22:29:46.000000000 +0200
+++ ./src/daemon/common/guiDecoding.ml	2006-10-08 00:34:12.000000000 +0200
@@ -750,12 +750,14 @@
     server_banner = "";
     server_users = None;
     server_preferred = preferred;
+    server_master = false;
     server_version = ve; 
     server_max_users = ma;
     server_lowid_users = lo;
     server_soft_limit = so;
     server_hard_limit = ha;
     server_ping = pi;
+    server_published_files = 0;
   }, pos
 
 let get_client_type s pos = 
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/guiTypes.ml ./src/daemon/common/guiTypes.ml
--- ./src/daemon/common/guiTypes.ml	2006-09-23 22:29:46.000000000 +0200
+++ ./src/daemon/common/guiTypes.ml	2006-10-08 00:34:12.000000000 +0200
@@ -169,12 +169,14 @@
     mutable server_users : int list option;
     mutable server_banner : string;
     mutable server_preferred : bool;
+    mutable server_master : bool;
     mutable server_version : string;
     mutable server_max_users : int64;
     mutable server_soft_limit : int64;
     mutable server_hard_limit : int64;
     mutable server_lowid_users : int64;
     mutable server_ping : int;
+    mutable server_published_files : int;
 
   } 
 
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-10-01 19:53:59.000000000 +0200
+++ ./src/daemon/driver/driverCommands.ml	2006-10-08 01:53:23.000000000 +0200
@@ -764,6 +764,23 @@
         ""
     ), "<num> :\t\t\tprint banner of connected server <num>";
 
+    "server_shares", Arg_one (fun num o ->
+	if user2_is_admin o.conn_user.ui_user_name then
+        let s = server_find (int_of_string num) in
+        (match server_state s with
+           Connected _ -> let list = ref [] in
+	    List.iter (fun f -> 
+	      match file_shared f with
+		None -> ()
+	      | Some sh -> list := (as_shared_impl sh) :: !list)
+	      (server_published s);
+	    print_upstats o !list (Some s)
+	  | _ -> ()
+	)
+	else print_command_result o o.conn_buf "You are not allowed to use this command";
+	_s ""
+    ), "<num> :\t\t\tshow list of files published on server <num>";
+
     "c", Arg_multiple (fun args o ->
         let buf = o.conn_buf in
         match args with
@@ -2188,109 +2205,17 @@
               html_mods_table_one_row buf "upstatsTable" "upstats" [
                 ("", "srh", "You are not allowed to see upload statistics") ]
             else
-              Printf.bprintf buf "You are not allowed to see upload statistics\n"
+              print_command_result o buf "You are not allowed to see upload statistics"
           end
         else
-        begin
-
-        if use_html_mods o then begin
-
-if !!html_mods_use_js_tooltips then Printf.bprintf buf 
-"\\<div id=\\\"object1\\\" style=\\\"position:absolute; background-color:FFFFDD;color:black;border-color:black;border-width:20;font-size:8pt; visibility:show; left:25px; top:
--100px; z-index:+1\\\" onmouseover=\\\"overdiv=1;\\\"  onmouseout=\\\"overdiv=0; setTimeout(\\\'hideLayer()\\\',1000)\\\"\\>\\&nbsp;\\</div\\>";
-
-            Printf.bprintf buf "\\<div class=\\\"upstats\\\"\\>";
-            html_mods_table_one_row buf "upstatsTable" "upstats" [
-              ("", "srh", Printf.sprintf "Session: %s uploaded | Shared(%d): %s\n"
-                (size_of_int64 !upload_counter) !nshared_files (size_of_int64 !nshared_bytes)); ]
-          end
-        else begin
-            Printf.bprintf buf "Upload statistics:\n";
-            Printf.bprintf buf "Session: %s uploaded | Shared(%d): %s\n"
-              (size_of_int64 !upload_counter) !nshared_files (size_of_int64 !nshared_bytes)
-          end;
-        let list = ref [] in
-        shared_iter (fun s ->
-            let impl = as_shared_impl s in
-            list := impl :: !list
-        );
-
-        if use_html_mods o then
-          html_mods_table_header buf "upstatsTable" "upstats" [
-            ( "1", "srh", "Total file requests", "Reqs" ) ;
-            ( "1", "srh", "Total bytes sent", "Total" ) ;
-            ( "1", "srh", "Upload Ratio", "UPRatio" ) ;
-            ( "0", "srh", "Preview", "P" ) ;
-            ( "0", "srh", "Filename", "Filename" );
-            ( "0", "srh", "Statistic links", "Stats" ) ]
-        else
-          begin
-            Printf.bprintf buf " Requests |  Bytes   | Uploaded | File\n";
-            Printf.bprintf buf "----------+----------+----------+----------------------------------------------------\n";
-          end;
-
-        let counter = ref 0 in
-
-        let list = Sort.list (fun f1 f2 ->
-              (f1.impl_shared_requests = f2.impl_shared_requests &&
-                f1.impl_shared_uploaded > f2.impl_shared_uploaded) ||
-              (f1.impl_shared_requests > f2.impl_shared_requests )
-          ) !list in
-
-        List.iter (fun impl ->
-            if use_html_mods o then
-              begin
-                incr counter;
-
-                let ed2k = file_print_ed2k_link
-                    (Filename.basename impl.impl_shared_codedname)
-                  impl.impl_shared_size impl.impl_shared_id in
-
-                Printf.bprintf buf "\\<tr class=\\\"%s\\\""
-                  (if (!counter mod 2 == 0) then "dl-1" else "dl-2";);
-
-          (if !!html_mods_use_js_tooltips then
-                        Printf.bprintf buf " onMouseOver=\\\"mOvr(this);setTimeout('popLayer(\\\\\'%s<br>%s\\\\\')',%d);setTimeout('hideLayer()',%d);return true;\\\" onMouseOut=\\\"mOut(this);hideLayer();setTimeout('hideLayer()',%d)\\\"\\>"
-                        (Http_server.html_real_escaped (Filename.basename impl.impl_shared_codedname))
-			(match impl.impl_shared_magic with
-			   None -> ""
-			 | Some magic -> "File type: " ^ (Http_server.html_real_escaped magic) ^ "<br>")
-			!!html_mods_js_tooltips_wait
-			!!html_mods_js_tooltips_timeout
-			!!html_mods_js_tooltips_wait
-			 else Printf.bprintf buf " onMouseOver=\\\"mOvr(this);return true;\\\" onMouseOut=\\\"mOut(this);\\\"\\>");
-
-                let uploaded = Int64.to_float impl.impl_shared_uploaded in
-                let size = Int64.to_float impl.impl_shared_size in
-
-                html_mods_td buf [
-                  ("", "sr ar", Printf.sprintf "%d" impl.impl_shared_requests);
-                  ("", "sr ar", size_of_int64 impl.impl_shared_uploaded);
-                  ("", "sr ar", Printf.sprintf "%5.1f" ( if size < 1.0 then 0.0 else (uploaded *. 100.) /. size));
-                  ("", "sr", Printf.sprintf "\\<a href=\\\"preview_upload?q=%d\\\"\\>P\\</a\\>"
-			impl.impl_shared_num);
-                  ("", "sr", (if impl.impl_shared_id = Md4.null then
-                    (Filename.basename impl.impl_shared_codedname)
-                  else
-                    Printf.sprintf "\\<a href=\\\"%s\\\"\\>%s\\</a\\>"
-                      ed2k (shorten (Filename.basename impl.impl_shared_codedname) !!max_name_len)));
-                  ("", "sr", (if impl.impl_shared_id = Md4.null then "" else
-                    Printf.sprintf "\\<a href=\\\"http://tothbenedek.hu/ed2kstats/ed2k?hash=%s\\\"\\>%s\\</a\\>
-\\<a href=\\\"http://bitzi.com/lookup/ed2k:%s\\\"\\>%s\\</a\\>"
-                      (Md4.to_string impl.impl_shared_id) "T1"
-                      (Md4.to_string impl.impl_shared_id) "B")) ];
-                Printf.bprintf buf "\\</tr\\>\n";
-              end
-            else
-              Printf.bprintf buf "%9d | %8s | %7s%% | %-50s\n"
-		(impl.impl_shared_requests)
-              (size_of_int64 impl.impl_shared_uploaded)
-              (Printf.sprintf "%3.1f" ((Int64.to_float impl.impl_shared_uploaded *. 100.) /. Int64.to_float impl.impl_shared_size))
-              (shorten (Filename.basename impl.impl_shared_codedname) !!max_name_len);
-        ) list;
-
-        if use_html_mods o then Printf.bprintf buf "\\</table\\>\\</div\\>\\</div\\>"
-        end;
+	  begin
+	    let list = ref [] in
+	    shared_iter (fun s ->
+	      let impl = as_shared_impl s in
+	      list := impl :: !list
+	    );
+	    print_upstats o !list None;
+	  end;
         _s ""
     ), ":\t\t\t\tstatistics on upload";
 
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/driverInteractive.ml ./src/daemon/driver/driverInteractive.ml
--- ./src/daemon/driver/driverInteractive.ml	2006-10-01 19:53:59.000000000 +0200
+++ ./src/daemon/driver/driverInteractive.ml	2006-10-08 02:03:11.000000000 +0200
@@ -21,6 +21,8 @@
 
 open Printf2
 open CommonClient
+open CommonShared
+open CommonServer
 open CommonNetwork
 open CommonResult
 open CommonFile
@@ -2379,3 +2381,117 @@
 	shorten fileinfo.file_name 80;
 	string_of_int nc |]
     ) sorted_score_list)
+
+let print_upstats o list server =
+  let buf = o.conn_buf in
+  if use_html_mods o then
+    begin
+      if !!html_mods_use_js_tooltips then Printf.bprintf buf 
+"\\<div id=\\\"object1\\\" style=\\\"position:absolute; background-color:FFFFDD;color:black;border-color:black;border-width:20;font-size:8pt; visibility:show; left:25px; top:
+-100px; z-index:+1\\\" onmouseover=\\\"overdiv=1;\\\"  onmouseout=\\\"overdiv=0; setTimeout(\\\'hideLayer()\\\',1000)\\\"\\>\\&nbsp;\\</div\\>";
+
+      Printf.bprintf buf "\\<div class=\\\"upstats\\\"\\>";
+      match server with
+	None ->
+	  html_mods_table_one_row buf "upstatsTable" "upstats" [
+	    ("", "srh", Printf.sprintf "Session: %s uploaded | Shared(%d): %s\n"
+	    (size_of_int64 !upload_counter) !nshared_files (size_of_int64 !nshared_bytes)); ]
+      | Some s -> let info = server_info s in
+	  html_mods_table_one_row buf "upstatsTable" "upstats" [
+	    ("", "srh", Printf.sprintf "%d files shared on %s (%s:%s)"
+              info.G.server_published_files info.G.server_name
+              (Ip.string_of_addr info.G.server_addr)
+              (string_of_int info.G.server_port)); ]
+    end
+  else
+    begin
+      Printf.bprintf buf "Upload statistics:\n";
+      Printf.bprintf buf "Session: %s uploaded | Shared(%d): %s\n"
+	(size_of_int64 !upload_counter) !nshared_files (size_of_int64 !nshared_bytes)
+    end;
+
+  if use_html_mods o then
+    html_mods_table_header buf "upstatsTable" "upstats" [
+      ( "1", "srh", "Total file requests", "Reqs" ) ;
+      ( "1", "srh", "Total bytes sent", "Total" ) ;
+      ( "1", "srh", "Upload Ratio", "UPRatio" ) ;
+      ( "0", "srh", "Preview", "P" ) ;
+      ( "0", "srh", "Filename", "Filename" );
+      ( "0", "srh", "Statistic links", "Stats" );
+      ( "0", "srh", "Published on servers", "Publ" ) ]
+  else
+    begin
+      Printf.bprintf buf " Requests |  Bytes   | Uploaded | File\n";
+      Printf.bprintf buf "----------+----------+----------+----------------------------------------------------\n";
+    end;
+
+  html_mods_cntr_init ();
+  let list = Sort.list (fun f1 f2 ->
+      (f1.impl_shared_requests = f2.impl_shared_requests &&
+       f1.impl_shared_uploaded > f2.impl_shared_uploaded) ||
+      (f1.impl_shared_requests > f2.impl_shared_requests )
+    ) list in
+
+  List.iter (fun impl ->
+    if use_html_mods o then
+      begin
+	let published = List.length impl.impl_shared_servers in
+	let ed2k = file_print_ed2k_link
+	  (Filename.basename impl.impl_shared_codedname)
+	  impl.impl_shared_size impl.impl_shared_id in
+
+	Printf.bprintf buf "\\<tr class=\\\"dl-%d\\\"" (html_mods_cntr ());
+	(if !!html_mods_use_js_tooltips then
+	   Printf.bprintf buf " onMouseOver=\\\"mOvr(this);setTimeout('popLayer(\\\\\'%s<br>%s%s\\\\\')',%d);setTimeout('hideLayer()',%d);return true;\\\" onMouseOut=\\\"mOut(this);hideLayer();setTimeout('hideLayer()',%d)\\\"\\>"
+	    (Http_server.html_real_escaped (Filename.basename impl.impl_shared_codedname))
+	    (match impl.impl_shared_magic with
+	       None -> ""
+	     | Some magic -> "File type: " ^ (Http_server.html_real_escaped magic) ^ "<br>")
+	    (if impl.impl_shared_servers = [] then "" else
+	       Printf.sprintf "<br>Published on %d %s<br>%s"
+		published (if published = 1 then "server" else "servers")
+		(let listbuf = Buffer.create 100 in
+		   List.iter (fun s -> let info = server_info s in
+		     Printf.bprintf listbuf "%s (%s:%s%s)<br>"
+			info.server_name
+			(Ip.string_of_addr info.server_addr)
+			(string_of_int info.server_port)
+			(if info.server_realport <> 0
+			   then "(" ^ (string_of_int info.server_realport) ^ ")" else "")
+			) impl.impl_shared_servers;
+		 Buffer.contents listbuf))
+		!!html_mods_js_tooltips_wait
+		!!html_mods_js_tooltips_timeout
+		!!html_mods_js_tooltips_wait
+	 else Printf.bprintf buf " onMouseOver=\\\"mOvr(this);return true;\\\" onMouseOut=\\\"mOut(this);\\\"\\>");
+
+	let uploaded = Int64.to_float impl.impl_shared_uploaded in
+	let size = Int64.to_float impl.impl_shared_size in
+
+	html_mods_td buf [
+	  ("", "sr ar", Printf.sprintf "%d" impl.impl_shared_requests);
+	  ("", "sr ar", size_of_int64 impl.impl_shared_uploaded);
+	  ("", "sr ar", Printf.sprintf "%5.1f" ( if size < 1.0 then 0.0 else (uploaded *. 100.) /. size));
+	  ("", "sr", Printf.sprintf "\\<a href=\\\"preview_upload?q=%d\\\"\\>P\\</a\\>" impl.impl_shared_num);
+	  ("", "sr", (if impl.impl_shared_id = Md4.null then
+		        (Filename.basename impl.impl_shared_codedname)
+		      else
+			Printf.sprintf "\\<a href=\\\"%s\\\"\\>%s\\</a\\>"
+			  ed2k (shorten (Filename.basename impl.impl_shared_codedname) !!max_name_len)));
+	  ("", "sr", (if impl.impl_shared_id = Md4.null then "" else
+			Printf.sprintf "\\<a href=\\\"http://tothbenedek.hu/ed2kstats/ed2k?hash=%s\\\"\\>%s\\</a\\>
+\\<a href=\\\"http://bitzi.com/lookup/ed2k:%s\\\"\\>%s\\</a\\>"
+                      (Md4.to_string impl.impl_shared_id) "T1"
+                      (Md4.to_string impl.impl_shared_id) "B"));
+	  ("", "sr ar", Printf.sprintf "%d" published ) ];
+	Printf.bprintf buf "\\</tr\\>\n";
+      end
+    else
+      Printf.bprintf buf "%9d | %8s | %7s%% | %-50s\n"
+	(impl.impl_shared_requests)
+	(size_of_int64 impl.impl_shared_uploaded)
+	(Printf.sprintf "%3.1f" ((Int64.to_float impl.impl_shared_uploaded *. 100.) /. Int64.to_float impl.impl_shared_size))
+	(shorten (Filename.basename impl.impl_shared_codedname) !!max_name_len)
+  ) list;
+
+  if use_html_mods o then Printf.bprintf buf "\\</table\\>\\</div\\>\\</div\\>"
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/networks/bittorrent/bTInteractive.ml ./src/networks/bittorrent/bTInteractive.ml
--- ./src/networks/bittorrent/bTInteractive.ml	2006-10-06 17:57:18.000000000 +0200
+++ ./src/networks/bittorrent/bTInteractive.ml	2006-10-08 00:34:13.000000000 +0200
@@ -1171,6 +1171,11 @@
   file_ops.op_file_cancel <- op_file_cancel;
   file_ops.op_file_info <- op_file_info;
   file_ops.op_file_save_as <- (fun file name -> ());
+  file_ops.op_file_shared <- (fun file ->
+      match file.file_shared with
+        None -> None
+      | Some sh -> Some (as_shared sh)
+  );
 
   network.op_network_gui_message <- op_gui_message;
   network.op_network_connected <- op_network_connected;
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/networks/bittorrent/bTShare.ml ./src/networks/bittorrent/bTShare.ml
--- ./src/networks/bittorrent/bTShare.ml	2006-05-12 23:08:30.000000000 +0200
+++ ./src/networks/bittorrent/bTShare.ml	2006-10-08 00:34:13.000000000 +0200
@@ -45,6 +45,7 @@
           impl_shared_val = file;
           impl_shared_requests = 0;
           impl_shared_magic = None;
+          impl_shared_servers = [];
         } in
         file.file_shared <- Some impl;
         incr CommonGlobals.nshared_files;
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/donkeyClient.ml ./src/networks/donkey/donkeyClient.ml
--- ./src/networks/donkey/donkeyClient.ml	2006-10-01 19:54:00.000000000 +0200
+++ ./src/networks/donkey/donkeyClient.ml	2006-10-08 00:34:13.000000000 +0200
@@ -2473,11 +2473,11 @@
           (if is_connecting_server then
             ( try 
                 let s = Hashtbl.find servers_by_key from_ip in
-                Printf.sprintf " %s (%s)" s.server_name (Ip.to_string s.server_ip)
+                Printf.sprintf " %s (%s)" s.server_name (string_of_server s)
               with _ ->
                 try 
                   let s = Hashtbl.find servers_by_key connecting_server in
-                  Printf.sprintf " %s (%s)" s.server_name (Ip.to_string s.server_ip)
+                  Printf.sprintf " %s (%s)" s.server_name (string_of_server s)
                 with _ -> "Unknown server"
             )
            else ""
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-10-01 19:54:00.000000000 +0200
+++ ./src/networks/donkey/donkeyGlobals.ml	2006-10-08 00:34:13.000000000 +0200
@@ -183,7 +183,6 @@
 let udp_sock = ref (None: UdpSocket.t option)
 let listen_sock = ref (None : TcpServerSocket.t option)
 let porttest_sock = ref (None : TcpBufferedSocket.t option)
-let new_shared = ref false
 
 (*************************************************************************)
 (*                                                                       *)
@@ -228,7 +227,6 @@
 let shared_files_info = (Hashtbl.create 127
     : (string * int64 * float, shared_file_info) Hashtbl.t)
 let shared_files = ref ([] : file_to_share list)
-let new_shared_files = ref []
 
 let udp_servers_replies = (Hashtbl.create 127 : (Md4.t, server) Hashtbl.t)
 
@@ -428,10 +426,7 @@
                 Verification (Array.of_list (List.map (fun md4 -> Ed2k md4) md4s))
             );
             CommonSwarming.set_verified swarmer (fun nblocks num ->
-                if nblocks = 1 then begin
-                    new_shared_files := file :: !new_shared_files;
-                    file_must_update file
-                  end)
+                if nblocks = 1 then file_must_update file)
       );
 
       update_best_name file;
@@ -518,6 +513,7 @@
         server_lowid_users = None;
         server_soft_limit = None;
         server_hard_limit = None;
+        server_sent_shared = [];
         server_max_users = None;
         server_last_ping = 0.;
         server_ping = 0;
@@ -700,6 +696,8 @@
     | Invalid_address _ -> ""
   )
 
+let string_of_server s =
+  Printf.sprintf "%s:%d" (Ip.to_string s.server_ip) s.server_port
 
 let set_client_name c name md4 =
   if name <> c.client_name || c.client_md4 <> md4 then begin
@@ -811,7 +809,6 @@
   Printf.bprintf buf "  udp_servers_list: %d\n" (List.length !udp_servers_list);
   Printf.bprintf buf "  interesting_clients: %d\n" (List.length !interesting_clients);
   Printf.bprintf buf "  shared_files: %d\n" (List.length !shared_files);
-  Printf.bprintf buf "  new_shared_files: %d\n" (List.length !new_shared_files);
   Printf.bprintf buf "  servers_by_key: %d\n" (Hashtbl.length servers_by_key);
   Printf.bprintf buf "  banned_ips: %d\n" (Hashtbl.length banned_ips);
   Printf.bprintf buf "  old_requests: %d\n" (Hashtbl.length old_requests);
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-10-01 19:54:00.000000000 +0200
+++ ./src/networks/donkey/donkeyInteractive.ml	2006-10-08 00:34:13.000000000 +0200
@@ -725,8 +725,8 @@
     "id", Arg_none (fun o ->
         let buf = o.conn_buf in
         List.iter (fun s ->
-            Printf.bprintf buf "For %s:%d (%s) --->   %s\n"
-              (Ip.to_string s.server_ip) s.server_port s.server_name
+            Printf.bprintf buf "For %s (%s) --->   %s\n"
+              (string_of_server s) s.server_name
               (match s.server_cid with
                 None -> "waiting"
               | Some ip ->
@@ -1078,6 +1078,8 @@
           P.server_description = s.server_description;
           P.server_banner = s.server_banner;
           P.server_preferred = s.server_preferred;
+          P.server_master = s.server_master;
+          P.server_published_files = (List.length s.server_sent_shared);
           P.server_version = s.server_version;
           P.server_max_users = (match s.server_max_users with None -> 0L | Some v -> v);
           P.server_soft_limit = (match s.server_soft_limit with None -> 0L | Some v -> v);
@@ -1177,6 +1179,9 @@
   server_ops.op_server_users <- (fun s ->
       List2.tail_map (fun u -> as_user u.user_user) s.server_users)    ;
 
+  server_ops.op_server_published <- (fun s ->
+      List.map (fun f -> as_file f) s.server_sent_shared);
+
   server_ops.op_server_cid <- (fun s -> ip_of_server_cid s);
 
   server_ops.op_server_low_id <- (fun s -> low_id (ip_of_server_cid s));
@@ -1196,6 +1201,11 @@
       add_file_filenames (as_file file) name;
       set_file_best_name (as_file file) name "" 0
   );
+  file_ops.op_file_shared <- (fun file ->
+      match file.file_shared with
+	None -> None
+      | Some sh -> Some (as_shared sh)
+  );
   file_ops.op_file_set_format <- (fun file format ->
       file.file_format <- format);
   file_ops.op_file_check <- op_file_check;
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/donkeyMain.ml ./src/networks/donkey/donkeyMain.ml
--- ./src/networks/donkey/donkeyMain.ml	2006-10-01 19:54:00.000000000 +0200
+++ ./src/networks/donkey/donkeyMain.ml	2006-10-08 00:34:13.000000000 +0200
@@ -69,7 +69,6 @@
   clean_join_queue_tables ()
 
 let fivemin_timer timer =
-  DonkeyShare.send_new_shared ();
   clients_root := []
 
 let second_timer timer =
@@ -95,10 +94,7 @@
  (try
       DonkeyServers.query_locations_timer ();
     with _ -> ());
-  (List.iter (fun file -> DonkeyShare.must_share_file file) !new_shared_files;
-  new_shared_files := [])
-(*  DonkeyIndexer.add_to_local_index_timer () *)
-
+  DonkeyShare.send_new_shared ()
 
 let local_login () =
   if !!login = "" then !!global_login else !!login
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/donkeyOneFile.ml ./src/networks/donkey/donkeyOneFile.ml
--- ./src/networks/donkey/donkeyOneFile.ml	2006-09-19 19:07:43.000000000 +0200
+++ ./src/networks/donkey/donkeyOneFile.ml	2006-10-08 00:34:13.000000000 +0200
@@ -111,8 +111,11 @@
   match file.file_shared with
     None -> ()
   | Some s -> 
-      if !verbose_share then
-        lprintf_nl "unshare_file %s" file.file_diskname;
+      if !verbose_share || !verbose then
+        lprintf_nl "Unsharing file %s" (file_best_name file);
+      List.iter (fun s ->
+        s.server_sent_shared <- List2.removeq file s.server_sent_shared;
+      ) (connected_servers ());
       file.file_shared <- None;
       decr nshared_files;
       CommonShared.shared_calculate_total_bytes ();
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/donkeyOptions.ml ./src/networks/donkey/donkeyOptions.ml
--- ./src/networks/donkey/donkeyOptions.ml	2006-09-04 23:30:27.000000000 +0200
+++ ./src/networks/donkey/donkeyOptions.ml	2006-10-08 00:34:13.000000000 +0200
@@ -100,8 +100,7 @@
     int_option 1
 
 let walker_server_lifetime = define_expert_option donkey_section ["walker_server_lifetime"]
-  "The maximal delay a connection with a server should last when walking
-  through the list (should be greater than become_master_delay)"
+  "The maximal delay a connection with a server should last when walking through the list"
     int_option 300
 
 let log_clients_on_console = define_expert_option donkey_section ["log_clients_on_console"]
@@ -260,10 +259,6 @@
   "port for overnet"
     int_option (2000 + Random.int 20000)
 
-let become_master_delay = define_expert_option donkey_section ["become_master_delay"]
-  "(only for development tests)"
-    int_option 120
-
 let options_version = define_expert_option donkey_section ["options_version"]
   "(internal option)"
     int_option 3
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/donkeyProtoCom.ml ./src/networks/donkey/donkeyProtoCom.ml
--- ./src/networks/donkey/donkeyProtoCom.ml	2006-05-20 01:43:54.000000000 +0200
+++ ./src/networks/donkey/donkeyProtoCom.ml	2006-10-08 00:34:13.000000000 +0200
@@ -341,7 +341,7 @@
       if !verbose_share || !verbose then
          lprintf_nl "Sending %d share(s) to server %s:%d%s"
 	   nfiles (Ip.to_string (peer_ip sock)) (peer_port sock)
-	   (if compressed then "(zlib)" else "");
+	   (if compressed then " (zlib)" else "");
       Buffer.reset buf;
       let s_c =
         if compressed then
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/donkeyServers.ml ./src/networks/donkey/donkeyServers.ml
--- ./src/networks/donkey/donkeyServers.ml	2006-09-01 18:25:15.000000000 +0200
+++ ./src/networks/donkey/donkeyServers.ml	2006-10-08 00:34:13.000000000 +0200
@@ -34,6 +34,7 @@
 open CommonOptions
 open CommonGlobals
 open CommonSources
+open CommonShared
 
 open DonkeyMftp
 open DonkeyImport
@@ -210,6 +211,30 @@
 
 
 let disconnect_server s reason =
+  let choose_new_master_server s =
+    match !DonkeyGlobals.master_server with
+      Some ss when s == ss ->
+	DonkeyGlobals.master_server := None;
+        (try
+	  DonkeyGlobals.master_server :=
+	    Some (List.find (fun s -> s.server_master) !servers_list);
+	  lprintf_nl "changed main master server from %s to %s"
+	    (string_of_server ss) (string_of_server s)
+        with Not_found -> ())
+    | _ -> ();
+  in
+(* remove this server from the list of servers a file was published to *)
+  let remove_server_from_shared_files s =
+    List.iter (fun file ->
+      shared_iter (fun sh ->
+        let impl = as_shared_impl sh in
+	  impl.impl_shared_servers <-
+	    List2.removeq (as_server s.server_server) impl.impl_shared_servers)
+    ) s.server_sent_shared;
+    s.server_sent_shared <- []
+  in
+  choose_new_master_server s;
+  remove_server_from_shared_files s;
   match s.server_sock with
       NoConnection -> ()
     | ConnectionWaiting token ->
@@ -225,16 +250,11 @@
         s.server_users <- [];
         set_server_state s (NotConnected (reason, -1));
         s.server_master <- false;
-        (match !DonkeyGlobals.master_server with
-          | Some ss when s == ss ->
-              DonkeyGlobals.master_server := None;
-          | _ -> ());
         s.server_banner <- "";
         s.server_sent_all_queries <- false;
         remove_connecting_server s;
         remove_connected_server s
 
-
 let server_handler s sock event =
   match event with
       BASIC_EVENT (CLOSED r) ->
@@ -282,8 +302,8 @@
 
   | M.MessageReq msg ->
       if !last_message_sender <> server_num s then begin
-          let server_header = Printf.sprintf "\n+-- From server %s [%s:%d] ------"
-              s.server_name (Ip.to_string s.server_ip) s.server_port in
+          let server_header = Printf.sprintf "\n+-- From server %s [%s] ------"
+              s.server_name (string_of_server s) in
           CommonEvent.add_event (Console_message_event (Printf.sprintf "%s\n" server_header));
           if !CommonOptions.verbose_msg_servers then
       lprintf_nl "%s" server_header;
@@ -297,7 +317,7 @@
 
   | M.ServerListReq l ->
       if !!update_server_list_server then begin
-        if !verbose_msg_servers then lprintf_nl "Received serverlist from server";
+        if !verbose_msg_servers then lprintf_nl "Received %d servers from server" (List.length l);
         let module Q = M.ServerList in
         List.iter (fun s ->
             safe_add_server s.Q.ip s.Q.port
@@ -339,8 +359,8 @@
       s.server_nfiles <- Some (Int64.of_int files);
       if (users < !!min_users_on_server && not s.server_preferred) then
         begin
-          lprintf_nl "%s:%d remove server min_users_on_server limit hit!"
-            (Ip.to_string s.server_ip) s.server_port;
+          lprintf_nl "%s remove server min_users_on_server limit hit!"
+            (string_of_server s);
 
           disconnect_server s Closed_for_timeout;
           server_remove (as_server s.server_server);
@@ -618,8 +638,7 @@
         if ls < min_last_conn && s.server_sock = NoConnection
           && not s.server_preferred then begin
           if !verbose then
-            lprintf_nl "old servers: Server too old: %s:%d"
-              (Ip.to_string s.server_ip) s.server_port;
+            lprintf_nl "old servers: Server too old: %s" (string_of_server s);
 
           to_remove := s :: !to_remove
         end
@@ -674,16 +693,14 @@
                   if connection_can_try s.server_connection_control then
                     begin
                       if !verbose then
-                        lprintf_nl "WALKER: try connect %s"
-                          (Ip.to_string s.server_ip);
+                        lprintf_nl "WALKER: try connect %s" (string_of_server s);
                       connect_server s
                     end
                   else
                     begin
                       delayed_list := s :: !delayed_list;
                       if !verbose then
-                        lprintf_nl "WALKER: connect %s delayed"
-                          (Ip.to_string s.server_ip);
+                        lprintf_nl "WALKER: connect %s delayed" (string_of_server s);
                     end
               | _ -> ()
 
@@ -749,13 +766,13 @@
         match s.server_sock with
         | Connection _ ->
             if !verbose_location then begin
-        if !tag2 then begin
+	      if !tag2 then begin
                 lprintf_n "master servers (old):";
-    tag1 := false;
-    tag2 := false
-        end;
-        lprintf " %s" (Ip.to_string s.server_ip)
-      end;
+		tag1 := false;
+		tag2 := false
+	      end;
+	      lprintf " %s" (string_of_server s)
+	    end;
             masters := s :: !masters
         | _ -> s.server_master <- false
   ) server_list;
@@ -772,8 +789,7 @@
         masters := s :: !masters;
         masters := List.rev (List.sort compare_servers !masters);
 
-        server_send_share s.server_has_zlib sock
-          (DonkeyShare.all_shared ())
+	DonkeyGlobals.master_server := Some s;
     )
   in
 
@@ -786,7 +802,7 @@
     if !nconnected_servers > max_allowed_connected_servers then
       begin
         if !verbose_location then
-            lprintf_nl "master servers: disconnect %s" (Ip.to_string s.server_ip);
+            lprintf_nl "master servers: disconnect %s" (string_of_server s);
         nconnected_servers := !nconnected_servers - 3;
         do_if_connected  s.server_sock (fun sock ->
             (* We will disconnect from this server.
@@ -805,23 +821,14 @@
             - connection_last_conn s.server_connection_control
           in
           if !verbose_location then
-              lprintf_nl "master servers: Checking ip:%s, users: %Ld, ct:%d"
-          (Ip.to_string s.server_ip)
-	  (match s.server_nusers with None -> 0L | Some v -> v)
-	  connection_time;
-          if not s.server_master
-            && (s.server_preferred
-                 || connection_time > !!become_master_delay
-               )
-            then
+              lprintf_nl "master servers: Checking %s, users: %Ld, ct:%d"
+		(string_of_server s)
+		(match s.server_nusers with None -> 0L | Some v -> v)
+		connection_time;
+          if not s.server_master && s.server_preferred then
               begin
                 if (!nmasters < max_allowed_connected_servers) then
-                  begin
-                    if !verbose_location then
-                        lprintf_nl "master servers: raising  %s"
-                                  (Ip.to_string s.server_ip);
                     make_master s
-                  end
                 else if s.server_sent_all_queries then
                   match !masters with
                       [] -> disconnect_old_server s
@@ -847,7 +854,7 @@
                               if !verbose_location then
                                 lprintf_nl
                                   "master servers: raising %s, disconnected %s"
-                                  (Ip.to_string s.server_ip) (Ip.to_string ss.server_ip);
+                                  (string_of_server s) (string_of_server ss);
                               ss.server_master <- false;
                               masters := tail;
                               make_master s
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/donkeyShare.ml ./src/networks/donkey/donkeyShare.ml
--- ./src/networks/donkey/donkeyShare.ml	2006-09-26 00:37:57.000000000 +0200
+++ ./src/networks/donkey/donkeyShare.ml	2006-10-08 00:34:13.000000000 +0200
@@ -39,13 +39,10 @@
 
 module VB = VerificationBitmap
 
-let new_shared_files = ref []
-
 let must_share_file file codedname has_old_impl =
   match file.file_shared with
   | Some _ -> ()
   | None ->
-      new_shared := true;
       let full_name = file_disk_name file in
       let magic =
         match Magic.M.magic_fileinfo full_name false with
@@ -65,9 +62,9 @@
           impl_shared_val = file;
           impl_shared_requests = 0;
           impl_shared_magic = magic;
+          impl_shared_servers = []
         } in
       file.file_shared <- Some impl;
-      new_shared_files := file :: !new_shared_files;
       incr CommonGlobals.nshared_files;
       CommonShared.shared_calculate_total_bytes ();
       match has_old_impl with
@@ -162,41 +159,72 @@
         None -> ()
       | Some _ ->  shared_files := file :: !shared_files
   ) files_by_md4;
-  if !verbose_share then lprintf_nl "%d files shared" (List.length !shared_files);
+  if !verbose_share then lprintf_nl "scanned shared files, %d files found" (List.length !shared_files);
   !shared_files
 
-(* Check whether new files are shared, and send them to connected servers.
-   Do it only once per 5 minutes to prevent sending to many times all files.
-   Change: Just send *new* shared files to servers, they never forget a
-     clients files until disconnection.
-   Should I only do it for master servers, no ?
-*)
+(* publish shared files to servers, called once per minute *)
 let send_new_shared () =
-  let tag = ref false in
-  if !new_shared then
-    begin
-      new_shared := false;
-      if !new_shared_files <> [] then
-        begin
-          List.iter (fun s ->
-            if s.server_master then
-              begin
-                if !verbose_share || !verbose then
-                  lprintf_nl "send_new_shared: found master server %s:%d"
-                   (Ip.to_string s.server_ip) s.server_port;
-                tag := true;
-                do_if_connected s.server_sock (fun sock ->
-                  server_send_share s.server_has_zlib sock !new_shared_files)
-              end
-          ) (connected_servers ());
-          if !tag && (!verbose_share || !verbose) then
-              lprintf_nl "send_new_shared: Sent %d new shared files to servers"
-                (List.length !new_shared_files);
-          new_shared_files := []
-        end
-      else
-          lprintf_nl "donkey send_new_share: No new shared files to send to servers"
-    end
+(* emule sends 200 files in this period to avoid server blacklist *)
+  let limit_per_minute = 200 in
+
+(* sort list to publish least published files first *)
+  let ( |> ) x f = f x in
+  let all_shared =
+    all_shared ()
+    |> List.map (fun e -> 
+	(match e.file_shared with
+	  Some s -> List.length s.impl_shared_servers
+	 | _ -> 0) , e)
+    |> List.sort (fun (a,_) (b,_) -> compare a b)
+    |> List.map snd
+  in
+
+(* iter through connected servers *)
+  List.iter (fun s ->
+
+(* publish files only on master servers and do not publish more files than hard limit allows *)
+    if s.server_master &&
+      (match s.server_hard_limit with
+	  Some v when (Int64.to_int v) < List.length s.server_sent_shared -> false
+	| _ -> true) then
+
+(* iter through all shared files and check if the file is already published on the current server
+   build a list of files_to_send with yet unpublished files *)
+      begin
+	let files_to_send = ref [] in
+        List.iter (fun f ->
+          match f.file_shared with
+	    Some impl ->
+	      if not (List.mem (CommonServer.as_server s.server_server) impl.impl_shared_servers)
+		&& List.length !files_to_send < limit_per_minute then
+	      files_to_send := f :: !files_to_send
+	    | _ -> () (* this case never happens *)
+	) all_shared;
+
+	if !files_to_send <> [] then
+	  begin
+	    if !verbose_share || !verbose then
+	      lprintf_nl "publishing %d new files to %s (holds %d files)"
+		(List.length !files_to_send) (string_of_server s)
+		(List.length s.server_sent_shared);
+
+(* publish files on server *)
+	    do_if_connected s.server_sock (fun sock ->
+	      server_send_share s.server_has_zlib sock !files_to_send);
+
+(* append new published files to server structure *)
+	    s.server_sent_shared <- !files_to_send @ s.server_sent_shared;
+
+(* iter through published files and append current server *)
+	    List.iter (fun file ->
+	      match file.file_shared with
+		Some impl -> impl.impl_shared_servers <-
+		  impl.impl_shared_servers @ [(CommonServer.as_server s.server_server)]
+	      | _ -> ()) !files_to_send
+
+	end
+      end
+  ) (connected_servers ());
 
 (*
 The problem: sh.shared_fd might be closed during the execution of the
@@ -326,6 +354,7 @@
               impl_shared_val = pre_shared;
               impl_shared_requests = 0;
               impl_shared_magic = magic;
+              impl_shared_servers = [];
             } and
             pre_shared = {
               shared_shared = impl;
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/donkeyTypes.ml ./src/networks/donkey/donkeyTypes.ml
--- ./src/networks/donkey/donkeyTypes.ml	2006-09-23 22:29:47.000000000 +0200
+++ ./src/networks/donkey/donkeyTypes.ml	2006-10-08 00:34:13.000000000 +0200
@@ -430,7 +430,21 @@
         | Invalid_address _ -> failwith "Invalid address"
     end)
 
-type server = (*[]*){
+type file = {
+    file_file : file CommonFile.file_impl;
+    file_md4 : Md4.t;
+    mutable file_swarmer : CommonSwarming.t option;
+    mutable file_nchunks : int;
+    mutable file_nchunk_hashes : int;
+    mutable file_diskname : string;
+    mutable file_computed_md4s : Md4.t array;
+    mutable file_format : format;
+    mutable file_shared : file CommonShared.shared_impl option;
+    mutable file_sources : DonkeySources.file_sources_manager;
+    mutable file_comments : (Ip.t * string * int * string) list;
+  }
+
+and server = (*[]*){
     mutable server_server : server CommonServer.server_impl;
     mutable server_ip : Ip.t;
     mutable server_cid : Ip.t option;
@@ -470,6 +484,7 @@
     mutable server_soft_limit : int64 option;
     mutable server_hard_limit : int64 option;
     mutable server_max_users : int64 option;
+    mutable server_sent_shared : file list
   }
 
 
@@ -579,20 +594,6 @@
   int * (* last connection attempt *)
   int   (* booked client num *)
 
-and file = {
-    file_file : file CommonFile.file_impl;
-    file_md4 : Md4.t;
-    mutable file_swarmer : CommonSwarming.t option;
-    mutable file_nchunks : int;
-    mutable file_nchunk_hashes : int;
-    mutable file_diskname : string;
-    mutable file_computed_md4s : Md4.t array;
-    mutable file_format : format;
-    mutable file_shared : file CommonShared.shared_impl option;
-    mutable file_sources : DonkeySources.file_sources_manager;
-    mutable file_comments : (Ip.t * string * int * string) list;
-  }
-
 and file_to_share = {
     shared_name : string;
     shared_size : int64;
