mldonkey-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Mldonkey-commits] mldonkey distrib/ChangeLog src/daemon/common/co...


From: mldonkey-commits
Subject: [Mldonkey-commits] mldonkey distrib/ChangeLog src/daemon/common/co...
Date: Sun, 23 May 2010 09:18:31 +0000

CVSROOT:        /sources/mldonkey
Module name:    mldonkey
Changes by:     spiralvoice <spiralvoice>       10/05/23 09:18:31

Modified files:
        distrib        : ChangeLog 
        src/daemon/common: commonGlobals.ml commonTypes.ml 
        src/networks/direct_connect: dcGlobals.ml dcInteractive.ml 
                                     dcMain.ml dcProtocol.ml 
        src/utils/lib  : charset.ml charset.mli 

Log message:
        patch #7183

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/mldonkey/distrib/ChangeLog?cvsroot=mldonkey&r1=1.1432&r2=1.1433
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/daemon/common/commonGlobals.ml?cvsroot=mldonkey&r1=1.90&r2=1.91
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/daemon/common/commonTypes.ml?cvsroot=mldonkey&r1=1.77&r2=1.78
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/networks/direct_connect/dcGlobals.ml?cvsroot=mldonkey&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/networks/direct_connect/dcInteractive.ml?cvsroot=mldonkey&r1=1.36&r2=1.37
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/networks/direct_connect/dcMain.ml?cvsroot=mldonkey&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/networks/direct_connect/dcProtocol.ml?cvsroot=mldonkey&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/utils/lib/charset.ml?cvsroot=mldonkey&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/utils/lib/charset.mli?cvsroot=mldonkey&r1=1.6&r2=1.7

Patches:
Index: distrib/ChangeLog
===================================================================
RCS file: /sources/mldonkey/mldonkey/distrib/ChangeLog,v
retrieving revision 1.1432
retrieving revision 1.1433
diff -u -b -r1.1432 -r1.1433
--- distrib/ChangeLog   23 May 2010 09:12:14 -0000      1.1432
+++ distrib/ChangeLog   23 May 2010 09:18:31 -0000      1.1433
@@ -14,6 +14,7 @@
 ChangeLog
 =========
 
+7183: DC: magnet links and html ui usability tweaks (ygrek)
 7180: DC: better encoding handling (ygrek)
 - new option default_encoding for communications with hubs, default CP1252
 7181: HTML: Fix sorting of friends' file list (ygrek)

Index: src/daemon/common/commonGlobals.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/daemon/common/commonGlobals.ml,v
retrieving revision 1.90
retrieving revision 1.91
diff -u -b -r1.90 -r1.91
--- src/daemon/common/commonGlobals.ml  23 May 2010 09:12:14 -0000      1.90
+++ src/daemon/common/commonGlobals.ml  23 May 2010 09:18:31 -0000      1.91
@@ -682,29 +682,6 @@
   | VerificationBitmap.State_complete | VerificationBitmap.State_verified -> 
       false
 
-let parse_magnet url =
-  let url = Url.of_string url in
-  if url.Url.short_file = "magnet:" then
-    let uids = ref [] in
-    let name = ref "" in
-    List.iter (fun (value, arg) ->
-        if String2.starts_with value "xt" then
-          uids := Uid.expand (Uid.of_string arg :: !uids)
-        else
-        if String2.starts_with value "dn" then
-          name := Url.decode arg
-        else
-        if arg = "" then
-(* This is an error in the magnet, where a & has been kept instead of being
-  url-encoded *)
-          name := Printf.sprintf "%s&%s" !name value
-        else
-          lprintf_nl "MAGNET: unused field %s = %s"
-            value arg
-    ) url.Url.args;
-    !name, !uids
-  else raise Not_found
-
     (*
 module CanBeCompressed = struct
 

Index: src/daemon/common/commonTypes.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/daemon/common/commonTypes.ml,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -b -r1.77 -r1.78
--- src/daemon/common/commonTypes.ml    20 Jan 2009 16:47:28 -0000      1.77
+++ src/daemon/common/commonTypes.ml    23 May 2010 09:18:31 -0000      1.78
@@ -58,9 +58,7 @@
 let string_of_uid_sep uid sep =
   match uid with
     Bitprint (sha1,ttr) ->
-      "urn" ^ sep ^ "bitprint" ^ sep ^
-        (Sha1.to_string sha1) ^ "." ^
-          (TigerTree.to_string ttr)
+      "urn" ^ sep ^ "bitprint" ^ sep ^ (Sha1.to_string sha1) ^ "." ^ 
(TigerTree.to_string ttr)
   | Sha1 sha1 ->
       "urn" ^ sep ^ "sha1" ^ sep ^ (Sha1.to_string sha1)
   | Ed2k ed2k ->
@@ -68,12 +66,11 @@
   | Md5 md5 ->
       "urn" ^ sep ^ "md5" ^ sep ^ (Md5.to_string md5)
   | TigerTree ttr -> 
-      "urn" ^ sep ^ "ttr" ^ sep ^ (TigerTree.to_string ttr)
+      "urn" ^ sep ^ "tree" ^ sep ^ "tiger" ^ sep ^ (TigerTree.to_string ttr)
   | Md5Ext md5 ->
-      "urn" ^ sep ^ "sig2dat" ^ sep ^
-        (Md5Ext.to_base32 md5)
+      "urn" ^ sep ^ "sig2dat" ^ sep ^ (Md5Ext.to_base32 md5)
   | BTUrl url ->
-      "urn" ^ sep ^ "bt" ^ sep ^ (Sha1.to_string url)
+      "urn" ^ sep ^ "btih" ^ sep ^ (Sha1.to_string url)
   | FileTP file ->
       "urn" ^ sep ^ "filetp" ^ sep ^ (Md4.to_string file)
   | NoUid -> ""
@@ -105,6 +102,7 @@
   let (sign, rem) = String2.cut_at rem !sep in
   match sign with
   | "ed2k" -> Ed2k (Md4.of_string rem)
+(*   | "aich" -> ??? *)
   | "bitprint" | "bp" -> 
       let (sha1, ttr) = String2.cut_at rem '.' in
       let sha1 = Sha1.of_string sha1 in
@@ -119,7 +117,7 @@
   | "ttr" -> TigerTree (TigerTree.of_string rem)
   | "md5" ->  Md5 (Md5.of_string rem)
   | "sig2dat" -> Md5Ext (Md5Ext.of_base32 rem)
-  | "bt" | "bittorrent" -> 
+  | "bt" | "bittorrent" | "btih" -> 
       BTUrl (Sha1.of_string rem)
   | "filetp" -> FileTP (Md4.of_string rem)
   | _ -> raise (Illegal_urn (s ^ " at " ^ sign ^ " is not known"))
@@ -207,6 +205,50 @@
       (fun uid -> string_to_value (to_string uid))
   end
 
+(* TODO group settings: xt.1 xt.2 .. *)
+let parse_magnet_url url =
+  let url = Url.of_string url in
+  if url.Url.short_file = "magnet:" then
+    let uids = ref [] in
+    let name = ref "" in
+    let size = ref None in
+    let each k v =
+      match String2.split k '.' with
+      | "xt"::_ -> uids := Uid.of_string v :: !uids
+      | "xl"::_ -> size := Some (Int64.of_string v) (* exact length *)
+      | "dn"::_ -> name := Url.decode v
+      | "as"::_ -> () (* acceptable source *)
+      | "xs"::_ -> () (* eXtra source *)
+      | "mt"::_ -> () (* manifest topic: url or urn, see 
http://rakjar.de/gnuticles/MAGMA-Specsv22.txt *)
+      | "kt"::_ -> () (* keywords topic *)
+      | "tr"::_ -> () (* BT tracker *)
+      | "x"::_ -> () (* extensions *)
+(*
+      | _ when v = "" ->
+(* This is an error in the magnet, where a & has been kept instead of being
+  url-encoded *)
+          name := Printf.sprintf "%s&%s" !name k
+*)
+      | _ -> lprintf_nl "MAGNET: unused field %S=%S" k v
+    in
+    List.iter (fun (k, v) ->
+      try each k v
+      with exn -> lprintf_nl "MAGNET: field %S=%S, exn %s" k v 
(Printexc2.to_string exn)
+    ) url.Url.args;
+    object method name = !name method size = !size method uids = List.map 
Uid.to_uid (Uid.expand !uids) end
+  else 
+    raise Not_found
+
+let show_magnet_url x =
+  let args = ("dn", x#name) :: List.map (fun uid -> "xt", string_of_uid uid) 
x#uids in
+  let args = match x#size with Some n -> ("xl", Int64.to_string n) :: args | 
None -> args in
+  Url.put_args "magnet:" args
+
+(* compatibility, used in G2 module *)
+let parse_magnet url =
+  let magnet = parse_magnet_url url in
+  magnet#name, (List.map Uid.create magnet#uids)
+
 let string_of_uids list =
   match list with
     [] -> "<unknown>"

Index: src/networks/direct_connect/dcGlobals.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/networks/direct_connect/dcGlobals.ml,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- src/networks/direct_connect/dcGlobals.ml    9 Jul 2007 23:45:44 -0000       
1.14
+++ src/networks/direct_connect/dcGlobals.ml    23 May 2010 09:18:31 -0000      
1.15
@@ -289,7 +289,12 @@
     
 (* Shorten string to some maximum length *)
 let shorten_string s length =
-  if (String.length s > length) then String.sub s 0 (length-1)
+  if length < String.length s then
+    try
+      let n = Charset.utf8_nth s length in
+      String.sub s 0 n
+    with
+      _ -> s (* relies on bounds checking! FIXME? *)
   else s 
 
 (* Replace one string to another string from string *)
@@ -497,6 +502,17 @@
   } 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 *)     
 let new_file tiger_root (directory:string) (filename:string) (file_size:int64) 
=
   (try
@@ -511,12 +527,9 @@
       if !verbose_download then lprintf_nl "File exists: (%s) (%s)" 
f.file_directory f.file_name;
       f 
   with _ ->
-      let temp_filename =
+      let temp_filename = safe_filename
         (match tiger_root with
-        | "" ->
-          let dname = ref (String.copy directory) in
-          String2.replace_char !dname '/' '_';  
-          Printf.sprintf "DC_%s_%s" !dname filename  
+        | "" -> Printf.sprintf "DC_%s_%s" directory filename
         | _ -> Printf.sprintf "DC_%s" tiger_root )
       in 
       let fullname = Filename.concat !!temp_directory temp_filename in

Index: src/networks/direct_connect/dcInteractive.ml
===================================================================
RCS file: 
/sources/mldonkey/mldonkey/src/networks/direct_connect/dcInteractive.ml,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -b -r1.36 -r1.37
--- src/networks/direct_connect/dcInteractive.ml        23 May 2010 09:12:14 
-0000      1.36
+++ src/networks/direct_connect/dcInteractive.ml        23 May 2010 09:18:31 
-0000      1.37
@@ -55,13 +55,13 @@
     
 (* Start new dowload from result *)
 let start_new_download u tth fdir fname fsize =
-    (try
+    try
       ignore (Hashtbl.find dc_shared_files_by_hash tth);
       if !verbose_download then lprintf_nl "Shared file with same hash exists 
(%s) (%s)" fname tth;
       None 
     with _ ->
         let f = new_file tth fdir fname fsize in   (* ...create new file *)
-        (match (file_state f) with
+        match (file_state f) with
         | FileDownloaded | FileShared -> if !verbose_download then lprintf_nl 
"File already downloaded"; None
         | FileDownloading -> if !verbose_download then lprintf_nl "File being 
downloaded"; None
         | FilePaused -> if !verbose_download then lprintf_nl "File paused"; 
None
@@ -69,28 +69,58 @@
             if !verbose_download then lprintf_nl "File state invalid"; None
         | FileNew -> 
             file_add f.file_file FileDownloading;
-            let c = new_client_to_user_with_file u f in
+            match u with
+            | None -> Some f
+            | Some user ->
+              let c = new_client_to_user_with_file user f in
             c.client_state <- DcDownloadWaiting f;
-            if (can_user_start_downloading u) then begin
-              u.user_state <- TryingToSendFirstContact;
+              if (can_user_start_downloading user) then begin
+                user.user_state <- TryingToSendFirstContact;
               c.client_state <- DcDownloadConnecting (f,current_time ());
               ignore (DcClients.try_connect_client c)
             end;
-            Some f ) )
+              Some f
                     
 (* Start downloading of a file by user selection from resultlist *) 
 let start_result_download r =
   let filename = List.hd r.result_names in
   let rinfo = Hashtbl.find dc_result_info r.result_num in
-  let newfile = start_new_download rinfo.user rinfo.tth rinfo.directory 
filename r.result_size in
+  let newfile = start_new_download (Some rinfo.user) rinfo.tth rinfo.directory 
filename r.result_size in
   (match newfile with 
   | Some f -> as_file f.file_file (* return CommonFile.file *) 
   | _ -> raise Not_found )
 
+let exn_catch f x = try `Ok (f x) with exn -> `Exn exn
+let opt_default default = function None -> default | Some v -> v
+let filter_map f l = List.fold_left (fun acc x -> match f x with Some y -> y 
:: acc | None -> acc) [] l
+
+let parse_url url user group =
+  match exn_catch parse_magnet_url url with
+  | `Exn _ -> "Not a magnet url", false
+  | `Ok magnet ->
+    if !verbose then
+      lprintf_nl "Got magnet url %S" url;
+    (* TODO multiple TTHs, multiple xt, automatic merge of downloads from 
different networks (?!) *) 
+    match filter_map (function TigerTree tth -> Some tth | _ -> None) 
magnet#uids with
+    | [] -> "No TTH found in magnet url", false
+    | tth::_ ->
+      let _ = start_new_download None (TigerTree.to_string tth) "" magnet#name 
(opt_default 0L magnet#size) in
+      magnet#name, true
+
 (* register DC commands *)
 let register_commands list =
   register_commands (List2.tail_map (fun (n,f,h) -> (n, "Direct Connect", 
f,h)) list)
 
+let td_command text title ?(blink=false) ?(target=`Output) cmd =
+  Printf.sprintf
+     "\\<td class=\\\"srb\\\" %sonMouseOver=\\\"mOvr(this);\\\"
+     onMouseOut=\\\"mOut(this);\\\" title=\\\"%s\\\"
+     onClick=\\\"parent.%s.location.href='submit?q=%s'\\\"\\>%s\\</td\\>"
+     (if blink then "style=\\\"text-decoration:blink\\\" " else "")
+     title (match target with `Output -> "output" | `Status -> "fstatus") 
+     (String.concat "+" cmd) (* Url.encode ? *)
+     text
+
 (* Print DC hubs header *)
 let dc_hublist_print_html_header buf ext =
     html_mods_table_header buf "serversTable" (Printf.sprintf "servers%s" ext) 
[
@@ -104,10 +134,8 @@
 (* print in html or txt list of hubs *)
 let hublist_print h hnum o =
   let buf = o.conn_buf in
-  let hname = if (String.length h.dc_name > 50) then String.sub h.dc_name 0 49
-       else h.dc_name in
-  let hinfo = if (String.length h.dc_info > 50) then String.sub h.dc_info 0 49
-       else h.dc_info in
+  let hname = shorten_string h.dc_name 50 in
+  let hinfo = shorten_string h.dc_info 50 in
   if use_html_mods o then begin
     Printf.bprintf buf "
     \\<tr class=\\\"dl-%d\\\"\\>
@@ -119,11 +147,8 @@
     \\<td width=\\\"100%%\\\" class=\\\"sr\\\"\\>%s\\</td\\>\\</tr\\>\n"
     (html_mods_cntr ())
     hnum
-    (Printf.sprintf
-     "\\<td class=\\\"srb\\\" onMouseOver=\\\"mOvr(this);\\\"
-     onMouseOut=\\\"mOut(this);\\\" title=\\\"Add\\\"
-     
onClick=\\\"parent.fstatus.location.href='submit?q=dcn+%s+%d'\\\"\\>Add\\</td\\>"
-     (Ip.string_of_addr h.dc_ip) h.dc_port)
+    (td_command "Add" "Add" ~target:`Status
+      ["dcn"; Ip.string_of_addr h.dc_ip; string_of_int h.dc_port])
     hname
     (Ip.string_of_addr h.dc_ip) h.dc_port
     h.dc_nusers hinfo
@@ -140,21 +165,21 @@
 let dc_user_print_html_header buf =
     html_mods_table_header buf "serversTable" "servers" [
                 ( "1", "srh", "User number", "#" );
-                ( "1", "srh", "User name", "Name" );
-                ( "1", "srh", "User type", "Type" );
+                ( "0", "srh", "User name", "Name" );
+                ( "0", "srh", "User type", "Type" );
                 ( "1", "srh", "Users slots (all/free)", "Slots" );
                 ( "1", "srh", "Users connected hubs (Normal/Vipped/Opped)", 
"Hubs" );
-                ( "1", "srh", "Users mode", "Mode" );
+                ( "0", "srh", "Users mode", "Mode" );
                 ( "1", "srh", "Users shared size", "Shared" );
-                ( "1", "srh", "User state", "State" );
-                ( "1", "srh", "User description field", "Description" );
+                ( "0", "srh", "User state", "State" );
+                ( "0", "srh", "User description field", "Description" );
                 ( "1", "srh", "User clients number", "Clients" );
                 ( "1", "srh", "Users servers number", "Servers" );
                 ( "0", "srh", "Download this clients filelist", "Filelist" );
                 ( "0", "srh", "Open chat window with this user. Blinking tells 
there are new unread messages", "Chat");
                 ( "1", "srh", "User total uploaded bytes", "Up" );
                 ( "1", "srh", "User total downloaded bytes", "Down" );
-                ( "1", "srh", "User client supports", "Supports" ); ];
+                ( "0", "srh", "User client supports", "Supports" ); ];
     ()
 
 (* print in html or txt list of users *)
@@ -213,10 +238,7 @@
     (html_mods_cntr ()) num user.user_nick utype user.user_myinfo.slots hubs 
user.user_myinfo.mode
     (size_of_int64 user.user_myinfo.sharesize) state 
user.user_myinfo.description clients servers
     (if not hasmynick && (servers > 0) then  (* is connected to any servers 
with us *)
-       (Printf.sprintf "\\<td class=\\\"srb\\\" onMouseOver=\\\"mOvr(this);\\\"
-       onMouseOut=\\\"mOut(this);\\\" title=\\\"Download user filelist\\\"
-       
onClick=\\\"parent.fstatus.location.href='submit?q=dcloadfilelist+%s'\\\"\\>Get 
List\\</td\\>"
-       user.user_nick )
+       td_command "Get List" "Download user filelist" ~target:`Status 
["dcloadfilelist"; user.user_nick]
      else begin
        let txt =
          if hasmynick then "Me"
@@ -225,11 +247,9 @@
        Printf.sprintf "\\<td class=\\\"sr\\\"\\>%s\\</td\\>" txt
      end ) 
     (if not hasmynick then (* not me  *)
-       (Printf.sprintf "\\<td class=\\\"srb\\\" 
%sonMouseOver=\\\"mOvr(this);\\\"
-       onMouseOut=\\\"mOut(this);\\\" title=\\\"Open message window to this 
user\\\"
-       
onClick=\\\"parent.output.location.href='submit?q=dcmessages+%s'\\\"\\>Open 
chat\\</td\\>"
-       (if messages then "style=\\\"text-decoration:blink\\\" " else "") 
user.user_nick ) 
-     else "\\<td class=\\\"sr\\\"\\>\\</td\\>" )
+       td_command "Open chat" "Open message window to this user" 
~blink:messages ["dcmessages"; user.user_nick]
+     else 
+       "\\<td class=\\\"sr\\\"\\>\\</td\\>" )
      (size_of_int64 user.user_uploaded) (size_of_int64 user.user_downloaded) 
supports
   end else 
     Printf.bprintf buf "[%5d] %-20s %8s %20s\n" num user.user_nick utype state
@@ -269,23 +289,14 @@
     %s\\</tr\\>\n"
     (html_mods_cntr ())
     num
-    (Printf.sprintf
-     "\\<td class=\\\"srb\\\" onMouseOver=\\\"mOvr(this);\\\"
-     onMouseOut=\\\"mOut(this);\\\" title=\\\"Set this server/hub 
autoconnection state\\\"
-     
onClick=\\\"parent.output.location.href='submit?q=dcautoconnect+%s+%s'\\\"\\>%s\\</td\\>"
-     (if s.server_autoconnect then "false" else "true") sip (if 
s.server_autoconnect then "UnSet" else "Set") )
+    (td_command 
+      (if s.server_autoconnect then "UnSet" else "Set") 
+      "Set this server/hub autoconnection state"
+      ["dcautoconnect"; (if s.server_autoconnect then "false" else "true"); 
sip] )
     sname sip sport sstate 
-    (Printf.sprintf
-     "\\<td class=\\\"srb\\\" onMouseOver=\\\"mOvr(this);\\\"
-     onMouseOut=\\\"mOut(this);\\\" title=\\\"Click to show users for this hub 
only\\\"
-     
onClick=\\\"parent.output.location.href='submit?q=dcusers+%s'\\\"\\>%d\\</td\\>"
-     sip susers )
+    (td_command (string_of_int susers) "Show users for this hub only" 
["dcusers";sip] )
     sinfo
-    (Printf.sprintf
-     "\\<td class=\\\"srb\\\" %sonMouseOver=\\\"mOvr(this);\\\"
-     onMouseOut=\\\"mOut(this);\\\" title=\\\"Open this hubs chat windows\\\"
-     
onClick=\\\"parent.output.location.href='submit?q=dcmessages+%s+%d'\\\"\\>Open 
chat\\</td\\>"
-     (if smessages then "style=\\\"text-decoration:blink\\\" " else "") sip 
sport)
+    (td_command "Open chat" "Open this hubs chat windows" ~blink:smessages 
["dcmessages";sip;string_of_int sport])
   end else begin
     Printf.bprintf buf "[%5d] %20s %25s:%-10d Users:%-8d %20s\n"
       num
@@ -299,13 +310,13 @@
 let dc_client_print_html_header buf =
     html_mods_table_header buf "serversTable" "servers" [
                 ( "1", "srh", "Client number", "#" );
-                ( "1", "srh", "Remove Client", "Rem" );
-                ( "1", "srh", "Clientname", "Name" );
-                ( "1", "srh", "Client ip/port", "Ip:Port" );
-                ( "1", "srh", "Client state", "State" );
-                ( "1", "srh", "Client connection", "Conn" );
-                ( "1", "srh", "Client last error/count", "Error" );
-                ( "1", "srh", "Client file", "File" ); ];
+                ( "0", "srh", "Remove Client", "Rem" );
+                ( "0", "srh", "Client name", "Name" );
+                ( "0", "srh", "Client ip/port", "Ip:Port" );
+                ( "0", "srh", "Client state", "State" );
+                ( "0", "srh", "Client connection", "Conn" );
+                ( "0", "srh", "Client last error/count", "Error" );
+                ( "0", "srh", "Client file", "File" ); ];
             ()
       
 (* print in html or txt list of clients *)
@@ -358,11 +369,8 @@
     \\<td class=\\\"sr\\\" \\>%s\\</td\\>
     \\<td class=\\\"sr\\\" \\>%s\\</td\\>\\</tr\\>\n"
     (html_mods_cntr ()) num
-    (Printf.sprintf
-     "\\<td class=\\\"srb\\\" onMouseOver=\\\"mOvr(this);\\\"
-     onMouseOut=\\\"mOut(this);\\\" title=\\\"Remove client\\\"
-     
onClick=\\\"parent.fstatus.location.href='submit?q=dcremclient+%d'\\\"\\>Rem\\</td\\>"
-     (client_num (as_client client.client_client)) )
+    (td_command "Rem" "Remove client" ~target:`Status 
+      ["dcremclient"; string_of_int (client_num (as_client 
client.client_client))] )
     name ip port state conn error fil
   end else 
     Printf.bprintf buf "[%5d] %25s %25s:%-10d S:%15s C:%15s F:%15s\n" 
@@ -372,15 +380,33 @@
 let dc_file_print_html_header buf =
     html_mods_table_header buf "serversTable" "servers" [
                 ( "1", "srh", "File number", "#" );
-                ( "1", "srh", "File name/path", "File" );
+                ( "0", "srh", "File name/path", "File" );
                 ( "1", "srh", "File size", "Size" );
-                ( "1", "srh", "TTH Hash", "Hash" ); 
+                ( "0", "srh", "Tiger Tree Hash and magnet url", "TTH and 
magnet" ); 
                 ( "1", "srh", "Files clients number (sources)", "Clients" );
                 ( "1", "srh", "Autosearches done", "Searches" );
-                ( "1", "srh", "Find new source by tth", "Find TTH" );
-                ( "1", "srh", "Find new source by similar name context", "Find 
similar" );  ];
+                ( "0", "srh", "Find new source by tth", "Find TTH" );
+                ( "0", "srh", "Find new source by similar name context", "Find 
similar" );  ];
     ()  
 
+let html_show_tth file size tth =
+  begin match exn_catch TigerTree.of_string tth with
+  | `Exn _ -> ""
+  | `Ok hash ->
+    let magnet = object 
+      method name = Filename.basename file
+      method size = match size with 0L -> None | _ -> Some size (* do not 
report size if not available *)
+      method uids = [TigerTree hash]
+    end in
+    Printf.sprintf "\\<a href=\\\"%s\\\"\\>%s\\</a\\>" (show_magnet_url 
magnet) tth
+  end
+
+let html_show_shared dcsh =
+  html_show_tth dcsh.dc_shared_fullname dcsh.dc_shared_size 
dcsh.dc_shared_tiger_root
+
+let html_show_file file =
+  html_show_tth file.file_name file.file_file.impl_file_size 
file.file_unchecked_tiger_root
+
 (* print in html or txt list of files *)
 let file_print file num o =
   let buf = o.conn_buf in
@@ -400,17 +426,9 @@
     %s
     %s\\</tr\\>\n"
     (html_mods_cntr ()) num file.file_name file.file_file.impl_file_size 
-    (file.file_unchecked_tiger_root) (List.length file.file_clients) 
file.file_autosearch_count
-    (Printf.sprintf
-     "\\<td class=\\\"srb\\\" onMouseOver=\\\"mOvr(this);\\\"
-     onMouseOut=\\\"mOut(this);\\\" title=\\\"Find new client for this file by 
TTH\\\"
-     
onClick=\\\"parent.output.location.href='submit?q=dcfindsource+%s'\\\"\\>Find 
TTH\\</td\\>"
-     file.file_unchecked_tiger_root )
-    (Printf.sprintf
-     "\\<td class=\\\"srb\\\" onMouseOver=\\\"mOvr(this);\\\"
-     onMouseOut=\\\"mOut(this);\\\" title=\\\"Find new client for this file by 
similar name\\\"
-     
onClick=\\\"parent.output.location.href='submit?q=dcfindsource+%s'\\\"\\>Find 
similar\\</td\\>"
-     !fname )
+    (html_show_file file) (List.length file.file_clients) 
file.file_autosearch_count
+    (td_command "Find TTH" "Find new client for this file by TTH" 
["dcfindsource"; file.file_unchecked_tiger_root])
+    (td_command "Find similar" "Find new client for this file by similar name" 
["dcfindsource"; !fname])
   end else
     Printf.bprintf buf "[%5d] %40s %-15Ld %5d\n"
       num file.file_name file.file_file.impl_file_size (List.length 
file.file_clients)
@@ -419,9 +437,9 @@
 let dc_shared_print_html_header buf =
     html_mods_table_header buf "serversTable" "servers" [
                 ( "1", "srh", "File number", "#" );
-                ( "1", "srh", "Shared file codedname", "Codedname" );
+                ( "0", "srh", "Shared file name", "Name" );
                 ( "1", "srh", "Shared file size", "Size" );
-                ( "1", "srh", "TTH Hash", "Hash" );
+                ( "0", "srh", "Tiger Tree Hash and magnet url", "TTH and 
magnet" );
                 (*( "1", "srh", "Shared files Tiger tree array length", "TTree 
#" );*) ];
     ()
 
@@ -437,22 +455,43 @@
     \\<td class=\\\"srb\\\" \\>%Ld\\</td\\>
     \\<td class=\\\"srb\\\" \\>%s\\</td\\>\\</tr\\>\n"
     (html_mods_cntr ()) num dcsh.dc_shared_codedname dcsh.dc_shared_size
-    dcsh.dc_shared_tiger_root (*(Array.length dcsh.dc_shared_tiger_array)*)
+    (html_show_shared dcsh)
   end else
     Printf.bprintf buf "[%5d] %40s %-15Ld %24s\n"
       num dcsh.dc_shared_codedname dcsh.dc_shared_size 
dcsh.dc_shared_tiger_root 
-     (*(Array.length dcsh.dc_shared_tiger_array)*)
 
-type dc_int_groups = G_users|G_hubs|G_clients|G_files|G_shared
+(* Print DC filelist header *)
+let dc_filelist_print_html_header buf =
+    html_mods_table_header buf "serversTable" "servers" [
+                ( "1", "srh", "Number", "#" ) ;
+                ( "0", "srh", "Filelist name", "Filelist" ) ]
+
+(* Print one line from filelist *)
+let filelist_print fname line o =
+  let buf = o.conn_buf in
+  if use_html_mods o then begin
+    Printf.bprintf buf "
+    \\<tr class=\\\"dl-%d\\\"\\>
+    \\<td class=\\\"srb\\\" \\>%d\\</td\\>
+    %s
+    \\</tr\\>\n"
+    (html_mods_cntr ())
+    line
+    (td_command fname "Open filelist" ["dcshowfilelist"; fname])
+  end else begin
+    Printf.bprintf buf "[%5d] %s\n" line fname
+  end
+
+type dc_int_groups = G_users|G_hubs|G_clients|G_files|G_shared|G_filelists
 
 (* register users,clients,files *)
 let dc_list o group_type group_name =
     let buf = o.conn_buf in
     let num = ref 1 in
     html_mods_cntr_init ();
-    if use_html_mods o then begin 
-      (try 
-        (match group_type with
+    let html f = if use_html_mods o then f buf else () in
+    begin try
+         begin match group_type with
          | G_users -> 
              let new_messages_list = ref [] in       (* lets order users with 
unread messages to the top *)
              let others_list = ref [] in
@@ -460,66 +499,44 @@
                if user_has_new_messages user then new_messages_list := user :: 
!new_messages_list
                else others_list := user :: !others_list
              ) users_by_name;
-             dc_user_print_html_header buf;
+             html dc_user_print_html_header;
              List.iter (fun user -> user_print user !num o; incr num) 
!new_messages_list;
              List.iter (fun user -> user_print user !num o; incr num) 
!others_list;
          | G_hubs ->
-             dc_hub_print_html_header buf;
+             html dc_hub_print_html_header;
              Hashtbl.iter (fun _ s -> hub_print s !num o; incr num) 
servers_by_ip
              (*List.iter (fun s -> hub_print s !num o; incr num) 
!connected_servers*)
          | G_clients ->
-             dc_client_print_html_header buf;
+             html dc_client_print_html_header;
              List.iter (fun c ->
                (match c.client_name with
                  | Some n -> client_print n c !num o; incr num
                  | None -> () )
              ) !clients_list
          | G_files ->
-             dc_file_print_html_header buf;
+             html dc_file_print_html_header;
              List.iter (fun file -> file_print file !num o; incr num) 
!current_files;
          | G_shared ->
-             dc_shared_print_html_header buf;
-             Hashtbl.iter (fun _ dcsh -> shared_print dcsh !num o; incr num) 
dc_shared_files_by_codedname;
-             Printf.bprintf buf "\\</table\\>\\</div\\>";
-             num := 1;
-             dc_shared_print_html_header buf;
-             Hashtbl.iter (fun _ dcsh -> shared_print dcsh !num o; incr num) 
dc_shared_files_by_hash; )
-      with e -> lprintf_nl "Exception %s in printing %s" (Printexc2.to_string 
e) group_name );
+             html dc_shared_print_html_header;
+             Hashtbl.iter (fun _ dcsh -> shared_print dcsh !num o; incr num) 
dc_shared_files_by_codedname
+         | G_filelists ->
+             html dc_filelist_print_html_header;
+             let filelist = Unix2.list_directory filelist_directory in
+             List.iter (fun fname -> filelist_print fname !num o; incr num) 
filelist;
+         end;
+         if use_html_mods o then 
       Printf.bprintf buf "\\</table\\>\\</div\\>";
+      with e -> 
+        lprintf_nl "Exception %s in printing %s" (Printexc2.to_string e) 
group_name
     end;
     empty_string
 
-(* Print DC filelist header *)
-let dc_filelist_print_html_header buf =
-    html_mods_table_header buf "serversTable" "servers" [
-                ( "1", "srh", "Number", "#" ) ;
-                ( "0", "srh", "Filelist name", "Filelist" ) ]
-
-(* Print one line from filelist *)
-let filelist_print fname line o =
-  let buf = o.conn_buf in
-  if use_html_mods o then begin
-    Printf.bprintf buf "
-    \\<tr class=\\\"dl-%d\\\"\\>
-    \\<td class=\\\"srb\\\" \\>%d\\</td\\>
-    %s"
-    (html_mods_cntr ())
-    line
-    (Printf.sprintf
-     "\\<td class=\\\"srb\\\" onMouseOver=\\\"mOvr(this);\\\"
-     onMouseOut=\\\"mOut(this);\\\" title=\\\"Click to open filelist\\\"
-     
onClick=\\\"parent.output.location.href='submit?q=dcshowfilelist+%s'\\\"\\>%s\\</td\\>\\</tr\\>\n"
-       fname fname);
-  end else begin
-    Printf.bprintf buf "[%5d] %s\n" line fname
-  end
-
 (* Print DC filelist files header *)
 let dc_filelist_files_print_html_header buf =
     html_mods_table_header buf "serversTable" (Printf.sprintf "servers") [
                 ( "1", "srh", "Number", "#" );
-                ( "0", "srh", "File/Firectory name", "File/Directory name" );
-                ( "0", "srh", "File Size", "Size" );
+                ( "0", "srh", "File/Directory name", "File/Directory name" );
+                ( "1", "srh", "File Size", "Size" );
                 ( "0", "srh", "Files TTH", "TTH" ) ]
 
 (* Print one line from filelist file *)  
@@ -552,13 +569,10 @@
     (html_mods_cntr ())
     line
     (if is_file then
-      (Printf.sprintf
-       "\\<td class=\\\"srb\\\" onMouseOver=\\\"mOvr(this);\\\"
-       onMouseOut=\\\"mOut(this);\\\" title=\\\"Click to start loading \\\"
-       
onClick=\\\"parent.fstatus.location.href='submit?q=dcloadfile+%s+%s+%s+%s+%s'\\\"\\>%s%s\\</td\\>"
-          username ftth !sdir !sname fsize spaces fname )
+       td_command (spaces^fname) "Start downloading" ~target:`Status
+         ["dcloadfile"; username; ftth; !sdir; !sname; fsize]
                 else
-       (Printf.sprintf "\\<td class=\\\"srb\\\" 
\\>\\<b\\>%s%s\\</b\\>\\</td\\>" spaces fname)
+       Printf.sprintf "\\<td class=\\\"srb\\\" 
\\>\\<b\\>%s%s\\</b\\>\\</td\\>" spaces fname
   )
     fsize
     ftth
@@ -585,50 +599,38 @@
     Printf.bprintf buf "%s:  %s\n" info data
   end
 
+let show_dc_buttons o =
+  let buf = o.conn_buf in
+  let button id ?(cmd="dc"^id) ?(txt=String.capitalize id) () =
+    Printf.bprintf buf "\\<form style=\\\"margin: 0px;\\\" id=\\\"%s\\\" 
name=\\\"%s\\\"
+      action=\\\"javascript:parent.output.location.href='submit?q=%s'\\\"\\>
+      \\<td\\>\\<input style=\\\"font-family: verdana; font-size: 12px;\\\" 
type=submit
+      Value=\\\"%s\\\"\\>\\</td\\>\\</form\\>" id id cmd txt
+  in
+  if use_html_mods o then 
+  begin
+    Printf.bprintf buf "\\<table\\>\\<tr\\>";
+    button "users" ~cmd:"dcusers+all" ();
+    button "clients" ~cmd:"dcclients" ();
+    button "hubs" ();
+    button "shared" ();
+    button "files" ();
+    button "info" ~txt:"DC Info" ();
+    button "hublistshow" ~cmd:"dchublist" ~txt:"Show hublist" ();
+    button "filelists" ();
+    Printf.bprintf buf "\\</tr\\>\\</table\\>";
+  end
   
 (* List of commands to register *)
 let commands = [
     
   "dc", Arg_none (fun o ->
-    let buf = o.conn_buf in
-    if use_html_mods o then begin
-      Printf.bprintf buf "\\<table\\>\\<tr\\>\\<form style=\\\"margin: 
0px;\\\" id=\\\"users\\\" name=\\\"users\\\"
-        
action=\\\"javascript:parent.output.location.href='submit?q=dcusers+all'\\\"\\>
-        \\<td\\>\\<input style=\\\"font-family: verdana; font-size: 12px;\\\" 
type=submit
-        Value=\\\"Users\\\"\\>\\</td\\>\\</form\\>";
-      Printf.bprintf buf "\\<form style=\\\"margin: 0px;\\\" 
id=\\\"clients\\\" name=\\\"clients\\\"
-        
action=\\\"javascript:parent.output.location.href='submit?q=dcclients'\\\"\\>
-        \\<td\\>\\<input style=\\\"font-family: verdana; font-size: 12px;\\\" 
type=submit
-        Value=\\\"Clients\\\"\\>\\</td\\>\\</form\\>";
-      Printf.bprintf buf "\\<form style=\\\"margin: 0px;\\\" id=\\\"hubs\\\" 
name=\\\"hubs\\\"
-        
action=\\\"javascript:parent.output.location.href='submit?q=dchubs'\\\"\\>
-        \\<td\\>\\<input style=\\\"font-family: verdana; font-size: 12px;\\\" 
type=submit
-        Value=\\\"Hubs\\\"\\>\\</td\\>\\</form\\>";
-      Printf.bprintf buf "\\<form style=\\\"margin: 0px;\\\" id=\\\"shared\\\" 
name=\\\"shared\\\"
-        
action=\\\"javascript:parent.output.location.href='submit?q=dcshared'\\\"\\>
-        \\<td\\>\\<input style=\\\"font-family: verdana; font-size: 12px;\\\" 
type=submit
-        Value=\\\"Shared\\\"\\>\\</td\\>\\</form\\>";
-      Printf.bprintf buf "\\<form style=\\\"margin: 0px;\\\" id=\\\"files\\\" 
name=\\\"files\\\"
-        
action=\\\"javascript:parent.output.location.href='submit?q=dcfiles'\\\"\\>
-        \\<td\\>\\<input style=\\\"font-family: verdana; font-size: 12px;\\\" 
type=submit
-        Value=\\\"Files\\\"\\>\\</td\\>\\</form\\>";
-      Printf.bprintf buf "\\<form style=\\\"margin: 0px;\\\" id=\\\"info\\\" 
name=\\\"info\\\"
-        
action=\\\"javascript:parent.output.location.href='submit?q=dcinfo'\\\"\\>
-        \\<td\\>\\<input style=\\\"font-family: verdana; font-size: 12px;\\\" 
type=submit
-        Value=\\\"DC Info\\\"\\>\\</td\\>\\</form\\>";
-      Printf.bprintf buf "\\<form style=\\\"margin: 0px;\\\" 
id=\\\"hublistshow\\\" name=\\\"hublistshow\\\"
-        
action=\\\"javascript:parent.output.location.href='submit?q=dchublist'\\\"\\>
-        \\<td\\>\\<input style=\\\"font-family: verdana; font-size: 12px;\\\" 
type=submit
-        Value=\\\"Show hublist\\\"\\>\\</td\\>\\</form\\>";
-      Printf.bprintf buf "\\<form style=\\\"margin: 0px;\\\" 
id=\\\"filelists\\\" name=\\\"filelists\\\"
-        
action=\\\"javascript:parent.output.location.href='submit?q=dcfilelists'\\\"\\>
-        \\<td\\>\\<input style=\\\"font-family: verdana; font-size: 12px;\\\" 
type=submit
-        Value=\\\"Filelists\\\"\\>\\</td\\>\\</form\\>";
-      Printf.bprintf buf "\\</tr\\>\\</table\\>";
-    end else
-      Printf.bprintf buf "Received command dc\n";
-    empty_string
-  ), ": Show direct connect buttons";
+    if use_html_mods o then
+      show_dc_buttons o
+    else
+      Printf.bprintf buf "Try `?? dc` for more commands\n";
+    dc_list o G_hubs "hubs"
+  ), ": Show Direct Connect buttons";
 
   (* 'dcn address [port]'  Add a new DC server with optional port (default 
411) *)
   "dcn", Arg_multiple (fun args o ->
@@ -648,11 +650,12 @@
   ), "<ip> [<port>] : Add a server. Default port number is 411";
 
   (* List connected hubs for chatting *)
-  "dchubs", Arg_none (fun o -> dc_list o G_hubs "hubs" 
+  "dchubs", Arg_none (fun o -> show_dc_buttons o; dc_list o G_hubs "hubs" 
   ), ": Show connected DC hubs"; 
 
   (* List all DC users *)
   "dcusers", Arg_one (fun args o ->
+    show_dc_buttons o;
     let buf = o.conn_buf in
     (match args with
     | "all" -> dc_list o G_users "users"
@@ -674,19 +677,20 @@
   ), "<all>|<ip> :Show DC users"; 
 
   (* List all DC clients *)
-  "dcclients", Arg_none (fun o -> dc_list o G_clients "clients"
+  "dcclients", Arg_none (fun o -> show_dc_buttons o; dc_list o G_clients 
"clients"
   ), ": Show all DC clients"; 
 
   (* List all DC files *)
-  "dcfiles", Arg_none (fun o -> dc_list o G_files "files"
+  "dcfiles", Arg_none (fun o -> show_dc_buttons o; dc_list o G_files "files"
   ), ": Show all DC files";
 
   (* List all DC shared files *)
-  "dcshared", Arg_none (fun o -> dc_list o G_shared "shared"
+  "dcshared", Arg_none (fun o -> show_dc_buttons o; dc_list o G_shared "shared"
   ), ": Show all DC shared files. All/Hashed ";
 
-  (* 'dchubs [args]' - Show dchub list with optional filters args (max 5) *)
+  (* 'dchublist [args]' - Show dchub list with optional filters args (max 5) *)
   "dchublist", Arg_multiple (fun args o ->
+    show_dc_buttons o;
     let buf = o.conn_buf in
     let filter = ref [] in
     let print_hublist () =
@@ -786,7 +790,7 @@
             in
             s.server_read_messages <- List.length s.server_messages;      (* 
messages are set as read before   *) 
             s.server_messages,                                            (* 
they are actually printed to user *)
-            (if (String.length s.server_name > 50) then String.sub 
s.server_name 0 49 else s.server_name),
+            (shorten_string s.server_name 50),
             topic
           with _ ->
               if !verbose_unexpected_messages then lprintf_nl "dcmsglog: No 
server with address found";
@@ -830,7 +834,7 @@
           html_mods_td buf [
             (empty_string, "sr", Date.simple (BasicSocket.date_of_int t));
             (empty_string, "sr", f);
-            (empty_string, "srw", msg) ];
+            (empty_string, "srw", String2.replace msg '\r' "\\<br/\\>") ];
           Printf.bprintf buf "\\</tr\\>"
       end else begin
         Printf.bprintf buf "\n%s [%s] : %s\n" (Date.simple 
(BasicSocket.date_of_int t)) f msg
@@ -842,6 +846,7 @@
   ), "<refresh> <user> | <refresh> <serverip> <serverport>";
 
   "dcmessages", Arg_multiple (fun args o ->
+    show_dc_buttons o;
     let buf = o.conn_buf in
     let s,u =
       (match args with
@@ -1014,7 +1019,7 @@
         Printf.bprintf buf "Trying to download file: %s from user: %s\n" 
!sname uname;
         (try 
           let u = search_user_by_name uname in
-          ignore (start_new_download u tth !sdir !sname (Int64.of_string 
fsize))
+          ignore (start_new_download (Some u) tth !sdir !sname 
(Int64.of_string fsize))
         with _ -> if !verbose_download then lprintf_nl "dcloadfile: No user 
found" )
     | _ ->
         if !verbose_unexpected_messages then
@@ -1050,18 +1055,7 @@
     empty_string
   ), "<name> : Download filelist from user";
 
-  "dcfilelists", Arg_none (fun o -> 
-    let buf = o.conn_buf in
-    html_mods_cntr_init ();
-    let line = ref 1 in
-    if use_html_mods o then dc_filelist_print_html_header buf;
-    let filelist = Unix2.list_directory filelist_directory in
-    List.iter (fun fname ->
-      filelist_print fname !line o;
-      incr line
-    ) filelist;
-    if use_html_mods o then Printf.bprintf buf "\\</table\\>\\</div\\>";
-    empty_string
+  "dcfilelists", Arg_none (fun o -> show_dc_buttons o; dc_list o G_filelists 
"filelists"
   ), ": List all filelists on disk";
 
   "dcremclient", Arg_one (fun args o ->
@@ -1130,13 +1124,13 @@
   ), ": Find new source for a file";
 
   "dcinfo", Arg_none (fun o ->
+    show_dc_buttons o;
     let buf = o.conn_buf in
     let server_list =
       let lst = ref [] in
         List.iter (fun s ->
           let data = 
-            String.sub s.server_name 0 (if (String.length s.server_name > 20) 
then 20 else
-              String.length s.server_name) ^ "  (nick = " ^ s.server_last_nick 
^ ")  (uptime = " ^
+            shorten_string s.server_name 20 ^ "  (nick = " ^ 
s.server_last_nick ^ ")  (uptime = " ^
               (Date.time_to_string (int_of_float (current_time ()) -
                 int_of_float (s.server_connection_time)) "verbose") ^
                 (string_of_int (List.length s.server_users)) ^ ")"
@@ -1170,6 +1164,7 @@
 
   (* load filelist from user *)
   "dcshowfilelist", Arg_one (fun args o ->
+    show_dc_buttons o;
     let buf = o.conn_buf in
     (match args with
     | filename -> 
@@ -1553,7 +1548,30 @@
     file_ops.op_file_resume <- (fun _ -> ());
     file_ops.op_file_set_format <- (fun _ _ -> ());
     file_ops.op_file_check <- (fun _ -> ());
-    file_ops.op_file_recover <- (fun _ -> ())
+    file_ops.op_file_recover <- (fun _ -> ());
+    file_ops.op_file_print <- (fun file o ->
+      let buf = o.conn_buf in
+      if use_html_mods o then 
+      begin
+        let td l =
+          Printf.bprintf buf "\\</tr\\>\\<tr class=\\\"dl-%d\\\"\\>" 
(html_mods_cntr ());
+          html_mods_td buf l
+        in
+        td [
+          ("Directory", "sr br", "Directory");
+          ("", "sr", file.file_directory) ];
+        td [
+          ("Filename", "sr br", "Filename");
+          ("", "sr", file.file_name) ];
+        td [
+          ("Tiger tree hash and magnet url", "sr", "TTH and magnet");
+          ("", "sr", html_show_file file) ];
+        td [
+          ("Automatic TTH searches performed", "sr", "Autosearches");
+          ("", "sr", string_of_int file.file_autosearch_count) ];
+      end
+      else
+        ())
     (*file_ops.op_file_print_html <- (fun _ _ -> lprintf_nl "Received 
(op_file_print_html)"; ());*)
     (*file_ops.op_file_print_sources_html <- (fun _ _ -> lprintf_nl "Received 
(op_file_print_sources_html)"; ())*)
 (*    mutable op_file_files : ('a -> 'a file_impl -> file list);

Index: src/networks/direct_connect/dcMain.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/networks/direct_connect/dcMain.ml,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- src/networks/direct_connect/dcMain.ml       18 Mar 2008 08:24:38 -0000      
1.9
+++ src/networks/direct_connect/dcMain.ml       23 May 2010 09:18:31 -0000      
1.10
@@ -215,7 +215,7 @@
   network.op_network_connected <- (fun _ ->
     !connected_servers <> []
   );
-  network.op_network_parse_url <- (fun _ _ _ -> empty_string, false);
+  network.op_network_parse_url <- (fun url user group -> 
DcInteractive.parse_url url user group);
   network.op_network_download <- (fun r _ _ -> 
DcInteractive.start_result_download r);
   network.op_network_ports <- (fun _ ->
     [

Index: src/networks/direct_connect/dcProtocol.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/networks/direct_connect/dcProtocol.ml,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- src/networks/direct_connect/dcProtocol.ml   23 May 2010 09:12:14 -0000      
1.8
+++ src/networks/direct_connect/dcProtocol.ml   23 May 2010 09:18:31 -0000      
1.9
@@ -880,7 +880,7 @@
     message : string;
       }
     let parse s = 
-    if ((String.length s) > 1000) then begin
+    if ((String.length s) > 2048) then begin
       lprintf_nl "Overlength $To: (%s)" (shorten_string s 50);
           raise Not_found
     end else begin

Index: src/utils/lib/charset.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/utils/lib/charset.ml,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- src/utils/lib/charset.ml    23 May 2010 09:12:15 -0000      1.10
+++ src/utils/lib/charset.ml    23 May 2010 09:18:31 -0000      1.11
@@ -172,7 +172,7 @@
 
(**********************************************************************************)
 
 (* taken from camomile *)
-(* $Id: charset.ml,v 1.10 2010/05/23 09:12:15 spiralvoice Exp $ *)
+(* $Id: charset.ml,v 1.11 2010/05/23 09:18:31 spiralvoice Exp $ *)
 (* Copyright 2002, 2003 Yamagata Yoriyuki. distributed with LGPL *)
 
 let utf8_look s i =
@@ -243,9 +243,9 @@
   if n = 0 then i else
   nth_aux s (utf8_next s i) (n - 1)
 
-let nth s n = nth_aux s 0 n
+let utf8_nth s n = nth_aux s 0 n
 
-let utf8_get s n = utf8_look s (nth s n)
+let utf8_get s n = utf8_look s (utf8_nth s n)
 
 
(**********************************************************************************)
 (*                                                                             
   *)
@@ -254,7 +254,7 @@
 
(**********************************************************************************)
 
 (* taken from camomile *)
-(* $Id: charset.ml,v 1.10 2010/05/23 09:12:15 spiralvoice Exp $ *)
+(* $Id: charset.ml,v 1.11 2010/05/23 09:18:31 spiralvoice Exp $ *)
 (* Copyright 2002, 2003 Yamagata Yoriyuki. distributed with LGPL *)
 
 let rec length_aux s c i =
@@ -281,7 +281,7 @@
 
 
 (* taken from camomile *)
-(* $Id: charset.ml,v 1.10 2010/05/23 09:12:15 spiralvoice Exp $ *)
+(* $Id: charset.ml,v 1.11 2010/05/23 09:18:31 spiralvoice Exp $ *)
 (* Copyright 2002, 2003 Yamagata Yoriyuki. distributed with LGPL *)
 
 external uint_code : uchar -> int = "%identity"

Index: src/utils/lib/charset.mli
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/utils/lib/charset.mli,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- src/utils/lib/charset.mli   23 May 2010 09:12:15 -0000      1.6
+++ src/utils/lib/charset.mli   23 May 2010 09:18:31 -0000      1.7
@@ -167,6 +167,9 @@
     returns the number of Unicode characters contained in s *)
 val utf8_length : string -> int
 
+(** [utf8_nth s n] @return index of [n]-th utf-8 character in [s] (must be 
valid utf-8 string). O(n) *)
+val utf8_nth : string -> int -> int
+
 (** [add_uchar buf u]
     add one Unicode character to the buffer. *)
 val add_uchar : Buffer.t -> uchar -> unit



reply via email to

[Prev in Thread] Current Thread [Next in Thread]