Simplest command line irc client - spartanIrcClient.tcl

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
# v1: unified parametrized callback
#
# 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]

proc react {from to line} { ;# returns "" if nothing is to be logged
  set str ""
  if {($from != "stdin") && [regexp {^PING :(.*)$} $line dummy server]} {
    set str "PONG :$server"; puts $from $str
  }
  return $str
}

proc readsock {from to {msg ""}} {
  if {[gets $from line] < 0} {
    if {[eof $from]} {
      close $from; if {$msg != "" } {puts $to $msg}; exit 0
    }
  } else {
    puts $to $line
    set str [react $from $to $line]; if {$str != ""} {puts $to $str}
  }
}

set ::s [socket -async irc.freenode.net 6667]
fconfigure $::s -blocking 0 -buffering line -encoding binary -translation binary
fileevent $::s readable "readsock $::s stdout {Remote closed socket. Quitting.}"
fconfigure stdin -blocking 0 -buffering line -encoding binary -translation binary
fileevent stdin readable "readsock stdin $::s"
vwait forever