unset gsfile
}
+proc manyset {list args} {
+ foreach val $list var $args {
+ upvar 1 $var my
+ set my $val
+ }
+}
+
proc try_except_finally {try except finally} {
global errorInfo errorCode
set er [catch { uplevel 1 $try } emsg]
}
proc sendprivmsg {dest l} {
- sendout [expr {[ischan $dest] ? "PRIVMSG" : "NOTICE"}] $dest $l
+ foreach v [split $l "\n"] {
+ sendout [expr {[ischan $dest] ? "PRIVMSG" : "NOTICE"}] $dest $v
+ }
}
proc sendaction {dest what} { sendout PRIVMSG $dest "\001ACTION $what\001" }
proc msendprivmsg {dest ll} { foreach l $ll { sendprivmsg $dest $l } }
}
proc chanmode_o1 {m g p chan} {
- global nick
+ global nick chan_initialop
prefix_nick
set who [chanmode_arg]
recordlastseen_n $n "being nice to $who" 1
if {"[irctolower $who]" == "[irctolower $nick]"} {
- sendprivmsg $n Thanks.
+ set nl [irctolower $n]
+ upvar #0 nick_unique($n) u
+ if {[chandb_exists $chan]} {
+ sendprivmsg $n Thanks.
+ } elseif {![info exists u]} {
+ sendprivmsg $n {Op me while not on the channel, why don't you ?}
+ } else {
+ set chan_initialop([irctolower $chan]) $u
+ sendprivmsg $n \
+ "Thanks. You can use `channel manager ...' to register this channel."
+ if {![nickdb_exists $n] || ![string length [nickdb_get $n username]]} {
+ sendprivmsg $n \
+ "(But to do that you must register your nick securely first.)"
+ }
+ }
}
}
nick_forget $user
}
-set nick_arys {onchans username}
+set nick_counter 0
+set nick_arys {onchans username unique}
proc nick_forget {n} {
global nick_arys
nick_case $newnick
}
+proc nick_ishere {n} {
+ global nick_counter
+ upvar #0 nick_unique($n) u
+ if {![info exists u]} { set u [incr nick_counter].$n.[clock seconds] }
+ nick_case $n
+}
+
proc msg_JOIN {p c chan} {
prefix_nick
recordlastseen_n $n "joining $chan" 1
upvar #0 nick_onchans($n) oc
lappend oc [irctolower $chan]
- nick_case $n
+ nick_ishere $n
}
proc msg_PART {p c chan} {
prefix_nick
check_nick $n
upvar #0 nick_onchans($n) oc
lappend oc $chan
- nick_case $n
+ nick_ishere $n
}
}
ucmdr $help_topics() {}
}
-proc manyset {list args} {
- foreach val $list var $args {
- upvar 1 $var my
- set my $val
- }
-}
-
proc check_username {target} {
if {
[string length $target] > 8 ||
} { error "invalid username" }
}
-proc nickdb__head {} {
+proc somedb__head {} {
uplevel 1 {
- set nl [irctolower $n]
- upvar #0 nickdb($nl) ndbe
- binary scan $nl H* nh
- set nfn users/n$nh
- if {![info exists ndbe] && [file exists $nfn]} {
- set f [open $nfn r]
+ set idl [irctolower $id]
+ upvar #0 ${nickchan}db($idl) ndbe
+ binary scan $idl H* idh
+ set idfn $fprefix$idh
+ if {![info exists iddbe] && [file exists $idfn]} {
+ set f [open $idfn r]
try_except_finally { set newval [read $f] } {} { close $f }
if {[llength $newval] % 2} { error "invalid length" }
- set ndbe $newval
+ set iddbe $newval
}
}
}
-proc def_nickdb {name arglist body} {
- proc nickdb_$name $arglist "nickdb__head; $body"
+proc def_somedb {name arglist body} {
+ foreach {nickchan fprefix} {nick users/n chan chans/c} {
+ proc ${nickchan}db_$name $arglist \
+ "set nickchan $nickchan; set fprefix $fprefix; somedb__head; $body"
+ }
}
-def_nickdb exists {n} {
- return [info exists ndbe]
+def_somedb exists {id} {
+ return [info exists iddbe]
}
-def_nickdb delete {n} {
- catch { unset ndbe }
- file delete $nfn
+def_somedb delete {id} {
+ catch { unset iddbe }
+ file delete $idfn
}
-set default_settings {timeformat ks}
+set default_settings_nick {timeformat ks}
+set default_settings_chan {autojoin 1}
-def_nickdb set {n args} {
- global default_settings
- if {![info exists ndbe]} { set ndbe $default_settings }
- foreach {key value} [concat $ndbe $args] { set a($key) $value }
+def_somedb set {id args} {
+ upvar #0 default_settings_$nickchan def
+ if {![info exists iddbe]} { set iddbe $def }
+ foreach {key value} [concat $iddbe $args] { set a($key) $value }
set newval {}
foreach {key value} [array get a] { lappend newval $key $value }
- set f [open $nfn.new w]
+ set f [open $idfn.new w]
try_except_finally {
puts $f $newval
close $f
- file rename -force $nfn.new $nfn
+ file rename -force $idfn.new $idfn
} {
} {
catch { close $f }
}
- set ndbe $newval
+ set iddbe $newval
}
-proc opt {key} {
- global calling_nick
- if {[info exists calling_nick]} { set n $calling_nick } { set n {} }
- return [nickdb_opt $n $key]
-}
-
-def_nickdb opt {n key} {
- global default_settings
- if {[info exists ndbe]} {
- set l $ndbe
+def_somedb get {id key} {
+ upvar #0 default_settings_$nickchan def
+ if {[info exists iddbe]} {
+ set l $iddbe
} else {
- set l $default_settings
+ set l $def
}
foreach {tkey value} $l {
if {"$tkey" == "$key"} { return $value }
error "unset setting $key"
}
+proc opt {key} {
+ global calling_nick
+ if {[info exists calling_nick]} { set n $calling_nick } { set n {} }
+ return [nickdb_get $n $key]
+}
+
proc check_notonchan {} {
upvar 1 dest dest
if {[ischan $dest]} { error "that command must be sent privately" }
proc nick_securitycheck {strict} {
upvar 1 n n
if {![nickdb_exists $n]} { error "you are unknown to me, use `register'." }
- set wantu [nickdb_opt $n username]
+ set wantu [nickdb_get $n username]
if {![string length $wantu]} {
if {$strict} {
error "that feature is only available to secure users, sorry."
}
}
+proc channel_securitycheck {channel n} {
+ # You must also call `nick_securitycheck 1'
+ set mgrs [chandb_get $channel managers]
+ if {[lsearch -exact [irctolower $mgrs] [irctolower $n]] < 0} {
+ error "you are not a manager of $channel"
+ }
+}
+
+proc def_chancmd {name body} {
+ proc channel/$name {} \
+ " upvar 1 target chan; upvar 1 n n; upvar 1 text text; $body"
+}
+
+def_chancmd manager {
+ set opcode [ta_word]
+ switch -exact _$opcode {
+ _= { set ml {} }
+ _+ - _- {
+ if {[chandb_exists $chan]} {
+ set ml [chandb_get $chan managers]
+ } else {
+ set ml [list [irctolower $n]]
+ }
+ }
+ default {
+ error "`channel manager' opcode must be one of + - ="
+ }
+ }
+ foreach nn [split $text " "] {
+ if {![string length $nn]} continue
+ check_nick $nn
+ set nn [irctolower $nn]
+ if {"$opcode" != "-"} {
+ lappend ml $nn
+ } else {
+ set ml [grep nq {"$nq" != "$nn"} $ml]
+ }
+ }
+ if {[llength $ml]} {
+ chandb_set $chan managers $ml
+ ucmdr "Managers of $chan: $ml" {}
+ } else {
+ chandb_delete $chan
+ ucmdr {} {} "forgets about managing $chan." {}
+ }
+}
+
+def_chancmd autojoin {
+ set yesno [ta_word]
+ switch -exact [string tolower $yesno] {
+ no { set nv 0 }
+ yes { set nv 1 }
+ default { error "channel autojoin must be `yes' or `no' }
+ }
+ chandb_set $chan autojoin $nv
+}
+
+def_chancmd show {
+ if {[chandb_exists $chan]} {
+ set l "Settings for $chan: autojoin "
+ append l [lindex {no yes} [chandb_get $chan autojoin]]
+ append l "\nManagers: "
+ append l [join [chandb_get $chan managers] " "]
+ ucmdr {} $l
+ } else {
+ ucmdr {} "The channel $chan is not managed."
+ }
+}
+
+def_ucmd op {
+ if {[ischan $dest]} { set target $dest }
+ if {[ta_anymore]} { set target [ta_word] }
+ ta_nomore
+ if {![info exists target]} { error "you must specify, or !... on, the channel" }
+ if {![ischan $target]} { error "not a valid channel" }
+ if {![chandb_exists $target]} { error "$target is not a managed channel." }
+ prefix_nick
+ nick_securitycheck 1
+ channel_securitycheck $target $n
+ sendout MODE $target +o $n
+}
+
+def_ucmd channel {
+ if {[ischan $dest]} { set target $dest }
+ if {![ta_anymore]} {
+ set subcmd show
+ } else {
+ set subcmd [ta_word]
+ }
+ if {[ischan $subcmd]} {
+ set target $subcmd
+ if {![ta_anymore]} {
+ set subcmd show
+ } else {
+ set subcmd [ta_word]
+ }
+ }
+ if {![info exists target]} { error "privately, you must specify a channel" }
+ set procname channel/$subcmd
+ if {"$subcmd" != "show"} {
+ if {[catch { info body $procname }]} { error "unknown channel setting $subcmd" }
+ prefix_nick
+ nick_securitycheck 1
+ if {[chandb_exists $target]} {
+ channel_securitycheck $target $n
+ } else {
+ upvar #0 chan_initialop([irctolower $target]) io
+ upvar #0 nick_unique($n) u
+ if {![info exists io]} { error "$target is not a managed channel" }
+ if {"$io" != "$u"} { error "you are not the interim manager of $target" }
+ if {"$subcmd" != "manager"} { error "use `channel manager' first" }
+ }
+ }
+ channel/$subcmd
+}
+
def_ucmd who {
if {[ta_anymore]} {
set target [ta_word]; ta_nomore
}
if {![nickdb_exists $target]} {
set ol "$nshow is not a registered nick."
- } elseif {[string length [set username [nickdb_opt $target username]]]} {
+ } elseif {[string length [set username [nickdb_get $target username]]]} {
set ol "The nick $nshow belongs to the user $username."
} else {
set ol "The nick $nshow is registered (but not to a username)."
}
def_setting timeformat {
- set tf [nickdb_opt $n timeformat]
+ set tf [nickdb_get $n timeformat]
return "$tf: [timeformat_desc $tf]"
} {
set tf [string tolower [ta_word]]
}
def_setting security {
- set s [nickdb_opt $n username]
+ set s [nickdb_get $n username]
if {[string length $s]} {
return "Your nick, $n, is controlled by the user $s."
} else {