chiark / gitweb /
Working on implementation of tell. Have done: tell, and set tellme. Need to do...
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 19 Oct 2001 16:42:40 +0000 (16:42 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 19 Oct 2001 16:42:40 +0000 (16:42 +0000)
bot.tcl
helpinfos
nctest.tcl [new file with mode: 0644]

diff --git a/bot.tcl b/bot.tcl
index e021af774f92c1c3ecca647b42331b362427c177..fb537d7481c25314236629bc2308a4207d0a428d 100755 (executable)
--- a/bot.tcl
+++ b/bot.tcl
@@ -83,6 +83,23 @@ proc showtime {when} {
     return [showinterval [expr {[clock seconds] - $when}]]
 }
 
     return [showinterval [expr {[clock seconds] - $when}]]
 }
 
+proc parse_interval {specified min} {
+    if {![regexp {^([0-9]+)([a-z]+)$} $specified dummy value unit]} {
+       error "invalid syntax for interval"
+    }
+    switch -exact $unit {
+       s { set u 1 }
+       ks { set u 1000 }
+       m { set u 60 }
+       h { set u 3600 }
+       default { error "unknown unit of time $unit" }
+    }
+    if {$value > 86400*21/$u} { error "interval too large" }
+    set result [expr {$value*$u}]
+    if {$result < $min} { error "interval too small (<${min}s)" }
+    return $result
+}
+
 proc def_msgproc {name argl body} {
     proc msg_$name "varbase $argl" "\
     upvar #0 msg/\$varbase/dest d\n\
 proc def_msgproc {name argl body} {
     proc msg_$name "varbase $argl" "\
     upvar #0 msg/\$varbase/dest d\n\
@@ -530,7 +547,11 @@ proc somedb__head {} {
 }
 
 proc def_somedb {name arglist body} {
 }
 
 proc def_somedb {name arglist body} {
-    foreach {nickchan fprefix} {nick users/n chan chans/c} {
+    foreach {nickchan fprefix} {
+       nick users/n
+       chan chans/c
+       msgs users/m
+    } {
        proc ${nickchan}db_$name $arglist \
             "set nickchan $nickchan; set fprefix $fprefix; $body"
     }
        proc ${nickchan}db_$name $arglist \
             "set nickchan $nickchan; set fprefix $fprefix; $body"
     }
@@ -559,7 +580,13 @@ def_somedb_id delete {} {
     file delete $idfn
 }
 
     file delete $idfn
 }
 
-set default_settings_nick {timeformat ks  marktime off}
+set default_settings_nick {
+    timeformat ks
+    marktime off
+    tellsec insecure
+    tellrel {remind 3600 30}
+}
+
 set default_settings_chan {
     autojoin 1
     mode *
 set default_settings_chan {
     autojoin 1
     mode *
@@ -569,6 +596,13 @@ set default_settings_chan {
     topictell {}
 }
 
     topictell {}
 }
 
+set default_settings_msgs {
+    inbound {}
+    outbound {}
+}
+# inbound -> [<nick> <time_t> <message>] ...
+# outbound -> [<nick> <time_t(earliest)> <count>] ...
+
 def_somedb_id set {args} {
     upvar #0 default_settings_$nickchan def
     if {![info exists iddbe]} { set iddbe $def }
 def_somedb_id set {args} {
     upvar #0 default_settings_$nickchan def
     if {![info exists iddbe]} { set iddbe $def }
@@ -962,6 +996,73 @@ def_ucmd channel {
     channel/$subcmd
 }
 
     channel/$subcmd
 }
 
+def_ucmd tell {
+    global nick_case ownmailaddr ownfullname
+    
+    prefix_nick
+    set target [ta_word]
+    if {![string length $text]} { error "tell them what?" }
+
+    set ltarget [irctolower $target]
+    set ctarget $target
+    if {[info exists nick_case($ltarget)]} { set ctarget $nick_case($ltarget) }
+
+    manyset [nickdb_get $target tellsec] sec mailto mailwhy
+    switch -exact $sec {
+       insecure - secure {
+           set now [clock seconds]
+           set inbound [msgsdb_get $ltarget inbound]
+           lappend inbound $n $now $text
+           msgsdb_set $ltarget inbound $inbound
+
+           set outbound [msgsdb_get $n outbound]
+           set noutbound {}
+           set found 0
+           foreach {recip time count} $outbound {
+               if {"[irctolower $recip]" == "$ltarget"} {
+                   incr count
+                   set recip $ctarget
+                   set found 1
+               }
+               lappend noutbound $recip $time $count
+           }
+           if {!$found} {
+               lappend noutbound $ctarget $now 1
+           }
+           msgsdb_set $n outbound $noutbound
+           if {!$found} {
+               ucmdr "OK, I'll tell $ctarget." {}
+           } else {
+               ucmdr "OK, I'll tell $ctarget that too." {}
+           }
+       }
+       mailto {
+           set fmtmsg [exec fmt << " $text"]
+           exec /usr/sbin/sendmail -odb -oi -t -oee -f $mailwhy \
+                   > /dev/null << \
+ "From: $ownmailaddr ($ownfullname)
+To: $mailto
+Subject: IRC tell from $n
+
+$n asked me[expr {[ischan $dest] ? " on $dest" : ""}] to tell you:
+[exec fmt << " $text"]
+
+(This message was for your nick $ctarget; your account $mailwhy
+ arranged for it to be forwarded to $mailto.)
+"
+            ucmdr \
+ "I've mailed $ctarget at $mailto, which is what they prefer." \
+                {}
+       }
+       refuse {
+           usererror "Sorry, $ctarget does not want me to take messages."
+       }
+       default {
+           error "bad tellsec $sec"
+       }
+    }
+}
+
 def_ucmd who {
     if {[ta_anymore]} {
        set target [ta_word]; ta_nomore
 def_ucmd who {
     if {[ta_anymore]} {
        set target [ta_word]; ta_nomore
@@ -1046,7 +1147,10 @@ proc timeformat_desc {tf} {
     }
 }
 
     }
 }
 
+set settings {}
 proc def_setting {opt show_body set_body} {
 proc def_setting {opt show_body set_body} {
+    global settings
+    lappend settings $opt
     proc set_show/$opt {} "
         upvar 1 n n
         set opt $opt
     proc set_show/$opt {} "
         upvar 1 n n
         set opt $opt
@@ -1059,6 +1163,47 @@ proc def_setting {opt show_body set_body} {
         $set_body"
 }
 
         $set_body"
 }
 
+proc tellme_sec_desc {v} {
+    manyset $v sec mailto
+    switch -exact $sec {
+       insecure {
+           return "I'll tell you your messages whenever I see you."
+       }
+       secure {
+           return \
+ "I'll keep the bodies of your messages private until you identify yourself."
+       }
+       refuse {
+           return "I shan't accept messages for you."
+       }
+       mailto {
+           return "I'll forward your messages by email to $mailto."
+       }
+       default {
+           error "bad tellsec $sec"
+       }
+    }
+}
+
+proc tellme_rel_desc {v} {
+    manyset $v rel every within
+    switch -exact $rel {
+       unreliable {
+           return "As soon as I've told you, I'll forget the message - note that this means messages can get lost !"
+       }
+       pester {
+           set u {}
+       }
+       remind {
+           set u ", or talk on channel within [showintervalsecs $within 1] of me having told you"
+       }
+       default {
+           error "bad tellrel $rel"
+       }
+    }
+    return "I'll remind you every [showintervalsecs $every 1] until you say delmsg$u."
+}
+
 def_setting timeformat {
     set tf [nickdb_get $n timeformat]
     return "$tf: [timeformat_desc $tf]"
 def_setting timeformat {
     set tf [nickdb_get $n timeformat]
     return "$tf: [timeformat_desc $tf]"
@@ -1093,19 +1238,8 @@ def_setting marktime {
     ta_nomore
 
     if {"$mt" == "off" || "$mt" == "once"} {
     ta_nomore
 
     if {"$mt" == "off" || "$mt" == "once"} {
-    } elseif {[regexp {^([0-9]+)([a-z]+)$} $mt dummy value unit]} {
-       switch -exact $unit {
-           s { set u 1 }
-           ks { set u 1000 }
-           m { set u 60 }
-           h { set u 3600 }
-           default { error "unknown unit of time $unit" }
-       }
-       if {$value > 86400*21/$u} { error "marktime interval too large" }
-       set mt [expr {$value*$u}]
-       if {$mt < $marktime_min} { error "marktime interval too small" }
     } else {
     } else {
-       error "invalid syntax for marktime"
+       set mt [parse_interval $mt $marktime_min]
     }
     nickdb_set $n marktime $mt
     lnick_marktime_start [irctolower $n] "So:" 500
     }
     nickdb_set $n marktime $mt
     lnick_marktime_start [irctolower $n] "So:" 500
@@ -1121,7 +1255,74 @@ def_setting security {
     }
 } {}
 
     }
 } {}
 
+def_setting tellme {
+    set secv [nickdb_get $n tellsec]
+    set ms [tellme_sec_desc $secv]
+    manyset $secv sec
+    switch -exact $sec {
+       insecure - secure {
+           set mr [tellme_rel_desc [nickdb_get $n tellrel]]
+           return "$ms  $mr"
+       }
+       refuse - mailto {
+           return $ms
+       }
+    }
+} {
+    set setting [string tolower [ta_word]]
+    switch -exact $setting {
+       insecure - secure - refuse {
+           ta_nomore
+           if {"$setting" == "refuse" && [llength [msgsdb_get $n inbound]]} {
+               usererror "You must delete the messages you have, first."
+           }
+           set sr sec
+           set v $setting
+       }
+       mailto {
+           set u [nickdb_get $n username]
+           if {![string length $u]} {
+               usererror "Sorry, you must register secure to have your messages mailed (to prevent the use of this feature for spamming)."
+           }
+           set sr sec
+           set v [list mailto [ta_word] $u]
+       }
+       unreliable - pester - remind {
+           manyset [nickdb_get $n tellsec] sec
+           switch -exact $sec {
+               refuse - mailto {
+                   error "can't change message delivery conditions when message disposition prevents messages from being left"
+               }
+           }
+           set sr rel
+           set v $setting
+           if {"$setting" != "unreliable"} {
+               set every [parse_interval [ta_word] 300]
+               lappend v $every
+           }
+           if {"$setting" == "remind"} {
+               if {[ta_anymore]} {
+                   set within [parse_interval [ta_word] 5]
+               } else {
+                   set within 30
+               }
+               if {$within > $every} {
+                   error "remind interval must be at least time to respond"
+               }
+               lappend v $within
+           }
+           ta_nomore
+       }
+       default {
+           error "invalid tellme setting $setting"
+       }
+    }
+    nickdb_set $n tell$sr $v
+    ucmdr [tellme_${sr}_desc $v] {}
+}
+
 def_ucmd set {
 def_ucmd set {
+    global settings
     prefix_nick
     check_notonchan
     if {![nickdb_exists $n]} {
     prefix_nick
     check_notonchan
     if {![nickdb_exists $n]} {
@@ -1129,8 +1330,7 @@ def_ucmd set {
     }
     if {![ta_anymore]} {
        set ol {}
     }
     if {![ta_anymore]} {
        set ol {}
-       foreach proc [lsort [info procs]] {
-           if {![regexp {^set_show/(.*)$} $proc dummy opt]} continue
+       foreach opt $settings {
            lappend ol [format "%-10s %s" $opt [set_show/$opt]]
        }
        ucmdr {} [join $ol "\n"]
            lappend ol [format "%-10s %s" $opt [set_show/$opt]]
        }
        ucmdr {} [join $ol "\n"]
@@ -1140,7 +1340,7 @@ def_ucmd set {
            error "no setting $opt"
        }
        if {![ta_anymore]} {
            error "no setting $opt"
        }
        if {![ta_anymore]} {
-           ucmdr {} "$opt [set_show/$opt]"
+           ucmdr {} "$opt: [set_show/$opt]"
        } else {
            nick_securitycheck 0
            if {[catch { info body set_set/$opt }]} {
        } else {
            nick_securitycheck 0
            if {[catch { info body set_set/$opt }]} {
index a8466954b4f22fa689f3772f5bd4e9685da919e1..cefe77e124dd2162183c2620fdac66d515769dbb 100644 (file)
--- a/helpinfos
+++ b/helpinfos
@@ -36,8 +36,10 @@ tell <nick> <message ...>
  Forgets about all message(s) you've sent with !tell, or those to
  particular nick(s).  Use !delmsg to delete messages sent *to* you.
  There is no way to untell individual messages to the same nick.
  Forgets about all message(s) you've sent with !tell, or those to
  particular nick(s).  Use !delmsg to delete messages sent *to* you.
  There is no way to untell individual messages to the same nick.
+ If your nick is secure, you must !identify yourself to use untell.
 
 :tellme
 
 :tellme
+!tellme  repeats any messages you have outstanding.
 !set tellme configures how you receive messages sent with !tell:
  set tellme insecure              When I see you.  (Default.)
  set tellme secure                Hide body until secure ident.
 !set tellme configures how you receive messages sent with !tell:
  set tellme insecure              When I see you.  (Default.)
  set tellme secure                Hide body until secure ident.
@@ -46,7 +48,6 @@ tell <nick> <message ...>
 and also when to consider them delivered (see `help !untell'):
  set tellme unreliable            Tell you once, then forget.
  set tellme pester <interval>     Remind until you say !delmsg
 and also when to consider them delivered (see `help !untell'):
  set tellme unreliable            Tell you once, then forget.
  set tellme pester <interval>     Remind until you say !delmsg
- set tellme reliable <interval>   Like pester, but identify req'd.
  set tellme remind <every-!interval> [<within-interval>]
     Remind until you talk on channel within <within-interval>
     of me having told you.  (Default is remind 1h 30s.)
  set tellme remind <every-!interval> [<within-interval>]
     Remind until you talk on channel within <within-interval>
     of me having told you.  (Default is remind 1h 30s.)
diff --git a/nctest.tcl b/nctest.tcl
new file mode 100644 (file)
index 0000000..503060b
--- /dev/null
@@ -0,0 +1,10 @@
+# Configuration for testbot
+
+set host cam.irc.devel.ncipher.com
+set nick testbot
+set ownfullname confused
+set socketargs {}
+set marktime_min 10
+set ownmailaddr iwj@ncipher.com
+
+source bot.tcl