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