+def_chancmd mode {
+ set mode [ta_word]
+ if {"$mode" != "*" && ![regexp {^(([-+][imnpst]+)+)$} $mode mode]} {
+ error {channel mode must be * or match ([-+][imnpst]+)+}
+ }
+ chandb_set $chan mode $mode
+ if {"$mode" == "*"} {
+ ucmdr "I won't ever change the mode of $chan." {}
+ } else {
+ ucmdr "Whenever I'm alone on $chan, I'll set the mode to $mode." {}
+ }
+}
+
+def_chancmd show {
+ if {[chandb_exists $chan]} {
+ set l "Settings for $chan: autojoin "
+ append l [lindex {no yes} [chandb_get $chan autojoin]]
+ append l ", mode " [chandb_get $chan mode]
+ append l ", userinvite " [chandb_get $chan userinvite] "."
+ append l "\nManagers: "
+ append l [join [chandb_get $chan managers] " "] "\n"
+ set t [chandb_get $chan topicset]
+ if {[string length $t]} {
+ append l "Topic to set: $t"
+ } else {
+ append l "I will not change the topic."
+ }
+ foreach {ts sep} {see "\n" tell " "} {
+ set t [chandb_get $chan topic$ts]
+ append l $sep
+ if {[llength $t]} {
+ append l "Topic $ts list: $t."
+ } else {
+ append l "Topic $ts list is empty."
+ }
+ }
+ 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 invite {
+ global chan_nicks
+
+ if {[ischan $dest]} {
+ set target $dest
+ set onchan 1
+ } else {
+ set target [ta_word]
+ set onchan 0
+ }
+ set ltarget [irctolower $target]
+ if {![ischan $target]} { error "$target is not a channel." }
+ if {![info exists chan_nicks($ltarget)]} { error "I am not on $target." }
+ set ui [chandb_get $ltarget userinvite]
+ if {"$ui" == "pub" && !$onchan} {
+ error "Invitations to $target must be made with !invite."
+ }
+ if {"$ui" != "all"} {
+ prefix_nick
+ if {[lsearch -exact $chan_nicks($ltarget) [irctolower $n]] < 0} {
+ error "Invitations to $target may only be made by a user on the channel."
+ }
+ }
+ if {"$ui" == "none"} {
+ error "Sorry, I've not been authorised to invite people to $target."
+ }
+ if {![ta_anymore]} {
+ error "You have to say who to invite."
+ }
+ set invitees {}
+ while {[ta_anymore]} {
+ set invitee [ta_word]
+ check_nick $invitee
+ lappend invitees $invitee
+ }
+ foreach invitee $invitees {
+ sendout INVITE $invitee $ltarget
+ }
+ set who [lindex $invitees 0]
+ switch -exact llength $invitees {
+ 0 { error "zero invitees" }
+ 1 { }
+ 2 { append who " and [lindex $invitees 1]" }
+ * {
+ set who [join [lreplace $invitees end end] ", "]
+ append who " and [lindex $invitees [llength $invitees]]"
+ }
+ }
+ ucmdr {} "invites $who to $target."
+}
+
+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([irctolower $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
+ set myself 1
+ } else {
+ prefix_nick
+ set target $n
+ set myself [expr {"$target" != "$n"}]
+ }
+ set ltarget [irctolower $target]
+ upvar #0 nick_case($ltarget) ctarget
+ set nshow $target
+ if {[info exists ctarget]} {
+ upvar #0 nick_onchans($ltarget) oc
+ upvar #0 nick_username($ltarget) nu
+ if {[info exists oc]} { set nshow $ctarget }
+ }
+ if {![nickdb_exists $ltarget]} {
+ set ol "$nshow is not a registered nick."
+ } 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)."
+ }
+ if {![info exists ctarget] || ![info exists oc]} {
+ if {$myself} {
+ append ol "\nI can't see $nshow on anywhere."
+ } else {
+ append ol "\nYou aren't on any channels with me."
+ }
+ } elseif {![info exists nu]} {
+ append ol "\n$nshow has not identified themselves."
+ } elseif {![info exists username]} {
+ append ol "\n$nshow has identified themselves as the user $nu."
+ } elseif {"$nu" != "$username"} {
+ append ol "\nHowever, $nshow is being used by the user $nu."
+ } else {
+ append ol "\n$nshow has identified themselves to me."
+ }
+ ucmdr {} $ol
+}
+
+def_ucmd register {
+ prefix_nick
+ check_notonchan
+ set old [nickdb_exists $n]
+ if {$old} { nick_securitycheck 0 }
+ set luser [irctolower $n]
+ switch -exact [string tolower [string trim $text]] {
+ {} {
+ upvar #0 nick_username($luser) nu
+ if {![info exists nu]} {
+ ucmdr {} \
+ "You must identify yourself before using `register'. See `help identify', or use `register insecure'."
+ }
+ nickdb_set $n username $nu
+ ucmdr {} {} "makes a note of your username." {}
+ }
+ delete {
+ nickdb_delete $n
+ ucmdr {} {} "forgets your nickname." {}
+ }
+ insecure {
+ nickdb_set $n username {}
+ if {$old} {
+ ucmdr {} "Security is now disabled for your nickname !"
+ } else {
+ ucmdr {} "This is fine, but bear in mind that people will be able to mess with your settings. Channel management features need a secure registration." "makes an insecure registration for your nick."
+ }
+ }
+ }
+}
+
+proc timeformat_desc {tf} {
+ switch -exact $tf {
+ ks { return "Times will be displayed in seconds or kiloseconds." }
+ hms { return "Times will be displayed in hours, minutes, etc." }
+ default { error "invalid timeformat: $v" }
+ }
+}
+
+proc def_setting {opt show_body set_body} {
+ proc set_show/$opt {} "
+ upvar 1 n n
+ set opt $opt
+ $show_body"
+ if {![string length $set_body]} return
+ proc set_set/$opt {} "
+ upvar 1 n n
+ upvar 1 text text
+ set opt $opt
+ $set_body"
+}
+
+def_setting timeformat {
+ set tf [nickdb_get $n timeformat]
+ return "$tf: [timeformat_desc $tf]"
+} {
+ set tf [string tolower [ta_word]]
+ ta_nomore
+ set desc [timeformat_desc $tf]
+ nickdb_set $n timeformat $tf
+ ucmdr {} $desc
+}
+
+def_setting security {
+ set s [nickdb_get $n username]
+ if {[string length $s]} {
+ return "Your nick, $n, is controlled by the user $s."
+ } else {
+ return "Your nick, $n, is not secure."
+ }
+} {}
+
+def_ucmd set {
+ prefix_nick
+ check_notonchan
+ if {![nickdb_exists $n]} {
+ ucmdr {} "You are unknown to me and so have no settings. (Use `register'.)"
+ }
+ if {![ta_anymore]} {
+ set ol {}
+ foreach proc [lsort [info procs]] {
+ if {![regexp {^set_show/(.*)$} $proc dummy opt]} continue
+ lappend ol [format "%-10s %s" $opt [set_show/$opt]]
+ }
+ ucmdr {} [join $ol "\n"]
+ } else {
+ set opt [ta_word]
+ if {[catch { info body set_show/$opt }]} {
+ error "no setting $opt"
+ }
+ if {![ta_anymore]} {
+ ucmdr {} "$opt [set_show/$opt]"
+ } else {
+ nick_securitycheck 0
+ if {[catch { info body set_set/$opt }]} {
+ error "setting $opt cannot be set with `set'"
+ }
+ set_set/$opt
+ }
+ }
+}
+
+def_ucmd identpass {
+ set username [ta_word]
+ set passmd5 [md5sum "[ta_word]\n"]
+ ta_nomore
+ prefix_nick
+ check_notonchan
+ set luser [irctolower $n]
+ upvar #0 nick_onchans($luser) onchans
+ if {![info exists onchans] || ![llength $onchans]} {
+ ucmdr "You must be on a channel with me to identify yourself." {}
+ }
+ check_username $username
+ exec userv --timeout 3 $username << "$passmd5\n" > /dev/null \
+ irc-identpass $n
+ upvar #0 nick_username($luser) rec_username
+ set rec_username $username
+ ucmdr "Pleased to see you, $username." {}
+}
+