/*_____________________________________________________________________________ |/ / TCP/IP add-on by David "Saturn" van Moolenbroek | Version 0.1a, released 08-01-2004 -- support on #help.script/Quakenet | Use/modify however you want, but please keep my name in it. Thank you! | | Keywords: connect, listen, custom window, sockets, binvars, groups | | This add-on allows you to make a TCP connection in a dedicated window, | either by connecting to a specific target (using /connect), or by | listening for an incoming connection on a port (using /listen). It is | pretty much line-based, but it can also display and send lines that are | not terminated by a CR/LF. These options, among others, are available | from the popup menu of the custom window that this add-on uses. | | The script defines the following commands/identifiers: | | /connect [port] | | This command opens the custom window if it wasn't already open, closes | the previous connection (if any), and starts a connection to the | specified host and port. If the port number is omitted, the default is | used (see the $default-port alias below). | | /listen [address] | | This opens the custom window if it wasn't already open, closes any | previous connection, and attempts to listen at the specified port. If | an address is also specified, the script will listen on that (dotted) | IP-address, instead of on all interfaces. | | Simple example | | /connect www.quakenet.org 80 \ _\_____________________________________________________________________________ */ alias -l default-port return 23 alias connect sockcreate $true $1- alias listen sockcreate $false $1- alias -l text1 echo $color(own) -ti2 @TCP/IP -> $2- $+ $iif(!$1,$chr(3) $+ $color(gray) $+ $chr(172)) alias -l text2 echo $color(normal) -ti2 @TCP/IP <- $2- $+ $iif(!$1,$chr(3) $+ $color(gray) $+ $chr(172)) alias -l info1 echo $color(info) -ti2 @TCP/IP * $1- alias -l info2 echo $color(info2) -ti2 @TCP/IP * $1- alias -l sep if ($line(@TCP/IP,0)) echo $color(info) -t @TCP/IP - alias -l title if ($window(@TCP/IP)) titlebar @TCP/IP - $1- alias -l sockkill { if ($sock(tcp-ip)) { if ($sock(tcp-ip).status == listening) { info1 Stopped listening at $& $iif($sock(tcp-ip).bindip != 0.0.0.0,$ifmatch $+ :) $+ $sock(tcp-ip).port } elseif ($sock(tcp-ip).status == active) { if ($sock(tcp-ip).mark != $null) text2 $false $ifmatch info2 Disconnected from $sock(tcp-ip).ip $+ : $+ $sock(tcp-ip).port } else info1 Cancelled connecting to $sock(tcp-ip).mark $+ : $+ $sock(tcp-ip).port sockclose tcp-ip } title not connected } alias -l sockcheck { if (!$sock(tcp-ip)) { info1 Failed listening at $1- title not connected } } alias -l sockcreate { var %t = $1 tokenize 58 $2- | tokenize 32 $1- if (!$window(@TCP/IP)) window -exk0 @TCP/IP sockkill if ($0 < 1) return if (%t) { sep if ($2 !isnum) tokenize 32 $1 $default-port sockopen tcp-ip $1-2 sockmark tcp-ip $1 info1 Connecting to $1 $+ : $+ $2 title connecting to $1 $+ : $+ $2 } else { sep if ($2 !isnum) tokenize 32 0.0.0.0 $1 if ($2 !isnum) tokenize 32 $1 $default-port if (!$portfree($2)) { info1 Port $2 in use return } .timer 1 0 sockcheck $iif($1 != 0.0.0.0,$ifmatch $+ :) $+ $2 socklisten -d $1 tcp-ip $2 info1 Listening at $iif($1 != 0.0.0.0,$ifmatch $+ : $+ $2,port $2) title listening at $iif($1 != 0.0.0.0,$ifmatch $+ : $+ $2,port $2) } } on *:SOCKOPEN:tcp-ip:{ if ($sockerr) { if ($sock(tcp-ip).mark == $null) return info1 Failed connecting to $sock(tcp-ip).mark $+ : $+ $sock(tcp-ip).port title not connected return } info2 Connected to $sock(tcp-ip).ip $+ : $+ $sock(tcp-ip).port title connected to $sock(tcp-ip).ip $+ : $+ $sock(tcp-ip).port sockmark tcp-ip } on *:SOCKLISTEN:tcp-ip:{ sockaccept listen sockclose tcp-ip sockrename listen tcp-ip info2 Connected to $sock(tcp-ip).ip $+ : $+ $sock(tcp-ip).port title Connected to $sock(tcp-ip).ip $+ : $+ $sock(tcp-ip).port } alias -l sockdata { if ($1) { if ($bvar(&data,1) == 32) bset &data 1 160 var %i = 1 while ($bfind(&data,%i,32 32)) { %i = $calc($ifmatch + 1) if (%i >= $1) break bset &data %i 160 } } $2- $bvar(&data,1,$1).text } on *:SOCKREAD:tcp-ip:{ if ($sockerr) { if ($sock(tcp-ip).mark != $null) text2 $false $ifmatch info1 Receive error from $sock(tcp-ip).ip $+ : $+ $sock(tcp-ip).port title not connected return } while ($true) { var %p, %i, %b, %s = $sock(tcp-ip).mark sockread -nf $iif(%s != $null,&new,&data) if ($sockbr == 0) return if (%s != $null) { bset -t &data 1 %s bcopy &data $calc($bvar(&data,0) + 1) &new 1 -1 bunset &new sockmark tcp-ip unset %s } while (($bfind(&data,1,13)) || ($bfind(&data,1,10)) || (900 < $bvar(&data,0))) { %p = $iif($ifmatch <= 901,$ifmatch,900) %b = $findtok(13 10,$bvar(&data,%p),32) sockdata $iif(%b,$calc(%p - 1),%p) text2 $iif(%b,$true,$false) if ((%b == 1) && ($bvar(&data,$calc(%p + 1)) == 10)) inc %p %i = $calc($bvar(&data,0) - %p) if (%i < 1) return bcopy -c &data 1 &data $calc(%p + 1) %i } sockdata 900 $iif($group(#dump).status == off,sockmark tcp-ip,text2 $false) } } on *:SOCKCLOSE:tcp-ip:{ if ($sock(tcp-ip).mark != $null) text2 $false $ifmatch info2 Disconnected from $sock(tcp-ip).ip $+ : $+ $sock(tcp-ip).port title not connected } on *:CLOSE:@TCP/IP:sockkill alias -l sockinput { if ($input(Enter the text to send:,e,Send unterminated string..) != $null) { sockwrite -t tcp-ip $ifmatch text1 $false $ifmatch } } on *:INPUT:@TCP/IP:{ if ((/* !iswm $1) || ($ctrlenter)) { if ($sock(tcp-ip).status == active) { sockwrite -tn tcp-ip $1- text1 $true $1- } else { if ($sock(tcp-ip).status != connecting) sep info1 You are not connected! } halt } } alias -l sockfast { if ($group(#dump).status == off) { if ($sock(tcp-ip).mark != $null) { text2 $false $ifmatch sockmark tcp-ip } } toggle #dump } alias -l toggle $iif($group($$1).status == on,.disable,.enable) $1 menu @TCP/IP { Connect to..:{ connect $$input(Enter the destination host/IP and port:,e,Connect to..) } Listen at..:{ listen $$input(Enter a port number:,e,Listen at..) } $iif($sock(tcp-ip) == $null,$style(2)) Disconnect:{ sockkill } - $iif($group(#dump).status == off,$style(1)) Display terminated lines only:{ sockfast } $iif($sock(tcp-ip).status != active,$style(2)) Send unterminated string..:{ sockinput } - $iif($group(#auto).status == on,$style(1)) Open window at startup: { toggle #auto } Close window:{ sockkill | window -c @TCP/IP } } #auto off on *:START:sockcreate #auto end #dump off #dump end