22 |
open Printf2 |
open Printf2 |
23 |
open Md4 |
open Md4 |
24 |
open BasicSocket |
open BasicSocket |
25 |
|
|
26 |
open CommonSearch |
open CommonSearch |
27 |
open CommonGlobals |
open CommonGlobals |
28 |
open CommonUser |
open CommonUser |
37 |
open CommonShared |
open CommonShared |
38 |
open CommonInteractive |
open CommonInteractive |
39 |
open Autoconf |
open Autoconf |
40 |
|
|
41 |
open BTTypes |
open BTTypes |
42 |
open BTOptions |
open BTOptions |
43 |
open BTGlobals |
open BTGlobals |
44 |
open BTComplexOptions |
open BTComplexOptions |
45 |
open BTProtocol |
open BTProtocol |
46 |
|
|
47 |
open Bencode |
open Bencode |
48 |
|
|
49 |
open Gettext |
open Gettext |
50 |
let _s x = _s "BTInteractive" x |
let _s x = _s "BTInteractive" x |
51 |
let _b x = _b "BTInteractive" x |
let _b x = _b "BTInteractive" x |
52 |
|
|
53 |
let op_file_all_sources file = |
let op_file_all_sources file = |
54 |
(* lprintf "file_sources\n"; *) |
(* lprintf "file_sources\n"; *) |
83 |
if not (List.mem (file.file_name, file_size file) !!old_files) then |
if not (List.mem (file.file_name, file_size file) !!old_files) then |
84 |
old_files =:= (file.file_name, file_size file) :: !!old_files; |
old_files =:= (file.file_name, file_size file) :: !!old_files; |
85 |
set_file_state file FileShared; |
set_file_state file FileShared; |
86 |
|
|
87 |
if Unix32.destroyed (file_fd file) then |
if Unix32.destroyed (file_fd file) then |
88 |
if !verbose_files then lprintf "op_file_commit: FD is destroyed... repairing\n"; |
if !verbose_files then lprintf_nl "[BT]: op_file_commit: FD is destroyed... repairing"; |
89 |
|
|
90 |
(* During the commit operation, for security, the file_fd is destroyed. So |
(* During the commit operation, for security, the file_fd is destroyed. So |
91 |
we create it again to be able to share this file again. *) |
we create it again to be able to share this file again. *) |
92 |
set_file_fd (as_file file) (create_temp_file new_name file.file_files); |
set_file_fd (as_file file) (create_temp_file new_name file.file_files); |
93 |
|
|
94 |
if Unix32.destroyed (file_fd file) then |
if Unix32.destroyed (file_fd file) then |
95 |
lprintf "op_file_commit: FD is destroyed... could not repair !!!\n"; |
lprintf_nl "[BT]: op_file_commit: FD is destroyed... could not repair !!!"; |
96 |
|
|
97 |
let new_torrent_diskname = |
let new_torrent_diskname = |
98 |
Filename.concat seeded_directory |
Filename.concat seeded_directory |
177 |
( "1", "srh br ar", "Num try", "N" ); |
( "1", "srh br ar", "Num try", "N" ); |
178 |
|
|
179 |
(* |
(* |
180 |
( "0", "srh", "Bitmap (absent|partial|present|verified)", (colored_chunks |
( "0", "srh", "Bitmap (absent|partial|present|verified)", (colored_chunks |
181 |
(Array.init (String.length info.G.file_chunks) |
(Array.init (String.length info.G.file_chunks) |
182 |
(fun i -> ((int_of_char info.G.file_chunks.[i])-48)))) ) ; |
(fun i -> ((int_of_char info.G.file_chunks.[i])-48)))) ) ; |
183 |
*) |
*) |
184 |
( "1", "srh ar", "Number of full chunks", (Printf.sprintf "%d" |
( "1", "srh ar", "Number of full chunks", (Printf.sprintf "%d" |
185 |
(String.length (String2.replace |
(String.length (String2.replace |
186 |
(String2.replace chunks '0' "") '1' "")) )) ] ; |
(String2.replace chunks '0' "") '1' "")) )) ] ; |
187 |
|
|
188 |
Hashtbl.iter (fun _ c -> |
Hashtbl.iter (fun _ c -> |
189 |
Printf.bprintf buf "\\<tr class=\\\"dl-%d\\\"\\>" (html_mods_cntr()); |
Printf.bprintf buf "\\<tr class=\\\"dl-%d\\\"\\>" (html_mods_cntr()); |
190 |
|
|
223 |
(Printf.sprintf "%d" !fc) ) ) ]; |
(Printf.sprintf "%d" !fc) ) ) ]; |
224 |
|
|
225 |
Printf.bprintf buf "\\</tr\\>"; |
Printf.bprintf buf "\\</tr\\>"; |
226 |
|
|
227 |
) file.file_clients; |
) file.file_clients; |
228 |
|
|
229 |
Printf.bprintf buf "\\</table\\>\\</div\\>\\<br\\>"; |
Printf.bprintf buf "\\</table\\>\\</div\\>\\<br\\>"; |
230 |
|
|
231 |
end |
end |
232 |
|
|
233 |
let op_file_check file = |
let op_file_check file = |
234 |
lprintf "Checking chunks of %s\n" file.file_name; |
lprintf_nl "[BT]: Checking chunks of %s" file.file_name; |
235 |
match file.file_swarmer with |
match file.file_swarmer with |
236 |
None -> |
None -> |
237 |
lprintf "verify_chunks: no swarmer to verify chunks" |
lprintf_nl "[BT]: verify_chunks: no swarmer to verify chunks" |
238 |
| Some swarmer -> |
| Some swarmer -> |
239 |
Int64Swarmer.verify_all_chunks swarmer true |
Int64Swarmer.verify_all_chunks swarmer true |
240 |
|
|
249 |
|
|
250 |
let op_ft_commit ft newname = |
let op_ft_commit ft newname = |
251 |
Hashtbl.remove ft_by_num ft.ft_id |
Hashtbl.remove ft_by_num ft.ft_id |
252 |
|
|
253 |
let op_file_info file = |
let op_file_info file = |
254 |
|
|
255 |
let module P = GuiTypes in |
let module P = GuiTypes in |
286 |
P.file_last_seen = BasicSocket.last_time (); |
P.file_last_seen = BasicSocket.last_time (); |
287 |
P.file_priority = file_priority (as_file file); |
P.file_priority = file_priority (as_file file); |
288 |
P.file_uids = [Uid.create (BTUrl file.file_id)]; |
P.file_uids = [Uid.create (BTUrl file.file_id)]; |
289 |
} |
} |
290 |
|
|
291 |
let op_ft_info ft = |
let op_ft_info ft = |
292 |
|
|
293 |
let module P = GuiTypes in |
let module P = GuiTypes in |
294 |
|
|
295 |
{ |
{ |
296 |
P.file_fields = P.Fields_file_info.all; |
P.file_fields = P.Fields_file_info.all; |
297 |
|
|
316 |
P.file_last_seen = BasicSocket.last_time (); |
P.file_last_seen = BasicSocket.last_time (); |
317 |
P.file_priority = 0; |
P.file_priority = 0; |
318 |
P.file_uids = []; |
P.file_uids = []; |
319 |
} |
} |
320 |
|
|
321 |
|
|
322 |
|
|
|
|
|
|
|
|
323 |
let load_torrent_string s = |
let load_torrent_string s = |
324 |
let file_id, torrent = BTTorrent.decode_torrent s in |
let file_id, torrent = BTTorrent.decode_torrent s in |
325 |
|
|
332 |
File.from_string torrent_diskname s; |
File.from_string torrent_diskname s; |
333 |
|
|
334 |
if !verbose_torrent then |
if !verbose_torrent then |
335 |
lprintf "Starting torrent download with diskname:%s\n" |
lprintf_nl "[BT]: Starting torrent download with diskname:%s" |
336 |
torrent_diskname; |
torrent_diskname; |
337 |
let file = new_download file_id torrent torrent_diskname in |
let file = new_download file_id torrent torrent_diskname in |
338 |
BTClients.get_sources_from_tracker file; |
BTClients.get_sources_from_tracker file; |
342 |
|
|
343 |
let load_torrent_file filename = |
let load_torrent_file filename = |
344 |
if !verbose_torrent then |
if !verbose_torrent then |
345 |
lprintf "BTInteractive.load_torrent_file %s\n" filename; |
lprintf_nl "[BT]: BTInteractive.load_torrent_file %s" filename; |
346 |
let s = File.to_string filename in |
let s = File.to_string filename in |
347 |
(* Delete the torrent if it is in the downloads dir. because it gets saved |
(* Delete the torrent if it is in the downloads dir. because it gets saved |
348 |
again under the torrent name and we don't want to clutter up this dir. .*) |
again under the torrent name and we don't want to clutter up this dir. .*) |
354 |
let parse_tracker_reply file t filename = |
let parse_tracker_reply file t filename = |
355 |
(*This is the function which will be called by the http client |
(*This is the function which will be called by the http client |
356 |
for parsing the response*) |
for parsing the response*) |
357 |
(* Intrested only in interval*) |
(* Interested only in interval*) |
358 |
if !verbose_msg_servers then lprintf "Filename %s\n" filename; |
if !verbose_msg_servers then lprintf_nl "[BT]: Filename %s" filename; |
359 |
let v = Bencode.decode (File.to_string filename) in |
let v = Bencode.decode (File.to_string filename) in |
360 |
|
|
361 |
if !verbose_msg_servers then lprintf "Received: %s\n" (Bencode.print v); |
if !verbose_msg_servers then lprintf_nl "[BT]: Received: %s" (Bencode.print v); |
362 |
t.tracker_interval <- 600; |
t.tracker_interval <- 600; |
363 |
match v with |
match v with |
364 |
Dictionary list -> |
Dictionary list -> |
366 |
match (key, value) with |
match (key, value) with |
367 |
String "interval", Int n -> |
String "interval", Int n -> |
368 |
t.tracker_interval <- Int64.to_int n; |
t.tracker_interval <- Int64.to_int n; |
369 |
if !verbose_msg_servers then lprintf ".. interval %d ..\n" t.tracker_interval |
if !verbose_msg_servers then lprintf_nl "[BT]: .. interval %d .." t.tracker_interval |
370 |
| String "failure reason", String failure -> |
| String "failure reason", String failure -> |
371 |
lprintf "Failure from BT-Tracker in file: %s Reason: %s\n" file.file_name failure |
lprintf_nl "[BT]: Failure from BT-Tracker in file: %s Reason: %s" file.file_name failure |
372 |
(*TODO: merge with f from get_sources_from_tracker and parse the rest of the answer, too. |
(*TODO: merge with f from get_sources_from_tracker and parse the rest of the answer, too. |
373 |
also connect to the sources we receive or instruct tracker to send none, perhaps based |
also connect to the sources we receive or instruct tracker to send none, perhaps based |
374 |
on an config option. firewalled people could activate the option and then seed torrents, too.*) |
on an config option. firewalled people could activate the option and then seed torrents, too.*) |
375 |
| _ -> () |
| _ -> () |
376 |
) list; |
) list; |
377 |
| _ -> assert false |
| _ -> assert false |
378 |
|
|
379 |
let try_share_file torrent_diskname = |
let try_share_file torrent_diskname = |
380 |
if !verbose_share then lprintf "BTInteractive.try_share_file: %s\n" torrent_diskname; |
if !verbose_share then lprintf_nl "[BT]: BTInteractive.try_share_file: %s" torrent_diskname; |
381 |
let s = File.to_string torrent_diskname in |
let s = File.to_string torrent_diskname in |
382 |
let file_id, torrent = BTTorrent.decode_torrent s in |
let file_id, torrent = BTTorrent.decode_torrent s in |
383 |
|
|
384 |
try |
try |
385 |
let filename = |
let filename = |
386 |
let rec iter list = |
let rec iter list = |
394 |
let filename = |
let filename = |
395 |
Filename.concat sh.shdir_dirname torrent.torrent_name |
Filename.concat sh.shdir_dirname torrent.torrent_name |
396 |
in |
in |
397 |
if !verbose_share then lprintf "Checking for %s\n" filename; |
if !verbose_share then lprintf_nl "[BT]: Checking for %s" filename; |
398 |
if Sys.file_exists filename then filename else |
if Sys.file_exists filename then filename else |
399 |
iter tail |
iter tail |
400 |
else |
else |
402 |
in |
in |
403 |
iter !!shared_directories |
iter !!shared_directories |
404 |
in |
in |
405 |
|
|
406 |
let file = new_file file_id torrent torrent_diskname |
let file = new_file file_id torrent torrent_diskname |
407 |
filename FileShared in |
filename FileShared in |
408 |
BTShare.must_share_file file; |
BTShare.must_share_file file; |
409 |
if !verbose_share then lprintf "Sharing file %s\n" filename; |
if !verbose_share then lprintf_nl "[BT]: Sharing file %s" filename; |
410 |
BTClients.connect_trackers file "started" |
BTClients.connect_trackers file "started" |
411 |
(parse_tracker_reply file) |
(parse_tracker_reply file) |
412 |
with e -> |
with e -> |
413 |
lprintf "BTInteractive: cannot share torrent %s for %s\n" |
lprintf_nl "[BT]: BTInteractive: cannot share torrent %s for %s" |
414 |
torrent_diskname (Printexc2.to_string e) |
torrent_diskname (Printexc2.to_string e) |
415 |
|
|
416 |
(* Call one minute after start, and then every 20 minutes. Should |
(* Call one minute after start, and then every 20 minutes. Should |
417 |
automatically contact the tracker. *) |
automatically contact the tracker. *) |
418 |
let share_files _ = |
let share_files _ = |
419 |
if !verbose_share then lprintf "BTInteractive.share_files\n"; |
if !verbose_share then lprintf_nl "[BT]: BTInteractive.share_files"; |
420 |
List.iter (fun dir -> |
List.iter (fun dir -> |
421 |
let filenames = Unix2.list_directory dir in |
let filenames = Unix2.list_directory dir in |
422 |
List.iter (fun file -> |
List.iter (fun file -> |
429 |
if not (Sys.file_exists file.file_torrent_diskname) && |
if not (Sys.file_exists file.file_torrent_diskname) && |
430 |
file_state file = FileShared then |
file_state file = FileShared then |
431 |
begin |
begin |
432 |
if !verbose_share then lprintf "Removing torrent share for %s\n" file.file_torrent_diskname; |
if !verbose_share then lprintf_nl "[BT]: Removing torrent share for %s" file.file_torrent_diskname; |
433 |
BTClients.file_stop file; |
BTClients.file_stop file; |
434 |
remove_file file; |
remove_file file; |
435 |
BTClients.disconnect_clients file |
BTClients.disconnect_clients file |
439 |
let retry_all_ft () = |
let retry_all_ft () = |
440 |
Hashtbl.iter (fun _ ft -> |
Hashtbl.iter (fun _ ft -> |
441 |
try ft.ft_retry ft with e -> |
try ft.ft_retry ft with e -> |
442 |
lprintf "ft_retry: exception %s\n" (Printexc2.to_string e) |
lprintf_nl "[BT]: ft_retry: exception %s" (Printexc2.to_string e) |
443 |
) ft_by_num |
) ft_by_num |
444 |
|
|
445 |
let load_torrent_from_web r ft = |
let load_torrent_from_web r ft = |
446 |
if !verbose_torrent then |
if !verbose_torrent then |
447 |
lprintf "load_torrent_from_web...\n"; |
lprintf_nl "[BT]: load_torrent_from_web..."; |
448 |
let module H = Http_client in |
let module H = Http_client in |
449 |
|
|
450 |
if !verbose_torrent then |
if !verbose_torrent then |
451 |
lprintf "calling...\n"; |
lprintf_nl "[BT]: calling..."; |
452 |
H.wget r (fun filename -> |
H.wget r (fun filename -> |
453 |
if !verbose_torrent then |
if !verbose_torrent then |
454 |
lprintf "done...\n"; |
lprintf_nl "[BT]: done..."; |
455 |
if ft_state ft = FileDownloading then begin |
if ft_state ft = FileDownloading then begin |
456 |
load_torrent_file filename; |
load_torrent_file filename; |
457 |
file_cancel (as_ft ft); |
file_cancel (as_ft ft); |
458 |
end) |
end) |
459 |
|
|
460 |
let valid_torrent_extension url = |
let valid_torrent_extension url = |
461 |
let ext = String.lowercase (Filename2.last_extension url) in |
let ext = String.lowercase (Filename2.last_extension url) in |
462 |
if !verbose_torrent then lprintf "Last extension: %s\n" ext; |
if !verbose_torrent then lprintf_nl "[BT]: Last extension: %s" ext; |
463 |
if ext = ".torrent" || ext = ".tor" then true else false |
if ext = ".torrent" || ext = ".tor" then true else false |
464 |
|
|
465 |
let get_regexp_string text r = |
let get_regexp_string text r = |
472 |
let location_regexp = "Location: \\(.*\\)" in |
let location_regexp = "Location: \\(.*\\)" in |
473 |
try |
try |
474 |
let real_url = get_regexp_string url (Str.regexp location_regexp) in |
let real_url = get_regexp_string url (Str.regexp location_regexp) in |
475 |
if !verbose_torrent then lprintf "Trying to load %s realy %s\n" url real_url; |
if !verbose_torrent then lprintf_nl "[BT]: Trying to load %s really %s" url real_url; |
476 |
if (valid_torrent_extension real_url) |
if (valid_torrent_extension real_url) |
477 |
|| (String2.contains url "Content-Type: application/x-bittorrent") |
|| (String2.contains url "Content-Type: application/x-bittorrent") |
478 |
then ( |
then ( |
482 |
H.basic_request with |
H.basic_request with |
483 |
H.req_url = u; |
H.req_url = u; |
484 |
H.req_proxy = !CommonOptions.http_proxy; |
H.req_proxy = !CommonOptions.http_proxy; |
485 |
H.req_user_agent = |
H.req_user_agent = Printf.sprintf "MLdonkey/%s" Autoconf.current_version; |
|
Printf.sprintf "MLdonkey/%s" Autoconf.current_version; |
|
486 |
H.req_referer = ( |
H.req_referer = ( |
487 |
let referers = !!BTOptions.referers in |
let referers = !!BTOptions.referers in |
488 |
let (rule_search,rule_value) = |
let (rule_search,rule_value) = |
507 |
let ft = new_ft file_diskname in |
let ft = new_ft file_diskname in |
508 |
ft.ft_retry <- load_torrent_from_web r ; |
ft.ft_retry <- load_torrent_from_web r ; |
509 |
load_torrent_from_web r ft; |
load_torrent_from_web r ft; |
510 |
if !verbose_torrent then lprintf "wget started\n"; |
if !verbose_torrent then lprintf_nl "[BT]: wget started"; |
511 |
true |
true |
512 |
) |
) |
513 |
else |
else |
516 |
| Not_found -> |
| Not_found -> |
517 |
if (valid_torrent_extension url) then |
if (valid_torrent_extension url) then |
518 |
try |
try |
519 |
if !verbose_torrent then lprintf "Not_found and trying to load %s\n" url; |
if !verbose_torrent then lprintf_nl "[BT]: Not_found and trying to load %s" url; |
520 |
load_torrent_file url; |
load_torrent_file url; |
521 |
true |
true |
522 |
with e -> |
with e -> |
523 |
lprintf "Exception %s while 2nd loading\n" (Printexc2.to_string e); |
lprintf_nl "[BT]: Exception %s while 2nd loading" (Printexc2.to_string e); |
524 |
false |
false |
525 |
else |
else |
526 |
begin |
begin |
527 |
if !verbose_torrent then lprintf "Not_found and url has non valid torrent extension: %s\n" url; |
if !verbose_torrent then lprintf_nl "[BT]: Not_found and url has non valid torrent extension: %s" url; |
528 |
false |
false |
529 |
end |
end |
530 |
| e -> |
| e -> |
531 |
lprintf "Exception %s while loading\n" (Printexc2.to_string e); |
lprintf_nl "[BT]: Exception %s while loading" (Printexc2.to_string e); |
532 |
false |
false |
533 |
|
|
534 |
let op_client_info c = |
let op_client_info c = |
590 |
let cinfo = client_info cc in |
let cinfo = client_info cc in |
591 |
Printf.bprintf buf " \\<tr onMouseOver=\\\"mOvr(this);\\\" |
Printf.bprintf buf " \\<tr onMouseOver=\\\"mOvr(this);\\\" |
592 |
onMouseOut=\\\"mOut(this);\\\" class=\\\"%s\\\"\\>" str; |
onMouseOut=\\\"mOut(this);\\\" class=\\\"%s\\\"\\>" str; |
593 |
|
|
594 |
let show_emulemods_column = ref false in |
let show_emulemods_column = ref false in |
595 |
if Autoconf.donkey = "yes" then begin |
if Autoconf.donkey = "yes" then begin |
596 |
if !!emule_mods_count then |
if !!emule_mods_count then |
597 |
show_emulemods_column := true |
show_emulemods_column := true |
598 |
end; |
end; |
599 |
|
|
600 |
html_mods_td buf ([ |
html_mods_td buf ([ |
601 |
("", "srb ar", Printf.sprintf "%d" (client_num c)); |
("", "srb ar", Printf.sprintf "%d" (client_num c)); |
602 |
((string_of_connection_state (client_state cc)), "sr", |
((string_of_connection_state (client_state cc)), "sr", |
658 |
), _s " :\t\t\t\tprint all .torrent files on this server"; |
), _s " :\t\t\t\tprint all .torrent files on this server"; |
659 |
|
|
660 |
"seeded_torrents", "Network/Bittorrent", Arg_none (fun o -> |
"seeded_torrents", "Network/Bittorrent", Arg_none (fun o -> |
|
|
|
661 |
List.iter (fun file -> |
List.iter (fun file -> |
662 |
if file_state file = FileShared then |
if file_state file = FileShared then |
663 |
Printf.bprintf o.conn_buf "%s [%s]\n" file.file_name (Int64.to_string file.file_uploaded) |
Printf.bprintf o.conn_buf "%s [%s]\n" file.file_name (Int64.to_string file.file_uploaded) |
665 |
_s "done" |
_s "done" |
666 |
|
|
667 |
), _s " :\t\t\tprint all seeded .torrent files on this server"; |
), _s " :\t\t\tprint all seeded .torrent files on this server"; |
668 |
|
|
669 |
"reshare_torrents", "Network/Bittorrent", Arg_none (fun o -> |
"reshare_torrents", "Network/Bittorrent", Arg_none (fun o -> |
670 |
share_files (); |
share_files (); |
671 |
_s "done" |
_s "done" |
672 |
), _s " :\t\t\trecheck torrents/* directories for changes"; |
), _s " :\t\t\trecheck torrents/* directories for changes"; |
673 |
|
|
674 |
"stop_all_bt", "Network/Bittorrent", Arg_none (fun o -> |
"stop_all_bt", "Network/Bittorrent", Arg_none (fun o -> |
675 |
List.iter (fun file -> BTClients.file_stop file ) !current_files; |
List.iter (fun file -> BTClients.file_stop file ) !current_files; |
676 |
_s "started sending stops" |
_s "started sending stops" |
677 |
), _s " :\t\t\t\tstops all bittorrent downloads, use this if you want to make sure that the stop signal actualy gets to the tracker\n\t\t\t\twhen shuting mlnet down, but you have to wait till the stops get to the tracker and not wait too long,\n\t\t\t\tso mldonkey reconnects to the tracker :)"; |
), _s " :\t\t\t\tstops all bittorrent downloads, use this if you want to make sure that the stop signal actualy gets to the tracker\n\t\t\t\twhen shuting mlnet down, but you have to wait till the stops get to the tracker and not wait too long,\n\t\t\t\tso mldonkey reconnects to the tracker :)"; |
678 |
|
|
679 |
(* |
(* |
680 |
"print_torrent", Arg_one (fun filename o -> |
"print_torrent", Arg_one (fun filename o -> |
681 |
|
|
682 |
".torrent file printed" |
".torrent file printed" |
683 |
), " <filename.torrent> : print the content of filename" |
), " <filename.torrent> : print the content of filename" |
684 |
*) |
*) |
685 |
|
|
686 |
] |
] |
687 |
|
|
688 |
open LittleEndian |
open LittleEndian |
689 |
|
|
690 |
let op_gui_message s = |
let op_gui_message s = |
691 |
match get_int16 s 0 with |
match get_int16 s 0 with |
692 |
0 -> |
0 -> |
693 |
let text = String.sub s 2 (String.length s - 2) in |
let text = String.sub s 2 (String.length s - 2) in |
694 |
if !verbose_torrent then lprintf "BT: received torrent from gui...\n"; |
if !verbose_torrent then lprintf_nl "[BT]: received torrent from gui..."; |
695 |
let _ = load_torrent_string text in |
let _ = load_torrent_string text in |
696 |
() |
() |
697 |
| opcode -> failwith (Printf.sprintf "BT: Unknown message opcode %d" opcode) |
| opcode -> failwith (Printf.sprintf "[BT]: Unknown message opcode %d" opcode) |
698 |
|
|
699 |
let _ = |
let _ = |
700 |
|
|
701 |
ft_ops.op_file_cancel <- op_ft_cancel; |
ft_ops.op_file_cancel <- op_ft_cancel; |
702 |
ft_ops.op_file_commit <- op_ft_commit; |
ft_ops.op_file_commit <- op_ft_commit; |
703 |
ft_ops.op_file_info <- op_ft_info; |
ft_ops.op_file_info <- op_ft_info; |
704 |
|
|
705 |
file_ops.op_file_all_sources <- op_file_all_sources; |
file_ops.op_file_all_sources <- op_file_all_sources; |
706 |
file_ops.op_file_files <- op_file_files; |
file_ops.op_file_files <- op_file_files; |
707 |
file_ops.op_file_active_sources <- op_file_all_sources; |
file_ops.op_file_active_sources <- op_file_all_sources; |
728 |
network.op_network_recover_temp <- |
network.op_network_recover_temp <- |
729 |
(fun _ -> |
(fun _ -> |
730 |
if !verbose_hidden_errors then |
if !verbose_hidden_errors then |
731 |
lprintf "recover_temp is not implemented for Bittorrent.\n"; |
lprintf_nl "[BT]: recover_temp is not implemented for Bittorrent."; |
732 |
); |
); |
733 |
|
|
734 |
client_ops.op_client_info <- op_client_info; |
client_ops.op_client_info <- op_client_info; |
735 |
client_ops.op_client_connect <- op_client_connect; |
client_ops.op_client_connect <- op_client_connect; |
736 |
client_ops.op_client_disconnect <- op_client_disconnect; |
client_ops.op_client_disconnect <- op_client_disconnect; |
737 |
client_ops.op_client_bprint <- op_client_bprint; |
client_ops.op_client_bprint <- op_client_bprint; |
738 |
client_ops.op_client_dprint <- op_client_dprint; |
client_ops.op_client_dprint <- op_client_dprint; |
739 |
client_ops.op_client_dprint_html <- op_client_dprint_html; |
client_ops.op_client_dprint_html <- op_client_dprint_html; |
740 |
|
|
741 |
CommonNetwork.register_commands commands; |
CommonNetwork.register_commands commands; |
742 |
|
|
743 |
shared_ops.op_shared_unshare <- (fun file -> |
shared_ops.op_shared_unshare <- (fun file -> |
744 |
(if !verbose_share then lprintf "************ UNSHARE FILE ************\n"); |
(if !verbose_share then lprintf_nl "[BT]: ************ UNSHARE FILE ************"); |
745 |
BTShare.unshare_file file); |
BTShare.unshare_file file); |
746 |
shared_ops.op_shared_info <- (fun file -> |
shared_ops.op_shared_info <- (fun file -> |
747 |
let module T = GuiTypes in |
let module T = GuiTypes in |