****Simplest command line irc client - spartanIrcClient.tcl**** [ccbbaa] 20210520: I wrote this ~20 loc irc client just because we were discussing very simple irc clients in `#tcl` on `freenode.net` . It took about 30 minutes including testing using `tclircd` and then on `freenode`. The client responds to server pings properly and won't drop out because of that. ====== #!/usr/bin/tclsh # # spartanIrcClient.tcl # # v0: simple irc client in 10loc or so - plp 20210520 # v0a: close application when remote closes socket # # sample session: # # $ ./spartanIrcClient.tcl # :card.freenode.net NOTICE * :*** Looking up your hostname... # :card.freenode.net NOTICE * :*** Checking Ident # :card.freenode.net NOTICE * :*** Couldn't look up your hostname # USER nic nic * * : descr # NICK nicnic # : lots of server output elided # JOIN #somechannel # WHO #somechannel # PRIVMSG #somechannel hi, I'm a spartan irc client # QUIT # [press enter to exit the session] set ::s [socket -async irc.freenode.net 6667] fconfigure $::s -blocking 0 -buffering line -encoding binary -translation binary fileevent $::s readable "readsock $s" proc readsock {chan} { if {[gets $chan line] < 0} { if {[eof $chan]} { close $chan; puts "Remote closed socket. Quitting."; exit 0 } } else { puts stdout $line; flush stdout if {[regexp {^PING :(.*)$} $line dummy server]} { puts $chan "PONG :$server"; puts "PONG :$server" } } } fconfigure stdin -blocking 0 -buffering line -encoding binary -translation binary fileevent stdin readable "readstdin stdin" proc readstdin {chan} { if {[gets $chan line] < 0} { if {[eof $chan]} {exit 0} ;# user issued ^D } else { if {[catch "puts $::s $line" err]} {exit 0} } } vwait forever ======