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.String
((:=) announce),
53 "<url> : set the tracker to put in the torrent file";
54 "-torrent", Arg.String
((:=) torrent_filename),
55 "<filename.torrent> : the .torrent file to use";
56 "-comment", Arg.String
((:=) torrent_comment),
57 "\"<string>\" : some comments on the torrent";
58 "-private", Arg.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_string
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" (Int64.to_string
torrent.torrent_private);
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_string
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>: change the tracker inside a .torrent file";
102 "-create", Arg.String
(fun filename
->
105 BTTorrent.generate_torrent
!announce !torrent_filename !torrent_comment
106 (Int64.of_int
!torrent_private) filename
;
107 Printf.printf
"Torrent file generated\n";
108 )," <filename> : compute hashes of filename(s) (can be a directory) and generate a .torrent file";
110 "-split", Arg.String
(fun filename
->
113 let s = File.to_string
!torrent_filename in
114 let torrent_id, torrent = BTTorrent.decode_torrent
s in
117 String.sub
!torrent_filename 0 ((String.length
!torrent_filename) - 8)
120 let bt_fd = Unix32.create_ro filename
in
121 let rec iter begin_pos list
=
124 | (filename
, size
) :: tail
->
125 let end_pos = begin_pos
++ size
in
126 let filename = Filename.concat
base_dir_name filename in
127 let dirname = Filename.dirname filename in
128 Unix2.safe_mkdir
dirname;
129 lprintf
"Copying %Ld %Ld to 0\n"
130 begin_pos
(end_pos -- begin_pos
);
131 let fd = Unix32.create_rw
filename in
132 Unix32.copy_chunk
bt_fd fd begin_pos
zero
133 (Int64.to_int
(end_pos -- begin_pos
));
138 iter zero torrent.torrent_files
;
141 ), "<filename> : split a file corresponding to a .torrent file";
143 "-check", Arg.String
(fun filename ->
145 let s = File.to_string
!torrent_filename in
146 let torrent_id, torrent = BTTorrent.decode_torrent
s in
148 if torrent.torrent_name
<> Filename.basename
filename then begin
149 Printf.printf
"WARNING: %s <> %s\n"
150 torrent.torrent_name
(Filename.basename
filename);
152 let t = if torrent.torrent_files
<> [] then
153 Unix32.create_multifile
filename false
154 torrent.torrent_files
155 else Unix32.create_ro
filename
158 let length = Unix32.getsize64
t in
160 if torrent.torrent_length
<> length then begin
161 Printf.printf
"ERROR: computed size %Ld <> torrent size %Ld\n"
162 length torrent.torrent_length
;
166 let chunk_size = torrent.torrent_piece_size
in
167 let npieces = 1 + Int64.to_int
((length -- one) // chunk_size) in
169 if Array.length torrent.torrent_pieces
<> npieces then begin
170 Printf.printf
"ERROR: computed npieces %d <> torrent npieces %d\n"
171 npieces (Array.length torrent.torrent_pieces
);
176 for i
= 0 to npieces - 1 do
177 let begin_pos = chunk_size ** (Int64.of_int i
) in
179 let end_pos = begin_pos ++ chunk_size in
181 if end_pos > length then length else end_pos in
183 let sha1 = Sha1.digest_subfile
t
184 begin_pos (end_pos -- begin_pos) in
185 if torrent.torrent_pieces
.(i
) <> sha1 then begin
186 Printf.printf
"WARNING: piece %d (%Ld-%Ld) has SHA1 %s instead of %s\n"
188 (Sha1.to_string
sha1)
189 (Sha1.to_string
torrent.torrent_pieces
.(i
));
193 Printf.printf
"Torrent file verified !!!\n";
195 ), " <filename> : check that <filename> is well encoded by a .torrent";
198 Printf.printf
"Don't know what to do with %s\n" s;
199 Printf.printf
"Use --help to get some help\n";
202 ("make_torrent : manipulate .torrent files\n\n" ^
204 "- create a new torrent:\n" ^
205 "make_torrent -tracker http://ip:port/announce -torrent file.torrent " ^
206 "-comment \"www.mldonkey.org\" -create file\n\n" ^
207 "- change the tracker of a torrent file:\n" ^
208 "make_torrent -tracker http://ip:port/tracker -torrent myfile.torrent -change\n\n" ^
209 "- print the infos of a torrent file:\n" ^
210 "make_torrent -torrent myfile.torrent -print\n\n\n" ^