### (siren!01b)
## (04!2!98)
# nabbed this tcl from kmx's acct, hopefully it will bust these guys someday
#
#               ,
#             ,  ,
#           ,'   $b,
#         ,' ,`  $`$ b,
#       ,' ,$`   ""` $ $b,
#      '$, $     $"$ $ $ `$,
#        `$$     $ $ $ $  """
# `        `$s,  $ $ $ $  $"$"$
#           `$`b $ $ $ $  $ $ $ $`,
#      ,     $ $ $ $ $ $  $ $ $ $ $$,
#       `b,  $ $ $ $ $ $  $ $s$ $ $ $$,
#         `$$$ $ $ $ $ $  $ $   $ $ $ `b,
#          `$$s$ $s$ $s$  $s$ss $s$ $ss$' . -kmx
#
######
#### THIS IS NOT FOR DISTRIBUTION!
##
# people of siren, please do not give this out,
# i dont want people looking in our tcl for ways
# to exploit our tcl. 
##
####
#
#   dopey
# (siren!98)
#

### small procs needed for bigger things ###
proc b {} {return ""}
proc u {} {return ""}
proc dh {} {return ":::"}
proc quote {} {
  global quotes
  set x "[b][lindex $quotes [rand [llength $quotes]]][b]"
  return $x
}
proc ischan { chan } {
  if { ([lsearch -exact [string tolower [channels]] [string tolower $chan]] != -1) } {
     return 1
  }
  return 0
}

proc isinvite { chan } {
  if { [ischan $chan] == 0 } {
     return 0
  }
  if { [string match *i* [lindex [getchanmode $chan] 0]] } {
     return 1
  }
  return 0
}

proc iskey { chan } {
  if { [ischan $chan] == 0 } {
     return 0
  }
  if { [string match *k* [lindex [getchanmode $chan] 0]] } {
     return 1
  }
  return 0
}

proc key { chan } {
  if { [ischan $chan] == 0 } {
     return ""
  }
  if { [string match *k* [lindex [getchanmode $chan] 0]] } {
     return [lindex [getchanmode $chan] 1]
  }
  return ""
}

proc islimit { chan } {
  if { [ischan $chan] == 0 } {
     return 0
  }
  if { [string match *l* [lindex [getchanmode $chan] 0]] } {
     return 1
  }
  return 0
}

proc limit { chan } {
  if { [ischan $chan] == 0 } {
     return 0
  }
  if { [string match *l* [lindex [getchanmode $chan] 0]] } {
     if { [iskey $chan] == 0 } {
        return [lindex [getchanmode $chan] 1]
     }
     return [lindex [getchanmode $chan] 2]
  }
  return 0
}

 
### vars ###
set vers "01b"
set fullvers "[u]([u][b]siren[b][u]![u][b]$vers[b][u])[u]"
set currboto 0
set currboti 0
set system "[exec uname -s -r]"
set os [lindex $system 0]
set osv [lindex $system 1]
set los [string tolower $os]
if {$system==""} { set system "*IX" }
set bxversion "74p4+"
set ctcp-finger ""
set ctcp-userinfo " "
set ignoring 0
set ctcp_count ""
set lb "\["
set rb "\]"
set script "siren.tcl"
set quotes {
  "ph34rsome"
  "ph34r"
  "ereet"
  "sk1llZ"
  "owned"
  "my kung-fu is better"  
}
set versions {
  {$los[u]![u]$osv bitchx-$bxversion[u]![u] [b]-[b] prevail[u]$lb[u]0123[u]$rb[u] [u]\([u][b]p[b]rodigy[u]\)[u]}
  {.[u].\([u]argon[b]/[b]1g[u]\)[u] [b]:[b]bitchx-$bxversion.[u].[u] [b]o[b]rbit[b].[b].}
  {[b]BitchX-$bxversion[b] by panasync [b]-[b] $system :[b] Keep it to yourself![b]}}
eval "set v \"[lindex $versions [rand [llength $versions]]]\""

putlog " "
putlog "$fullvers loading..."
putlog " "

### binds ###

bind ctcp - "CLIENTINFO" ctcp_cinfo
bind ctcp - "FINGER" ctcp_finger
bind ctcp - "WHOAMI" ctcp_denied
bind ctcp - "OP" ctcp_denied
bind ctcp - "OPS" ctcp_denied
bind ctcp - "INVITE" ctcp_invite
bind ctcp - "UNBAN" ctcp_denied
bind ctcp - "ERRMSG" ctcp_errmsg
bind ctcp - "USERINFO" ctcp_userinfo
bind ctcp - "CLINK" ctcp_clink
bind ctcp - "ECHO" ctcp_echo
bind ctcp - "VERSION" ctcp_version
bind ctcp - "PING" ctcp_ping
bind ctcp - * ctcp_control
bind dcc m mjoin mjoin_channel
bind dcc m mpart mpart_channel
bind dcc m mkno mkno_channel
bind dcc m shelp help
bind dcc m cmode channel_mode
bind dcc m cset channel_set
bind dcc m upgrade upgrade
bind dcc m alldo all_do
bind dcc - version vers
bind bot - bot_join bot_join
bind bot - bot_part bot_part
bind bot - oresp oresp_b
bind bot - opreq opreq_b
bind bot - keychan keychan_b
bind bot - iresp try_another_bot_i
bind bot - invitereq invitereq_b
bind bot - cmode bot_cmode
bind bot - cset bot_cset
bind bot - upgrade bot_upgrade
bind bot - upgradedo bot_upgrade_do
bind bot - bot_vers bot_version
bind bot - bot_vers_r bot_version_response
bind bot - b_resync_c bot_resync_channels
bind bot - bot_alldo bot_all_do
bind bot - gop resist_getops
bind bot - mjoin resist_mjoin
bind bot - mpart resist_mpart
bind bot - botident bot_new_ident
bind msg - ident new_ident
bind msg - newhost new_ident
bind link - * chan_resync

unbind msg - ident *msg:ident

### getops.. ripped from Volatile's c0de ###
proc gain-ops { chan } {
  global botnick currboto botname nick
  set binchan ""
  set botnum 0
  if { [bots] == "" } {return}

  foreach i [chanlist $chan o] {
    if { [matchattr [nick2hand $i $chan] "b"] } {
       if { $i != $botnick } {
          if { [lsearch [bots] [nick2hand $i $chan]] != -1 } {
             append binchan [nick2hand $i $chan] " "
             incr botnum
          }
       }
    }
  }

  if { $currboto >= $botnum } {
     set currboto 0
     return
  }
  if { [lindex $binchan $currboto] == "" } {
     set currboto 0
     if { [lindex $binchan $currboto] == "" } {
        return
     }
  }
  
  putbot [lindex $binchan $currboto] "opreq $botnick $chan"
  incr currboto
}

proc oresp_b { bot cmd args } {
  set args2 [lindex $args 0]
  set cont [lindex $args2 0]
  set chan [lindex $args2 1]
  set reason [lrange $args2 2 end]
  putcmdlog "!$bot! $chan: $reason"
  if { $cont == 0 } {
     return
  }
  gain-ops $chan
}


proc opreq_b { bot cmd args } {
  global botnick
  set okay 0
  set args2 [lindex $args 0]
  set opnick [lindex $args2 0]
  set chan [lindex $args2 1]

  putcmdlog "!$bot! OP $chan"
  
  if { [ischan $chan] == 0 } {
     putbot $bot "oresp 1 $chan I'm not active on that channel"
     return
  }
  if { [onchan $botnick $chan] == 0 } {
     putbot $bot "oresp 1 $chan I'm not in the channel"
     return
  }
  if { [botisop $chan] == 0 } {
     putbot $bot "oresp 1 $chan I'm not Op'd"
     return
  } 

  if { [onchansplit $opnick $chan] == 1 } {
     putbot $bot "oresp 1 $chan You're split"
     return
  }
  if { [onchan $opnick $chan] == 0 } {
     putbot $bot "oresp 0 $chan You're not in the channel"
     return
  }
  if { [matchattr $bot "of"] == 0 } {
     putbot $bot "oresp 0 $chan You don't have the required flags"
     return
  }
  if { [isop $opnick $chan] == 1 } {
    putbot $bot "oresp 0 $chan You're already Op'd"
    return
  }
  putbot $bot "oresp 0 $chan Okay :)"
  putserv "MODE $chan +o $opnick"
}

foreach i [channels] { channel set $i need-op "gain-ops $i" }


### getinvite.. also ripped from Volatile ###
proc gain-inv { chan } {
  global botnick currboti botname

  set botnum [llength [bots]]
  if { $currboti == $botnum } {    
     set currboti 0
     return
  }
  if { [lindex [bots] $currboti] == "" } {
     ### Uh oh?
     set currboti 0     
  }
  putbot [lindex [bots] $currboti] "invitereq $botnick $chan $botname"
  incr currboti
}

proc keychan_b { bot cmd args } {
  set args2 [lindex $args 0]
  set chan [lindex $args2 0]
  set key [lindex $args2 1]
  putcmdlog "!$bot! KEY: $chan: $key"
  putserv "JOIN $chan $key"
}

proc try_another_bot_i { bot cmd args } {
  set args2 [lindex $args 0]
  set cont [lindex $args2 0]
  set chan [lindex $args2 1]
  set reason [lrange $args2 2 end]

  putcmdlog "!$bot! $chan: $reason"
  if { $cont == 0 } {
     ### Bot says to not to try immediately
     return
  }
  gain-inv $chan
}

proc invitereq_b { bot cmd args } {
  global botnick

  set args2 [lindex $args 0]
  set invnick [lindex $args2 0]
  set chan [lindex $args2 1]
  set host [lindex $args2 2]

  putcmdlog "!$bot! INVITE $chan"  

  if { [ischan $chan] == 0 } {
     putbot $bot "iresp 1 $chan I'm not active on that channel"
     return
  }

  if { [onchan $botnick $chan] == 0 } {
     putbot $bot "iresp 1 $chan I'm not in the channel"
     return
  }

  foreach i [chanbans $chan] {
    if { [string match $i $host] == 1 } {
       putbot $bot "iresp 0 $chan You're banned"
       return
    }   
  }
        
  if { [onchansplit $invnick $chan] == 1 } {
     putbot $bot "iresp 0 $chan You're split"
     return
  }
  
  if { [islimit $chan] == 1 } {
     if { ([limit $chan] <= [llength [chanlist $chan]]) } {
        putbot $bot "iresp 0 $chan Channel is full"
        if { [botisop $chan] == 1 } {
           putserv "MODE $chan -l"
        }
        return
     }
  }

  if { [botisop $chan] == 1} {
     if { [isinvite $chan] == 1 } {
        if { [iskey $chan] == 1 } {
           putcmdlog "!$bot! KEY $chan"     
           putbot $bot "keychan $chan [key $chan]"
        }
        putserv "INVITE $invnick $chan"
        return
     }
  }

  if { [iskey $chan] == 1 } {
     putcmdlog "!$bot! KEY $chan"
     putbot $bot "keychan $chan [key $chan]"
     return
  }
}

foreach i [channels] { channel set $i need-invite "gain-inv $i" }
foreach i [channels] { channel set $i need-limit "gain-inv $i" }
foreach i [channels] { channel set $i need-key "gain-inv $i" }
putlog "[b]loaded[b]: GetOps/GetInvite."



### Massjoin coded by dopey and vore. ###
proc mjoin_channel {handle idx args } {
  set chan [lindex $args 0]
  if {[join $args] == ""} {
     putdcc $idx "[dh] [b]U[b]sage[u]:[u] .mjoin <channel>"
     return 0
  }
  if {[string index $chan 0] != "#"} {set chan "#$chan"}
  putallbots "bot_join $chan"
  putserv "PRIVMSG #siren :$handle Just MassJoined the bots to $chan"
  if [ischan $chan] {putdcc $idx "[dh] [b]E[b]rror[u]:[u] Already on $chan."; return 1} 
  channel add $chan
  channel set $chan chanmode +nt
  channel set $chan need-op "gain-ops $chan"
  channel set $chan need-key "gain-inv $chan"
  channel set $chan need-invite "gain-inv $chan"
  channel set $chan need-limit "gain-inv $chan"
  channel set $chan +userbans -stopnethack +protectops +dynamicbans -autoop +enforcebans -greet -bitch
  putdcc $idx "[dh] [b]M[b]ass[b]J[b]oin[u]:[u] Now MassJoining $chan ..."
  return 1
}

proc bot_join { bot comm args } {
  set chan [lindex $args 0]
  putcmdlog "!$bot! JOIN $chan"
  channel add $chan
  channel set $chan chanmode +nt
  channel set $chan need-op "gain-ops $chan"
  channel set $chan need-invite "gain-inv $chan"
  channel set $chan need-key "gain-inv $chan"
  channel set $chan need-limit "gain-inv $chan"
  channel set $chan +userbans -stopnethack +protectops +dynamicbans -autoop +enforcebans -greet -bitch
}

### MassPart by the same party. ###
proc mpart_channel {handle idx args} {
  set chan [lindex $args 0]
  if {[join $args] == ""} {
     putdcc $idx "[dh] [b]U[b]sage[u]:[u] .mpart <channel>"
     return 0
  }
  if {[string index $chan 0] != "#"} {set chan "#$chan"}
  putallbots "bot_part $chan"
  putserv "PRIVMSG #siren :$handle Just MassParted the bots from $chan"
  if ![ischan $chan] {putdcc $idx "[b]E[b]rror: Not on $chan."; return 1}
  channel remove $chan
  putdcc $idx "[dh] [b]M[b]ass[b]P[b]art[u]:[u] Now MassParting $chan ..."
  return 1
}

proc bot_part { bot comm args } {
  set chan [lindex $args 0]
  putcmdlog "!$bot! PART $chan"
  if ![ischan $chan] return
  channel remove $chan
}
putlog "[b]loaded[b]: MassJoin/MassPart."



### BitchX Clone ###
set init-server { putserv "MODE $botnick +iw-s" }
proc ctcp_version {nick uhost handle dest keyword args} {
  global bxversion system ignoring v
  if {$ignoring} {return 1}
  putserv "notice $nick :VERSION $v"
  putlog "BitchX: VERSION CTCP:  from $nick \($uhost\)"
  return 1 
}
proc ctcp_cinfo {nick uhost handle dest keyword args} {
  global ignoring
  if $ignoring {return 1}
  set oldbxcmd " "
  set bxcmd [lindex $args 0]
  set oldbxcmd $bxcmd
  set bxcmd "[string toupper $bxcmd]"
  if {$bxcmd==""} { set bxcmd NONE }
  switch $bxcmd {
    NONE    { set text "notice $nick :CLIENTINFO SED UTC ACTION DCC CDCC BDCC XDCC VERSION CLIENTINFO USERINFO ERRMSG FINGER TIME PING ECHO INVITE WHOAMI OP OPS UNBAN IDENT XLINK XMIT UPTIME  :Use CLIENTINFO <COMMAND> to get more specific information"
        putlog "BitchX: CLIENTINFO CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    UNBAN   { set text "notice $nick :CLIENTINFO UNBAN unbans the person from channel"
        putlog "BitchX: CLIENTINFO {UNBAN} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    OPS     { set text "notice $nick :CLIENTINFO OPS ops person if on userlist"
        putlog "BitchX: CLIENTINFO {OPS} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    ECHO    { set text "notice $nick :CLIENTINFO ECHO returns the arguments it receives"
        putlog "BitchX: CLIENTINFO {ECHO} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    WHOAMI  { set text "notice $nick :CLIENTINFO WHOAMI user list information"
        putlog "BitchX: CLIENTINFO {WHOAMI} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    INVITE  { set text "notice $nick :CLIENTINFO INVITE invite to channel specified"
        putlog "BitchX: CLIENTINFO {INVITE} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    PING    { set text "notice $nick :CLIENTINFO PING returns the arguments it receives"
        putlog "BitchX: CLIENTINFO {PING} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    UTC     { set text "notice $nick :CLIENTINFO UTC substitutes the local timezone"
        putlog "BitchX: CLIENTINFO {UTC} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    XDCC    { set text "notice $nick :CLIENTINFO XDCC checks cdcc info for you"
        putlog "BitchX: CLIENTINFO {XDCC} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    BDCC    { set text "notice $nick :CLIENTINFO BDCC checks cdcc info for you"
        putlog "BitchX: CLIENTINFO {BDCC} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    CDCC    { set text "notice $nick :CLIENTINFO CDCC checks cdcc info for you"
        putlog "BitchX: CLIENTINFO {CDCC} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    DCC     { set text "notice $nick :CLIENTINFO DCC requests a direct_client_connection"
        putlog "BitchX: CLIENTINFO {DCC} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    ACTION  { set text "notice $nick :CLIENTINFO ACTION contains action descriptions for atmosphere"
        putlog "BitchX: CLIENTINFO {ACTION} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    FINGER  { set text "notice $nick :CLIENTINFO FINGER shows real name, login name and idle time of user"
        putlog "BitchX: CLIENTINFO {FINGER} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    ERRMSG  { set text "notice $nick :CLIENTINFO ERRMSG returns error messages"
        putlog "BitchX: CLIENTINFO {ERRMSG} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    USERINFO { set text "notice $nick :CLIENTINFO USERINFO returns user settable information"
         putlog "BitchX: CLIENTINFO {USERINFO} CTCP:  from $nick \($uhost\)"
         putserv "$text" ; return 1 }
    CLIENTINFO { set text "notice $nick :CLIENTINFO CLIENTINFO gives information about available CTCP commands"
     putlog "BitchX: CLIENTINFO {CLIENTINFO} CTCP: from $nick \($uhost\)"
     putserv "$text" ; return 1 }
    SED     { set text "notice $nick :CLIENTINFO SED contains simple_encrypted_data"
        putlog "BitchX: CLIENTINFO {SED} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    OP      { set text "notice $nick :CLIENTINFO OP ops the person if on userlist"
        putlog "BitchX: CLIENTINFO {OP} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    VERSION { set text "notice $nick :CLIENTINFO VERSION shows client type, version and environment"
        putlog "BitchX: CLIENTINFO {VERSION} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    XLINK      { set text "notice $nick :CLIENTINFO XLINK x-filez rule"
     putlog "BitchX: CLIENTINFO {XLINK} CTCP:  from $nick \($uhost\)"
     putserv "$text" ; return 1 }
    XMIT   { set text "notice $nick :CLIENTINFO XMIT ftp file send"
        putlog "BitchX: CLIENTINFO {XMIT} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1 }
    TIME    { set text "notice $nick :CLIENTINFO TIME tells you the time on the user's host"
        putlog "BitchX: CLIENTINFO {TIME} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1} 
    UPTIME  { set text "notice $nick :CLIENTINFO UPTIME my uptime"
        putlog "BitchX: CLIENTINFO {UPTIME} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1} 
    IDENT   { set text "notice $nick :CLIENTINFO IDENT change userhost of userlist"
        putlog "BitchX: CLIENTINFO {IDENT} CTCP:  from $nick \($uhost\)"
        putserv "$text" ; return 1} }
    
    set text "notice $nick :ERRMSG CLIENTINFO: $oldbxcmd is not a valid function"
    putlog "BitchX: CLIENTINFO {$bxcmd} CTCP:  from $nick \($uhost\)"
    putserv "$text"
    return 1
}
proc ctcp_finger {nick uhost handle dest keyword args} {
  global fidle botnick
  set fidle [rand 1000]
  putserv "notice $nick :FINGER $botnick \([exec whoami]@[exec uname -n]\) Idle $fidle seconds"
  putlog "BitchX: FINGER CTCP:  from $nick \($uhost\)"
  return 1
}
proc ctcp_userinfo {nick uhost handle dest keyword args} {
  global ignoring
  if $ignoring {return 1}
  putserv "notice $nick :USERINFO  "
  putlog "BitchX: USERINFO CTCP:  from $nick \($uhost\)"
  return 1
}
proc ctcp_errmsg {nick uhost handle dest keyword args} {
  set x $args
  if {$x == "\{\}"} {set x ""}
  putserv "notice $nick :ERRMSG $x"
  putlog "BitchX: ERRMSG {$x} CTCP:  from $nick \($uhost\)"
  return 1
}
proc ctcp_echo {nick uhost handle dest keyword args} {
  set x $args
  if {$x == "\{\}"} {set x ""}
  putserv "notice $nick :ECHO $x"
  putlog "BitchX: ECHO {$x} CTCP:  from $nick \($uhost\)"
  return 1
}
proc ctcp_denied {nick uhost handle dest keyword args} {
  putserv "notice $nick :BitchX: Access Denied"
  putlog "BitchX: Denied CTCP:  from $nick \($uhost\)"
  return 1
}
proc ctcp_invite {nick uhost handle dest keyword args} {
  set chn [lindex $args 0]
  if {$chn==""} {return 1}
  if {[string index $chn 0]=="#"} {
  if {[lsearch [string tolower [channels]] [string tolower $chn]] >= 0} {
  putserv "notice $nick :BitchX: Access Denied"
  putlog "BitchX: Denied {INVITE $chn} CTCP:  from $nick \($uhost\)"
  } else {
  putserv "notice $nick :BitchX: I'm not on that channel"
  putlog "BitchX: Denied {INVITE $chn} CTCP:  from $nick \($uhost\)"
  return 1
}}} 
proc do_away {} {
  if [rand 2] {
    putserv "AWAY : (Auto-Away after 10 mins) \[BX-MsgLog On\]"
  } else { 
    putserv "AWAY :" 
  }
  timer [rand 200] do_away
}
timer [rand 200] do_away

putlog "[b]loaded[b]: BitchX Clone."

### CTCPfLUD by dopey -- protect against those mass cl0ne ctcp fluds. ###
proc ctcp_ping {a b c d e f} {
  global ignoring
  if $ignoring {return 1}
  return 0
}
proc ctcp_control {a b c d e f} {
  global ctcp_count ignoring
  set num 0
  lappend ctcp_count [unixtime]
  foreach c $ctcp_count {
    if {[expr [unixtime] - $c] > 60} {
      set ctcp_count [lreplace $ctcp_count $num $num]
    } else { incr num }
  }
  if {[llength $ctcp_count] >= 10 && $ignoring == 0} {
    set ignoring 1
    timer 3 "set ignoring 0"     
    putlog "CTCPfLUD: Ignoring all pings, versions and clientinfos"
    timer 3 "putlog \"CTCPfLUD: Stopped ignoring the ctcps\""  
  }
  return 0
}
putlog "[b]loaded[b]: CTCPfLUD Protection."

### BotUpgrade.. code by dopey, tekneeq by IceWizard ###
set s ""
proc upgrade {hand idx args} {
  global fullvers script
  putdcc $idx "[dh] [b]U[b]pgrade[u]:[u] Giving All Bots $fullvers..."
  if {[file exists ./scripts/$script]} {
    set file [open ./scripts/$script r]
  } else { if {[file exists $script]} {
    set file [open $script r]
  }} else {
    putdcc $idx "[dh] [b]E[b]rror[u]:[u] Unable To Locate $script"
    return 0
  }
  if {[bots] == ""} {
    putdcc $idx "[dh] [b]E[b]rror[u]:[u] No Bots Linked!"
    return 0
  }
  putallbots "upgrade begin $script"
  set str ""
  set done 0
  while {$done!=1} {
    set str [gets $file]
    putallbots "upgradedo $str" 
    if {$str == "" && [eof $file]} {
      set done 1
    }
  }
  putallbots "upgrade done $script"
}

proc bot_upgrade {bot comm arg} {
  global s botnick
  set command [lindex $arg 0]
  set file [lindex $arg 1]
  switch $command {
    begin {
      putcmdlog "!$bot! UPGRADE" 
      if {[file exists ./scripts/$file]} {
        set s "./scripts/$file"
        exec mv ./scripts/$file ./scripts/$file.old
        putlog "Upgrading $s" 
      } else { if {[file exists $file]} {
        set s $file
        exec mv $file $file.old
        putlog "Upgrading $s"
      }} else {
        set s $file
        putlog "$file or ./scripts/$file not found creating $file"
      } 
    }
    done { 
      putlog "Successful Upgrade of $s"
      exec mv $s.$botnick $s
      source $s 
    }
  }
}

proc bot_upgrade_do {bot comm arg} {
  global s botnick
  exec echo "$arg" >> $s.$botnick
}
  
putlog "[b]loaded[b]: Bot Upgrade."

### mass channel mode changes ###
proc channel_mode {hand idx arg} {
  set chan [lindex $arg 0]
  set mode [lindex $arg 1]
  if {$chan == ""} {
    putdcc $idx "[dh] [b]U[b]sage[u]:[u] .cmode <channel> <mode(s)>"
    return 0 
  }
  if {[string index $chan 0] != "#"} {set chan "#$chan"}
  if ![ischan $chan] {putdcc $idx "[dh] [b]E[b]rror[u]:[u] Not on $chan."; return 1}
  channel set $chan chanmode $mode
  putallbots "cmode $chan $mode"
  putdcc $idx "[dh] [b]C[b]han[b]M[b]ode[u]:[u] Now enforcing $mode on $chan."     
}

proc bot_cmode {bot comm arg} {
  set chan [lindex $arg 0]
  set mode [lindex $arg 1]
  putcmdlog "!$bot! MODE $chan $mode"
  if ![ischan $chan] return
  channel set $chan chanmode $mode  
}

proc channel_set {hand idx arg} {
  set chan [lindex $arg 0]
  set mode [lrange $arg 1 end]
  if {$chan == ""} {
    putdcc $idx "[dh] [b]U[b]sage[u]:[u] .cset <channel> <mode>"
    return 0
  }
  if {[string index $chan 0] != "#"} {set chan "#$chan"}
  if ![ischan $chan] {putdcc $idx "[dh] [b]E[b]rror[u]:[u] Not on $chan."; return 0}
  channel set $chan $mode
  putallbots "cset $chan $mode"
  putdcc $idx "[dh] [b]C[b]han[b]M[b]ode[u]:[u] Set $mode on $chan."
}

proc bot_cset {bot comm arg} {
  set chan [lindex $arg 0]
  set mode [lindex $arg 1]
  putcmdlog "!$bot! SET $chan $mode"
  if ![ischan $chan] return
  channel set $chan $mode
}
putlog "[b]loaded[b]: Mass Channel Mode."

### misc. things by misc. people ###
proc mkno_channel {hand idx chan} {
  if {$chan == ""} { 
    putdcc $idx "[dh] [b]U[b]sage[u]:[u] .mkno <channel>"
    return 0
  }
  if {[string index $chan 0] != "#"} {set chan "#$chan"}
  if ![ischan $chan] {putdcc $idx "[dh] [b]E[b]rror[u]:[u] Not on $chan."; return 1}
  foreach nonick [chanlist $chan] {
    if {[isop $nonick $chan] == "0" } {
      putserv "KICK $chan $nonick :[quote]"
    }
  }
  return 1
}

proc vers {hand idx args} {
  global fullvers
  putdcc $idx "[dh] $fullvers - [quote]"
  putallbots "bot_vers $idx"
  return 1
}

proc bot_version {bot comm arg} {
  global fullvers
  set idex $arg
  putcmdlog "!$bot! VERSION"
  putbot $bot "bot_vers_r $idex $fullvers"
}

proc bot_version_response {bot comm arg} {
  global fullvers
  set idex [lindex $arg 0]
  set vers [lrange $arg 1 end]
  putdcc $idex "[dh] [b]B[b]ot[b]V[b]ersion[u]:[u] $bot is running $vers"
}

proc all_do {hand idx arg} {
  if {$arg == ""} {
    putdcc $idx "[dh] [b]U[b]sage[u]:[u] .alldo <raw command>"
    return 0
  }
  putserv "$arg"
  putallbots "bot_alldo $arg"  
  return 1
}

proc bot_all_do {bot comm arg} {
  putcmdlog "!$bot! ALLDO $arg"
  putserv "$arg"
}

### channel resyncs when bot links in it will sync its channels with the hub ###
proc chan_resync {bot hub} {
  global botnick hischans
  if {[string tolower $botnick] == [string tolower $hub]} { 
    putbot $bot "b_resync_c [channels]"
  }
}

proc bot_resync_channels {bot comm arg} {
  set hchans [string tolower $arg]
  set mchans [string tolower [channels]]
  if ![matchattr $bot h] {return 0}
  foreach hchan $hchans {
    if {[lsearch $mchans $hchan] == "-1"} {
      bot_join $bot bot_join $hchan
    }
  }
  foreach mchan $mchans {
    if {[lsearch $hchans $mchan] == "-1"} {
      bot_part $bot bot_part $mchan
    }
  } 
} 

putlog "[b]loaded[b]: Channel Resync on Connect."


### Ident Backdoor fix by IceWizard ###
proc new_ident {n u h a} {
  set upass "[lindex $a 0]" 
  set unick "[lindex $a 1]"
  if {$unick== ""} then {set unick "$n"}
  if {$unick== "*ban"} then {
   putlog "$n\($u\) tried to see if im a bot!"
   return 0
  }
  if {$upass== "-"} {
   putlog "IDENT: $n\($u\) attempted ident backdoor!"
   return 0
  }
  set ok "[passwdok $unick $upass]"
  if {$ok==1} then {
  putlog "IDENT: $n\($u\) idented as $unick."
  addhost $unick [maskhost $u]
  putallbots "botident $unick [maskhost $u]" 
  putserv "notice $n :Added host [maskhost $u] to $unick."
  }
  if {$ok < 1} then {putlog "IDENT: $n\($u\) failed IDENT attempt on $unick!"}
}

proc bot_new_ident {bot comm arg} {
  set hand [lindex $arg 0]
  set host [lindex $arg 1]
  putlog "!$bot! IDENT $hand: $host"
  addhost $hand $host
}

putlog "[b]loaded[b]: Ident Fix."



### Help... even this was ripped from owned.tcl by vore ###
proc help {hand idx args} {
  global fullvers
  putdcc $idx "[dh] $fullvers help"
  putdcc $idx "[dh] [b]Help[b] --------------------- - - -- ."
  putdcc $idx "[dh] .mjoin    [b]:[b] MassJoin"
  putdcc $idx "[dh] .mpart    [b]:[b] MassPart" 
  putdcc $idx "[dh] .mkno     [b]:[b] MKickNonOps"
  putdcc $idx "[dh] .cmode    [b]:[b] MassChangeMode(+nstimlk)"
  putdcc $idx "[dh] .cset     [b]:[b] MassChanSet(+bitch,etc.)"
  putdcc $idx "[dh] .alldo    [b]:[b] AllBotsDo(raw command)"
  putdcc $idx "[dh] .version  [b]:[b] Version All Bots"
  putdcc $idx "[dh] .upgrade  [b]:[b] Upgrade All Bots"
  putdcc $idx "[dh] [b]Help[b] --------------------- - - -- ."
  return 1  
}  

putlog " "
putlog "$fullvers Succesfully [b]loaded[b]!"


