IRC gateway: Difference between revisions
Added Go |
|||
Line 79: | Line 79: | ||
irc1.Loop() |
irc1.Loop() |
||
}</lang> |
}</lang> |
||
=={{header|Phix}}== |
|||
<!--<lang Phix>(phixonline)--> |
|||
For use with [[Chat_server#Phix]] |
|||
<span style="color: #000080;font-style:italic;">-- |
|||
-- demo\rosetta\IRC_Gateway.exw |
|||
-- ============================ |
|||
-- |
|||
-- Run ChatServer first, then this, then ChatClient.exw with bViaGateway set to true. |
|||
-- |
|||
-- Translation between the various IRC protocols left as an exercise for the reader, |
|||
-- this is just a simple passthrough service. |
|||
-- |
|||
-- Also this uses a simpler server <--> gateway <--> {clients} model, rather than |
|||
-- a more sensible server <-> {gateway1 <-> client1, gateway2 <-> client2} model, |
|||
-- probably easily changed, see the {ci,gi} = connection[i] etc comments below. |
|||
-- Hence as is this will broadcast eg /nt (name taken) rather than send it to a |
|||
-- single specific client, which would obviously be better. |
|||
--</span> |
|||
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">dl</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">`Download rosetta\eulibnet\ from http://phix.x10.mx/pmwiki/pmwiki.php?n=Main.Eulibnet`</span> |
|||
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">get_file_type</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"eulibnet"</span><span style="color: #0000FF;">)=</span><span style="color: #004600;">FILETYPE_DIRECTORY</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dl</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">include</span> <span style="color: #000000;">eulibnet</span><span style="color: #0000FF;">/</span><span style="color: #000000;">eulibnet</span><span style="color: #0000FF;">.</span><span style="color: #000000;">ew</span> |
|||
<span style="color: #004080;">atom</span> <span style="color: #000000;">gateway_listconn</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">server_listconn</span> |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">IP</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"127.0.0.1"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">server_port</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"29029"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">gateway_port</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"29030"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">server_address</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">IP</span> <span style="color: #0000FF;">&</span> <span style="color: #008000;">":"</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">server_port</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">gateway_address</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">IP</span> <span style="color: #0000FF;">&</span> <span style="color: #008000;">":"</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">gateway_port</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">timeout</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">20</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">MAX_MSG</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">550</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">Escape</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">#1B</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">connections</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> <span style="color: #000080;font-style:italic;">-- (inbound on the gateway port) |
|||
-- (should maybe {inbound,outbound}) </span> |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">args</span><span style="color: #0000FF;">={})</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">args</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #000000;">msg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span><span style="color: #000000;">args</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">})</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">shutDown</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Shutting down euLibnet..."</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">connections</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #000080;font-style:italic;">--DEV/SUG |
|||
-- integer {ci,gi} = connections[i] |
|||
-- if net_closeconn(ci) then crash("Error closing client connection!") end if |
|||
-- if net_closeconn(gi) then crash("Error closing gateway connection!") end if</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">net_closeconn</span><span style="color: #0000FF;">(</span><span style="color: #000000;">connections</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Error closing connection!"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">net_closeconn</span><span style="color: #0000FF;">(</span><span style="color: #000000;">gateway_listconn</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Error closing gateway_listconn!"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">net_closeconn</span><span style="color: #0000FF;">(</span><span style="color: #000000;">server_listconn</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Error closing server_listconn!"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">net_shutdown</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Error shutting down euLibnet!"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
<span style="color: #000080;font-style:italic;">--DEV to go if {ci,gi} model adopted... probably</span> |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">sendToAll</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000080;font-style:italic;">-- Send msg to all clients</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">connections</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #004080;">atom</span> <span style="color: #000000;">ci</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">connections</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Sending to connection %d"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">ci</span><span style="color: #0000FF;">})</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">net_send_rdm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ci</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Error sending to connection %d"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">ci</span><span style="color: #0000FF;">})</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Initializing euLibnet..."</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">net_init</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Error initializing euLibnet!"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"done."</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Initializing driver..."</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">net_initdriver</span><span style="color: #0000FF;">(</span><span style="color: #000000;">NET_DRIVER_WSOCK_WIN</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">!=</span> <span style="color: #000000;">1</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Error initializing WinSock driver!"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"done."</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Opening port "</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">gateway_address</span> <span style="color: #0000FF;">&</span> <span style="color: #008000;">"..."</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">gateway_listconn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">net_openconn</span><span style="color: #0000FF;">(</span><span style="color: #000000;">NET_DRIVER_WSOCK_WIN</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gateway_address</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">gateway_listconn</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Couldn't open connection (gateway already running?)"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"done."</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">net_listen</span><span style="color: #0000FF;">(</span><span style="color: #000000;">gateway_listconn</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Error trying to listen to port"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Listening on port "</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">gateway_address</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000080;font-style:italic;">--DEV some/all probably better as {ci,gi} in connections[i]:</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Opening server connection..."</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">server_listconn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">net_openconn</span><span style="color: #0000FF;">(</span><span style="color: #000000;">NET_DRIVER_WSOCK_WIN</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">server_listconn</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Couldn't open connection."</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"done."</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Attempting to connect to chat server..."</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">ret</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">net_connect_wait_time</span><span style="color: #0000FF;">(</span><span style="color: #000000;">server_listconn</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">server_address</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">timeout</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">ret</span> <span style="color: #0000FF;"><</span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Error trying to establish connection."</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">ret</span> <span style="color: #0000FF;">></span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Timeout trying to establish connection."</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"done."</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000080;font-style:italic;">-- main loop (poll until Escape keyed)</span> |
|||
<span style="color: #008080;">while</span> <span style="color: #7060A8;">get_key</span><span style="color: #0000FF;">()!=</span><span style="color: #000000;">Escape</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">conn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">net_poll_listen</span><span style="color: #0000FF;">(</span><span style="color: #000000;">gateway_listconn</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000080;font-style:italic;">-- integer ci = net_poll_listen(gateway_listconn), gi</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">conn</span> <span style="color: #0000FF;">!=</span> <span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000080;font-style:italic;">--DEV make a new gateway connection to the server here...? |
|||
-- gi = <as server_listconn above?> |
|||
-- connections = append(connections, {ci,gi})</span> |
|||
<span style="color: #000000;">connections</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">connections</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">conn</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"New connection open from "</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">net_getpeer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">conn</span><span style="color: #0000FF;">))</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000080;font-style:italic;">-- Check for messages from clients</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">connections</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">ci</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">connections</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #000080;font-style:italic;">-- {ci,gi} = connections[i]</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">net_query_rdm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ci</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">></span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000080;font-style:italic;">--Get the message</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">msg</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">net_receive_rdm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ci</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">MAX_MSG</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"received msg \"%s\" of length %d from %d"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">],</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">ci</span><span style="color: #0000FF;">})</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;"><</span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">--Exit on error</span> |
|||
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">net_ignore_rdm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ci</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Server error: some data may be lost"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000000;">msg</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Sending to server"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">net_send_rdm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">server_listconn</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000080;font-style:italic;">-- if net_send_rdm(gi, msg) then</span> |
|||
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Error sending to server"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000080;font-style:italic;">-- <as below but for gi instead of server_listcomm here?></span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">net_query_rdm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">server_listconn</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">></span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">--Check for message |
|||
-- if net_query_rdm(gi) > 0 then --Check for message</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">msg</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">net_receive_rdm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">server_listconn</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">MAX_MSG</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000080;font-style:italic;">-- sequence msg = net_receive_rdm(gi, MAX_MSG)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;"><</span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Error receiving message!"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">net_ignore_rdm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">server_listconn</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000080;font-style:italic;">-- {} = net_ignore_rdm(gi)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000000;">msg</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #000000;">message</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">sendToAll</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000080;font-style:italic;">--DEV maybe instead: |
|||
-- if net_send_rdm(ci, msg) then |
|||
-- crash("Error sending to clent") |
|||
-- end if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #7060A8;">sleep</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span> |
|||
<span style="color: #000000;">shutDown</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #000080;font-style:italic;">--?"done" |
|||
--{} = wait_key()</span> |
|||
<!--</lang>--> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
Revision as of 07:12, 20 December 2021
Create an IRC Gateway capable of connecting an IRC server with another IRC server or Chat server
Go
Just a bare-bones gateway.
<lang go>package main
import (
"crypto/tls" "fmt" "github.com/thoj/go-ircevent" "log" "os"
)
func main() {
if len(os.Args) != 9 { fmt.Println("To use this gateway, you need to pass 8 command line arguments, namely:") fmt.Println(" <server1> <channel1> <nick1> <user1> <server2> <channel2> <nick2> <user2>") return } server1, channel1, nick1, user1 := os.Args[1], os.Args[2], os.Args[3], os.Args[4] server2, channel2, nick2, user2 := os.Args[5], os.Args[6], os.Args[7], os.Args[8]
irc1 := irc.IRC(nick1, user1) irc1.VerboseCallbackHandler = true irc1.Debug = false irc1.UseTLS = true irc1.TLSConfig = &tls.Config{InsecureSkipVerify: true}
irc2 := irc.IRC(nick2, user2) irc2.VerboseCallbackHandler = true irc2.Debug = false irc2.UseTLS = true irc2.TLSConfig = &tls.Config{InsecureSkipVerify: true}
irc1.AddCallback("001", func(e *irc.Event) { irc1.Join(channel1) msg := fmt.Sprintf("<gateway> Hello %s. Please send your first message to %s.", nick1, nick2) irc1.Privmsg(nick1, msg) log.Println(msg) })
irc1.AddCallback("366", func(e *irc.Event) {})
irc1.AddCallback("PRIVMSG", func(e *irc.Event) { msg := fmt.Sprintf("<%s> %s", nick1, e.Message) irc2.Privmsg(nick2, msg) log.Println(msg) })
irc2.AddCallback("001", func(e *irc.Event) { irc2.Join(channel2) msg := fmt.Sprintf("<gateway> Hello %s. Please wait for your first message from %s.", nick2, nick1) irc2.Privmsg(nick2, msg) log.Println(msg) })
irc2.AddCallback("366", func(e *irc.Event) {})
irc2.AddCallback("PRIVMSG", func(e *irc.Event) { msg := fmt.Sprintf("<%s> %s", nick2, e.Message) irc1.Privmsg(nick1, msg) log.Println(msg) })
err1 := irc1.Connect(server1) if err1 != nil { log.Fatal(err1) }
err2 := irc2.Connect(server2) if err2 != nil { log.Fatal(err2) }
go irc2.Loop() irc1.Loop()
}</lang>
Phix
For use with Chat_server#Phix
-- -- demo\rosetta\IRC_Gateway.exw -- ============================ -- -- Run ChatServer first, then this, then ChatClient.exw with bViaGateway set to true. -- -- Translation between the various IRC protocols left as an exercise for the reader, -- this is just a simple passthrough service. -- -- Also this uses a simpler server <--> gateway <--> {clients} model, rather than -- a more sensible server <-> {gateway1 <-> client1, gateway2 <-> client2} model, -- probably easily changed, see the {ci,gi} = connection[i] etc comments below. -- Hence as is this will broadcast eg /nt (name taken) rather than send it to a -- single specific client, which would obviously be better. -- without js constant dl = `Download rosetta\eulibnet\ from http://phix.x10.mx/pmwiki/pmwiki.php?n=Main.Eulibnet` assert(get_file_type("eulibnet")=FILETYPE_DIRECTORY,dl) include eulibnet/eulibnet.ew atom gateway_listconn, server_listconn constant IP = "127.0.0.1", server_port = "29029", gateway_port = "29030", server_address = IP & ":" & server_port, gateway_address = IP & ":" & gateway_port, timeout = 20, MAX_MSG = 550, Escape = #1B sequence connections = {} -- (inbound on the gateway port) -- (should maybe {inbound,outbound}) procedure message(string msg, sequence args={}) if length(args) then msg = sprintf(msg,args) end if printf(1,"%s\n",{msg}) end procedure procedure shutDown() message("Shutting down euLibnet...") for i = 1 to length(connections) do --DEV/SUG -- integer {ci,gi} = connections[i] -- if net_closeconn(ci) then crash("Error closing client connection!") end if -- if net_closeconn(gi) then crash("Error closing gateway connection!") end if if net_closeconn(connections[i]) then crash("Error closing connection!") end if end for if net_closeconn(gateway_listconn) then crash("Error closing gateway_listconn!") end if if net_closeconn(server_listconn) then crash("Error closing server_listconn!") end if if net_shutdown() then crash("Error shutting down euLibnet!") end if end procedure --DEV to go if {ci,gi} model adopted... probably procedure sendToAll(string msg) -- Send msg to all clients for i=1 to length(connections) do atom ci = connections[i] message("Sending to connection %d",{ci}) if net_send_rdm(ci, msg) then message("Error sending to connection %d",{ci}) end if end for end procedure message("Initializing euLibnet...") if net_init() then crash("Error initializing euLibnet!") end if message("done.") message("Initializing driver...") if net_initdriver(NET_DRIVER_WSOCK_WIN) != 1 then crash("Error initializing WinSock driver!") end if message("done.") message("Opening port " & gateway_address & "...") gateway_listconn = net_openconn(NET_DRIVER_WSOCK_WIN, gateway_address) if gateway_listconn = NULL then crash("Couldn't open connection (gateway already running?)") end if message("done.") if net_listen(gateway_listconn) then crash("Error trying to listen to port") end if message("Listening on port " & gateway_address) --DEV some/all probably better as {ci,gi} in connections[i]: message("Opening server connection...") server_listconn = net_openconn(NET_DRIVER_WSOCK_WIN, NULL) if server_listconn = NULL then crash("Couldn't open connection.") end if message("done.") message("Attempting to connect to chat server...") integer ret = net_connect_wait_time(server_listconn, server_address, timeout) if ret < 0 then crash("Error trying to establish connection.") elsif ret > 0 then crash("Timeout trying to establish connection.") end if message("done.") -- main loop (poll until Escape keyed) while get_key()!=Escape do integer conn = net_poll_listen(gateway_listconn) -- integer ci = net_poll_listen(gateway_listconn), gi if conn != NULL then --DEV make a new gateway connection to the server here...? -- gi = <as server_listconn above?> -- connections = append(connections, {ci,gi}) connections = append(connections, conn) message("New connection open from " & net_getpeer(conn)) end if -- Check for messages from clients for i=1 to length(connections) do integer ci = connections[i] -- {ci,gi} = connections[i] if net_query_rdm(ci) > 0 then --Get the message sequence msg = net_receive_rdm(ci, MAX_MSG) message("received msg \"%s\" of length %d from %d",{msg[2],msg[1],ci}) if msg[1] < 0 then --Exit on error {} = net_ignore_rdm(ci) crash("Server error: some data may be lost") end if msg = msg[2] message("Sending to server") if net_send_rdm(server_listconn, msg) then -- if net_send_rdm(gi, msg) then crash("Error sending to server") end if end if -- <as below but for gi instead of server_listcomm here?> end for if net_query_rdm(server_listconn) > 0 then --Check for message -- if net_query_rdm(gi) > 0 then --Check for message sequence msg = net_receive_rdm(server_listconn, MAX_MSG) -- sequence msg = net_receive_rdm(gi, MAX_MSG) if msg[1] < 0 then message("Error receiving message!") {} = net_ignore_rdm(server_listconn) -- {} = net_ignore_rdm(gi) end if msg = msg[2] message(msg) sendToAll(msg) --DEV maybe instead: -- if net_send_rdm(ci, msg) then -- crash("Error sending to clent") -- end if end if sleep(1) end while shutDown() --?"done" --{} = wait_key()
Tcl
This code is called as a complete script, perhaps like this: <lang sh>./ircgateway.tcl irc://hostA.org/fishing bait irc://hostB.com:6667/haxors botfly</lang>
<lang tcl>#!/bin/env tclsh8.5 package require picoirc
- Parse script arguments
- URL form: irc://foobar.org/secret
if {$argc != 4} {
puts stderr "wrong # args: should be \"$argv0 ircA nickA ircB nickB\"" exit 1
} lassign $argv url1 nick1 url2 nick2
- How to do the forwarding from one side to the other
proc handle {from to -> state args} {
upvar #0 conn($from) f conn($to) t chan($to) chan switch -exact -- $state {
"chat" { lassign $args target nick message type if {![string match "*>>*<<*" $message]} { picoirc::post $t $chan ">>$nick said<< $message" } } "traffic" { lassign $args action channel nick newnick switch -exact -- $action { "entered" - "left" { picoirc::post $t $chan ">>$nick has $action<<" } } } "close" { exit }
}
}
- Connect and run the event loop
set chan(1) [lindex [picoirc::splituri $url1] 2] set chan(2) [lindex [picoirc::splituri $url1] 2] interp alias {} handle1to2 {} handle 1 2 interp alias {} handle2to1 {} handle 2 1 set conn(1) [picoirc::connect handle1to2 $nick1 $url1] set conn(2) [picoirc::connect handle2to1 $nick2 $url2] vwait forever</lang>