1 (* Copyright 2001, 2002 b8_bavard, b8_fee_carabine, INRIA *)
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
30 let dump_file filename
=
31 Unix2.tryopen_read filename
(fun ic
->
32 let s = String.create
20 in
34 lprintf
"file: %s\n" filename
;
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);
43 with End_of_file
| Exit
-> ())
45 module Server
= struct
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
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
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);
109 None
-> List.rev left
110 | Some
(server
, pos) ->
111 read_servers s pos (server
:: left
)
118 buf_int buf
(List.length t
);
122 buf_tags buf
s.tags names_of_tag
126 lprintf
"SERVER.MET: %d servers\n" (List.length t
);
128 lprintf
" SERVER %s:%d\n" (Ip.to_string
s.ip) s.port;
135 module Known
= struct
140 blocks
: Md4.t array
;
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 (); *)
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) ({
172 let nfiles = get_int
s 1 in
173 read_files s 5 nfiles []
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
187 lprintf_nl
"KNOWN.MET: %d files" (List.length t
);
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);
194 lprintf_nl
" %s" (Md4.to_string m
);
198 with _
-> lprintf_nl
"Error : no file in known.met\n";
206 blocks : Md4.t array
;
208 absents
: (int64
* int64
) list
;
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";
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 (); *)
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;
245 let absents = List.sort
(fun (s1
,e1
) (s2
,e2
) ->
256 assert (get_uint8
s 0 = 224);
257 (* assert (get_int s 1 = 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
270 lprintf_nl
" FILE %s" (Md4.to_string f
.md4);
271 lprintf_nl
" Blocks: %d" (Array.length f
.blocks);
273 lprintf_nl
" %s" (Md4.to_string m
);
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
);
281 with _
-> lprintf
"Error: no file\n";
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 = []
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
316 client_tags = client_tags;
317 option_tags = option_tags;
321 lprintf
"PREF.MET %s\n" (Md4.to_string t
.md4);
323 print_tags t
.client_tags;
326 print_tags t
.option_tags;
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
338 (5)(0)(118)(107)(105)(115)(109)
346 (0)(0)(0)(0) # second record
347 (0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(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"