chiark / gitweb /
Reorganised so that we can have bwbridge too.
[ircbot] / irccore.tcl
index 0efb0e99c60a67862b8c838fdee6032c66f9fcca..7a6f1574edac633aefb6023909430408911efd9c 100644 (file)
@@ -1,5 +1,5 @@
 proc defset {varname val} {
-    upvar #0 $varname var
+    upvar 1 $varname var
     if {![info exists var]} { set var $val }
 }
 
@@ -162,17 +162,14 @@ proc bgerror {msg} {
 }
 
 proc onread {args} {
-    global sock nick calling_nick errorInfo errorCode
-    
+    global sock nick calling_nick errorInfo errorCode line_org_1char
+
     if {[gets $sock line] == -1} { fail "EOF/error on input" }
+    set line_org_1char [string range $line 0 0]
     regsub -all "\[^ -\176\240-\376\]" $line ? line
     set org $line
     
-    set ei $errorInfo
-    set ec $errorCode
-    catch { unset calling_nick }
-    set errorInfo $ei
-    set errorCode $ec
+    new_event
     
     if {[regexp -nocase {^:([^ ]+) (.*)} $line dummy prefix remain]} {
        set line $remain
@@ -199,7 +196,8 @@ proc onread {args} {
        log "junk at end: $org"
        return
     }
-    if {"$command" == "PRIVMSG" && [privmsg_unlogged $prefix $params]} {
+    if {"$command" == "PRIVMSG" && \
+        [privmsg_unlogged $prefix [ischan [lindex $params 0]] $params]} {
        return
     }
     log "[clock seconds] <- $org"
@@ -243,9 +241,63 @@ proc irctolower {v} {
     return [string tolower $v]
 }
 
+proc prefix_none {} {
+    upvar 1 p p
+    if {[string length $p]} { error "prefix specified" }
+}
+
+proc prefix_nick {} {
+    global nick
+    upvar 1 p p
+    upvar 1 n n
+    if {![regexp {^([^!]+)!} $p dummy n]} { error "not from nick" }
+    check_nick $n
+    if {"[irctolower $n]" == "[irctolower $nick]"} {
+       error "from myself" {} {}
+    }
+}
+
 proc msg_PING {p c s1} {
     global musthaveping_after
     prefix_none
     sendout PONG $s1
-    if {[info exists musthaveping_after]} connected
+    if {[info exists musthaveping_after]} {
+       after cancel $musthaveping_after
+       unset musthaveping_after
+       connected
+    }
+}
+
+proc ensure_outqueue {} {
+    out__vars
+    if {[info exists out_queue]} return
+    set out_creditms 0
+    set out_creditat [clock seconds]
+    set out_queue {}
+    set out_lag_reported 0
+    set out_lag_reportwhen $out_creditat
+}
+
+proc fail {msg} {
+    logerror "failing: $msg"
+    exit 1
+}
+
+proc ensure_connecting {} {
+    global sock ownfullname host port nick socketargs
+    global musthaveping_ms musthaveping_after
+
+    ensure_outqueue
+    
+    if {[info exists sock]} return
+    set sock [eval socket $socketargs [list $host $port]]
+    fconfigure $sock -buffering line
+    fconfigure $sock -translation crlf
+
+    sendout USER blight 0 * $ownfullname
+    sendout NICK $nick
+    fileevent $sock readable onread
+
+    set musthaveping_after [after $musthaveping_ms \
+           {fail "no ping within timeout"}]
 }