patch #7310
[mldonkey.git] / src / networks / donkey / donkeyImport.ml
blobc079911cd4b73a7f2c1bcbe352700bafe7705885
1 (* Copyright 2001, 2002 b8_bavard, b8_fee_carabine, INRIA *)
2 (*
3 This file is part of mldonkey.
5 mldonkey is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 mldonkey is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with mldonkey; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 open AnyEndian
20 open Printf2
21 open Md4
22 open LittleEndian
24 open CommonTypes
25 open CommonGlobals
27 open DonkeyTypes
28 open DonkeyMftp
30 let dump_file filename =
31 Unix2.tryopen_read filename (fun ic ->
32 let s = String.create 20 in
33 try
34 lprintf "file: %s\n" filename;
35 let pos = ref 0 in
36 while true do
37 let n = input ic s 0 20 in
38 lprintf "pos = %d\n" !pos;
39 if n = 0 then raise Exit;
40 dump (String.sub s 0 n);
41 pos := !pos + n;
42 done
43 with End_of_file | Exit -> ())
45 module Server = struct
47 type server = {
48 ip : Ip.t;
49 port : int;
50 tags : tag list;
53 type t = server list
56 let names_of_tag =
57 (* eMule sourcefile opcodes.h //server.met *)
59 "\001", Field_KNOWN "name"; (* 0x01 string *)
60 "\011", Field_KNOWN "description"; (* 0x0B string *)
61 "\012", Field_KNOWN "ping"; (* 0x0C uint32 *)
62 "\013", Field_KNOWN "history"; (* 0x0D ST_FAIL *)
63 "\014", Field_KNOWN "prof"; (* 0x0E ST_PREFERENCE *)
64 "\015", Field_KNOWN "port"; (* 0x0F uint32 *)
65 "\016", Field_KNOWN "ip"; (* 0x10 uint32 *)
66 "\133", Field_KNOWN "dynip"; (* 0x85 string *)
67 "\135", Field_KNOWN "maxusers"; (* 0x87 uint32 *)
68 "maxusers", Field_KNOWN "maxusers";
69 "\136", Field_KNOWN "softfiles"; (* 0x88 uint32 *)
70 "\137", Field_KNOWN "hardfiles"; (* 0x89 uint32 *)
71 "\144", Field_KNOWN "lastping"; (* 0x90 uint32 *)
72 "\145", Field_KNOWN "version"; (* 0x91 string|uint32 *)
73 "\146", Field_KNOWN "udpflags"; (* 0x92 uint32 *)
74 "\147", Field_KNOWN "auxportslist"; (* 0x93 string *)
75 "\148", Field_KNOWN "lowusers"; (* 0x94 uint32 *)
76 "lowusers", Field_KNOWN "lowusers";
77 "\149", Field_KNOWN "udpkey"; (* 0x95 uint32 *)
78 "\150", Field_KNOWN "udpkeyip"; (* 0x96 uint32 *)
79 "\151", Field_KNOWN "tcpportobfuscation"; (* 0x97 uint16 *)
80 "\152", Field_KNOWN "udpportobfuscation"; (* 0x98 uint16 *)
81 "files", Field_KNOWN "files";
82 "users", Field_KNOWN "users";
83 "country", Field_KNOWN "country";
84 "refs", Field_KNOWN "refs";
88 let rec read_servers s pos left =
89 if pos + 9 >= String.length s then List.rev left else
90 match
91 try
92 let ip = get_ip s pos in
93 let port = get_port s (pos+4) in
94 let tags, pos = get_tags s (pos+6) names_of_tag in
95 Some ({
96 ip = ip;
97 port = port;
98 tags = tags;
99 }, pos)
100 with e ->
102 let len = String.length s - pos in
103 lprintf "Error while reading servers %s (left %d)\n"
104 (Printexc2.to_string e) len;
105 dump (String.sub s pos len);
107 None
108 with
109 None -> List.rev left
110 | Some (server, pos) ->
111 read_servers s pos (server :: left)
113 let read s =
114 read_servers s 5 []
116 let write buf t =
117 buf_int8 buf 14;
118 buf_int buf (List.length t);
119 List.iter (fun s ->
120 buf_ip buf s.ip;
121 buf_port buf s.port;
122 buf_tags buf s.tags names_of_tag
125 let print t =
126 lprintf "SERVER.MET: %d servers\n" (List.length t);
127 List.iter (fun s ->
128 lprintf " SERVER %s:%d\n" (Ip.to_string s.ip) s.port;
129 print_tags s.tags;
130 lprintf "\n";
131 ) t;
135 module Known = struct
137 type file = {
138 mtime : int64;
139 md4 : Md4.t;
140 blocks : Md4.t array;
141 tags : tag list;
144 type t = file list
146 let names_of_tag = file_common_tags
149 let rec read_files s pos n left =
150 if n = 0 then List.rev left else
151 let mtime = get_uint64_32 s pos in
152 (* lprintf "file at pos %d" pos; lprint_newline (); *)
153 let md4 = get_md4 s (pos+4) in
154 let nblocks = get_int16 s (pos+20) in
155 (* lprintf "nblocks = %d" nblocks; lprint_newline (); *)
156 let blocks = Array.init nblocks (fun i ->
157 let b = get_md4 s (pos+22+16*i) in
158 (* lprintf "b: [%s]" (String.escaped b);
159 lprint_newline (); *)
161 ) in
162 let pos = pos + 22 + 16 * nblocks in
163 let tags, pos = get_tags s pos names_of_tag in
164 read_files s pos (n-1) ({
165 mtime = mtime;
166 md4 = md4;
167 blocks = blocks;
168 tags = tags;
169 } :: left)
171 let read s =
172 let nfiles = get_int s 1 in
173 read_files s 5 nfiles []
175 let write buf t =
176 buf_int8 buf 14;
177 buf_int buf (List.length t);
178 List.iter (fun file ->
179 buf_int64_32 buf file.mtime;
180 buf_md4 buf file.md4;
181 buf_int16 buf (Array.length file.blocks);
182 Array.iter (buf_md4 buf) file.blocks;
183 buf_tags buf file.tags names_of_tag
186 let print t =
187 lprintf_nl "KNOWN.MET: %d files" (List.length t);
188 List.iter (fun f ->
190 lprintf_nl " FILE %s" (Md4.to_string f.md4);
191 lprintf_nl " mtime: %s" (Int64.to_string f.mtime);
192 lprintf_nl " Blocks: %d" (Array.length f.blocks);
193 Array.iter (fun m ->
194 lprintf_nl " %s" (Md4.to_string m);
195 ) f.blocks;
196 print_tags f.tags;
197 lprint_newline ();
198 with _ -> lprintf_nl "Error : no file in known.met\n";
199 ) t;
202 module Part = struct
204 type t = {
205 md4 : Md4.t;
206 blocks : Md4.t array;
207 tags : tag list;
208 absents : (int64 * int64) list;
211 let names_of_tag =
213 "\008", Field_KNOWN "downloaded";
214 "\018", Field_KNOWN "diskname";
215 "\019", Field_KNOWN "priority";
216 "\020", Field_KNOWN "status";
217 "\t", Field_KNOWN "start_pos";
218 "\n", Field_KNOWN "absent";
219 ] @ file_common_tags
222 let rec read_file s pos =
223 (* lprintf "file at pos %d" pos; lprint_newline (); *)
224 let md4 = get_md4 s (pos) in
225 let nblocks = get_int16 s (pos+16) in
226 (* lprintf "nblocks = %d" nblocks; lprint_newline (); *)
227 let blocks = Array.init nblocks (fun i ->
228 let b = get_md4 s (pos+18+16*i) in
229 (* lprintf "b: [%s]" (String.escaped b);
230 lprint_newline (); *)
232 ) in
233 let pos = pos + 18 + 16 * nblocks in
234 let tags, pos = get_tags s pos names_of_tag in
235 let start_pos = ref Int64.zero in
236 let absents = ref [] in
237 List.iter (fun tag ->
238 let s = tag.tag_name in
239 match s, tag.tag_value with
240 Field_KNOWN "start_pos", Uint64 p -> start_pos := p;
241 | Field_KNOWN "absent", Uint64 p ->
242 absents := (!start_pos, p) :: !absents;
243 | _ -> ()
244 ) tags;
245 let absents = List.sort (fun (s1,e1) (s2,e2) ->
246 compare s1 s2
247 ) !absents in
249 md4 = md4;
250 blocks = blocks;
251 tags = tags;
252 absents = absents;
255 let read s =
256 assert (get_uint8 s 0 = 224);
257 (* assert (get_int s 1 = 0); *)
258 read_file s 5
260 let write buf file =
261 buf_int8 buf 224;
262 buf_int buf 0;
263 buf_md4 buf file.md4;
264 buf_int16 buf (Array.length file.blocks);
265 Array.iter (buf_md4 buf) file.blocks;
266 buf_tags buf file.tags names_of_tag
268 let print f =
270 lprintf_nl " FILE %s" (Md4.to_string f.md4);
271 lprintf_nl " Blocks: %d" (Array.length f.blocks);
272 Array.iter (fun m ->
273 lprintf_nl " %s" (Md4.to_string m);
274 ) f.blocks;
275 lprintf_nl " Absent blocks:";
276 List.iter (fun (t1,n1) ->
277 lprintf_nl "%10s - %10s" (Int64.to_string t1)
278 (Int64.to_string n1);
279 ) f.absents;
280 print_tags f.tags;
281 with _ -> lprintf "Error: no file\n";
284 module Pref = struct
286 type t = {
287 md4: Md4.t;
288 client_tags : tag list;
289 option_tags : tag list;
292 let names_of_client_tag =
294 "\001", Field_KNOWN "name";
295 "\017", Field_KNOWN "version";
296 "\015", Field_KNOWN "port";
299 let names_of_option_tag = []
301 let read s =
302 assert (get_int s 1 = 2);
303 assert (get_int s 5 = 0);
304 let md4 = get_md4 s 9 in
305 assert (get_int16 s 25 = 0);
306 (* lprintf "ntags : %d at pos %d" ntags 27; lprint_newline (); *)
307 let client_tags, pos = get_tags s 27 names_of_client_tag in
309 assert (get_int s pos = 0);
310 assert (get_md4 s (pos+4) = Md4.null);
311 assert (get_int16 s (pos + 20) = 0);
312 let option_tags, pos = get_tags s (pos+22) names_of_option_tag in
315 md4 = md4;
316 client_tags = client_tags;
317 option_tags = option_tags;
320 let print t =
321 lprintf "PREF.MET %s\n" (Md4.to_string t.md4);
323 print_tags t.client_tags;
324 lprint_newline ();
326 print_tags t.option_tags;
327 lprint_newline ()
329 (14)
330 (2)(0)(0)(0)
332 (0)(0)(0)(0) # premier record: client desc
333 (18)(36)(161)(160)(102)(31)(245)(198)(40)(142)(6)(63)(5)(92)(71)(240) # md4
334 (0)(0)
335 (3)(0)(0)(0) # ntags
337 (1)(0)(1) # name
338 (5)(0)(118)(107)(105)(115)(109)
340 (1)(0)(17) # version
341 (57)(0)(0)(0)
343 (1)(0)(15) # port
344 (48)(17)(0)(0)
346 (0)(0)(0)(0) # second record
347 (0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)
348 (0)(0)
349 (28)(0)(0)(0) # ntags
351 (8)(0)(105)(110)(99)(111)(109)(105)(110)(103) "incoming"
352 (39)(0)(47)(104)(111)(109)(101)(47)(108)(101)(102)(101)(115)(115)(97)(110)(47)(101)(100)(111)(110)(107)(101)(121)(47)(99)(108)(105)(101)(110)(116)(50)(47)(105)(110)(99)(111)(109)(105)(110)(103) "/home/.../incoming"
353 (2) ...