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
20 (** Communicating with the mldonkey client. *)
24 open TcpBufferedSocket
29 module M
= Gui_messages
30 module O
= Gui_options
35 if !!Gui_options.copy_messages
then
36 Marshal.from_string
(Marshal.to_string t
[]) 0
39 let when_disconnected gui
=
44 let to_gui_protocol_used = Array.make
(to_gui_last_opcode
+1)
45 GuiProto.best_gui_version
46 let from_gui_protocol_used = Array.make
47 (from_gui_last_opcode
+1)
48 GuiProto.best_gui_version
50 module UseSocket
= struct
52 let (!!) = Options.(!!)
54 let connection = ref None
56 let disconnect gui reason
=
57 match !connection with
60 TcpBufferedSocket.close sock reason
;
65 match !connection with
67 lprintf
"Message not sent since not connected";
70 GuiEncoding.gui_send
(GuiEncoding.from_gui
from_gui_protocol_used) sock t
72 let reconnect gui value_reader reason
=
73 (try disconnect gui reason
with _
-> ());
74 let hostname = if !!O.hostname = "" then Unix.gethostname
()
76 let token = create_token unlimited_connection_manager
in
77 let sock = TcpBufferedSocket.connect
token ""
79 let h = Ip.from_name
hostname in
83 lprintf
"Exception %s in gethostbyname" (Printexc2.to_string e
);
86 Unix.inet_addr_of_string
!!O.hostname
88 lprintf
"Exception %s in inet_addr_of_string"
89 (Printexc2.to_string e
);
92 lprintf
"mlgui was unable to find the IP address of the host [%s]" !!O.hostname; lprint_newline
();
95 lprintf
"Please, edit the $HOME/.mldonkey_gui.ini, and change the 'hostname' option"; lprint_newline
();
96 lprintf
"to the correct IP address of the host running mldonkey."; lprint_newline
();
105 if not
(List.mem
(hostname,!!O.port
) !!O.history
) then
107 O.history
=:= (hostname, !!O.port
) :: !!O.history
;
108 G.new_scanned_port
:= true
112 connection := Some
sock;
113 TcpBufferedSocket.set_closer
sock (fun _ msg
->
114 match !connection with
117 if s
== sock then begin
119 gui#label_connect_status#set_text
(gettext
M.not_connected
);
120 when_disconnected gui
123 TcpBufferedSocket.set_max_input_buffer
sock !!O.interface_buffer
;
124 TcpBufferedSocket.set_max_output_buffer
sock !!O.interface_buffer
;
125 TcpBufferedSocket.set_handler
sock TcpBufferedSocket.BUFFER_OVERFLOW
127 lprintf
"BUFFER OVERFLOW"; lprint_newline
();
128 TcpBufferedSocket.close
sock Closed_for_overflow
);
129 TcpBufferedSocket.set_reader
sock (
130 GuiDecoding.gui_cut_messages
133 let m = GuiDecoding.to_gui
to_gui_protocol_used opcode s
in
136 lprintf
"Exception %s in decode/exec" (Printexc2.to_string e
);
140 gui#label_connect_status#set_text
"Connecting";
141 send (GuiProto.GuiProtocol
GuiProto.best_gui_version
)
143 lprintf
"Exception %s in connecting\n" (Printexc2.to_string e
);
144 TcpBufferedSocket.close
sock (Closed_for_exception e
);
147 let connected _
= !connection <> None
151 module UseFifo
= struct
153 let timer_set = ref false
155 let send m = Fifo.put gui_core_fifo
(copy_message m)
157 let disconnect gui reason
=
158 when_disconnected gui
160 let reconnect gui value_reader reason
=
161 disconnect gui reason
;
162 gui_reconnected
:= true;
163 Fifo.clear core_gui_fifo
;
164 Fifo.clear gui_core_fifo
;
166 if not
!timer_set then begin
168 BasicSocket.add_infinite_timer
0.1 (fun _
->
172 let m = copy_message (Fifo.take core_gui_fifo
) in
176 with Fifo.Empty
-> ()
178 lprintf
"Exception %s in handle core message"
179 (Printexc2.to_string e
);
183 gui#label_connect_status#set_text
"Connecting";
184 send (GuiProto.GuiProtocol
GuiProto.best_gui_version
)
186 let connected _
= true
191 if !core_included
then UseFifo.disconnect
192 else UseSocket.disconnect
195 if !core_included
then UseFifo.connected
196 else UseSocket.connected
199 if !core_included
then UseFifo.reconnect
200 else UseSocket.reconnect
203 if !core_included
then UseFifo.send
207 let hostname = if !!O.hostname = "" then Unix.gethostname
() else !!O.hostname
209 let ip = Ip.from_name
hostname in
210 let addr = Ip.to_inet_addr
ip in
211 let rec scan_port prev_next i max
=
212 if !prev_next
&& i
< max
then
213 let next = ref true in
216 let token = create_token unlimited_connection_manager
in
217 let sock = TcpBufferedSocket.connect
token ""
221 BASIC_EVENT
(RTIMEOUT
) -> close
sock Closed_for_timeout
224 GuiEncoding.gui_send
(GuiEncoding.from_gui
from_gui_protocol_used) sock
225 (GuiProto.GuiProtocol
GuiProto.best_gui_version
);
226 set_closer
sock (fun _ _
->
227 scan_port next (i
+1) max
);
230 let console = ref "" in
231 TcpBufferedSocket.set_reader
sock (fun sock nread
->
232 GuiDecoding.gui_cut_messages
235 let m = GuiDecoding.to_gui
to_gui_protocol_used
238 CoreProtocol
(n
, _
, _
) ->
239 lprintf
"GUI version %d on port %d" n i
;
243 nets := n
.CommonTypes.network_netname
:: !nets
245 lprintf
"GUI:\n proto %d\nnets:\n" !proto; lprint_newline
();
250 lprintf
" motd:\n%s" m;
253 if not
(List.mem
(hostname,i
) !G.scanned_ports
) then
255 G.scanned_ports
:= (hostname, i
) :: !G.scanned_ports
;
256 G.new_scanned_port
:= true
260 | _
-> close
sock Closed_by_user
261 with e
-> close
sock Closed_by_user
266 set_rtimeout
sock 0.5;
268 scan_port next (i
+1) max
270 scan_port (ref true) 0 10000;
271 scan_port (ref true) 10000 20000;
272 scan_port (ref true) 20000 30000;
273 scan_port (ref true) 30000 40000;
274 scan_port (ref true) 40000 50000;
275 scan_port (ref true) 50000 60000;
276 scan_port (ref true) 60000 65536