####################################################
# by wiebe @ QuakeNet
#
####################################################


####################################################
# invalidbans:time
####################################################
bind time -|- "?5 * * * *" invalidbans:time
proc invalidbans:time { n h d m y } {
  foreach c [channels] {
    if {![botonchan $c]} { continue }
    if {![botisop $c] && ![botishalfop $c]} { continue }
    foreach b [chanbans $c] {
      set b [lindex $b 0]
      if {[isban $b $c] && [isbansticky $b $c]} { continue }
      if {[invalidbans:mask $b]} { continue }
      invalidbans:unban $c $b
    }
  }
}


####################################################
# invalidbans:unban
####################################################
proc invalidbans:unban { c b } {
  putloglev k $c "$c: removing invalid ban $b"
  pushmode $c -b $b
}


####################################################
# invalidbans:mask
####################################################
proc invalidbans:mask { b } {
  if {![string match "*!*@*" $b]} { return 0 }
  set n [lindex [split $b !] 0]; set h [join [lrange [split $b @] 1 end] @]
  set u [lindex [split [join [lrange [split $b !] 1 end] !] @] 0]
  if {![invalidbans:nick $n]} { return 0 }
  if {![invalidbans:user $u]} { return 0 }
  if {![invalidbans:host $h]} { return 0 }
  return 1
}


####################################################
# invalidbans:nick
####################################################
proc invalidbans:nick { n } {
  regsub -all {\*{2,}} $n * n; set l -1
  if {![string equal [info procs isupport] ""]} { set l [isupport nicklen] }
  if {[string equal $l "-1"]} { set l $::nicklen }
  if {[string length $n] > $l} { return 0 }
  set p ^(\[a-zA-Z\\^\\\[\\\]\\{\\}\\\\|`_\\?\\*\])(\[a-zA-Z0-9\\-\\^\\\[\\\]\\{\\}\\\\|`_\\?\\*\])*\$
  if {![regexp $p $n]} { return 0 }
  return 1
}


####################################################
# invalidbans:user
####################################################
proc invalidbans:user { u } {
  regsub -all {\*{2,}} $u * u; set l 10
  if {[string length $u] > $l} { return 0 }
  if {![regexp {^(~){0,1}[a-zA-Z0-9\-_\.\*\?]+$} $u]} { return 0 }
  return 1
}


####################################################
# invalidbans:host
####################################################
proc invalidbans:host { h } {
  regsub -all {\*{2,}} $h * h; set l 63
  if {[string length $h] > $l} { return 0 }
  if {[string match -nocase "*.users.quakenet.org" $h]} {
    set a [join [lrange [split $h .] 0 end-3] .]
    return [invalidbans:nick $a]
  }
  if {[invalidbans:ip $h]} { return 1 }
  if {[invalidbans:cidr $h]} { return 1 }
  if {![regexp {^[a-zA-Z0-9\-\.\?\*]+$} $h]} { return 0 }
  set h [split $h .]; set t [lindex $h end]
  if {[llength $h] > 1 && ![invalidbans:tld $t]} { return 0 }
  return 1
}


####################################################
# invalidbans:ip
####################################################
proc invalidbans:ip { i } {
  if {[regexp {^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|\*|\?{1,3})\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|\*|\?{1,3})$} $i]} { return 1 }
  return 0
}


####################################################
# invalidbans:cidr
####################################################
proc invalidbans:cidr { i } {
  if {[regexp {^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/(\d|[12]\d|3[0-2])$} $i]} { return 1 }
  return 0
}


####################################################
# invalidbans:tld
####################################################
proc invalidbans:tld { t } {
  if {![regexp {^[a-zA-Z\*\?]+$} $t]} { return 0 }
  set d "ac ad ae af ag ai al am an ao aq ar as at au aw az ax ba bb bd be bf bg bh bi bj bm bn bo br bs bt bv bw by bz ca cc cd cf cg ch ci ck cl cm cn co cr cs cu cv cx cy cz de dj dk dm do dz ec ee eg eh er es et eu fi fj fk fm fo fr ga gb gd ge gf gg gh gi gl gm gn gp gq gr gs gt gu gw gy hk hm hn hr ht hu id ie il im in io iq ir is it je jm jo jp ke kg kh ki km kn kp kr kw ky kz la lb lc li lk lr ls lt lu lv ly ma mc md mg mh mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nc ne nf ng ni nl no np nr nu nz om pa pe pf pg ph pk pl pm pn pr ps pt pw py qa re ro ru rw sa sb sc sd se sg sh si sj sk sl sm sn so sr st sv sy sz tc td tf tg th tj tk tl tm tn to tp tr tt tv tw tz ua ug uk um us uy uz va vc ve vg vi vn vu wf ws ye yt yu za zm zw aero biz cat com coop info jobs mobi museum name net org pro travel gov edu mil int"
  set d [split $d]; foreach e $d { if {[string match -nocase $t $e]} { return 1 } }
  return 0
}


set scriptdb(invalidbans) {
  "checks bans set on the channel every 10 minutes and removes bans that are invalid, in other words, bans that never match anyone"
}

