patternban.tcl 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #
  2. # 10/07/2011
  3. #
  4. namespace eval patternban {
  5. variable filename "scripts/patternbans.txt"
  6. variable ban_reason "bye"
  7. # List of pattern bans. Each item in list has the syntax:
  8. # {channel} {host pattern} {words pattern}
  9. variable patternbans [list]
  10. bind msg o|- "!addpatternban" ::patternban::add
  11. bind msg o|- "!listpatternbans" ::patternban::ls
  12. bind msg o|- "!delpatternban" ::patternban::rm
  13. bind pubm -|- "*" ::patternban::match
  14. }
  15. # Return a list consisting of the 3 parts of a uhost: nick!ident@host
  16. # Not used. Only part of match_mask.
  17. proc ::patternban::split_uhost {uhost} {
  18. set nick_uhost [split $uhost !]
  19. set nick [lindex $nick_uhost 0]
  20. set ident_host [split [lindex $nick_uhost 1] @]
  21. set ident [lindex $ident_host 0]
  22. set host [lindex $ident_host 1]
  23. return [list $nick $ident $host]
  24. }
  25. # Return whether uhost matches the given uhost_mask
  26. # Not used. Same as matchaddr?
  27. proc ::patternban::match_mask {uhost_mask uhost} {
  28. set mask_split [::patternban::split_uhost $uhost_mask]
  29. set uhost_split [::patternban::split_uhost $uhost]
  30. # Nick portion
  31. if {[string match [lindex $mask_split 0] [lindex $uhost_split 0]]} {
  32. # Ident portion
  33. if {[string match [lindex $mask_split 1] [lindex $uhost_split 1]]} {
  34. if {[string match [lindex $mask_split 2] [lindex $uhost_split 2]]} {
  35. return 1
  36. }
  37. }
  38. }
  39. return 0
  40. }
  41. proc ::patternban::ban {chan nick uhost} {
  42. putlog "Trying to ban ${nick}!${uhost} on $chan."
  43. putserv "mode $chan +b [maskhost $uhost 3]"
  44. putserv "kick $chan $nick :$::patternban::ban_reason"
  45. }
  46. proc ::patternban::match {nick uhost hand chan text} {
  47. foreach pattern $::patternban::patternbans {
  48. set pattern_channel [lindex $pattern 0]
  49. set pattern_uhost [lindex $pattern 1]
  50. set pattern_pattern [lindex $pattern 2]
  51. if {$chan == $pattern_channel} {
  52. if {[string match *${pattern_pattern}* $text] && [matchaddr $pattern_uhost ${nick}!${uhost}]} {
  53. ::patternban::ban $chan $nick $uhost
  54. return
  55. }
  56. }
  57. }
  58. }
  59. proc ::patternban::add {nick uhost hand text} {
  60. set text [split $text]
  61. if {[llength $text] != 3} {
  62. putserv "PRIVMSG $nick :Usage: !addpatternban <#channel> <nick!user@host pattern> <string pattern>"
  63. return
  64. }
  65. set channel [lindex $text 0]
  66. set uhost_pattern [lindex $text 1]
  67. set pattern [lindex $text 2]
  68. lappend ::patternban::patternbans [list $channel $uhost_pattern $pattern]
  69. ::patternban::save_patternbans
  70. putserv "PRIVMSG $nick :Added pattern ban on $channel for $uhost_pattern containing $pattern."
  71. }
  72. proc ::patternban::ls {nick uhost hand text} {
  73. set count 0
  74. putserv "PRIVMSG $nick :[llength $::patternban::patternbans] patternbans."
  75. foreach pattern $::patternban::patternbans {
  76. putserv "PRIVMSG $nick :#${count}: $pattern"
  77. incr count
  78. }
  79. }
  80. proc ::patternban::rm {nick uhost hand text} {
  81. set text [split $text]
  82. if {[llength $text] != 1 || ![string is digit $text]} {
  83. putserv "PRIVMSG $nick :Usage: !delpatternban <#>"
  84. return
  85. }
  86. if {$text >= [llength $::patternban::patternbans]} {
  87. putserv "PRIVMSG $nick :Error: No such pattern ban."
  88. return
  89. }
  90. set ::patternban::patternbans [lreplace $::patternban::patternbans $text $text]
  91. putserv "PRIVMSG $nick :Pattern ban deleted."
  92. ::patternban::save_patternbans
  93. }
  94. proc ::patternban::save_patternbans {} {
  95. if {[catch {open $::patternban::filename w} fid]} {
  96. return
  97. }
  98. puts -nonewline $fid $::patternban::patternbans
  99. close $fid
  100. }
  101. proc ::patternban::load_patternbans {} {
  102. if {[catch {open $::patternban::filename r} fid]} {
  103. return
  104. }
  105. set ::patternban::patternbans [read -nonewline $fid]
  106. close $fid
  107. }
  108. ::patternban::load_patternbans
  109. putlog "patternban.tcl loaded"