fix buffer overflows in DNS resolution
[mldonkey.git] / tools / make_torrent.ml
blob2d85ba6b87acb978bbd4f64389200dd12d41599e
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
20 open Md4
21 open LittleEndian
22 open Unix
23 open Printf2
25 open BTTypes
27 let announce = ref ""
28 let torrent_filename = ref ""
29 let torrent_comment = ref ""
30 let torrent_private = ref 0
31 let zero = Int64.zero
32 let one = Int64.one
33 let (++) = Int64.add
34 let (--) = Int64.sub
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";
41 exit 2;
42 end
44 let check_torrent () =
45 if !torrent_filename = "" then begin
46 Printf.printf "You must specify the .torrent filename with -torrent <filename>\n";
47 exit 2;
48 end
50 let _ =
51 let args = [
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 _ ->
62 check_tracker ();
63 check_torrent ();
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 ->
76 check_torrent ();
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;
99 end;
100 ), "<filename.torrent> print the contents of a .torrent file";
102 "-create", Arg.String (fun filename ->
103 check_tracker ();
104 check_torrent ();
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);
110 with
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 ->
115 check_torrent ();
117 let s = File.to_string !torrent_filename in
118 let torrent_id, torrent = BTTorrent.decode_torrent s in
120 let base_dir_name =
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 =
126 match list with
127 [] -> ()
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));
138 Unix32.close fd;
140 iter end_pos tail
142 iter zero torrent.torrent_files;
143 Unix32.close bt_fd;
145 ), "<filename> split a file corresponding to a .torrent file";
147 "-check", Arg.String (fun filename ->
148 check_torrent ();
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);
155 end;
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;
167 exit 2;
168 end;
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);
176 exit 2;
178 end;
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
184 let end_pos =
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"
191 i begin_pos end_pos
192 (Sha1.to_hexa sha1)
193 (Sha1.to_hexa torrent.torrent_pieces.(i));
195 done;
197 Printf.printf "Torrent file verified !!!\n";
199 ), "<filename> check that <filename> is well encoded by a .torrent";
202 Arg.parse (Arg.align args)
203 (fun s ->
204 Printf.printf "Don't know what to do with %s\n" s;
205 Printf.printf "Use --help to get some help\n";
206 exit 2;
208 ("make_torrent : manipulate .torrent files\n\n" ^
209 "Quick Howto:\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" ^
217 "All Options:");