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
28 let torrent_filename = ref ""
29 let torrent_comment = ref ""
30 let torrent_private = ref 0
35 let ( ** ) x y
= Int64.mul x y
36 let ( // ) x y
= Int64.div x y
38 let check_tracker () =
39 if !announce = "" then begin
40 Printf.printf
"You must specify the tracker url with -tracker <url>\n";
44 let check_torrent () =
45 if !torrent_filename = "" then begin
46 Printf.printf
"You must specify the .torrent filename with -torrent <filename>\n";
52 "-tracker", Arg.Set_string
announce,
53 "<url> set the tracker to put in the torrent file";
54 "-torrent", Arg.Set_string
torrent_filename,
55 "<filename.torrent> the .torrent file to use";
56 "-comment", Arg.Set_string
torrent_comment,
57 "\"<string>\" some comments on the torrent";
58 "-private", Arg.Set_int
torrent_private,
59 "<0|1> set the private flag";
61 "-change", Arg.Unit
(fun _ ->
64 let s = File.to_string
!torrent_filename in
65 let torrent_id, torrent
= BTTorrent.decode_torrent
s in
66 let torrent = { torrent with
67 BTTypes.torrent_announce
= !announce;
68 BTTypes.torrent_modified_by
= Printf.sprintf
"MLdonkey/%s" Autoconf.current_version
} in
69 let torrent_id, encoded
= BTTorrent.encode_torrent
torrent in
70 let s = Bencode.encode encoded
in
71 File.from_string
!torrent_filename s;
72 Printf.printf
"Torrent file of %s modified\n" (Sha1.to_hexa
torrent_id);
73 ), " change the tracker inside a .torrent file";
75 "-print", Arg.Unit
(fun filename
->
77 let s = File.to_string
!torrent_filename in
78 let torrent_id, torrent = BTTorrent.decode_torrent
s in
79 Printf.printf
"Torrent name: %s\n" torrent.torrent_name
;
80 Printf.printf
" comment: %s\n" torrent.torrent_comment;
81 Printf.printf
" created by: %s\n" torrent.torrent_created_by
;
82 Printf.printf
" creation date: %s\n" (Date.to_string
(Int64.to_float
83 torrent.torrent_creation_date
));
84 Printf.printf
" modified by: %s\n" torrent.torrent_modified_by
;
85 Printf.printf
" length: %Ld\n" torrent.torrent_length
;
86 Printf.printf
" encoding: %s\n" torrent.torrent_encoding
;
87 Printf.printf
" tracker: %s\n" torrent.torrent_announce
;
88 Printf.printf
" private: %s\n" (if torrent.torrent_private then "yes" else "no");
89 Printf.printf
" piece size: %Ld\n" torrent.torrent_piece_size
;
90 Printf.printf
" Pieces: %d\n" (Array.length
torrent.torrent_pieces
);
91 Array.iteri
(fun i
s ->
92 Printf.printf
" %3d: %s\n" i
(Sha1.to_hexa
s)
93 ) torrent.torrent_pieces
;
94 if torrent.torrent_files
<> [] then begin
95 Printf.printf
" Files: %d\n" (List.length
torrent.torrent_files
);
96 List.iter
(fun (s, len
) ->
97 Printf.printf
" %10Ld : %s\n" len
s
98 ) torrent.torrent_files
;
100 ), "<filename.torrent> print the contents of a .torrent file";
102 "-create", Arg.String
(fun filename
->
106 let hash = BTTorrent.generate_torrent
!announce !torrent_filename !torrent_comment
107 (!torrent_private<>0) filename
109 Printf.printf
"Torrent file generated : %s\n" (Sha1.to_hexa
hash);
111 exn
-> Printf.printf
"Cannot create torrent : %s\n" (Printexc2.to_string exn
); exit
2
112 ),"<filename> compute hashes of filename(s) (can be a directory) and generate a .torrent file";
114 "-split", Arg.String
(fun filename
->
117 let s = File.to_string
!torrent_filename in
118 let torrent_id, torrent = BTTorrent.decode_torrent
s in
121 String.sub
!torrent_filename 0 ((String.length
!torrent_filename) - 8)
124 let bt_fd = Unix32.create_ro filename
in
125 let rec iter begin_pos list
=
128 | (filename
, size
) :: tail
->
129 let end_pos = begin_pos
++ size
in
130 let filename = Filename.concat
base_dir_name filename in
131 let dirname = Filename.dirname filename in
132 Unix2.safe_mkdir
dirname;
133 lprintf
"Copying %Ld %Ld to 0\n"
134 begin_pos
(end_pos -- begin_pos
);
135 let fd = Unix32.create_rw
filename in
136 Unix32.copy_chunk
bt_fd fd begin_pos
zero
137 (Int64.to_int
(end_pos -- begin_pos
));
142 iter zero torrent.torrent_files
;
145 ), "<filename> split a file corresponding to a .torrent file";
147 "-check", Arg.String
(fun filename ->
149 let s = File.to_string
!torrent_filename in
150 let torrent_id, torrent = BTTorrent.decode_torrent
s in
152 if torrent.torrent_name
<> Filename.basename
filename then begin
153 Printf.printf
"WARNING: %s <> %s\n"
154 torrent.torrent_name
(Filename.basename
filename);
156 let t = if torrent.torrent_files
<> [] then
157 Unix32.create_multifile
filename false
158 torrent.torrent_files
159 else Unix32.create_ro
filename
162 let length = Unix32.getsize64
t in
164 if torrent.torrent_length
<> length then begin
165 Printf.printf
"ERROR: computed size %Ld <> torrent size %Ld\n"
166 length torrent.torrent_length
;
170 let chunk_size = torrent.torrent_piece_size
in
171 let npieces = 1 + Int64.to_int
((length -- one) // chunk_size) in
173 if Array.length torrent.torrent_pieces
<> npieces then begin
174 Printf.printf
"ERROR: computed npieces %d <> torrent npieces %d\n"
175 npieces (Array.length torrent.torrent_pieces
);
180 for i
= 0 to npieces - 1 do
181 let begin_pos = chunk_size ** (Int64.of_int i
) in
183 let end_pos = begin_pos ++ chunk_size in
185 if end_pos > length then length else end_pos in
187 let sha1 = Sha1.digest_subfile
t
188 begin_pos (end_pos -- begin_pos) in
189 if torrent.torrent_pieces
.(i
) <> sha1 then begin
190 Printf.printf
"WARNING: piece %d (%Ld-%Ld) has SHA1 %s instead of %s\n"
193 (Sha1.to_hexa
torrent.torrent_pieces
.(i
));
197 Printf.printf
"Torrent file verified !!!\n";
199 ), "<filename> check that <filename> is well encoded by a .torrent";
202 Arg.parse
(Arg.align
args)
204 Printf.printf
"Don't know what to do with %s\n" s;
205 Printf.printf
"Use --help to get some help\n";
208 ("make_torrent : manipulate .torrent files\n\n" ^
210 "- create a new torrent:\n" ^
211 "make_torrent -tracker http://ip:port/announce -torrent file.torrent " ^
212 "-comment \"www.mldonkey.org\" -create file\n\n" ^
213 "- change the tracker of a torrent file:\n" ^
214 "make_torrent -tracker http://ip:port/tracker -torrent myfile.torrent -change\n\n" ^
215 "- print the infos of a torrent file:\n" ^
216 "make_torrent -torrent myfile.torrent -print\n\n\n" ^