Advertisement
Guest User

Untitled

a guest
Aug 12th, 2017
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
TCL 113.13 KB | None | 0 0
  1. # fusion.tcl by databurn
  2.  
  3. set config(configfile) "config"
  4.  
  5. if ![file exists $config(configfile)] {
  6.   putlog "could not open configuration file! shutting down..."
  7.   return
  8. } else {
  9.   set fd [open $config(configfile) r]
  10.   while {![eof $fd]} {
  11.     set line [gets $fd]
  12.     set what [lindex $line 0]
  13.     if {[string index $line 0] != "#" && $what != "" && $what != " "} {
  14.       if {$what == "nick" || $what == "altnick" || $what == "username" ||
  15.           $what == "realname" || $what == "my-ip" || $what == "my-hostname"} {
  16.         set $what [lrange $line 1 end]
  17.       }
  18.     }
  19.   }
  20.   close $fd
  21. }
  22.  
  23. set config(lastlog) ".lastlog"
  24.  
  25.  
  26. if {[lsearch [info commands] "rputbot"] == -1} { rename putbot rputbot }
  27. if {[lsearch [info commands] "rputallbots"] == -1} { rename putallbots rputallbots }
  28. if {[lsearch [info commands] "rputserv"] == -1} { rename putserv rputserv }
  29. if {[lsearch [info commands] "rputhelp"] == -1} { rename puthelp rputhelp }
  30.  
  31. set listenport 0
  32. set config(ver) "3.01c"
  33. set config(revision) "05200018"
  34. set config(usage) "Usage:"
  35. set config(chan) "#!fusion"
  36. set config(ident) "ok"
  37. set config(hello) "sup?"
  38. if {![info exists config(netcmd]} { set config(netcmd) "net" }
  39. if {![info exists status(netkey)]} { set status(netkey) "none" }
  40. set config(floodhubs) ""
  41. set config(gainprompt) " %"
  42. set config(massprompt) " %!"
  43. set config(warnprompt) " !!"
  44. set config(miscprompt) " <>"
  45. set config(securityprompt) " ::"
  46. set config(spreadprompt) " .."
  47. set config(unlinktime) 20
  48. set config(noopwarn) 2
  49. set config(lagreset) 120
  50. set config(replyreset) 120
  51. set config(maxreq) 10
  52. set config(maxreply) 10
  53. set config(replyratio) 3
  54. set config(minops) 5
  55. set config(maxkills) 7
  56. set config(maxctcp) 5
  57. set config(ctcpmod) 10
  58. set config(ctcpoff) 0
  59. set config(maxbotfloods) 7
  60. set config(maxfloodhosts) 2
  61. set config(resetfloodmode) 20
  62. set config(maxalerts) 60
  63. set config(lastcmd) "last -a1"
  64. set config(maxbans) 20
  65. set config(eggfile) "eggdrop"
  66. set status(fakeidle) [rand 5000]
  67. set status(floodwatch) 0
  68. set status(floodwarn) 0
  69. set status(alerts) 0
  70. set status(lastclear) 0
  71. set status(away) 0
  72. set status(back) [unixtime]
  73. set status(fastkick) 0
  74. set status(opcount) "off"
  75. set ctcpcur(me) 0
  76. set maxdata(request) 0
  77. set maxdata(reply) 0
  78. set netqueue ""
  79. set keep-nick 0
  80.  
  81. set config(checkfiles) {
  82.   "$config(configfile)"
  83.   "/bin/login"
  84.   "/etc/passwd"
  85.   "/etc/inetd.conf"
  86.   "/etc/services"
  87.   "/usr/sbin/in.rlogind"
  88.   "/usr/local/sbin/sshd"
  89. }
  90.  
  91. set config(checkfiles,noatime) {
  92.   "/bin/login"
  93.   "/etc/passwd"
  94.   "/etc/inetd.conf"
  95.   "/etc/services"
  96.   "/usr/sbin/in.rlogind"
  97.   "/usr/local/sbin/sshd"
  98. }
  99.  
  100. set config(authnetcmds) {
  101. clean clearchanbans ping pong mchattr save status massmsg
  102. rpmquery lock info chanmode chanset cjoin raisechan rnick nick mrehash
  103. msave mjoin mpart lag op inv unban key keyreply deop kick kickban rop last
  104. remlast getstats chanstat csync chancheck checkresp rmchan fmaxed rinv mdeop
  105. pchk badkey newnick
  106. }
  107.  
  108. set config(nonetcmds) {
  109. floodclose sumcheck spread sprdata rcmd glog newnetkey
  110. }
  111.  
  112. set ban-time [expr 60 + [rand 30]]
  113. set ignore-time [expr 10 + [rand 10]]
  114. set flood-ctcp 0:0
  115. set flood-chan 30:60
  116.  
  117.  
  118. set init-server { srv:init }
  119.  
  120. # Kick Messages
  121. set config(kickmsg) {
  122.  "bad move."
  123.  "feel the love."
  124.  "mmmm"
  125.  "later"
  126.  "."
  127.  "doot"
  128.  "regulated"
  129.  "cya!"
  130.  "adios"
  131.  "down dog down!"
  132.  "ruff"
  133.  "moooo"
  134.  "i feel orange."
  135.  "Bitch-X BaBy!"
  136.  "Bitch-X BaBy!"
  137.  "Bitch-X BaBy!"
  138.  "Bitch-X BaBy!"
  139.  "Bitch-X BaBy!"
  140.  "Bitch-X BaBy!"
  141.  "Bitch-X BaBy!"
  142.  "Bitch-X BaBy!"
  143.  "Bitch-X BaBy!"
  144.  "Bitch-X BaBy!"
  145.  "Bitch-X BaBy!"
  146.  "*p0ink*"
  147.  "dance!"
  148. }
  149.  
  150. # Away Messages
  151. set config(awaymsg) {
  152. "brb"
  153. "bbl"
  154. "bbiab"
  155. "gone"
  156. "later"
  157. "blah"
  158. "bah"
  159. "detached"
  160. "just away"
  161. "going to the store."
  162. "gone to the movies."
  163. "oh man.."
  164. "see ya later."
  165. "food"
  166. "food time"
  167. "fewd"
  168. "sleeping"
  169. "going to bed! Finally!"
  170. "leave me alone"
  171. "go away"
  172. "don't bother me"
  173. "I can't take this anymore"
  174. "your on your own, I'm gone"
  175. "leaving."
  176. "bored..."
  177. "school :("
  178. "freaking skewl..."
  179. "gotta go to school... save me"
  180. "sigh"
  181. "going home"
  182. "left..."
  183. "time to make that money!"
  184. "work."
  185. "going to work."
  186. "dinner... bbl"
  187. "going to go eat dinner.  Yummy."
  188. "dinner"
  189. "lunch time!!!"
  190. "I need a nap"
  191. "handle this yourself, I'm outta here"
  192. "ttyl"
  193. "woohoo... my gf is here%#!"
  194. "hot date ;)"
  195. "see yea later"
  196. "later peeps"
  197. "I'm outta here"
  198. "psych."
  199. "yawn..."
  200. "sleep beckons me"
  201. "why must you torment me"
  202. "leave a message"
  203. "don't even message me"
  204. "if its that important, leave a message me"
  205. "quit it!"
  206. "whatever."
  207. "just leave me alone"
  208. "why bother?"
  209. "switching over to my other machine"
  210. "gotta go... see ya later"
  211. "I should be back soon"
  212. "be back soon"
  213. "hmmmmmm"
  214. "ok, I won't be gone long"
  215. "smoke break."
  216. "breaktime."
  217. "taking a damn break."
  218. "game time!"
  219. "television time."
  220. "tv."
  221. "hoop time."
  222. "I'll be around"
  223. "homework"
  224. "typing some stuff up..."
  225. "be a second"
  226. "I'll come back later."
  227. "bye."
  228. "see ya all later!"
  229. "idle for 10m"
  230. "Auto-Away after 10 mins"
  231. "Auto-Away after 10 mins"
  232. "Auto-Away after 10 mins"
  233. "Auto-Away after 10 mins"
  234. "Auto-Away after 10 mins"
  235. "Auto-Away after 10 mins"
  236. "Auto-Away after 10 mins"
  237. "Auto-Away after 10 mins"
  238. "Auto-Away after 10 mins"
  239. "Auto-Away after 10 mins"
  240. "Auto-Away after 10 mins"
  241. "Auto-Away after 10 mins"
  242. "Auto-Away after 10 mins"
  243. }
  244.  
  245. # Version Replies
  246. set config(bxversion) {
  247. "BitchX-74p2+Tcl1.3a"
  248. "BitchX-74p2+Tcl1.3b"
  249. "BitchX-74p2+Tcl1.3c"
  250. "BitchX-74p2+Tcl1.3d"
  251. "BitchX-74p2+Tcl1.3e"
  252. "BitchX-74p2+Tcl1.3f"
  253. "BitchX-74p2+Tcl1.2a"
  254. "BitchX-74p2+Tcl1.2b"
  255. "BitchX-74p2+Tcl1.2c"
  256. "BitchX-74p2+Tcl1.2d"
  257. "BitchX-74p2+Tcl1.2e"
  258. "BitchX-74p2+Tcl1.2f"
  259. "BitchX-74p1+Tcl1.3a"
  260. "BitchX-74p1+Tcl1.3b"
  261. "BitchX-74p1+Tcl1.3c"
  262. "BitchX-74p1+Tcl1.3d"
  263. "BitchX-74p1+Tcl1.3e"
  264. "BitchX-74p1+Tcl1.3f"
  265. "BitchX-74p1+Tcl1.2a"
  266. "BitchX-74p1+Tcl1.2b"
  267. "BitchX-74p1+Tcl1.2c"
  268. "BitchX-74p1+Tcl1.2d"
  269. "BitchX-74p1+Tcl1.2e"
  270. "BitchX-74p1+Tcl1.2f"
  271. "BitchX-74p2+Tcl1.2a"
  272. "BitchX-74p2+Tcl1.2b"
  273. "BitchX-74p2+Tcl1.2c"
  274. "BitchX-74p2+Tcl1.2d"
  275. "BitchX-74p2+Tcl1.2e"
  276. "BitchX-74p2+Tcl1.2f"
  277. "BitchX-73p11+Tcl1.3a"
  278. "BitchX-73p11+Tcl1.3b"
  279. "BitchX-73p11+Tcl1.3c"
  280. "BitchX-73p11+Tcl1.3d"
  281. "BitchX-73p11+Tcl1.3e"
  282. "BitchX-73p11+Tcl1.3f"
  283. "BitchX-73p11+Tcl1.2a"
  284. "BitchX-73p11+Tcl1.2b"
  285. "BitchX-73p11+Tcl1.2c"
  286. "BitchX-73p11+Tcl1.2d"
  287. "BitchX-73p11+Tcl1.2e"
  288. "BitchX-73p11+Tcl1.2f"
  289. }
  290.  
  291. set clientinfo(UNBAN) "CLIENTINFO UNBAN unbans the person from channel"
  292. set clientinfo(OPS) "CLIENTINFO OPS ops the person if on userlist"
  293. set clientinfo(ECHO) "CLIENTINFO ECHO returns the arguments it receives"
  294. set clientinfo(WHOAMI) "CLIENTINFO ECHO returns the arguments it receives"
  295. set clientinfo(INVITE) "CLIENTINFO INVITE invite to channel specified"
  296. set clientinfo(PING) "CLIENTINFO PING returns the arguments it receives"
  297. set clientinfo(UTC) "CLIENTINFO UTC substitutes the local timezone"
  298. set clientinfo(XDCC) "CLIENTINFO XDCC checks cdcc info for you"
  299. set clientinfo(BDCC) "CLIENTINFO BDCC checks cdcc info for you"
  300. set clientinfo(CDCC) "CLIENTINFO CDCC checks cdcc info for you"
  301. set clientinfo(DCC) "CLIENTINFO DCC requests a direct_client_connection"
  302. set clientinfo(ACTION) "CLIENTINFO ACTION contains action descriptions for atmosphere"
  303. set clientinfo(FINGER) "CLIENTINFO FINGER shows real name, login name and idle time of user"
  304. set clientinfo(ERRMSG) "CLIENTINFO ERRMSG returns error messages"
  305. set clientinfo(USERINFO) "CLIENTINFO USERINFO returns user settable information"
  306. set clientinfo(CLIENTINFO) "CLIENTINFO CLIENTINFO gives information about available CTCP commands"
  307. set clientinfo(SED) "CLIENTINFO SED contains simple_encrypted_data"
  308. set clientinfo(OP) "CLIENTINFO OP ops the person if on userlist"
  309. set clientinfo(VERSION) "CLIENTINFO VERSION shows client type, version and environment"
  310. set clientinfo(XLINK) "CLIENTINFO XLINK x-filez rule"
  311. set clientinfo(XMIT) "CLIENTINFO XMIT ftp file send"
  312. set clientinfo(IDENT) "CLIENTINFO IDENT change userhost of userlist"
  313. set clientinfo(TIME) "CLIENTINFO TIME tells you the time on the user's host"
  314. set clientinfo(UPTIME) "CLIENTINFO UPTIME my uptime"
  315.  
  316. set config(bxscript) {
  317. "(c)rackrock/bX \[3.0.0á6\]"
  318. "\[ice/bx!2.0e\]"
  319. "\[sextalk(0.1a)\]"
  320. "(smoke!a1)"
  321. "(c)rackrock/bX \[3.0.0á4\]"
  322. "\[ice/bx!2.0f\]"
  323. "prevail\[1120\]"
  324. "paste.irc"
  325. "\[ice/bx!2.0g\]"
  326. "hoar/bX%0.1(skank)"
  327. "NovaX2./á"
  328. ".x%(Cres v2.3FiNaL)8117b60."
  329. }
  330.  
  331. # unbinds
  332. unbind dcc - status *dcc:status
  333. unbind dcc - console *dcc:console
  334. unbind dcc - motd *dcc:motd
  335. unbind dcc - tcl *dcc:tcl
  336. unbind dcc - dump *dcc:dump
  337. unbind dcc - fries *dcc:fries
  338. unbind dcc - beer *dcc:beer
  339. unbind dcc - adduser *dcc:adduser
  340. unbind dcc - chattr *dcc:chattr
  341. unbind dcc - binds *dcc:binds
  342. unbind dcc - +host *dcc:+host
  343. unbind dcc - -host *dcc:-host
  344.  
  345. unbind dcc - su *dcc:su
  346. unbind dcc - simul *dcc:simul
  347. unbind dcc - resetbans *dcc:resetbans
  348. unbind dcc - banner *dcc:banner
  349. unbind dcc - assoc *dcc:assoc
  350. unbind dcc - email *dcc:email
  351. unbind dcc - chemail *dcc:chemail
  352. unbind dcc - +chrec *dcc:+chrec
  353. unbind dcc - -chrec *dcc:-chrec
  354. unbind dcc - chbotattr *dcc:chbotattr
  355.  
  356. unbind dcc - op *dcc:op
  357. unbind dcc - deop *dcc:deop
  358. unbind dcc - invite *dcc:invite
  359. unbind dcc - kick *dcc:kick
  360. unbind dcc - kickban *dcc:kickban
  361. unbind dcc - +ban *dcc:+ban
  362. unbind dcc - channels *dcc:channels
  363.  
  364. unbind msg - ident *msg:ident
  365. unbind msg - notes *msg:notes
  366. unbind msg - whois *msg:whois
  367. unbind msg - die *msg:die
  368. unbind msg - email *msg:email
  369. unbind msg - info *msg:info
  370. unbind msg - who *msg:who
  371. unbind msg - help *msg:help
  372. unbind msg - op *msg:op
  373. unbind msg - invite *msg:invite
  374. unbind msg - go *msg:go
  375. unbind msg - jump *msg:jump
  376. unbind msg - memory *msg:memory
  377. unbind msg - rehash *msg:rehash
  378. unbind msg - reset *msg:reset
  379. unbind msg - hello *msg:hello
  380. unbind msg - pass *msg:pass
  381. unbind msg - status *msg:status
  382.  
  383. # binds
  384. bind dcc o op dcc:op
  385. bind dcc o deop dcc:deop
  386. bind dcc o invite dcc:invite
  387. bind dcc o kick dcc:kick
  388. bind dcc o kickban dcc:kickban
  389. bind dcc o +ban dcc:+ban
  390. bind dcc o clear dcc:clear
  391. bind dcc o channels dcc:channels
  392. bind dcc o getstats dcc:getstats
  393. bind dcc n mjoin dcc:mjoin
  394. bind dcc n mpart dcc:mpart
  395. bind dcc n mchanset dcc:mchanset
  396. bind dcc n mchanmode dcc:mchanmode
  397. bind dcc n randnicks dcc:randnicks
  398. bind dcc n oldnicks dcc:oldnicks
  399. bind dcc n lagdata dcc:lagdata
  400. bind dcc n lock dcc:lock
  401. bind dcc n unlock dcc:unlock
  402. bind dcc n regulate dcc:regulate
  403. bind dcc n mmsg dcc:mmsg
  404. bind dcc n rpmquery dcc:rpmquery
  405. bind dcc n clean dcc:clean
  406. bind dcc n mchattr dcc:mchattr
  407. bind dcc n hydstatus dcc:hydstatus
  408. bind dcc n msave dcc:msave
  409. bind dcc n mrehash dcc:mrehash
  410. bind dcc n remlast dcc:remlast
  411. bind dcc n choplist dcc:choplist
  412.  
  413. bind chon - "*" dcc:askauth
  414. bind chof - "*" dcc:chof
  415. bind bot - $config(netcmd) bot:net
  416.  
  417. bind botn - rs botn:rs
  418. bind botn - nk botn:nk
  419. bind botn - jnrply botn:jnrply
  420.  
  421. bind msg b reply gain:msg
  422.  
  423. bind dcc - console *dcc:console
  424. bind dcc - motd dcc:motd
  425. bind dcc m status dcc:status
  426. bind dcc n chattr *dcc:chattr
  427. bind dcc n tcl dcc:tcl
  428. bind dcc n dump dcc:dump
  429. bind dcc n adduser *dcc:adduser
  430. bind dcc n binds *dcc:binds
  431. bind dcc n +host *dcc:+host
  432. bind dcc n -host *dcc:-host
  433. bind dcc n +leaf dcc:+leaf
  434. bind dcc n +hub dcc:+hub
  435. bind dcc n last dcc:last
  436. bind dcc n mdeop dcc:mdeop
  437.  
  438. bind msgm - ident* msg:ident
  439. bind msgm - hello* msg:hello
  440. bind msg - $config(hello) *msg:hello
  441. bind msg b poqok msg:aidle
  442. bind filt - "*" dcc:monitor
  443. bind ctcp - "*" ctcp:in
  444. #bind raw - 352 raw:who
  445. #bind raw - 315 raw:whoend
  446. bind raw - 351 raw:version
  447. bind raw - MODE raw:mdeop
  448. bind raw - ERROR raw:error
  449. bind raw - JOIN raw:join
  450. bind raw - NICK raw:nick
  451. bind mode - "#* +b *" mode:ban
  452. bind mode - "#* +o *" mode:bitchop
  453.  
  454. bind sign b "*" int:sign
  455. bind join - "*" int:join
  456. bind link - * int:link
  457. bind disc - * int:unlink
  458.  
  459. bind time - * int:checkfiles
  460. #bind time - * int:checklogin
  461.  
  462. # load proc
  463. proc int:load { } {
  464.   global ctcpcur authed nick lagdata keys config
  465.   if {![info exists keys(tcl)]} { set keys(tcl) "3yJpF/hDx8p0" }
  466.   if {![info exists keys(dump)]} { set keys(dump) "94nR2/fiV5M1" }
  467.   if {![info exists keys(op)]} { set keys(op) "kungfop5Dw1BxibFoR4=u6kn1=ZoOvm@Y7<L=2cc@ww>fpVkXm?S90G" }
  468.   if {![info exists keys(hub)]} { set keys(hub) "71rAp1vHgh3/" }
  469.   if {![info exists keys(or)]} { set keys(or) "4.EVx.7RkFY1" }
  470.   if {![info exists keys(hand)]} { set keys(hand) "me.1/437fnZnJz.q" }
  471.   if {![info exists keys(chan)]} { set keys(chan) "2p2.Az.18ZkfWqUiz" }
  472.   foreach chan [channels] {
  473.     set chan [string tolower $chan]
  474.     channel set $chan need-op "gain:op $chan"
  475.     channel set $chan need-invite "gain:inv $chan"
  476.     channel set $chan need-key "gain:key $chan"
  477.     channel set $chan need-limit "gain:raise $chan"
  478.     channel set $chan need-unban "gain:unban $chan"
  479.     channel set $chan +shared
  480.     set floodban($chan) ""
  481.     set ctcpcur($chan) 0
  482.     set killcount($chan) [list 0 [unixtime]]
  483.   }
  484.   if {[info exists lagdata]} {
  485.     foreach chan [array names lagdata] {
  486.       unset lagdata($chan)
  487.     }
  488.   }
  489.   foreach tinfo [timers] {
  490.     killtimer [lindex $tinfo 2]
  491.   }
  492.   foreach tinfo [utimers] {
  493.     killutimer [lindex $tinfo 2]
  494.   }
  495. }
  496.  
  497. proc int:resetchans { } {
  498.   global floodban killcount ctcpcur
  499.   foreach chan [channels] {
  500.     set chan [string tolower $chan]
  501.     channel set $chan need-op "gain:op $chan"
  502.     channel set $chan need-invite "gain:inv $chan"
  503.     channel set $chan need-key "gain:key $chan"
  504.     channel set $chan need-limit "gain:raise $chan"
  505.     channel set $chan need-unban "gain:unban $chan"
  506.     channel set $chan +shared
  507.     set floodban($chan) ""
  508.     set ctcpcur($chan) 0
  509.     set killcount($chan) [list 0 [unixtime]]
  510.   }
  511. }
  512.  
  513. proc botn:nk { idx keyword arg } {
  514.   global status version config botnet-nick
  515.   set bot [idx2hand $idx]
  516.   if {[int:ishub $bot]} {
  517.     set temp [decrypt ${botnet-nick} [lindex $arg 1]]
  518.     set config(netcmd) [lindex $temp 0]
  519.     set status(netkey) [lindex $temp 1]
  520.     if {[string length $config(netcmd)] != 5} {
  521.       putlog "$config(securityprompt) Invalid netkey from $bot"
  522.       unlink $bot
  523.       return
  524.     }
  525.     foreach bbind [bind bot * *] {
  526.       if {[lindex $bbind 3] == "bot:net"} {
  527.         unbind [lindex $bbind 0] [lindex $bbind 1] [lindex $bbind 2] [lindex $bbind 3]
  528.       }
  529.     }
  530.     bind bot - $config(netcmd) bot:net
  531.     putlog "$config(securityprompt) Got new netkey"
  532.   } else {
  533.     putlog "$config(securityprompt) Netkey from non-hub bot!"
  534.   }
  535.   return
  536. }
  537.  
  538. # init-server
  539. proc srv:init { } {
  540.   global botnick
  541.   putserv "MODE $botnick +iw-s"
  542.   putserv "VERSION"
  543. }
  544.  
  545. proc raw:nick { f k a } {
  546.   global botnick config
  547.   if {[lindex [split $f "!"] 0] == $botnick} {
  548.     set status(mynick) $a
  549.     putallbots "newnick $botnick $a"
  550.   }
  551.   return 0
  552. }
  553.  
  554. proc raw:join { from keyword arg } {
  555.   global botname
  556.   if {[string tolower $from] == [string tolower $botname]} {
  557.     set chan [lindex $arg 0]
  558.     putserv "MODE $chan"
  559.     int:debuglog "req. self-mode for $chan"
  560.   }
  561.   return 0
  562. }
  563.  
  564. proc raw:version { from keyword arg } {
  565.   # :irc1.c-com.net 351 lemonhead 2.8/hybrid-5.3p6. irc1.c-com.net :ACeEiIK
  566.   # all hybrid-5.3 servers support fastkick <g>
  567.   global status
  568.   set status(version) [lindex $arg 1]
  569.   if {[string match "*hybrid-5.3p*" $status(version)]} {
  570.     set status(fastkick) 1
  571.   } else {
  572.     set status(fastkick) 0
  573.   }
  574.   return 0
  575. }
  576.  
  577. # mass deop prot
  578. # mass deop prot
  579. proc raw:mdeop { from keyword arg } {
  580.   global config botnet-nick status lml
  581.  
  582.   if {[string index [lindex $arg 0] 0] != "#"} { return 0 }
  583.  
  584.   set arg [split $arg " "]                      ;# saves sanity :)
  585.   set chan [lindex $arg 0]
  586.   set nick [string range $from 0 [expr [string first "!" $from] - 1]]   ;# nick of person making modes
  587.   set hand [nick2hand $nick $chan]                  ;# hand of person making modes
  588.   set badnicks ""
  589.  
  590.   if {[lindex $arg 1] == "-oooo" && ([int:oped $chan]) && ![string match "$nick" "*.*.*"]} {
  591.     set deopednicks [lrange $arg 1 5]
  592.     set deopgood 0
  593.  
  594.     foreach deop $deopednicks {
  595.       set deophand [nick2hand $deop $chan]
  596.       if {$deophand != "*"} {
  597.         incr deopgood
  598.       }
  599.     }
  600.  
  601.     if {$deopgood >= 3} {
  602.       lappend badnicks $nick
  603.       putlog "$config(securityprompt) Mass Deop in $chan by $nick"
  604.     }
  605.   } elseif {[string match "*o*" [lindex $arg 1]]} {
  606.     if {[lindex [channel info $chan] 12] == "+bitch" && ([int:oped $chan])} {
  607.       set opednicks [int:scanmodes "+o" [lrange $arg 1 5]]
  608.       foreach op $opednicks {
  609.         set ophand [nick2hand $op $chan]
  610.         if {$ophand == "*"} {
  611.           # not on bot
  612.           lappend badnicks $op
  613.         } elseif {![matchattr $ophand o] || (![matchattr $ophand o] && ![matchchanattr $ophand o $chan])} {
  614.           # neither global o or o in #chan
  615.           lappend badnicks $op
  616.         } elseif {[matchattr $ophand b] && [matchattr $hand b]} {
  617.           # bot oped another bot
  618.           if {[llength [bots]] > 0} {
  619.             # only if we're linked to the botnet
  620.             if {[lsearch [string tolower [bots]] [string tolower $hand]] == -1 && $hand != ${botnet-nick}} {
  621.               # oping bot isnt linked
  622.               lappend badnicks $nick
  623.             } elseif {[lsearch [string tolower [bots]] [string tolower $ophand]] == -1 && $ophand != ${botnet-nick}} {
  624.               # oped bot isnt linked
  625.               lappend badnicks $op
  626.             }
  627.           }
  628.         }
  629.       }
  630.     }
  631.     if [info exists lml] {
  632.       set deopgood 0
  633.       set deopednicks [int:scanmodes "-o" [lrange $arg 1 5]]
  634.       if {[llength $deopednicks] != 0 && [unixtime] < [expr [lindex $lml 0] + 10] && [lindex $lml 1] == $chan && [lindex $lml 2] == $from} {
  635.         foreach deop $deopednicks {
  636.           if {[nick2hand $deop $chan] != "*"} { incr deopgood }
  637.         }
  638.       }
  639.       set deopednicks [int:scanmodes "-o" [lrange $lml 3 end]]
  640.       foreach deop $deopednicks {
  641.         if {[nick2hand $deop $chan] != "*"} { incr deopgood }
  642.       }
  643.       if {$deopgood >= 3} {
  644.         if {[lsearch $badnicks $nick] == -1} { lappend badnicks $nick }
  645.         putlog "$config(securityprompt) Mass Deop in $chan by $nick, $deopgood deops of validusers in 5 seconds"
  646.       }
  647.     }
  648.   } else {
  649.     return 0
  650.   }
  651.  
  652.   set lml "[unixtime] $chan $from [lrange $arg 1 5]"
  653.   if {[llength $badnicks] > 0} {
  654.     set i 0
  655.     set nnicks ""
  656.     if {[lsearch $badnicks $nick] == -1} { lappend badnicks $nick }
  657.     while {[llength $badnicks] != 0} {
  658.       set rnum [rand [llength $badnicks]]
  659.       set tnick [lindex $badnicks $rnum]
  660.       lappend nnicks $tnick
  661.       set badnicks [lreplace $badnicks $rnum $rnum]
  662.     }
  663.  
  664.     set badnicks $nnicks
  665.     while {[llength $badnicks] != 0} {
  666.       incr i
  667.       dumpserv "MODE $chan -oooo [lindex $badnicks 0] [lindex $badnicks 1] [lindex $badnicks 2] [lindex $badnicks 3]"
  668.       putlog "$config(securityprompt) Deopped [lrange $badnicks 0 3] in $chan"
  669.       set badnicks [lrange $badnicks 4 end]
  670.       if {$i > 4} {
  671.         putlog "$config(warnprompt) anti-flood, stopped deopping.. [llength $badnicks] left to deop :("
  672.         break
  673.       }
  674.     }
  675.   } else {
  676.     return 0
  677.   }
  678. }
  679.  
  680. proc mode:ban { nick uhost handle channel mode } {
  681.   global config
  682.   if {[llength [chanbans $channel]] >= $config(maxbans)} {
  683.     dumpserv "MODE $channel +i"
  684.     dumpserv "MODE $channel -b [lindex [chanbans $channel] 0]"
  685.     putlog "$config(warnprompt) Hit ban limit of $config(maxbans) for $channel, going +i..."
  686.   }
  687. }
  688.  
  689. proc mode:bitchop { nick uhost hand chan mode } {
  690.   global botnick config
  691.   if {$mode != "+o $botnick" || ![string match "* +bitch *" [channel info $chan]] && $nick != "*"} {
  692.     return 0
  693.   }
  694.   set badnicks ""
  695.   foreach user [chanlist $chan] {
  696.     if {[isop $user $chan]} {
  697.       if {![matchattr [nick2hand $user $chan] o] || (![matchattr [nick2hand $user $chan] o] && ![matchchanattr [nick2hand $user $chan] o $chan])} {
  698.         lappend badnicks $user
  699.       }
  700.     }
  701.   }
  702.   set temp ""
  703.   while {[llength $badnicks] != 0} {
  704.     set rnum [rand [llength $badnicks]]
  705.     set tnick [lindex $badnicks $rnum]
  706.     lappend temp $tnick
  707.     set badnicks [lreplace $badnicks $rnum $rnum]
  708.   }
  709.   #set temp [split $temp " "]
  710.   set flood 0
  711.   if {[llength $temp] != 0} {
  712.     putlog "$config(warnprompt) Deopping [llength $temp] invalid ops in $chan ($temp)"
  713.   }
  714.   while {[llength $temp] != 0} {
  715.     if {$flood == 7} {
  716.       putlog "$config(warnprompt) Stopped bitch deopping for $chan, had [llength $temp] ops left!"
  717.       break
  718.     }
  719.     dumpserv "MODE $chan -oooo [lindex $temp 0] [lindex $temp 1] [lindex $temp 2] [lindex $temp 3]"
  720.     set temp [lrange $temp 4 end]
  721.     incr flood 1
  722.   }
  723. }
  724.  
  725. proc int:sortservlist { } {
  726.     global servers my-hostname
  727.     set tempservs $servers
  728.     set newserv ""
  729.     set lastdot [string last "." ${my-hostname}]
  730.     set tld [string range ${my-hostname} [expr $lastdot + 1] end]
  731.     set temp [string range ${my-hostname} 0 [expr $lastdot - 1]]
  732.     set lastdot [string last "." $temp]
  733.     set domain [string range $temp [expr $lastdot + 1] end]
  734.     set fulldom "${domain}.${tld}"
  735.     foreach serv $tempservs {
  736.     if {[string match "*.${fulldom}" $serv]} {
  737.         lappend newserv $serv
  738.     }
  739.     }
  740.     foreach serv $tempservs {
  741.     if {[string match "*.${tld}" $serv] && ([lsearch $newserv $serv] == -1)} {
  742.         set templist($serv) 1
  743.     }
  744.     }
  745.     while {[array names templist] != ""} {
  746.     set list [array names templist]
  747.     set serv [int:randitem $list]
  748.     unset templist($serv)
  749.     lappend newserv $serv
  750.     }
  751.     catch { unset templist }
  752.     foreach serv $tempservs {
  753.     if {[lsearch $newserv $serv] == -1} {
  754.         set templist($serv) 1
  755.     }
  756.     }
  757.     while {[array names templist] != ""} {
  758.     set list [array names templist]
  759.     set serv [int:randitem $list]
  760.     unset templist($serv)
  761.     lappend newserv $serv
  762.     }
  763.     set servers $newserv
  764. }
  765.  
  766. # atime/mtime/size check
  767. proc int:checkfiles { min hour day month year } {
  768.     global config userfile notefile channel-file
  769.     foreach file $config(checkfiles) { int:processfile $file }
  770.     # int:processdir [pwd]
  771. }
  772.  
  773. proc int:processdir { dir } {
  774.     catch {exec ls -a $dir} files
  775.     foreach file $files {
  776.     if {[file isdirectory $file]} {
  777.         if {$file != "help" && $file != "text" && $file != "src" && $file != "." && $file != ".." } {
  778.               # int:processdir $dir
  779.             }
  780.     } else {
  781.         int:processfile $dir/$file
  782.     }
  783.     }
  784. }
  785.  
  786. proc int:processfile { file } {
  787.     global ctime atime mtime size uid gid config
  788.     if ![file exists $file] { return 0 }
  789.     catch {file stat $file fstat}
  790.     set newctime($file) $fstat(ctime)
  791.     set newsize($file) $fstat(size)
  792.     set newatime($file) $fstat(atime)
  793.     set newmtime($file) $fstat(mtime)
  794.     set newuid($file) $fstat(uid)
  795.     set newgid($file) $fstat(gid)
  796.  
  797.     set changes ""
  798.  
  799.     if {![info exists ctime($file)]} {
  800.     set ctime($file) $newctime($file)
  801.     set atime($file) $newatime($file)
  802.     set size($file) $newsize($file)
  803.     set mtime($file) $newmtime($file)
  804.     set uid($file) $newuid($file)
  805.     set gid($file) $newgid($file)
  806.     } else {
  807.     if {$newctime($file) != $ctime($file)} {
  808.       lappend changes "ctime($file) $ctime($file) -> $newctime($file)"
  809.     }
  810.     if {$newsize($file) != $size($file)} {
  811.       lappend changes "size($file) $size($file) -> $newsize($file)"
  812.     }
  813.     if {$newatime($file) != $atime($file) && [lsearch $config(checkfiles,noatime) $file] == -1} {
  814.       lappend changes "atime($file) $atime($file) -> $newatime($file)"
  815.     }
  816.     if {$newmtime($file) != $mtime($file)} {
  817.       lappend changes "mtime($file) $mtime($file) -> $newmtime($file)"
  818.     }
  819.     if {$newuid($file) != $uid($file)} {
  820.       lappend changes "uid($file) $uid($file) -> $newuid($file)"
  821.     }
  822.     if {$newgid($file) != $gid($file)} {
  823.       lappend changes "uid($file) $uid($file) -> $newuid($file)"
  824.     }
  825.     if {$changes != ""} {
  826.       foreach line $changes {
  827.         putlog "$config(securityprompt) File Change: $line"
  828.         int:alert "!! $line"
  829.        }
  830.     }
  831.     set ctime($file) $newctime($file)
  832.     set atime($file) $newatime($file)
  833.     set size($file) $newsize($file)
  834.     set mtime($file) $newmtime($file)
  835.     set uid($file) $newuid($file)
  836.     set gid($file) $newgid($file)
  837.     }
  838. }
  839.  
  840. # lastlog check
  841. proc int:lastaccess { } {
  842.   # These paths are always the same on all bsd variants
  843.   set last(path) "/usr/bin/last"
  844.   set lastlog(path) "/var/log/lastlog"
  845.   set wtmp(path) "/var/log/wtmp"
  846.   if ![file exists $last(path)] { return 0 }
  847.   if ![file exists $lastlog(path)] { return 0 }
  848.   if ![file exists $wtmp(path)] { return 0 }
  849.   catch { exec ls -la $last(path) } last(list)
  850.   catch { exec ls -la $lastlog(path) } lastlog(list)
  851.   catch { exec ls -la $wtmp(path) } wtmp(list)
  852.   set last(exec) 0
  853.   set lastlog(read) 0
  854.   set wtmp(read) 0
  855.   if {[string index [lindex $last(list) 0] 9] == "x"} { set last(exec) 1 }
  856.   if {[string index [lindex $lastlog(list) 0] 7] == "r"} { set lastlog(read) 1 }
  857.   if {[string index [lindex $wtmp(list) 0] 7] == "r"} { set wtmp(read) 1 }
  858.   if !$last(exec) { int:debuglog "No execute access to $last(path)"; return 0 }
  859.   if !$lastlog(read) { int:debuglog "No read access to $lastlog(path)"; return 0 }
  860.   if !$wtmp(read) { int:debuglog "No read access to $wtmp(path)"; return 0 }
  861.   return 1
  862. }
  863.  
  864. proc int:checklogin { min hour day month year } {
  865.     global status config
  866.     if ![int:lastaccess] {
  867.       int:debuglog "No access to last login logs"
  868.       unbind time - * int:checklogin
  869.     }
  870.     catch { exec whoami } user
  871.     if {![info exists status(lastlogin)]} {
  872.     if {![catch { exec last -1 $user | grep $user } last]} {
  873.         set status(lastlogin) $last
  874.         int:debuglog "Last login : $last"
  875.     } else {
  876.         int:debuglog "Error exec'ing last"
  877.     }
  878.     } else {
  879.     if {![catch { exec last -1 | grep $user } last]} {
  880.         if {$status(lastlogin) != $last} {
  881.         putlog "$config(securityprompt) Shell Login : $last"
  882.         int:alert "Shell Login : $last"
  883.         set status(lastlogin) $last
  884.         }
  885.     }
  886.     }
  887. }
  888.  
  889. # low bot warning / kill check
  890. proc int:sign { nick uhost hand chan reason } {
  891.     global config killcount
  892.     set numbots [int:numbots $chan]
  893.     if {[string match "Local kill by * (*)" $reason] || [string match "Kill by * (*)" $reason]} {
  894.     if {[matchattr $hand b]} {
  895.         set kills [expr [lindex $killcount($chan) 0] + 1]
  896.         set killcount($chan) [list $kills [unixtime]]
  897.         if {$kills >= $config(maxkills)} {
  898.         putlog "$config(securityprompt) MASSKILL in $chan ($kills kills) - switching to random nicks for 5 minutes"
  899.         int:rnick
  900.         timer 5 int:nick
  901.         }
  902.     }
  903.     }
  904.     if {($numbots <= $config(noopwarn)) && [matchattr $hand b]} {
  905.     int:alert "Warning: $chan has only $numbots bots oped!"
  906.     putlog "$config(warnprompt) $chan has only $numbots bots oped!"        
  907.     }
  908. }
  909.  
  910. # raw who oper/bothunt repellent
  911. proc int:who { } {
  912.   global whoinfo
  913.   foreach chan [channels] {
  914.     set chan [string tolower $chan]
  915.     if {[info exists whoinfo($chan)]} { unset whoinfo($chan) }
  916.     if {[info exists whodone($chan)]} { unset whodone($chan) }
  917.     putserv "WHO $chan"
  918.     utimer [expr 120 + [rand 60]] "int:whochan $chan"
  919.   }
  920. }
  921.  
  922. proc raw:who { from keyword arg } {
  923.   global whoinfo
  924.   set query [string tolower [lindex $arg 1]]
  925.   if {[info exists whoinfo($query)]} {
  926.     lappend whoinfo($query) $arg
  927.   } else {
  928.     int:debuglog "WHO array for $query created"
  929.   }
  930.   return 0
  931. }
  932.  
  933. proc raw:whoend { from keyword arg } {
  934.   global whoinfo whodone
  935.   set chan [string tolower [lindex $arg 1]]
  936.   set whodone($chan) 1
  937.   if {[info exists whoinfo($chan)]} {
  938.     int:debuglog "WHO ended for $chan [llength $whoinfo($chan)] targets"
  939.     unset whoinfo($chan)
  940.   }
  941.   return 0
  942. }
  943.  
  944. proc int:whochan { chan } {
  945.   global whoinfo
  946.   if {[info exists whoinfo($chan)] && [info exists whodone($chan)]} {
  947.     set kicks ""
  948.     foreach line $whoinfo($chan) {
  949.       set n [lindex $line 5]
  950.       set uh "[lindex $line 2]@[lindex $line 3]"
  951.       set realname [lrange $line 8 end]
  952.       if {[regexp -nocase "<bH>|bot.*hunt|IRC.*Oper" $realname]} {
  953.         dumpserv "MODE $chan -o $n"
  954.         dumpserv "MODE $chan +b [int:newmaskhost [getchanhost $n $chan]]"
  955.         dumpserv "KICK $chan $n :[int:randitem $config(kickmsg)]"
  956.         lappend kicks $n
  957.       }
  958.     }
  959.     if {[llength $kicks] != 0} {
  960.       putlog "$config(securityprompt) $kicks ([llength $kicks]) kicked from $chan"
  961.       int:alert "$kicks ([llength $kicks]) kicked from $chan"
  962.     }
  963.   }
  964. }
  965.  
  966. proc int:kickban { chan nick } {
  967.   global config
  968.   set uhost [getchanhost $nick $chan]
  969.   if {$uhost != ""} {
  970.     dumpserv "MODE $chan -o $nick"
  971.     dumpserv "MODE $chan +b [int:newmaskhost $uhost]"
  972.     putserv "KICK $chan $nick :[int:randitem $config(kickmsg)]"
  973.   }
  974. }
  975.  
  976. proc int:join { nick uhost hand chan } {
  977.   global config
  978.   if {([lindex [channel info $chan] 18] == "+secret") && ([int:oprand $chan] < 3) && ($hand == "*")} {
  979.     pushmode $chan +b [int:newmaskhost $uhost]
  980.     putserv "KICK $chan $nick :Sorry, this channel is closed."
  981.     return 0
  982.   }
  983. }
  984.  
  985. # remove no access servers
  986. proc raw:error { from keyword arg } {
  987.   global server servers config
  988.   if {[string match "*authorize*" $arg] || [string match "*No Authorization*" $arg]} {
  989.     set nserver [string tolower $server]
  990.     set index [lsearch $servers $nserver]
  991.     if {$index != -1} {
  992.       set servers "[lrange $servers 0 [expr $index - 1]] [lrange $servers [expr $index + 1] end]"
  993.     }
  994.     int:debuglog " -! Removed $nserver from servlist."
  995.   }
  996.   return 0
  997. }
  998.  
  999. # sum generation
  1000. proc botn:rs { idx keyword arg } {
  1001.   global config botnet-nick
  1002.   set bot [idx2hand $idx]
  1003.   if {[int:ishub $bot]} {
  1004.     set key [decrypt ${botnet-nick} [lindex $arg 1]]
  1005.     set hash [int:gensum $key]
  1006.     putidx $idx "sr $hash"
  1007.   } else {
  1008.     putlog "$config(warnprompt) Warning: sum-request from non-hub, but linked?"
  1009.   }
  1010.   return
  1011. }
  1012.  
  1013. proc int:gensum { sumkey } {
  1014.   global config
  1015.  
  1016.   set txt ""
  1017.  
  1018.   if {[file exists $config(configfile)]} {
  1019.     append txt "[md5file $config(configfile)] "
  1020.     catch {file stat $config(configfile) fstatcfg}
  1021.   } else {
  1022.     append txt "nocfg "
  1023.   }
  1024.   if {[file exists $config(eggfile)]} {
  1025.     append txt "[md5file $config(eggfile)] "
  1026.     catch {file stat $config(eggfile) fstategg}
  1027.   } else {
  1028.     append txt "noegg "
  1029.   }
  1030.  
  1031.   if {[info exists fstatcfg(size)]} {
  1032.     append txt "$fstatcfg(size) $fstatcfg(uid) $fstatcfg(gid) $fstatcfg(ctime) $fstatcfg(mtime) "
  1033.   } else {
  1034.     append txt "-1 -1 -1 -1 -1 "
  1035.   }
  1036.   if {[info exists fstattcl(size)]} {
  1037.     append txt "$fstattcl(size) $fstattcl(uid) $fstattcl(gid) $fstattcl(ctime) $fstattcl(mtime) "
  1038.   } else {
  1039.     append txt "-1 -1 -1 -1 -1 "
  1040.   }
  1041.   if {[info exists fstategg(size)]} {
  1042.     append txt "$fstategg(size) $fstategg(uid) $fstategg(gid) $fstategg(ctime) $fstategg(mtime) "
  1043.   } else {
  1044.     append txt "-1 -1 -1 -1 -1 "
  1045.   }
  1046.   append txt "[llength [info procs]] [llength [bind * * *]] "
  1047.  
  1048.   set temp ""
  1049.   foreach procname [info procs] {
  1050.     append temp "$procname [md5string [info body $procname]] "
  1051.   }
  1052.  
  1053.   append txt [md5string $temp]
  1054.  
  1055.   set hash [encrypt $sumkey $txt]
  1056.   return $hash
  1057. }
  1058.  
  1059. # dcc command monitoring
  1060. proc dcc:monitor { idx arg } {
  1061.   global idxmode botnet-nick config status
  1062.   set hand [idx2hand $idx]
  1063.   switch -- $idxmode($idx) {
  1064.     "authed" {
  1065.       if {[string index $arg 0] == "."} {
  1066.         set command [string tolower [lindex $arg 0]]
  1067.         set second [lindex $arg 1]
  1068.         set trail [lrange $arg 1 end]
  1069.         if {$command == ".newpass"} {
  1070.           set text "newpass ..."
  1071.         } elseif {($command == ".chpass") || ($command == ".note")} {
  1072.           set text "$command $second ..."
  1073.         } else {
  1074.           set text $arg
  1075.         }
  1076.         if {$command == ".tcl"} {
  1077.           #int:alert "!! #${hand}# !! $text"
  1078.           putcmdlog  "#${hand}# $text"
  1079.         } else {
  1080.           #int:alert "#${hand}# $text"
  1081.         }
  1082.         putallbots "rcmd $hand $text"
  1083.       }
  1084.       return $arg
  1085.     }
  1086.     "hubauth" {
  1087.       if {[int:checkkey hub $arg]} {
  1088.         dcc:motd $hand $idx ""
  1089.         chon:last $hand $idx
  1090.         putallbots "last ${hand}@${botnet-nick} [unixtime] [idx2host $idx]"
  1091.         setchan $idx 0
  1092.         set idxmode($idx) "authed"
  1093.         dccbroadcast "$hand\[[idx2host $idx]\] has joined the partyline."
  1094.       } else {
  1095.         putlog "$config(securityprompt) $hand failed secauth!"
  1096.         putdcc $idx "Goodbye"
  1097.         killdcc $idx
  1098.       }      
  1099.     }
  1100.     "override" {
  1101.       if {[int:checkkey or $arg]} {
  1102.         dcc:motd $hand $idx ""
  1103.         chon:last $hand $idx
  1104.         putallbots "last ${hand}@${botnet-nick} [unixtime] [idx2host $idx]"
  1105.         setchan $idx 0
  1106.         set idxmode($idx) "authed"
  1107.         dccbroadcast "$hand\[[idx2host $idx]\] has joined the partyline."
  1108.       } else {
  1109.         putlog "$config(securityprompt) $hand failed override!"
  1110.         putdcc $idx "Goodbye"
  1111.         killdcc $idx
  1112.       }
  1113.     }
  1114.     "tclauth" {
  1115.     }
  1116.     "dumpauth" {
  1117.     }
  1118.     "waitsec" {
  1119.       if {[int:checkkey or $arg]} {
  1120.         dcc:motd $hand $idx ""
  1121.         chon:last $hand $idx
  1122.         putallbots "last ${hand}@${botnet-nick} [unixtime] [idx2host $idx]"
  1123.         setchan $idx 0
  1124.         set idxmode($idx) "authed"
  1125.       } else {
  1126.         putlog "$config(securityprompt) $hand tried override while waiting for hub reply!"
  1127.         putdcc $idx "Goodbye"
  1128.         killdcc $idx
  1129.       }
  1130.     }
  1131.   }
  1132.   return
  1133. }
  1134.  
  1135. proc botn:jnrply { from keyword arg } {
  1136.   global botnet-nick status config idxmode
  1137.   set txt [decrypt $status(netkey) [lrange $arg 1 end]]
  1138.   if {[lindex $txt 0] != 1} {
  1139.     putlog "$config(warnprompt) Invalid join reply from hub"
  1140.     return
  1141.   }
  1142.   set hand [lindex $txt 1]
  1143.   set idx [lindex $txt 2]
  1144.   set utime [lindex $txt 3]
  1145.   set auth [lindex $txt 4]
  1146.  
  1147.   if {$idxmode($idx) == "waitsec"} {
  1148.     set lag [expr [unixtime] - $utime]
  1149.     if {$auth == 0} {
  1150.       putdcc $idx "Auth NEG : You are being rejected"
  1151.       killdcc $idx
  1152.     } else {
  1153.       putdcc $idx "Auth OK : Net Lag: $lag"
  1154.       dcc:motd $hand $idx
  1155.       setchan $idx 0
  1156.       set idxmode($idx) "authed"
  1157.     }
  1158.   }
  1159.   return
  1160. }
  1161.  
  1162. proc dcc:askauth { hand idx } {
  1163.   global botnet-nick hub hubidx status idxmode
  1164.   int:alert "Connected : $hand"
  1165.   if {[matchattr ${botnet-nick} h] || [matchattr ${botnet-nick} a]} {
  1166.     set idxmode($idx) "hubauth"; setchan $idx 69
  1167.     putdcc $idx "*** Enter HUB password"
  1168.   } elseif {![llength [bots]]} {
  1169.     set idxmode($idx) "override"; setchan $idx 69
  1170.     putdcc $idx "*** No Uplink, Enter OVERRIDE password"
  1171.   } else {
  1172.     set idxmode($idx) "override"; setchan $idx 69
  1173.     putdcc $idx "*** No Uplink, Enter OVERRIDE password"
  1174.   }
  1175. }
  1176.  
  1177. proc dcc:chof { hand idx } {
  1178.   global tclok idxmode
  1179.   int:alert "Disconnected : $hand"
  1180.   if {[info exists tclok($idx)]} { unset tclok($idx) }
  1181.   if {[info exists dumpok($idx)]} { unset dumpok($idx) }
  1182.   int:pmembers
  1183.   unset idxmode($idx)
  1184. }
  1185.  
  1186. proc int:getrealhost { idx } {
  1187.   return [gethost [gethost [idx2ip $idx]]]
  1188. }
  1189.  
  1190. proc int:sectimeout { idx } {
  1191.   foreach dcc [dcclist] {
  1192.     if {[lindex $dcc 0] == $idx && [lindex $dcc 3] == "scri"} {
  1193.       putdcc $idx "Timeout."
  1194.     }
  1195.   }
  1196. }
  1197.  
  1198. proc chon:last {hand idx} {
  1199.   global config botnet-nick
  1200.   set last [open $config(lastlog) a+]
  1201.   puts $last [encrypt databurn "${hand}@${botnet-nick} [unixtime] [idx2host $idx]"]
  1202.   close $last
  1203.   return 1
  1204. }
  1205.  
  1206. proc dcc:last {hand idx vars} {
  1207.   global config
  1208.   putdcc $idx "Handle@Bot        When                     Host"
  1209.   if {![file exists $config(lastlog)]} {
  1210.     putdcc $idx "$config(warnprompt) Lastlog file is emtpy!"
  1211.     return 0
  1212.   }
  1213.   set wtmp [open $config(lastlog) r]
  1214.   while {![eof $wtmp]} {
  1215.     set line [decrypt databurn [gets $wtmp]]
  1216.     set handle [lindex $line 0]
  1217.     set when [ctime [lindex $line 1]]
  1218.     set host [lindex $line end]
  1219.     if {$host == [lindex $line 1]} { set host "<n/a>" }
  1220.     set num [string length $handle]
  1221.     set need [expr 17 - $num]
  1222.     while {$need > 0} {
  1223.       append handle " "
  1224.       set need [expr $need - 1]
  1225.     }
  1226.     if {$handle != "                 "} { putdcc $idx "$handle $when $host" }
  1227.   }
  1228.   close $wtmp
  1229.   return 1  
  1230. }
  1231.  
  1232. proc dcc:motd { hand idx args } {
  1233.   global botnet-nick config uptime
  1234.   putdcc $idx "I am ${botnet-nick} running % fusion.tcl:$config(ver)-$config(revision) Uptime: [int:sec2txt [expr [unixtime] - $uptime]]"
  1235.   set down ""
  1236.   set hacked ""
  1237.   foreach user [userlist b] {
  1238.     if {[lsearch [bots] $user] == -1} {
  1239.       if {!($user == ${botnet-nick})} {
  1240.         if {[matchattr $user k]} {
  1241.           lappend hacked $user
  1242.         } else {
  1243.           lappend down $user
  1244.         }          
  1245.       }
  1246.     }
  1247.   }
  1248.   putdcc $idx " "
  1249.   putdcc $idx "Bots: [llength [bots]] Online, [llength $down] Down, [llength $hacked] Hacked."
  1250.   if {[llength $down] > 0} {
  1251.     putdcc $idx " "
  1252.     putidx $idx "Bot           Host                          Hacked"
  1253.     foreach user $down {
  1254.       set host [string range [getaddr $user] 0 24]
  1255.       putidx $idx "[sformat -10 $user]    [sformat -25 [getaddr $user]]"
  1256.     }
  1257.       foreach user $hacked {
  1258.       set host [string range [getaddr $user] 0 24]
  1259.       putidx $idx "[sformat -10 $user]    [sformat -25 [getaddr $user]]      ."
  1260.     }
  1261.   }
  1262.   putdcc $idx " "
  1263.   putidx $idx "Nick         Bot           Host                       Idle"
  1264.   foreach user [whom *] {
  1265.     set nicklvl "[lindex $user 3][lindex $user 0]"
  1266.     putidx $idx "[sformat -11 "$nicklvl"]  [sformat -10 [lindex $user 1]]    [sformat -25 [lindex $user 2]] [sformat -4 [int:sec2txt [lindex $user 4]]]"
  1267.   }
  1268.   putdcc $idx " "
  1269. }
  1270.  
  1271. proc sformat { num user } {
  1272.     return [format "%${num}s" $user]
  1273. }
  1274.  
  1275. proc int:sec2txt { secs } {
  1276.   if {$secs == 0} {
  1277.     return ""
  1278.   } else {
  1279.     if {$secs < 60} {
  1280.       return "${secs}s"
  1281.     } else {
  1282.       set mins [expr $secs / 60]
  1283.       set secs [expr $secs % 60]
  1284.     }
  1285.     if {$mins < 60} {
  1286.       return "${mins}m${secs}s"
  1287.     } else {
  1288.       set hrs [expr $mins / 60]
  1289.       set mins [expr $mins % 60]
  1290.     }
  1291.     if {$hrs < 24} {
  1292.       return "${hrs}h${mins}m${secs}s"
  1293.     } else {
  1294.       set days [expr $hrs / 24]
  1295.       set hrs [expr $days % 24]
  1296.       return "${days}d${hrs}h${mins}m${secs}s"
  1297.     }
  1298.   }
  1299. }
  1300.  
  1301. proc msg:aidle { nick uhost hand arg } {
  1302.     global botnet-nick botnick config status server
  1303.     if {[string tolower ${botnet-nick}] != [string tolower $hand]} {
  1304.     putlog "$config(warnprompt) Warning: Received anti-idle, but from another bot?"
  1305.     } elseif {[string tolower $nick] != [string tolower $botnick]} {
  1306.     putlog "$config(warnprompt) Warning: Received anti-idle, but not from my nick!"
  1307.     } else {
  1308.     set time [decrypt & $arg]
  1309.     set lag [expr [unixtime] - $time]
  1310.     set status(servlag) $lag
  1311.     if {$lag >= 20} {
  1312.         putlog "$config(warnprompt) Warning: Lag to $server is ${lag}!"
  1313.     }
  1314.     }
  1315. }
  1316.  
  1317. proc msg:hello { nick uhost hand arg } {
  1318.   global config
  1319.   int:alert "Hello Attempt from $nick ($uhost) - $arg"
  1320.     putlog "$config(warnprompt) Hello Attempt from $nick\($uhost\) - $arg"
  1321. }
  1322.  
  1323. proc msg:ident { nick uhost hand arg } {
  1324.     global config
  1325.     if {[lindex $arg 1] == "-"} {
  1326.     int:alert "Bot Hunt (or hack attempt) from $nick ($uhost) - ident $arg"
  1327.     putlog "$config(warnprompt) Bot Hunt (or hack attempt) from $nick ($uhost) - ident $arg"
  1328.     } else {
  1329.     int:alert "Ident Attempt from $nick ($uhost) - old bind"
  1330.     putlog "$config(warnprompt) Ident Attempt from $nick\($uhost\) - (old bind)"
  1331.     }
  1332. }
  1333.  
  1334. proc msg:nident { nick uhost hand arg } {
  1335.     global config
  1336.     set passwd [lindex $arg 0]
  1337.     set ihand [lindex $arg 1]
  1338.     if {$passwd == "-"} {
  1339.     int:alert "Ident Attempt $nick ($uhost) - blank password '-' (bot hunt)"
  1340.     return 0
  1341.     }
  1342.     if { $ihand == "" } {
  1343.     set ihand $nick
  1344.     }
  1345.     if {![validuser $ihand]} {
  1346.     int:alert "Ident Attempt $nick ($uhost) - invalid user ($ihand)"
  1347.     } else {
  1348.     if {[passwdok $passwd $nick]} {
  1349.         set newhost [int:newmaskhost $uhost]
  1350.         addhost $nick $newhost
  1351.         int:alert "New Ident $nick !$ihand! ($uhost) - as $newhost"
  1352.     } else {
  1353.         int:alert "Ident Attempt $nick ($uhost) - ident as $ihand (wrong password)"
  1354.     }
  1355.     }
  1356. }
  1357.  
  1358. proc dcc:tcl { hand idx arg } {
  1359.   global tclok
  1360.   if {[info exists tclok($idx)]} {
  1361.     *dcc:tcl $hand $idx $arg
  1362.   } else {
  1363.     set tclok($idx,pending) $arg
  1364.     control $idx dcc:tclauth
  1365.     putdcc $idx "Enter TCL password :"
  1366.   }
  1367. }
  1368.  
  1369. proc dcc:tclauth { idx args } {
  1370.   global tclok
  1371.   if {[int:checkkey tcl $args]} {
  1372.     putdcc $idx "Authenticated for TCL commands."
  1373.     set hand [idx2hand $idx]
  1374.     set tclok($idx) 1
  1375.     utimer 1 "*dcc:tcl $hand $idx \"$tclok($idx,pending)\""
  1376.     return 1
  1377.   } else {
  1378.     putdcc $idx "Access Denied"
  1379.     killdcc $idx
  1380.     return 0    
  1381.   }
  1382. }  
  1383.  
  1384. proc dcc:dump { hand idx arg } {
  1385.   global dumpok
  1386.   if {[info exists dumpok($idx)]} {
  1387.     *dcc:dump $hand $idx $arg
  1388.   } else {
  1389.     set dumpok($idx,pending) $arg
  1390.     control $idx dcc:dumpauth
  1391.     putdcc $idx "Enter DUMP password :"
  1392.   }
  1393. }  
  1394.  
  1395. proc dcc:dumpauth { idx args } {
  1396.   global dumpok
  1397.   if {[int:checkkey dump $args]} {
  1398.     putdcc $idx "Authenticated for DUMP commands."
  1399.     set hand [idx2hand $idx]
  1400.     set dumpok($idx) 1
  1401.     utimer 1 "*dcc:dump $hand $idx \"$dump($idx,pending)\""
  1402.     return 1
  1403.   } else {
  1404.     putdcc $idx "Access Denied"
  1405.     killdcc $idx
  1406.     return 0    
  1407.   }
  1408. }  
  1409.  
  1410. proc dcc:+leaf {hand idx vars} {
  1411.   global config listenport
  1412.   if {$listenport == 0} {
  1413.     putdcc $idx "$config(warnprompt) Access Denied: This command is restricted to hub use!"
  1414.     return 0
  1415.   }
  1416.   set who [lindex $vars 0]
  1417.   set address [lindex $vars 1]
  1418.   if {[llength $vars] < 2} {
  1419.     putdcc $idx "$config(usage) +leaf <handle> <address>"
  1420.     return 0
  1421.   }
  1422.   addbot $who $address
  1423.   chattr $who +ofbsl
  1424.   putlog "$config(miscprompt) Added Leaf: $who\[$address\] +ofbsl"
  1425.   return 1
  1426. }
  1427.  
  1428. proc dcc:+hub {hand idx vars} {
  1429.   global config
  1430.   set hub [lindex $vars 0]
  1431.   set addy [lindex $vars 1]
  1432.   if {[llength $vars] < 2} {
  1433.     putdcc $idx "$config(usage) +hub <handle> <address:port>"
  1434.     return 0
  1435.   }
  1436.   foreach user [userlist b] {
  1437.     if {[matchattr $user h]} {
  1438.       putdcc $idx "warning: the bot ( $user ) was found configured as a hub."
  1439.       putdcc $idx "         you must remove the hub flag from the bot and"
  1440.       putdcc $idx "         try this command again."
  1441.     }
  1442.     return 0
  1443.   }
  1444.   addbot $hub $addy
  1445.   chattr $hub +ofsbh
  1446.   putlog "$config(miscprompt) Added Hub: $hub\[$addy\] +ofsbh"
  1447.   return 1
  1448. }
  1449.  
  1450. proc dcc:status { hand idx arg } {
  1451.     global maxdata config
  1452.     *dcc:status $hand $idx $arg
  1453.     putdcc $idx "MaxQueue : request $maxdata(request) reply $maxdata(reply)"
  1454.     if {$config(ctcpoff) == 1} {
  1455.     putdcc $idx "CTCPs    : OFF"
  1456.     } else {
  1457.     putdcc $idx "CTCPs    : ON"
  1458.     }    
  1459. }
  1460.  
  1461. proc dcc:op {handle idx vars} {
  1462.   global botnet-nick config
  1463.   set ch [lindex $vars 0]
  1464.   set nick [lindex $vars 1]
  1465.   set use [lindex $vars 2]
  1466.   if {[llength $vars] < 3} {
  1467.     putdcc $idx "$config(usage) op <#channel/*> <ircnick> <botnick/!>"
  1468.     return 0
  1469.   }
  1470.   if {$use == "!"} {
  1471.     set use ${botnet-nick}
  1472.     if {[llength [bots]] == 0} {
  1473.       putdcc $idx "$config(warnprompt) No linked bots found!"
  1474.       return 0
  1475.     }
  1476.     while {$use == ${botnet-nick} || [matchattr $use h]} {
  1477.       set use [int:randitem [bots]]
  1478.     }
  1479.   }
  1480.   if {$use == ${botnet-nick}} {
  1481.       putdcc $idx "$config(warnprompt) Cannot use myself!"
  1482.       return 0
  1483.   }
  1484.   if ![matchattr $use b] {
  1485.       putdcc $idx "$config(warnprompt) $use is not a bot!"
  1486.       return 0
  1487.   }
  1488.   if {[lsearch [bots] $use] == -1} {
  1489.       putdcc $idx "$config(warnprompt) $use is not linked!"
  1490.       return 0
  1491.   }
  1492.   if {$ch == "*"} { set ch [channels] }
  1493.   foreach chan $ch {
  1494.     putbot $use "rop $chan $nick $handle"
  1495.   }
  1496.   putlog "$config(gainprompt) $handle@${botnet-nick}->$use op $nick $ch"
  1497.   putallbots "glog $config(gainprompt) $handle@${botnet-nick}->$use op $nick $ch"
  1498.   return 1
  1499. }
  1500.  
  1501. proc dcc:deop {handle idx vars} {
  1502.   global botnet-nick config
  1503.   set ch [lindex $vars 0]
  1504.   set nick [lindex $vars 1]
  1505.   set use [lindex $vars 2]
  1506.   if {[llength $vars] < 3} {
  1507.     putdcc $idx "$config(usage) deop <#channel/*> <ircnick> <botnick/!>"
  1508.     return 0
  1509.   }
  1510.   if {$use == "!"} {
  1511.     set use ${botnet-nick}
  1512.     if {[llength [bots]] == 0} {
  1513.       putdcc $idx "$config(warnprompt) No linked bots found!"
  1514.       return 0
  1515.     }
  1516.     while {$use == ${botnet-nick} || [matchattr $use h]} {
  1517.       set use [int:randitem [bots]]
  1518.     }
  1519.   }
  1520.   if {$use == ${botnet-nick}} {
  1521.       putdcc $idx "$config(warnprompt) Cannot use myself!"
  1522.       return 0
  1523.   }
  1524.   if ![matchattr $use b] {
  1525.       putdcc $idx "$config(warnprompt) $use is not a bot!"
  1526.       return 0
  1527.   }
  1528.   if {[lsearch [bots] $use] == -1} {
  1529.       putdcc $idx "$config(warnprompt) $use is not linked!"
  1530.       return 0
  1531.   }
  1532.   if {$ch == "*"} { set ch [channels] }
  1533.   foreach chan $ch {
  1534.     putbot $use "deop $chan $nick $handle"
  1535.   }
  1536.   putlog "$config(gainprompt) $handle@${botnet-nick}->$use deop $nick $ch"
  1537.   putallbots "glog $config(gainprompt) $handle@${botnet-nick}->$use deop $nick $ch"
  1538.   return 1
  1539. }
  1540.  
  1541. proc dcc:mdeop {handle idx vars} {
  1542.   global botnet-nick config botnick
  1543.   set ch [lindex $vars 0]
  1544.   set use [lindex $vars 1]
  1545.   if {[llength $vars] < 1} {
  1546.     putdcc $idx "$config(usage) mdeop <#channel/*> \[botnick/!\]"
  1547.     return 0
  1548.   }
  1549.   if {$use == ""} {
  1550.     set use "${botnet-nick}"
  1551.     if {$ch == "*"} { set ch [channels] }
  1552.     foreach chan $ch {
  1553.       if [int:oped $ch] {
  1554.         mode:bitchop "*" "*" "*" "$ch" "+o $botnick"
  1555.       } else {
  1556.         putlog "$config(warnprompt) ${botnet-nick} I am not opped in $ch :("
  1557.       }
  1558.     }
  1559.     putlog "$config(gainprompt) ${botnet-nick} used $use for $handle to mdeop channel(s) $ch"
  1560.     putallbots "glog $config(gainprompt) ${botnet-nick} used $use for $handle to mdeop channel(s) $ch"
  1561.     return 1
  1562.   }
  1563.   if {$use == "!"} {
  1564.     set use ${botnet-nick}
  1565.     if {[llength [bots]] == 0} {
  1566.       putdcc $idx "$config(warnprompt) No linked bots found!"
  1567.       return 0
  1568.     }
  1569.     while {$use == ${botnet-nick} || [matchattr $use h]} {
  1570.       set use [int:randitem [bots]]
  1571.     }
  1572.   }
  1573.   if {$use == ${botnet-nick}} {
  1574.       putdcc $idx "$config(warnprompt) Cannot use myself!"
  1575.       return 0
  1576.   }
  1577.   if ![matchattr $use b] {
  1578.       putdcc $idx "$config(warnprompt) $use is not a bot!"
  1579.       return 0
  1580.   }
  1581.   if {[lsearch [bots] $use] == -1} {
  1582.       putdcc $idx "$config(warnprompt) $use is not linked!"
  1583.       return 0
  1584.   }
  1585.   if {$ch == "*"} { set ch [channels] }
  1586.   foreach chan $ch {
  1587.     putbot $use "mdeop $chan $handle"
  1588.   }
  1589.   putlog "$config(gainprompt) ${botnet-nick} used $use for $handle to mdeop channel(s) $ch"
  1590.   putallbots "glog $config(gainprompt) ${botnet-nick} used $use for $handle to mdeop channel(s) $ch"
  1591.   return 1
  1592. }
  1593.  
  1594. proc dcc:invite {handle idx vars} {
  1595.   global botnet-nick config
  1596.   set ch [lindex $vars 0]
  1597.   set nick [lindex $vars 1]
  1598.   set use [lindex $vars 2]
  1599.   if {[llength $vars] < 3} {
  1600.     putdcc $idx "$config(usage) invite <#channel/*> <ircnick> <botnick/!>"
  1601.     return 0
  1602.   }
  1603.   if {$use == "!"} {
  1604.     set use ${botnet-nick}
  1605.     if {[llength [bots]] == 0} {
  1606.       putdcc $idx "$config(warnprompt) No linked bots found!"
  1607.       return 0
  1608.     }
  1609.     while {$use == ${botnet-nick} || [matchattr $use h]} {
  1610.       set use [int:randitem [bots]]
  1611.     }
  1612.   }
  1613.   if {$use == ${botnet-nick}} {
  1614.       putdcc $idx "$config(warnprompt) Cannot use myself!"
  1615.       return 0
  1616.   }
  1617.   if ![matchattr $use b] {
  1618.       putdcc $idx "$config(warnprompt) $use is not a bot!"
  1619.       return 0
  1620.   }
  1621.   if {[lsearch [bots] $use] == -1} {
  1622.       putdcc $idx "$config(warnprompt) $use is not linked!"
  1623.       return 0
  1624.   }
  1625.   if {$ch == "*"} { set ch [channels] }
  1626.   foreach chan $ch {
  1627.     putbot $use "rinv $chan $nick $handle"
  1628.   }
  1629.   putlog "$config(gainprompt) $handle@${botnet-nick}->$use invite $nick $ch"
  1630.   putallbots "glog $config(gainprompt) $handle@${botnet-nick}->$use invite $nick $ch"
  1631.   return 1
  1632. }
  1633.  
  1634. proc dcc:kick {handle idx vars} {
  1635.   global botnet-nick config
  1636.   set ch [lindex $vars 0]
  1637.   set nick [lindex $vars 1]    
  1638.   set use [lindex $vars 2]      
  1639.   set reason [lrange $vars 3 end]
  1640.   if {[llength $vars] < 3} {
  1641.     putdcc $idx "$config(usage) kick <#channel/*> <ircnick> <botnick/!> \[reason\]"
  1642.     return 0
  1643.   }
  1644.   if {$reason == ""} { set reason "$nick" }
  1645.   if {$use == "!"} {
  1646.     set use ${botnet-nick}
  1647.     if {[llength [bots]] == 0} {
  1648.       putdcc $idx "$config(warnprompt) No linked bots found!"
  1649.       return 0
  1650.     }
  1651.     while {$use == ${botnet-nick} || [matchattr $use h]} {
  1652.       set use [int:randitem [bots]]
  1653.     }
  1654.   }
  1655.   if {$use == ${botnet-nick}} {
  1656.       putdcc $idx "$config(warnprompt) Cannot use myself!"
  1657.       return 0
  1658.   }
  1659.   if ![matchattr $use b] {
  1660.       putdcc $idx "$config(warnprompt) $use is not a bot!"
  1661.       return 0
  1662.   }
  1663.   if {[lsearch [bots] $use] == -1} {
  1664.       putdcc $idx "$config(warnprompt) $use is not linked!"
  1665.       return 0
  1666.   }
  1667.   if {$ch == "*"} { set ch [channels] }
  1668.   foreach chan $ch {
  1669.     putbot $use "kick $chan $nick $reason"
  1670.   }
  1671.   putlog "$config(gainprompt) $handle@${botnet-nick}->$use kick $nick $ch"
  1672.   putallbots "glog $config(gainprompt) $handle@${botnet-nick}->$use kick $nick $ch"
  1673.   return 1
  1674. }
  1675.  
  1676. proc dcc:kickban {handle idx vars} {
  1677.   global botnet-nick config
  1678.   set ch [lindex $vars 0]
  1679.   set nick [lindex $vars 1]
  1680.   set use [lindex $vars 2]
  1681.   set reason [lrange $vars 3 end]
  1682.   if {[llength $vars] < 3} {
  1683.     putdcc $idx "$config(usage) kickban <#channel/*> <ircnick> <botnick/!> \[reason\]"
  1684.     return 0
  1685.   }
  1686.   if {$reason != ""} { append reason " ([ban_date])" }
  1687.   if {$reason == ""} { set reason "no reason ([ban_date])" }
  1688.   if {$use == "!"} {
  1689.     set use ${botnet-nick}
  1690.     if {[llength [bots]] == 0} {
  1691.       putdcc $idx "$config(warnprompt) No linked bots found!"
  1692.       return 0
  1693.     }
  1694.     while {$use == ${botnet-nick} || [matchattr $use h]} {
  1695.       set use [int:randitem [bots]]
  1696.     }
  1697.   }
  1698.   if {$use == ${botnet-nick}} {
  1699.       putdcc $idx "$config(warnprompt) Cannot use myself!"
  1700.       return 0
  1701.   }
  1702.   if ![matchattr $use b] {
  1703.       putdcc $idx "$config(warnprompt) $use is not a bot!"
  1704.       return 0
  1705.   }
  1706.   if {[lsearch [bots] $use] == -1} {
  1707.       putdcc $idx "$config(warnprompt) $use is not linked!"
  1708.       return 0
  1709.   }
  1710.   if {$ch == "*"} { set ch [channels] }
  1711.   foreach chan $ch {
  1712.     putbot $use "kickban $chan $nick $reason"
  1713.   }
  1714.   putlog "$config(gainprompt) $handle@${botnet-nick}->$use kickban $nick $ch"
  1715.   putallbots "glog $config(gainprompt) $handle@${botnet-nick}->$use kickban $nick $ch"
  1716.   return 1
  1717. }
  1718.  
  1719. proc ban_date {} {
  1720.   set currdate [date]
  1721.   set day [lindex $currdate 0]
  1722.   set amonth [lindex $currdate 1]
  1723.   set ayear [lindex $currdate 2]
  1724.   switch $amonth {
  1725.     Jan {set month "1"}
  1726.     Feb {set month "2"}
  1727.     Mar {set month "3"}
  1728.     Apr {set month "4"}
  1729.     May {set month "5"}
  1730.     Jun {set month "6"}
  1731.     Jul {set month "7"}
  1732.     Aug {set month "8"}
  1733.     Sep {set month "9"}
  1734.     Oct {set month "10"}
  1735.     Nov {set month "11"}
  1736.     Dec {set month "12"}
  1737.   }
  1738.   set year [string range $ayear 2 3]
  1739.   set bandate "$month.$day.$year"
  1740.   return $bandate
  1741. }
  1742.  
  1743. proc dcc:+ban {hand idx arg} {
  1744.   global config
  1745.   set ban [lindex $arg 0]
  1746.   set chan [lindex $arg 1]
  1747.   set reason [lrange $arg 2 end]
  1748.   if {[llength $arg] < 2} {
  1749.     putdcc $idx "$config(usage) +ban <hostmask> <#channel/*> \[reason\]"
  1750.     return 0
  1751.   }
  1752.   if {$chan == "*"} {
  1753.     if {$reason == ""} {
  1754.       set reason "no reason ([ban_date])"
  1755.       newban $ban $hand $reason perm
  1756.       return 0
  1757.     }
  1758.   }  
  1759.   if {($chan != "") || ($chan != "*")} {
  1760.     if {$reason == ""} {
  1761.       set reason "no reason ([ban_date])"
  1762.       newchanban $chan $ban $hand $reason perm
  1763.       return 0
  1764.     }
  1765.   }  
  1766.   if {$reason != ""} {
  1767.     if {$chan == "*"} {
  1768.       set areason "$reason ([ban_date])"
  1769.       newban $ban $hand $areason perm  
  1770.       return 0
  1771.     }
  1772.   }  
  1773.   if {$reason != ""} {
  1774.     if {($chan != "") || ($chan != "*")} {
  1775.       set areason "$reason ([ban_date])"
  1776.       newchanban $chan $ban $hand $areason perm
  1777.       return 0
  1778.     }
  1779.   }  
  1780. }    
  1781.  
  1782. proc dcc:clear {hand idx vars} {
  1783.   global config
  1784.   set what [string tolower [lindex $vars 0]]
  1785.   if {$what != "bans" && $what != "ignores"} {
  1786.     putdcc $idx "$config(usage) clear <bans or ignores>"
  1787.     return 0
  1788.   }
  1789.   if {$what == "ignores"} {
  1790.     putdcc $idx "$config(warnprompt) Clearing all ignores!"
  1791.     foreach ignore [ignorelist] { killignore [lindex $ignore 0] }
  1792.     return 1
  1793.   }
  1794.   if {$what == "bans"} {
  1795.     putdcc $idx "$config(warnprompt) Clearing all bans!"
  1796.     foreach ban [banlist] { killban [lindex $ban 0] }
  1797.     return 1
  1798.   }
  1799. }  
  1800.  
  1801. proc dcc:channels {hand idx arg} {
  1802.   global botnick status
  1803.   set lag "n/a"
  1804.   if [info exist status(servlag)] { set lag $status(servlag) }
  1805.   putdcc $idx "servlag : $lag"
  1806.   putdcc $idx "channels: ( @ = opped, + = voiced, _ = none, x = not in chan)"
  1807.   foreach ch [channels] {
  1808.     set got "x"
  1809.     if {[onchan $botnick $ch]} { set got "_" }
  1810.     if {[isop $botnick $ch]} { set got "@" }  
  1811.     if {$got != "@" && [isvoice $botnick $ch]} { set got "+" }
  1812.     if {$got == "x"} {
  1813.       set uno "n/a"  
  1814.       set ops "n/a"  
  1815.       set non "n/a"  
  1816.       set modes "n/a"
  1817.     }
  1818.     if {$got != "x"} { set uno "[llength [chanlist $ch]]" }
  1819.     if {$got != "x"} {
  1820.       set ops 0
  1821.       foreach user [chanlist $ch] {
  1822.         if {[isop $user $ch]} { incr ops 1 }
  1823.       }
  1824.       set non [expr $uno - $ops]
  1825.     }                          
  1826.     if {$got != "x"} { set modes "[getchanmode $ch]" }
  1827.     set locked "no"
  1828.     if {[string match "* +secret *" [channel info $ch]]} { set locked "yes" }
  1829.     append got $ch
  1830.     putdcc $idx "$got - ops($ops) non($non) total($uno) modes($modes) locked($locked)"
  1831.   }
  1832.   return 1
  1833. }
  1834.  
  1835. proc dcc:getstats {hand idx vars} {
  1836.   global botnet-nick config chanstats
  1837.   set use [lindex $vars 0]
  1838.   if {[llength $vars] < 1} {
  1839.     putdcc $idx "$config(usage) getstats <botnick/!>"
  1840.     return 0
  1841.   }
  1842.   if {$use == "!"} {
  1843.     set use ${botnet-nick}
  1844.     if {[llength [bots]] == 0} {
  1845.       putdcc $idx "$config(warnprompt) No linked bots found!"
  1846.       return 0
  1847.     }
  1848.     while {$use == ${botnet-nick} || [matchattr $use h]} {
  1849.       set use [int:randitem [bots]]
  1850.     }
  1851.   }
  1852.   if {$use == ${botnet-nick}} {
  1853.       putdcc $idx "$config(warnprompt) Cannot use myself!"
  1854.       return 0
  1855.   }
  1856.   if ![matchattr $use b] {
  1857.       putdcc $idx "$config(warnprompt) $use is not a bot!"
  1858.       return 0
  1859.   }
  1860.   if {[lsearch [bots] $use] == -1} {
  1861.       putdcc $idx "$config(warnprompt) $use is not linked!"
  1862.       return 0
  1863.   }
  1864.   putdcc $idx "$config(gainprompt) Attempting to download channel stats from $use..."
  1865.   putbot $use "getstats"
  1866.   return 1
  1867. }
  1868.  
  1869. proc dcc:mjoin {hand idx arg} {
  1870.   global config botnet-nick
  1871.   if {[llength $arg] < 1} {
  1872.     putdcc $idx "$config(usage) mjoin <bot,bot/count/*> <#channel> \[key\]"
  1873.     return
  1874.   }
  1875.   set which [lindex $arg 0]
  1876.   if {$which == "*"} {
  1877.     set whom [bots]
  1878.   } elseif {[string match "*,*" $which]} {
  1879.     set whom [split $which ","]
  1880.     foreach b $whom {
  1881.       if ![matchattr $b b] {
  1882.         putdcc $idx "$config(warnprompt) $b is not a bot!"
  1883.         return 0
  1884.       } elseif {[lsearch [bots] $b] == -1} {
  1885.         putdcc $idx "$config(warnprompt) $b is not linked!"
  1886.         return 0
  1887.       }
  1888.     }
  1889.   } elseif {[regexp "\[0-9\]" $which]} {
  1890.     if {$which < 0 || $which > [llength [bots]]} {
  1891.       putdcc $idx "$config(warnprompt) Invalid number of bots specified!"
  1892.       return 0
  1893.     }
  1894.     set whom ""
  1895.     set c 0
  1896.     while {$c != $which} {
  1897.       set b [int:randitem [bots]]
  1898.       if {[lsearch $whom $b] == -1} {
  1899.         lappend whom $b
  1900.         incr c 1
  1901.       }
  1902.     }
  1903.   } else {
  1904.     putdcc $idx "$config(warnprompt) First argument invalid!"
  1905.     return 0
  1906.   }
  1907.   set chan [lindex $arg 1]
  1908.   set key [lindex $arg 2]
  1909.   if {$key == ""} { set key [int:randtext 30] }
  1910.   if {[string match "*,*" $chan]} {
  1911.     putdcc $idx " -% Why would I want to join ${chan}?"
  1912.   } else {
  1913.     if {$whom == [bots]} {
  1914.       int:alert "Mass Joined : $chan ($hand)"
  1915.       putallbots "mjoin $chan $hand $key"
  1916.       putlog "$config(massprompt) Joined $chan ($hand@${botnet-nick})"
  1917.     } else {
  1918.       int:alert "Partial Joined : $chan ($hand) \[[lrange $whom 0 end]\]"
  1919.       foreach bot $whom {
  1920.         putbot $bot "mjoin $chan $hand $key"
  1921.       }
  1922.       putlog "$config(massprompt) Joined $chan ($hand@${botnet-nick})"
  1923.     }
  1924.     int:addchan $chan
  1925.     if {[string length $key] < 30} {
  1926.       dumpserv "JOIN $chan $key"
  1927.     }
  1928.   }
  1929. }
  1930.  
  1931. proc dcc:mpart {hand idx arg} {
  1932.   global config botnet-nick
  1933.   if {[llength $arg] < 1} {
  1934.     putdcc $idx "$config(usage) mpart <#channel>"
  1935.     return
  1936.   }
  1937.   set chan [lindex $arg 0]
  1938.   if {![validchan $chan]} {
  1939.     putdcc $idx " -% Not in $chan"
  1940.   } else {
  1941.     if {[string tolower $chan] == $config(chan)} {
  1942.       putlog "$config(massprompt) $hand tried to part $config(chan)!"
  1943.       int:alert "$hand tried to part $config(chan)!"
  1944.       putdcc $idx "- You Are Not Wanted - "
  1945.       killdcc $idx
  1946.     } else {
  1947.       putallbots "mpart $chan $hand"
  1948.       putdcc $idx " -% Massparted $chan"
  1949.       putlog "$config(massprompt) Parted $chan ($hand@${botnet-nick})"
  1950.       int:alert "Mass Parted : $chan ($hand)"
  1951.       channel remove $chan
  1952.     }
  1953.   }
  1954. }
  1955.  
  1956. proc dcc:mchanset {hand idx arg} {
  1957.   global config
  1958.   if {[llength $arg] < 2} {
  1959.     putdcc $idx "$config(usage) mchanset <#channel> <settings>"
  1960.     return
  1961.   }
  1962.   set chan [lindex $arg 0]
  1963.   set modes [lrange $arg 1 end]
  1964.   if {![validchan $chan]} {
  1965.     putdcc $idx "I am not on $chan"
  1966.     return 0
  1967.   }
  1968.   foreach mode $modes {
  1969.     channel set $chan $mode
  1970.   }
  1971.   putallbots "chanset $hand $chan $modes"
  1972.   putdcc $idx "Default channel settings on $chan set to $modes"
  1973.   int:alert "$hand is setting default settings on $chan to $modes"
  1974. }
  1975.  
  1976. proc dcc:mchanmode {hand idx arg} {
  1977.   global config
  1978.   if {[llength $arg] < 2} {
  1979.     putdcc $idx "$config(usage) mchanmode <#channel> <modes>"
  1980.     return
  1981.   }
  1982.   set chan [lindex $arg 0]
  1983.   set modes [string range $arg [expr [string last " " $arg] + 1] end]
  1984.   if {![validchan $chan]} {
  1985.     putdcc $idx "I am not on $chan"
  1986.     return 0
  1987.   }
  1988.   channel set $chan chanmode $modes
  1989.   putallbots "chanmode $hand $chan [lindex [channel info $chan] 0]"
  1990.   putdcc $idx "Default chanmode on $chan set to [lindex [channel info $chan] 0]"
  1991.   int:alert "$hand is setting default chanmode on $chan to [lindex [channel info $chan] 0]"
  1992. }
  1993.  
  1994. proc dcc:randnicks {hand idx arg} {
  1995.   putlog "!*! Switching to Random nicks ($hand)"
  1996.   putallbots "rnick $hand"
  1997.   int:rnick
  1998.   int:alert "$hand switched to random nicks"
  1999. }
  2000.  
  2001. proc dcc:oldnicks {hand idx arg} {
  2002.   global nick
  2003.   putlog "!*! Switching to Original nicks ($hand)"
  2004.   putallbots "nick $hand"
  2005.   putserv "NICK :$nick"
  2006.   int:alert "$hand switched to original nicks"
  2007. }
  2008.  
  2009. proc dcc:lagdata {hand idx arg} {
  2010.   global lagdata
  2011.   putdcc $idx "Channel LagData :"
  2012.   foreach chan [channels] {
  2013.     if {[int:validlag $chan]} {
  2014.       putdcc $idx " $chan : [lindex $lagdata($chan) 0] - lag: [lindex $lagdata($chan) 1]"
  2015.     } else {
  2016.       putdcc $idx " $chan : no lagdata (oped: [int:oped $chan])"
  2017.     }
  2018.   }
  2019. }
  2020.  
  2021. proc dcc:lock {hand idx arg} {
  2022.   global config botnet-nick
  2023.   if {[llength $arg] < 1} {
  2024.     putdcc $idx "$config(usage) lock <#channel>"
  2025.     return
  2026.   }
  2027.   set chan [lindex $arg 0]
  2028.   if {![validchan $chan]} {
  2029.     putdcc $idx "I am not on $chan"
  2030.     return 0
  2031.   }
  2032.   channel set $chan +secret
  2033.   putallbots "lock $hand $chan 1"
  2034.   putlog "$config(massprompt) Locked $chan ($hand@${botnet-nick})"
  2035.   int:alert "$hand is locking $chan"
  2036. }
  2037.  
  2038. proc dcc:unlock {hand idx arg} {
  2039.   global config botnet-nick
  2040.   if {[llength $arg] < 1} {
  2041.     putdcc $idx "$config(usage) unlock <#channel>"
  2042.     return
  2043.   }
  2044.   set chan [lindex $arg 0]
  2045.   if {![validchan $chan]} {
  2046.     putdcc $idx "I am not on $chan"
  2047.     return 0
  2048.   }
  2049.   channel set $chan -secret
  2050.   putallbots "lock $hand $chan 0"
  2051.   putlog "$config(massprompt) Unlocked $chan ($hand@${botnet-nick})"
  2052.   int:alert "$hand is unlocking $chan"
  2053. }
  2054.  
  2055. proc dcc:regulate {hand idx arg} {
  2056.   global config botnet-nick
  2057.   if {[llength $arg] < 1} {
  2058.     putdcc $idx "$config(usage) regulate <#channel>"
  2059.     return
  2060.   }
  2061.   set chan [lindex $arg 0]
  2062.   if {![validchan $chan]} {
  2063.     putdcc $idx "I am not on $chan"
  2064.     return 0
  2065.   }
  2066.   dcc:lock $hand $idx $chan
  2067.   dcc:mchanmode $hand $idx "$chan +stmin"
  2068.   dcc:clean $hand $idx $chan
  2069. }
  2070.  
  2071. proc dcc:mmsg {hand idx arg} {
  2072.   global config botnet-nick
  2073.   if {[llength $arg] < 2} {
  2074.     putdcc $idx "$config(usage) mmsg <nickname> <msg>"
  2075.     return
  2076.   }
  2077.   set mnick [lindex $arg 0]
  2078.   set msg [lrange $arg 1 end]
  2079.   putallbots "massmsg $hand $mnick $msg"
  2080.   putlog "$config(massprompt) ($hand@${botnet-nick}) Massmsg'ing $mnick : $msg"
  2081.   int:alert "$hand is massmsg'ing $mnick : $msg"
  2082. }
  2083.  
  2084. proc dcc:rpmquery {hand idx arg} {
  2085.   global config
  2086.   if {[llength $arg] < 1} {
  2087.     putdcc $idx "$config(usage) rpmquery <what>"
  2088.     return
  2089.   }
  2090.   set query [lindex $arg 0]
  2091.   putallbots "rpmquery $hand $query"
  2092.   putdcc $idx "Sent rpm query for $query"
  2093.   int:alert "$hand is sending an rpm query for $query"
  2094. }
  2095.  
  2096. proc dcc:clean {hand idx arg} {
  2097.   global config botnet-nick
  2098.   if {[llength $arg] < 1} {
  2099.     putdcc $idx "$config(usage) clean <#channel>"
  2100.     return
  2101.   }
  2102.   set chan [lindex $arg 0]
  2103.   putallbots "clean $hand $chan"
  2104.   putlog "$config(securityprompt) Cleaning $chan ($hand@${botnet-nick})"
  2105.   int:alert "$hand@${botnet-nick} is Cleaning $chan"
  2106. }
  2107.  
  2108. proc dcc:mchattr {hand idx arg} {
  2109.   global config botnet-nick
  2110.   if {[llength $arg] < 2} {
  2111.     putdcc $idx "$config(usage) mchattr <handle> <flags>"
  2112.     return
  2113.   }
  2114.   set cnick [lindex $arg 0]
  2115.   set flags [lindex $arg 1]
  2116.   chattr $cnick $flags
  2117.   putallbots "mchattr $hand $cnick $flags"
  2118.   putlog "$config(massprompt) ($hand@${botnet-nick}) Mass Chattr'ing : $cnick $flags"
  2119.   int:alert "$hand is Mass Chattr'ing $cnick $flags"
  2120. }
  2121.  
  2122. proc dcc:fsnstatus {hand idx arg} {
  2123.   global config version server botname
  2124.   putlog "[lindex $version 0] $config(ver)-$config(revision) $botname-$server"
  2125.   if {[llength $arg] == 2} {
  2126.     putbot $bot "status $hand"
  2127.   } else {
  2128.     putallbots "status $hand"
  2129.   }
  2130. }
  2131.  
  2132. proc dcc:msave {hand idx arg} {
  2133.   putallbots "save $hand"
  2134.   int:alert "Mass Save user/chan ($hand)"
  2135.   save
  2136.   savechannels
  2137. }
  2138.  
  2139. proc dcc:mrehash {hand idx arg} {
  2140.   putallbots "mrehash $hand"
  2141.   int:alert "Mass Rehash ($hand)"
  2142.   rehash
  2143. }
  2144.  
  2145. proc dcc:remlast {hand idx arg} {
  2146.   global config botnet-nick
  2147.   catch { exec rm -f $config(lastlog) }
  2148.   putlog "$config(massprompt) ($hand@${botnet-nick}) Deleted Lastlog File!"
  2149.   putallbots "remlast $hand"
  2150. }
  2151.  
  2152. proc dcc:choplist { hand idx args } {
  2153.   global config botnick
  2154.   set chan [lindex $args 0]
  2155.   if {$chan == ""} {
  2156.     putdcc $idx "$config(usage) choplist <#channel>"
  2157.     return 0
  2158.   }
  2159.   if ![validchan $chan] {
  2160.     putdcc $idx "$config(warnprompt) $chan is an invalid channel"
  2161.     return 0
  2162.   }
  2163.   if ![onchan $botnick $chan] {
  2164.     putdcc $idx "$config(warnprompt) I'm not on $chan"
  2165.     return 0
  2166.   }
  2167.   set chops ""
  2168.   foreach user [chanlist $chan] {
  2169.     if [isop $user $chan] { lappend chops $user }
  2170.   }
  2171.   putlog "$config(gainprompt) (Choplist Start)"
  2172.   foreach chop $chops {
  2173.     putdcc $idx "[lindex [split [getchanhost $chop $chan] "@"] 1]"
  2174.   }
  2175.   putlog "$config(gainprompt) (Choplist End) [llength $chops] hosts listed!"
  2176. }
  2177.  
  2178. proc int:resetmax { } {
  2179.     global maxdata config ctcpcur cmaxed botnick status floodban
  2180.     global botnick killcount ban-time ignore-time
  2181.     set qcheck 0
  2182.     if {($maxdata(reply) >= $config(maxreply)) && ($maxdata(request) >= $config(maxreq))} {
  2183.     putlog "$config(gainprompt) Reply and Request Queue are full!"
  2184.     int:alert "Reply and Request Queue are full!"
  2185.     set qcheck 1
  2186.     }
  2187.     if {($qcheck == 0) && ($maxdata(reply) >= $config(maxreply))} {
  2188.     putlog "$config(gainprompt) Reply Queue is full!"
  2189.     int:alert "Reply Queue is full!"
  2190.     }
  2191.     if {($qcheck == 0) && ($maxdata(request) >= $config(maxreq))} {
  2192.     putlog "$config(gainprompt) Request Queue is full!"
  2193.     int:alert "Request Queue is full!"
  2194.     }
  2195.     foreach chan [channels] {
  2196.     set chan [string tolower $chan]
  2197.     set floodban($chan) ""
  2198.     set ctcpcur($chan) 0
  2199.     set killcount($chan) [list 0 [unixtime]]
  2200.     set cmaxed($chan) ""
  2201.     }
  2202.     set maxdata(request) 0
  2203.     set maxdata(reply) 0
  2204.     set status(floodwatch) 0
  2205.     set status(floodwarn) 0
  2206.     set status(alerts) 0
  2207.     set status(lastkill) 0
  2208.     set ctcpcur(me) 0
  2209.     set ban-time [expr 60 + [rand 30]]
  2210.     set ignore-time [expr 20 + [rand 20]]
  2211.     putserv "PRIVMSG $botnick :poqok [encrypt & [unixtime]]"
  2212.     utimer 60 "int:resetmax"
  2213. }
  2214.  
  2215. proc gain:op { channel } {
  2216.     global botnick config maxdata lagdata nick botnet-nick
  2217.     if {[int:validlag $channel]} {
  2218.     set bot [lindex $lagdata($channel) 0]
  2219.     set lag [lindex $lagdata($channel) 1]
  2220.     if {[int:maxqueue request]} {
  2221.         return 0
  2222.     }
  2223.       putbot $bot "op $channel $botnick ${botnet-nick}"
  2224.     putlog "$config(gainprompt) Requesting Ops $bot@$channel (lag: $lag)"
  2225.     } else {
  2226.     if {![int:numbots $channel]} {
  2227.         return 0
  2228.     }
  2229.     int:getlag $channel
  2230.     }
  2231. }
  2232.  
  2233. proc gain:inv { channel } {
  2234.     global botnick config maxdata lagdata nick botnet-nick
  2235.     if {[int:validlag $channel]} {
  2236.     set bot [lindex $lagdata($channel) 0]
  2237.     set lag [lindex $lagdata($channel) 1]
  2238.     if {[int:maxqueue request]} {
  2239.         return 0
  2240.     }
  2241.     putbot $bot "inv $channel $botnick"
  2242.     putlog "$config(gainprompt) Requesting Invite $bot@$channel (lag: $lag)"
  2243.     } else {
  2244.     int:getlag $channel
  2245.     }
  2246. }
  2247.  
  2248. proc gain:unban { channel } {
  2249.      global botname botnick config maxdata lagdata nick botnet-nick
  2250.      if {[int:validlag $channel]} {
  2251.     set bot [lindex $lagdata($channel) 0]
  2252.     set lag [lindex $lagdata($channel) 1]
  2253.     if {[int:maxqueue request]} {
  2254.         return 0
  2255.     }
  2256.     putbot $bot "unban $channel $botname ${botnet-nick}"
  2257.     putlog "$config(gainprompt) Requesting Unban $bot@$channel (lag: $lag)"
  2258.     } else {
  2259.     int:getlag $channel
  2260.     }
  2261. }  
  2262.  
  2263. proc gain:key { channel } {
  2264.     global botnick config maxdata lagdata nick botnet-nick
  2265.     if {[int:validlag $channel]} {
  2266.     set bot [lindex $lagdata($channel) 0]
  2267.     set lag [lindex $lagdata($channel) 1]
  2268.     if {[int:maxqueue request]} {
  2269.         return 0
  2270.     }
  2271.     putlog "$config(gainprompt) Requesting Key $bot@$channel (lag: $lag)"
  2272.     putbot $bot "key $channel ${botnet-nick}"
  2273.     } else {
  2274.     int:getlag $channel
  2275.     }
  2276. }
  2277.  
  2278. proc gain:raise { channel } { }
  2279.  
  2280. # botnet traffic
  2281. proc putserv { arg } {
  2282.   global status
  2283.   set keyword [string toupper [lindex $arg 0]]
  2284.   if {$keyword == "PRIVMSG" || $keyword == "NOTICE" } {
  2285.     if {$status(back) == 0} { set $status(away) 1 }
  2286.     if {$status(away) == 0} { set $status(back) 1 }
  2287.   }
  2288.   rputserv $arg
  2289. }
  2290.  
  2291. proc puthelp { arg } {
  2292.   global status
  2293.   set keyword [string toupper [lindex $arg 0]]
  2294.   if {$keyword == "PRIVMSG" || $keyword == "NOTICE" } {
  2295.     if {$status(back) == 0} { set $status(away) [unixtime] }
  2296.     if {$status(away) == 0} { set $status(back) [unixtime] }
  2297.   }
  2298.   rputhelp $arg
  2299. }
  2300.  
  2301. proc putbot { bot arg } {
  2302.   global status config
  2303.   if {$status(netkey) != "none"} {
  2304.     rputbot $bot "$config(netcmd) [encrypt $status(netkey) $arg]"
  2305.   }
  2306. }
  2307.  
  2308. proc putallbots { arg } {
  2309.   global status config
  2310.   if {$status(netkey) != "none"} {
  2311.     rputallbots "$config(netcmd) [encrypt $status(netkey) $arg]"
  2312.   }
  2313. }
  2314.  
  2315. proc bot:netnoauth { bot cmd arg } {
  2316.   global config floodban botnet-nick spread spreadi status
  2317.    
  2318.   int:debuglog "(N) $bot -> $cmd $arg"
  2319.  
  2320.   switch -- $cmd {
  2321.     "glog" {
  2322.       putlog "-[lindex $bot 0]- $arg"
  2323.     }
  2324.     "rcmd" {
  2325.       set rnick [lindex $arg 0]
  2326.       putcmdlog "#${rnick}@${bot}# [lrange $arg 1 end]"
  2327.     }
  2328.     "newnetkey" {
  2329.       if {[int:ishub $bot]} {
  2330.         set keytime [lindex $arg 0]
  2331.         if {[info exists $status(keytime)] && $status(keytime) > $keytime} {
  2332.           putlog "$config(warnprompt) Warning: Ignoring outdated netkey from hub"
  2333.         } else {
  2334.           set key [decrypt [encrypt zPoSmJo lPakjOdQidJklmN] $arg]
  2335.           set status(netkey) $key
  2336.           set status(keytime) $keytime
  2337.         }
  2338.       } else {
  2339.         putlog "$config(securityprompt) Warning: Netkey from non-hub $bot"
  2340.       }
  2341.     }
  2342.   }
  2343. }
  2344.  
  2345. proc bot:netauth { bot cmd arg } {
  2346.   global maxdata config nick botnet-nick authed botnick lastlag ctcpcur floodban
  2347.   global server botname keys version chanstats floodin owner
  2348.  
  2349.   int:debuglog "(A) $bot -> $cmd $arg"
  2350.  
  2351.   switch -- $cmd {
  2352.     "pchk" {
  2353.      putlog "$config(securityprompt) SNIFF/HIJACK attempt on $bot"
  2354.      sendnote ${botnet-nick} $owner "SNIFF/HIJACK attempt on $bot at [ctime [unixtime]]"
  2355.      int:shitbot $bot
  2356.     }
  2357.     "badkey" {
  2358.      set badbot [lindex $arg 0]
  2359.      if {![matchattr ${botnet-nick} bh]} { return 0 }
  2360.      if {[matchattr $badbot +4dkr]} { return 0 }
  2361.      putlog "$config(securityprompt) $badbot oped with an invalid op key! (verified by: $bot)"
  2362.      int:shitbot $bot
  2363.      }
  2364.     "fmaxed" {
  2365.       set chan [lindex $arg 0]
  2366.       if ![info exists floodin($chan)] {
  2367.         putlog "$config(securityprompt) $bot reports flooding in $chan"
  2368.         set floodin($chan) 1
  2369.       }
  2370.       timer 5 { unset $floodin($chan) }
  2371.     }
  2372.     "chancheck" {
  2373.       if {![int:ishub $bot]} {
  2374.         putlog "$config(securityprompt) Non-Hub $bot sending chan-check"
  2375.         return
  2376.       }
  2377.       putbot $bot "checkresp [channels]"
  2378.     }
  2379.     "checkresp" {
  2380.       foreach ch $arg {
  2381.         if ![validchan $ch] { putbot $bot "rmchan $ch" }
  2382.       }
  2383.     }
  2384.     "rmchan" {
  2385.       if {![int:ishub $bot]} {
  2386.         putlog "$config(securityprompt) Non-Hub $bot sending remove channel [lindex $arg 0]"
  2387.         return
  2388.       }
  2389.       channel remove $arg
  2390.       putlog "$config(gainprompt) Removed [lindex $arg 0]"
  2391.     }
  2392.     "csync" {
  2393.       if {![int:ishub $bot]} {
  2394.         putlog "$config(securityprompt) Non-Hub $bot sending chan-sync $chan"
  2395.         return
  2396.       }
  2397.       set chan [lindex $arg 0]
  2398.       set cmode [lindex $arg 1]
  2399.       set emodes [lrange $arg 2 end]
  2400.       if {[lsearch [string tolower [channels]] [string tolower $chan]] == -1} {
  2401.         channel add $chan {
  2402.          chanmode $cmode
  2403.          idle-kick 0
  2404.         }
  2405.       } else {
  2406.         channel set $chan chanmode $cmode
  2407.       }
  2408.       foreach mode $emodes {
  2409.         channel set $chan $mode
  2410.       }
  2411.       channel set $chan need-op "gain:op $chan"
  2412.       channel set $chan need-invite "gain:inv $chan"
  2413.       channel set $chan need-key "gain:key $chan"
  2414.       channel set $chan need-limit "gain:raise $chan"
  2415.       channel set $chan need-unban "gain:unban $chan"
  2416.       channel set $chan +shared
  2417.       set floodban($chan) ""
  2418.       set ctcpcur($chan) 0
  2419.       set killcount($chan) [list 0 [unixtime]]
  2420.       putlog "$config(massprompt) Synced $chan/$cmode"
  2421.     }
  2422.     "clean" {
  2423.       set hand [lindex $arg 0]
  2424.       set chan [lindex $arg 1]
  2425.       if {[int:ishub $bot]} {
  2426.         if {![validchan $chan]} {
  2427.           putlog "$config(massprompt) $hand@$bot is Cleaning non-existant $chan"
  2428.         } else {
  2429.           putlog "$config(massprompt) $hand@$bot is Cleaning $chan"
  2430.           set badnicks ""                  
  2431.           set nbadnicks ""
  2432.           foreach knick [chanlist $chan] {
  2433.             set khand [nick2hand $knick $chan]                      
  2434.             if {$khand == "*"} {
  2435.               lappend badnicks $knick
  2436.             } elseif ![matchattr $khand o] {
  2437.               lappend badnicks $knick      
  2438.             }
  2439.           }
  2440.           int:kickmulti $chan $badnicks
  2441.         }
  2442.       } else {          
  2443.         putlog "$config(securityprompt) Non-Hub $hand@$bot sending Clean $chan"
  2444.         int:alert "Non-Hub $hand@$bot is sending Clean $chan"
  2445.       }                                                      
  2446.     }
  2447.     "clearchanbans" {
  2448.       set chan [lindex $arg 0]
  2449.       if {[int:ishub $bot]} {
  2450.         putlog "$config(massprompt) $hand@$bot is clearing chanbans for $chan"
  2451.         foreach ban [banlist $chan] {
  2452.           killchanban $chan $ban
  2453.         }
  2454.       } else {
  2455.         putlog "$config(securityprompt) Non-Hub $hand@$bot sending clearchanbans for $chan"
  2456.         int:alert "Non-Hub $hand@$bot is sending clearchanbans for $chan"
  2457.       }
  2458.     }
  2459.     "ping" {
  2460.       int:debuglog "$bot sent botnet-ping"
  2461.       putbot $bot "pong [lindex $arg 0]"
  2462.     }
  2463.     "pong" {
  2464.       set lag [expr [unixtime] - [lindex $arg 0]]
  2465.       if { $lag >= 20 } {
  2466.         putlog "$config(warnprompt) Warning: $bot is $lag seconds lagged!"
  2467.         int:alert "Warning: $bot is $lag seconds lagged!"
  2468.       }
  2469.     }
  2470.     "mchattr" {
  2471.       set hand [lindex $arg 0]
  2472.       set cnick [lindex $arg 1]
  2473.       set flags [lindex $arg 2]
  2474.       if {[int:ishub $bot]} {
  2475.         putlog "$config(massprompt) $hand@$bot is Mass Chattr $cnick $flags"
  2476.         chattr $cnick $flags
  2477.       } else {
  2478.         putlog "$config(securityprompt) Non-Hub $hand@$bot sending Mass Chattr $cnick $flags"
  2479.         int:alert "Non-Hub $hand@$bot is sending Mass Chattr $cnick $flags"
  2480.       }
  2481.     }
  2482.     "save" {
  2483.         set hand [lindex $arg 0]
  2484.         if {[int:ishub $bot]} {
  2485.         putlog "$config(massprompt) $hand@$bot is Mass Saving"
  2486.         save
  2487.         savechannels
  2488.         } else {
  2489.         putlog "$config(securityprompt) Non-Hub $bot sending Mass Save"
  2490.         int:alert "Non-Hub $bot sending Mass Save"
  2491.         }
  2492.     }
  2493.     "status" {
  2494.         set hand [lindex $arg 0]
  2495.         putbot $bot "glog [lindex $version 0] $config(ver)-$config(revision) $botname-$server"
  2496.         putlog "$config(miscprompt) $hand@$bot requested status info."
  2497.     }
  2498.     "massmsg" {
  2499.         set hand [lindex $arg 0]
  2500.         set target [lindex $arg 1]
  2501.         set msg [lrange $arg 2 end]
  2502.         if {[int:ishub $bot]} {
  2503.         putlog "$config(massprompt) $hand@$bot is massmsg'ing $target : $msg"
  2504.         putserv "PRIVMSG $target :$msg"
  2505.         } else {
  2506.         putlog "$config(securityprompt) Non-Hub $bot sending massmsg $target : $msg"
  2507.         int:alert "Non-Hub $bot sending mass-msg $target : $msg"
  2508.         }
  2509.     }
  2510.     "rpmquery" {
  2511.         set hand [lindex $arg 0]
  2512.         set query [lindex $arg 1]
  2513.         if {[int:ishub $bot]} {
  2514.         if {[file exists /bin/rpm]} {
  2515.             if {[catch {exec /bin/rpm -q $query} results]} {
  2516.             putbot $bot "glog rpm: error exec'ing rpm"
  2517.             } else {
  2518.             putbot $bot "glog rpm: $results"
  2519.             }
  2520.         } else {
  2521.             putbot $bot "glog rpm: non-redhat"
  2522.         }
  2523.         } else {
  2524.         putlog "$config(securityprompt) Non-Hub $bot sending rpmquery $query"
  2525.         int:alert "Non-Hub $bot sending rpmquery $query"
  2526.         }
  2527.     }
  2528.     "lock" {
  2529.         set hand [lindex $arg 0]
  2530.         set chan [lindex $arg 1]
  2531.         set which [lindex $arg 2]
  2532.         if {[int:ishub $bot]} {
  2533.         switch -- $which {
  2534.             "1" {
  2535.             putlog "$config(massprompt) $hand@$bot is locking $chan"
  2536.             channel set $chan +secret
  2537.             }
  2538.             "0" {
  2539.             putlog "$config(massprompt) $hand@$bot is unlocking $chan"
  2540.             channel set $chan idle-kick -secret
  2541.             }
  2542.         }
  2543.         } else {
  2544.         putlog "$config(securityprompt) Non-Hub $bot sending lock ($which) for $chan"
  2545.         int:alert "Non-Hub $bot sending lock ($which) for $chan"
  2546.         }
  2547.     }
  2548.     "chanmode" {
  2549.         if {[int:ishub $bot]} {
  2550.         set hand [lindex $arg 0]
  2551.         set chan [lindex $arg 1]
  2552.         set modes [lindex $arg 2]
  2553.         channel set $chan chanmode $modes
  2554.         putlog "$config(massprompt) $hand@$bot set default chanmode for $chan to [lindex [channel info $chan] 0]"
  2555.         } else {
  2556.         putlog "$config(securityprompt) Non-Hub $bot sending chanmode for $chan"
  2557.         int:alert "Non-Hub $bot sending chanmode for $chan"
  2558.         }
  2559.     }
  2560.     "chanset" {
  2561.         if {[int:ishub $bot]} {
  2562.         set hand [lindex $arg 0]
  2563.         set chan [lindex $arg 1]
  2564.         set modes [lrange $arg 2 end]
  2565.         foreach mode $modes {
  2566.             channel set $chan $mode
  2567.         }
  2568.         putlog "$config(massprompt) $hand@$bot set default channel settings for $chan to $modes"
  2569.         } else {
  2570.         putlog "$config(securityprompt) Non-Hub $bot sending chanmode for $chan"
  2571.         int:alert "Non-Hub $bot sending chanmode for $chan"
  2572.         }
  2573.     }
  2574.     "raisechan" {
  2575.             if {![int:ishub $bot]} {
  2576.               putlog "$config(securityprompt) Warning: Received channel limit raise request from non-hub bot ($bot)!"
  2577.               return
  2578.             }
  2579.         set chan [lindex $arg 0]
  2580.         set mode [lindex [getchanmode $chan] 0]
  2581.         if {[string match "*l*" $mode]} {
  2582.         set newlimit [expr [llength [chanlist $chan]] + 5]
  2583.                 set oldlimit [lindex [getchanmode $chan] end]
  2584.                 if {$newlimit != $oldlimit} {
  2585.                   dumpserv "MODE $chan +l $newlimit"
  2586.                 }
  2587.                 putlog "$config(gainprompt) Limit $chan to $newlimit"
  2588.         }
  2589.     }
  2590.     "rnick" {
  2591.         if {[int:ishub $bot]} {
  2592.         putlog "!*! Switching to Random nicks ([lindex $arg 1])"
  2593.         int:rnick
  2594.         } else {
  2595.         putlog "$config(securityprompt) Warning: Received random nick change from non-hub bot!"
  2596.         }
  2597.     }
  2598.     "nick" {
  2599.         if {[int:ishub $bot]} {
  2600.         putlog "!*! Switching to Original nicks ([lindex $arg 1])"
  2601.         putserv "NICK :$nick"
  2602.         } else {
  2603.         putlog "$config(securityprompt) Warning: Received random nick change from non-hub bot!"
  2604.         }
  2605.  
  2606.     }
  2607.     "mrehash" {
  2608.         putlog "$config(massprompt) Rehashing ([lindex $arg 0])"
  2609.         rehash
  2610.     }
  2611.     "msave" {
  2612.             set hand [lindex $arg 0]
  2613.         putlog "$config(massprompt) Saving chan/user files ([lindex $arg 0])"
  2614.         save
  2615.         savechannels
  2616.     }
  2617.     "mjoin" {
  2618.         set chan [lindex $arg 0]
  2619.         set hand [lindex $arg 1]
  2620.             set key [lindex $arg 2]
  2621.         if {[int:ishub $bot]} {
  2622.         putlog "$config(massprompt) Joined $chan ($hand@$bot)"
  2623.         int:addchan $chan
  2624.                 if {[string length $key] < 30} {
  2625.                   dumpserv "JOIN $chan $key"
  2626.                 }
  2627.         } else {
  2628.         putlog "$config(massprompt) Non-Hub Mass Join attempt $chan ($hand@$bot)"
  2629.         return 0
  2630.         }
  2631.     }
  2632.     "mpart" {
  2633.         set chan [lindex $arg 0]
  2634.         set hand [lindex $arg 1]
  2635.         if {[int:ishub $bot]} {
  2636.         putlog "$config(massprompt) Parted $chan ($hand@$bot)"
  2637.         channel remove $chan
  2638.         } else {
  2639.         putlog "$config(massprompt) Non-Hub Mass Part attempt $chan ($hand@$bot)"
  2640.         return 0
  2641.         }
  2642.     }
  2643.     "lag" {
  2644.         set channel [lindex $arg 0]
  2645.         set rnick [lindex $arg 1]
  2646.         set lag [lindex $arg 2]
  2647.         if {([int:oprand $channel] < 3)} {
  2648.         if {[int:oped $channel]} {
  2649.             if {[int:maxqueue reply]} {
  2650.             return 0
  2651.             }
  2652.             set chans ""
  2653.             foreach chan [channels] {
  2654.             if {$chan == $channel} {
  2655.                 lappend chans $chan
  2656.             } elseif {[int:oped $chan] && ([int:oprand $chan] <3)} {
  2657.                 lappend chans $chan
  2658.             }
  2659.             }
  2660.             putserv "PRIVMSG $rnick :reply lag ${botnet-nick} $lag $chans"
  2661.             set lastlag($bot) [unixtime]
  2662.         }
  2663.         }
  2664.     }
  2665.     "op" {
  2666.         if {[int:maxqueue reply]} {
  2667.         return 0
  2668.         }
  2669.         set channel [lindex $arg 0]
  2670.         set rnick [string tolower [lindex $arg 1]]
  2671.         if {[info exists lastlag($bot)]} {
  2672.         if {[expr [unixtime] - $lastlag($bot)] >= $config(lagreset)} {
  2673.             putlog "$config(gainprompt) Refused Op $rnick@$channel ($bot) - never sent lag!"
  2674.             int:alert "Warning : $bot ($rnick) op request $channel - never sent lag!"
  2675.             return 0
  2676.         }
  2677.         } else {
  2678.         putlog "$config(gainprompt) Refused Op $rnick@$channel ($bot) - never sent lag!"
  2679.         int:alert "Warning : $bot ($rnick op request $channel - never sent lag!"
  2680.         return 0
  2681.         }
  2682.         if {![matchattr $bot of]} {
  2683.         putlog "$config(gainprompt) Refused Op $rnick@$channel ($bot) not +of"
  2684.         int:alert "Warning : $bot ($rnick) op request $channel - not +of"
  2685.         return 0
  2686.         }
  2687.         if {[nick2hand $rnick $channel] != $bot} {
  2688.         putlog "$config(gainprompt) Refused Op $rnick@$channel ($bot) no hostmask"
  2689.         int:alert "Warning : $bot ($rnick) op request $channel - no hostmask"
  2690.         return 0
  2691.         }
  2692.         if {![onchan $rnick $channel]} {
  2693.         putlog "$config(gainprompt) Desynch: $rnick@$channel ($bot) requested op when not on chan"
  2694.         int:alert "$channel is desynched $bot ($rnick) requested op when not on chan"
  2695.         return 0
  2696.         }
  2697.         if {[isop $rnick $channel]} {
  2698.         putlog "$config(gainprompt) Desynch: $rnick@$channel ($bot) requested op when already oped"
  2699.         int:alert "$channel is desynched $bot ($rnick) requested op when already oped"
  2700.         return 0
  2701.         }
  2702.         if {[int:oped $channel]} {
  2703.                 set opkey "[encrypt $rnick$channel [encrypt $keys(op) [int:randtext 7]]]"
  2704.                 putserv "MODE $channel +o-b $rnick *!*@$opkey"
  2705.         putlog "$config(gainprompt) Oping $rnick@$channel for $bot"
  2706.         }
  2707.     }
  2708.     "rop" {
  2709.         if {[int:maxqueue reply]} {
  2710.         return 0
  2711.         }
  2712.           set channel [lindex $arg 0]
  2713.         set rnick [string tolower [lindex $arg 1]]
  2714.           set fnick [lindex $arg 2]
  2715.         set badhand 0
  2716.         if {$fnick == "" || ![validuser $fnick]} { set badhand 1 }
  2717.                 if $badhand {
  2718.                    putlog "$config(gainprompt) Refused Op $rnick@$channel ($fnick@$bot) - $fnick is not a user"
  2719.                    putallbots "glog $config(gainprompt) Refused Op $rnick@$channel ($fnick@$bot) - $fnick is not a user"
  2720.                        return 0
  2721.                 }
  2722.             if {![matchattr $bot h]} {
  2723.                    putlog "$config(gainprompt) Refused Op $rnick@$channel ($fnick@$bot) - $bot is not hub"
  2724.                    putallbots "glog $config(gainprompt) Refused Op $rnick@$channel ($fnick@$bot) - $bot is not hub"
  2725.                        return 0
  2726.                 }
  2727.             if {![onchan $rnick $channel]} {
  2728.             putlog "$config(gainprompt) Desynch: $rnick@$channel ($fnick@$bot) requested op when not on chan"
  2729.             putallbots "glog $config(gainprompt) Desynch: $rnick@$channel ($fnick@$bot) requested op when not on chan"
  2730.                         return 0
  2731.             }
  2732.             if {[isop $rnick $channel]} {
  2733.             putlog "$config(gainprompt) Desynch: $rnick@$channel ($fnick@$bot) requested op when already oped"
  2734.             putallbots "glog $config(gainprompt) Desynch: $rnick@$channel ($fnick@$bot) requested op when already oped"
  2735.                         return 0
  2736.             }
  2737.             if {[nick2hand $rnick $channel] != $fnick && [int:oped $channel]} {
  2738.             putlog "$config(warnprompt) Opping $rnick@$channel who does not match $fnick@$bot"
  2739.             putallbots "glog $config(warnprompt) Opping $rnick@$channel who does not match $fnick@$bot"
  2740.                         set opkey "[encrypt $rnick$channel [encrypt $keys(op) [int:randtext 7]]]"
  2741.                         dumpserv "MODE $channel +o-b $rnick *!*@$opkey"
  2742.                         return 1
  2743.             }
  2744.             if {[nick2hand $rnick $channel] != $fnick && ![int:oped $channel]} {
  2745.             putlog "$config(warnprompt) Could not op $rnick@$channel who does not match $fnick@$bot"
  2746.             putallbots "glog $config(warnprompt) Could not op $rnick@$channel who does not match $fnick@$bot"
  2747.                         return 0
  2748.             }
  2749.             if {[int:oped $channel]} {
  2750.                         set opkey "[encrypt $rnick$channel [encrypt $keys(op) [int:randtext 7]]]"
  2751.                         dumpserv "MODE $channel +o-b $rnick *!*@$opkey"
  2752.             putlog "$config(gainprompt) Oping $rnick@$channel for $fnick@$bot"
  2753.                         return 1
  2754.             } else {
  2755.             putlog "$config(warnprompt) Could not op $rnick@$channel for $fnick@$bot (not opped)"
  2756.                     putallbots "glog $config(warnprompt) Could not op $rnick@$channel for $fnick@$bot (not opped)"
  2757.                         return 0
  2758.                 }
  2759.     }
  2760.     "deop" {
  2761.         if {[int:maxqueue reply]} {
  2762.         return 0
  2763.         }
  2764.         set channel [lindex $arg 0]
  2765.         set rnick [string tolower [lindex $arg 1]]
  2766.             set fnick [lindex $arg 2]
  2767.                 if {$fnick == "" || ![validuser $fnick]} { set badhand 1 }
  2768.             if $badhand {
  2769.                    putlog "$config(gainprompt) Refused Deop $rnick@$channel ($fnick@$bot) - $fnick is not a user"
  2770.                    putallbots "glog $config(gainprompt) Refused Deop $rnick@$channel ($fnick@$bot) - $fnick is not a user"
  2771.                 }
  2772.             if {![matchattr $bot h]} {
  2773.                    putlog "$config(gainprompt) Refused Deop $rnick@$channel ($fnick@$bot) - $bot is not hub"
  2774.                    putallbots "glog $config(gainprompt) Refused Deop $rnick@$channel ($fnick@$bot) - $bot is not hub"
  2775.                 }
  2776.             if {![onchan $rnick $channel]} {
  2777.             putlog "$config(gainprompt) Desynch: $rnick@$channel ($fnick@$bot) requested deop when not on chan"
  2778.             putallbots "glog $config(gainprompt) Desynch: $rnick@$channel ($fnick@$bot) requested deop when not on chan"
  2779.             }
  2780.             if {![isop $rnick $channel]} {
  2781.             putlog "$config(gainprompt) Desynch: $rnick@$channel ($fnick@$bot) requested deop when already deoped"
  2782.             putallbots "glog $config(gainprompt) Desynch: $rnick@$channel ($fnick@$bot) requested deop when already deoped"
  2783.             }
  2784.             if {[int:oped $channel]} {
  2785.             pushmode $channel -o $rnick
  2786.             putlog "$config(gainprompt) Deoping $rnick@$channel for $fnick@$bot"
  2787.             } else {
  2788.             putlog "$config(warnprompt) Could not deop $rnick@$channel for $fnick@$bot (not opped)"
  2789.                     putallbots "glog $config(warnprompt) Could not deop $rnick@$channel for $fnick@$bot (not opped)"
  2790.                 }
  2791.     }
  2792.     "mdeop" {
  2793.         if {[int:maxqueue reply]} {
  2794.         return 0
  2795.         }
  2796.         set channel [lindex $arg 0]
  2797.         set for [lindex $arg 1]
  2798.             if [int:oped $channel] {
  2799.               mode:bitchop "*" "*" "*" "$channel" "+o $botnick"
  2800.             } else {
  2801.               putbot $bot "glog $config(warnprompt) I am not opped in $channel :("
  2802.             }
  2803.     }
  2804.     "rinv" {
  2805.         if {[int:maxqueue reply]} {
  2806.         return 0
  2807.         }
  2808.         set channel [lindex $arg 0]
  2809.         set rnick [lindex $arg 1]
  2810.             set fnick [lindex $arg 2]
  2811.         if {$fnick == ""} { set fnick "unknown" }
  2812.         if {![matchattr $fnick of]} {
  2813.           putlog "$config(gainprompt) Refused Invite $rnick@$channel ($bot) not +of"
  2814.           int:alert "Warning : $fnick@$bot ($rnick) inv request to $channel - not +of"
  2815.             }
  2816.         if {[int:oped $channel] && ![onchan $rnick $channel]} {
  2817.           putserv "INVITE $rnick $channel"
  2818.           putlog "$config(gainprompt) Inviting $rnick to $channel for $fnick@$bot"
  2819.         }
  2820.     }
  2821.     "inv" {
  2822.       if {[int:maxqueue reply]} {
  2823.         return 0
  2824.       }
  2825.       set channel [lindex $arg 0]
  2826.       set rnick [lindex $arg 1]
  2827.       if {![matchattr $bot of]} {
  2828.         putlog "$config(gainprompt) Refused Invite $rnick@$channel ($bot) not +of"
  2829.         int:alert "Warning : $fnick@$bot ($rnick) inv request to $channel - not +of"
  2830.       }
  2831.           if {[int:oped $channel] && ![onchan $rnick $channel]} {
  2832.         putserv "INVITE $rnick $channel"
  2833.         putlog "$config(gainprompt) Inviting $rnick@$channel for $bot"
  2834.           }
  2835.     }
  2836.     "unban" {
  2837.         if {[int:maxqueue reply]} {
  2838.         return 0
  2839.         }
  2840.         set channel [lindex $arg 0]
  2841.         set bothost [lindex $arg 1]
  2842.         if {![matchattr $bot of]} {
  2843.         putlog " $config(gainprompt) Refused Unban $bot@$channel not +of"
  2844.         int:alert "Warning : $bot unban request $channel - not +of"
  2845.         return 0
  2846.         }
  2847.         if {[int:oped $channel]} {
  2848.             foreach ban [chanbans $channel] {
  2849.             if {[string match $ban $bothost]} {
  2850.             putlog "$config(gainprompt) Unbanned $bot@$channel (chanban: $ban)"
  2851.             pushmode $channel -b $ban
  2852.             }
  2853.         }
  2854.         foreach ban [banlist $channel] {
  2855.             if {[string match $ban $bothost]} {
  2856.             putlog "$config(gainprompt) Unbanned $rnick@$channel (permchanban: $ban)"
  2857.             killchanban $channel $ban
  2858.             }
  2859.         }
  2860.         foreach ban [banlist] {
  2861.             if {[string match $ban $bothost]} {
  2862.             putlog "$config(gainprompt) Unbanned $rnick@$channel (permban: $ban)"
  2863.             killban $ban
  2864.             }
  2865.         }
  2866.         }
  2867.     }
  2868.     "key" {
  2869.         set channel [lindex $arg 0]
  2870.         if {![validchan $channel]} {
  2871.         putlog "$config(gainprompt) $bot requested key for invalid chan - $channel"
  2872.         }
  2873.         if {![onchan $botnick $channel]} { return 0 }
  2874.         set modes [lindex [getchanmode $channel] 0]
  2875.         set trail [lindex [getchanmode $channel] 1]
  2876.         if {![string match "*k*" $modes]} {
  2877.         putlog "$config(warnprompt) $chan is desynched $bot requested key for -k $channel"
  2878.         int:alert "$chan is desynched $bot requested key for -k $channel"
  2879.         } else {
  2880.         if {[string match "*kl" $modes]} {
  2881.             set key [lindex $trail 0]
  2882.         } else {
  2883.             set key [lindex $trail 0]
  2884.         }
  2885.         putbot $bot "keyreply $channel $key"
  2886.         putlog "$config(gainprompt) Sent Key $bot@$channel (key: $key)"
  2887.         }
  2888.     }
  2889.     "keyreply" {
  2890.         set channel [lindex $arg 0]
  2891.         set key [lindex $arg 1]
  2892.         if {![onchan $botnick $channel]} {
  2893.         putlog "$config(gainprompt) Joining $channel (key: $key)"
  2894.         putserv "JOIN $channel $key"
  2895.         }
  2896.     }
  2897.         "kick" {
  2898.           set ch [lindex $arg 0]
  2899.           set nick [lindex $arg 1]
  2900.           set reason [lrange $arg 2 end]
  2901.           putserv "KICK $ch $nick :$reason"
  2902.         }
  2903.         "kickban" {
  2904.           set ch [lindex $arg 0]
  2905.           set nick [lindex $arg 1]
  2906.           set reason [lrange $arg 2 end]
  2907.           set ban [getchanhost $nick $chan]
  2908.           newban $ban $handle $reason perm
  2909.           putserv "KICK $ch $nick :$reason"
  2910.         }
  2911.         "last" {
  2912.           set hand [lindex $arg 0]
  2913.           set time [lindex $arg 1]
  2914.           set host [lindex $arg 2]
  2915.           set last [open $config(lastlog) a+]
  2916.           puts $last [encrypt databurn "$hand $time $host"]
  2917.           close $last
  2918.           return 1
  2919.         }
  2920.         "remlast" {
  2921.           set for [lindex $arg 0]
  2922.           catch { exec rm -f $config(lastlog) }
  2923.           putlog "$config(massprompt) ($for@$bot) Deleted Lastlog File!"
  2924.         }
  2925.         "getstats" {
  2926.           foreach ch [channels] {
  2927.             set ops 0
  2928.             set voiced 0
  2929.             foreach user [chanlist $ch] { if [isop $user $ch] { incr ops 1 } }
  2930.             foreach user [chanlist $ch] { if [isvoice $user $ch] { incr voiced 1 } }
  2931.             set non [expr [llength [chanlist $ch]] - $ops - $voiced]
  2932.             set total [llength [chanlist $ch]]
  2933.             if ![onchan $botnick $ch] {
  2934.               putbot $bot "chanstat $ch n/a"
  2935.             } else {
  2936.               putbot $bot "chanstat $ch $ops $voiced $non [getchanmode $ch]"
  2937.             }
  2938.           }
  2939.         }
  2940.         "chanstat" {
  2941.           if [string match "* +secret *" [channel info [lindex $arg 0]]] {
  2942.             set locked "yes"
  2943.           } else {
  2944.             set locked "no"
  2945.           }
  2946.           if {[lindex $arg 1] == "n/a"} {
  2947.             putlog "$config(gainprompt) ([lindex $arg 0]) <$bot> stats n/a"
  2948.           } else {
  2949.             putlog "$config(gainprompt) ([lindex $arg 0]) o/[lindex $arg 1] v/[lindex $arg 2] n/[lindex $arg 3] m/[lrange $arg 4 end] l/$locked"
  2950.           }
  2951.         }
  2952.   }
  2953. }
  2954.  
  2955. proc bot:net { bot cmd arg } {
  2956.   global config status
  2957.  
  2958.   set bot [string tolower $bot]
  2959.   set oldarg $arg
  2960.   set arg [decrypt $status(netkey) $arg]
  2961.   set arg [split $arg " "]
  2962.   set trail [lrange $arg 1 end]
  2963.   set root [lindex $arg 0]
  2964.  
  2965.   putloglev 2 "*" "(E) $bot -> $cmd $oldarg ($arg)"
  2966.   if {[lsearch $config(authnetcmds) $root] != -1} {
  2967.     if {[matchattr $bot 3] || [int:ishub $bot]} {
  2968.       bot:netauth $bot $root $trail
  2969.     } else {
  2970.       int:debuglog "$bot not authed"
  2971.     }
  2972.   } elseif {[lsearch $config(nonetcmds) $root] != -1} {
  2973.     bot:netnoauth $bot $root $trail
  2974.   } else {
  2975.     putlog "$config(warnprompt) net:$arg invalid"
  2976.   }
  2977. }
  2978.  
  2979. proc gain:msg { nick uhost hand arg } {
  2980.   global lagdata lastlagout config
  2981.   set root [lindex $arg 0]
  2982.   switch -- $root {
  2983.     "lag" {
  2984.       set anick [lindex $arg 1]
  2985.       set lag [lindex $arg 2]
  2986.       set channel [string tolower [lrange $arg 3 [llength $arg]]]
  2987.       foreach chan $channel {
  2988.         if {![int:validlag $chan]} {
  2989.           set lagdata($chan) [list $anick [expr [unixtime] - $lag]]
  2990.         } else {
  2991.           if {[lindex $lagdata($chan) 1] > $lag} {
  2992.             set lagdata($chan) [list $anick [expr [unixtime] - $lag]]
  2993.           }
  2994.         }
  2995.         set lastlagout($chan) [unixtime]
  2996.       }
  2997.     }
  2998.   }
  2999. }
  3000.  
  3001. proc chan:kick { nick chan } {
  3002.   global config
  3003.   if {[onchan $nick $chan]} {
  3004.     set kickmsg [lindex $config(kickmsg) [rand [llength $config(kickmsg)]]]
  3005.     putserv "KICK $chan $nick :$kickmsg"
  3006.     putlog "$config(warnprompt) : auto-kicked ${nick}@$chan (+i)"
  3007.   }
  3008. }
  3009.  
  3010. proc int:maxqueue { type } {
  3011.   global maxdata config
  3012.   switch $type {
  3013.     "reply" {
  3014.       if {$maxdata(reply) >= $config(maxreply)} {
  3015.         # Too many lag replies/server requests, throttled
  3016.         incr maxdata(reply)
  3017.         return 1;
  3018.       } else {
  3019.         return 0
  3020.       }
  3021.     }
  3022.     "request" {
  3023.       if {$maxdata(request) >= $config(maxreq)} {
  3024.         # Too many op requests, throttled
  3025.         return 1;
  3026.       } else {
  3027.         incr maxdata(request)
  3028.         return 0
  3029.       }
  3030.     }
  3031.   }
  3032.   return 1;
  3033. }
  3034.  
  3035.  
  3036. proc int:getlag { channel } {
  3037.   global botnick lastlagreq
  3038.   if {[int:maxqueue request]} {
  3039.     return 0
  3040.   }
  3041.   if {[info exists lastlagreq($channel)]} {
  3042.     if {$lastlagreq($channel) >= [expr [unixtime] - 30]} {
  3043.       return 0
  3044.     }
  3045.   }
  3046.   if {[llength [bots]] != 0} {
  3047.     putallbots "lag $channel $botnick [unixtime]"
  3048.     int:debuglog " -> Requesting Lagcheck ($channel)"  
  3049.     set lastlagreq($channel) [unixtime]
  3050.   }
  3051. }
  3052.  
  3053. proc int:validlag { chan } {
  3054.   global lastlagout config
  3055.   if {[info exists lastlagout($chan)]} {
  3056.     if {$lastlagout($chan) >= [expr [unixtime] - $config(lagreset)]} {
  3057.       return 1
  3058.     } else {
  3059.       return 0
  3060.     }
  3061.   } else {
  3062.     return 0
  3063.   }
  3064. }
  3065.  
  3066. proc int:checknetlag { } {
  3067.   putallbots "ping [unixtime]"
  3068.   timer 5 int:checknetlag
  3069. }
  3070.  
  3071. # internal procs
  3072. proc int:link { bot via } {
  3073.   int:pmembers
  3074. }
  3075.  
  3076. proc int:kickmulti { chan nicks } {
  3077.   global config status
  3078.  
  3079.   set i 0
  3080.   set nnicks ""
  3081.   while {[llength $nicks] != 0} {
  3082.     set rnum [rand [llength $nicks]]
  3083.     set tnick [lindex $nicks $rnum]
  3084.     lappend nnicks $tnick
  3085.     set nicks [lreplace $nicks $rnum $rnum]
  3086.   }
  3087.   set nicks $nnicks
  3088.   if {$status(fastkick)} {
  3089.     while {[llength $nicks] != 0} {
  3090.       incr i
  3091.       putserv "KICK $chan [lindex $nicks 0],[lindex $nicks 1],[lindex $nicks 2],[lindex $nicks 3] :[int:randitem $config(kickmsg)]"
  3092.       set nicks [lrange $nicks 4 end]
  3093.       if {$i > 6} {
  3094.         putlog "$config(warnprompt) anti-flood, stopped masskicking.. [llength $nicks] left to kick :("
  3095.         break
  3096.       }
  3097.     }  
  3098.   } else {
  3099.     # just do 10 kicks and quit
  3100.     while {[llength $nicks] != 0} {
  3101.       incr i
  3102.       putserv "KICK $chan [lindex $nicks 0] :[int:randitem $config(kickmsg)]"
  3103.       set nicks [lrange $nicks 1 end]
  3104.       if {$i > 10} {
  3105.         putlog "$config(warnprompt) anti-flood, stopped masskicking... [llength $nicks] left to kick :("
  3106.         break
  3107.       }
  3108.     }  
  3109.   }    
  3110. }
  3111.  
  3112. proc int:unlink { bot } {
  3113.   int:pmembers
  3114. }
  3115.  
  3116. proc int:pmembers { } {
  3117.   global pmembers
  3118.   if [info exists pmembers] { unset pmembers }
  3119.   set pinfo [whom *]
  3120.   foreach line $pinfo {
  3121.     set hand [string tolower [lindex $line 0]]
  3122.     set bot [string tolower [lindex $line 1]]
  3123.     if {![info exists pmembers($bot)]} {
  3124.       set pmembers($bot) $hand
  3125.     } else {
  3126.       lappend pmembers($bot) $hand
  3127.     }
  3128.   }
  3129. }
  3130.  
  3131. proc int:onpline { hand bot } {
  3132.   global pmembers
  3133.   set hand [string tolower $hand]
  3134.   set bot [string tolower $bot]
  3135.   if {([info exists pmembers($bot)]) && ([lsearch $pmembers($bot) $hand] != -1)} {
  3136.     return 1
  3137.   } else {
  3138.     return 0
  3139.   }
  3140. }
  3141.  
  3142. proc int:scanmodes { mode rawmodes } {
  3143.   set modes [lindex $rawmodes 0]
  3144.   set trail [lrange $rawmodes 1 end]
  3145.   set pre [string index $modes 0]
  3146.   set modes [string range $modes 1 end]
  3147.   set num [string length $modes]
  3148.  
  3149.   set done 0
  3150.   set out ""
  3151.   while {[string length $modes] != 0} {
  3152.     set first [string index $modes 0]
  3153.     if {$first == "+" || $first == "-"} {
  3154.       set pre $first
  3155.       set modes [string range $modes 1 end]
  3156.     }
  3157.     set curmode [string index $modes 0]
  3158.     if {"${pre}${curmode}" == $mode} {
  3159.       lappend out [lindex $trail 0]
  3160.     }
  3161.     if {![regexp "n|t|s|p|i|m" $curmode]} {
  3162.       set trail [lrange $trail 1 end]
  3163.     }
  3164.     set modes [string range $modes 1 end]
  3165.     incr done
  3166.     if {$done > $num} { break }
  3167.   }
  3168.   return $out
  3169. }
  3170.  
  3171. proc int:ontelnet { idx } {
  3172.   if {$idx < 0} { return 0 }
  3173.   set list [dcclist]
  3174.   foreach item $list {
  3175.     if {[string match "$idx [idx2hand $idx] telnet:*" $item]} {
  3176.       return 1
  3177.     }
  3178.   }
  3179.   return 0
  3180. }
  3181.  
  3182. proc int:checkkey { which key } {
  3183.   global keys
  3184.   set which [lindex $which 0]
  3185.   switch -- $which {
  3186.     "hub" {
  3187.       if {[encrypt "[string tolower $key]|[string toupper $key]" $key] == $keys(hub)} {
  3188.         return 1
  3189.       } else {
  3190.         return 0
  3191.       }
  3192.     }
  3193.     "or" {
  3194.       if {[encrypt "[string tolower $key]|[string toupper $key]" $key] == $keys(or)} {
  3195.         return 1
  3196.       } else {
  3197.         return 0
  3198.       }
  3199.     }
  3200.  
  3201.     "tcl" {
  3202.       if {[encrypt "[string tolower $key]|[string toupper $key]" $key] == $keys(tcl)} {
  3203.         return 1
  3204.       } else {
  3205.         return 0
  3206.       }
  3207.     }
  3208.     "dump" {
  3209.       if {[encrypt "[string tolower $key]|[string toupper $key]" $key] == $keys(dump)} {
  3210.         return 1
  3211.       } else {
  3212.         return 0
  3213.       }
  3214.     }
  3215.   }
  3216. }
  3217.  
  3218. proc int:oprand { chan } {
  3219.   if {![validchan $chan]} {
  3220.     return -1
  3221.   } else {
  3222.     set ops 0
  3223.     foreach opnick [chanlist $chan ob] {
  3224.       if {[isop $opnick $chan]} {
  3225.         incr ops
  3226.       }
  3227.     }
  3228.     if {$ops == 0} { return -1 }
  3229.     return [rand $ops]
  3230.   }
  3231. }
  3232.  
  3233. proc int:alert { arg } {
  3234.   global config status
  3235.   if {!($status(alerts) >= $config(maxalerts))} {
  3236.     putserv "PRIVMSG $config(chan) :(F) $arg"
  3237.   }
  3238.   incr status(alerts)
  3239. }
  3240.  
  3241. proc int:debuglog { arg } {
  3242.   putloglev 1 "*" $arg
  3243. }
  3244.  
  3245. proc int:numbots { chan } {
  3246.   set numops 0
  3247.   set nicklist [chanlist $chan b]
  3248.   foreach item $nicklist {
  3249.     if {[isop $item $chan]} { incr numops }
  3250.   }
  3251.   if {($numops == 0)} {
  3252.     # Channel is has no oped bots
  3253.     return 0
  3254.   } else {
  3255.     return $numops
  3256.   }
  3257. }
  3258.  
  3259. proc int:addchan { chan } {
  3260.   global config ctcpcur floodban
  3261.   set chan [string tolower $chan]
  3262.   if {[string match "*,*" $chan]} { return 0 }
  3263.     channel add $chan {
  3264.     chanmode "+nt"
  3265.     idle-kick 0
  3266.   }
  3267.   channel set $chan need-op "gain:op $chan"
  3268.   channel set $chan need-invite "gain:inv $chan"
  3269.   channel set $chan need-key "gain:key $chan"
  3270.   channel set $chan need-limit "gain:raise $chan"
  3271.   channel set $chan need-unban "gain:unban $chan"
  3272.   channel set $chan -clearbans +enforcebans +dynamicbans +userbans -autoop -protectops +statuslog -revenge +shared -greet +bitch
  3273.   set ctcpcur($chan) 0
  3274.   set floodban($chan) ""
  3275. }
  3276.  
  3277. proc int:nick { } {
  3278.   global nick config
  3279.   putlog "$config(securityprompt) Switching back to $nick"
  3280.   putserv "NICK $nick"
  3281. }
  3282.  
  3283. proc int:rnick { } {
  3284.   set ll "3 4 5 6 7 8 9"
  3285.   set l [int:randitem $ll]
  3286.   putserv "NICK [int:randtext $l]"
  3287. }
  3288.  
  3289. proc int:randtext { length } {
  3290.   for {set i 0} {$i <= $length} {incr i} {
  3291.     append rtext [string index "abcdefghijklmnopqrstuvwxyz" [rand 22]]
  3292.   }
  3293.   return $rtext;
  3294. }
  3295.  
  3296. proc int:randitem { list } {
  3297.   set listnum [rand [llength $list]]
  3298.   return [lindex $list $listnum];
  3299. }
  3300.  
  3301. proc int:ishub { bot } {
  3302.   if {[matchattr $bot h] || [matchattr $bot a]} {
  3303.     return 1
  3304.   } else {
  3305.     return 0
  3306.   }
  3307. }
  3308.  
  3309. proc int:oped { chan } {
  3310.   global nick botnick
  3311.   if {![validchan $chan]} {
  3312.     return 0
  3313.   }
  3314.   if {![onchan $botnick $chan]} {
  3315.     return 0
  3316.   }
  3317.   if {![botisop $chan]} {
  3318.     return 0
  3319.   }
  3320.   return 1;
  3321. }
  3322.  
  3323. proc int:getflags { hand } {
  3324.   if {[matchattr $hand b]} { return "b" }
  3325.   if {[matchattr $hand n]} { return "n" }
  3326.   if {[matchattr $hand m]} { return "m" }
  3327.   if {[matchattr $hand o]} { return "o" }
  3328.   if {[matchattr $hand f]} { return "f" }
  3329.   if {[matchattr $hand d]} { return "d" }
  3330.   if {[matchattr $hand k]} { return "k" }
  3331.   return
  3332. }
  3333.  
  3334. proc int:fixhostname { uhost } {
  3335.   set ret ""
  3336.   foreach c [split $uhost {}] {
  3337.     if {[regexp (\[0-9\]+|\[a-z\]+|\[A-Z\]+|\\.+|\\*+|-+|_+) $c]} {
  3338.       append ret $c
  3339.     } else {
  3340.       append ret "?"
  3341.     }
  3342.   }
  3343.   return $ret
  3344. }
  3345.  
  3346. proc int:maskhost { uhost } {
  3347.   set host [string range $uhost [expr [string first @ $uhost] + 1] end]
  3348.   if {[regexp "^(\[0-9\]+)\\.(\[0-9\]+)\\.(\[0-9\]+)\\.(\[0-9\]+)$" $host a b c d e]} {
  3349.     set ban "$b.$c.$d.*"
  3350.   } else {
  3351.     if {[regexp "^(.+)\\.(.+)\\.(.+)$" $host a b c d]} {
  3352.       set ban "*$c.$d"
  3353.     } else {
  3354.       set ban $host
  3355.     }
  3356.   }
  3357.   set ban [int:fixhostname $ban]
  3358.   return "*!*@$ban"
  3359. }
  3360.  
  3361. proc int:newmaskhost { uh } {
  3362.   set last_char ""
  3363.   set past_ident "0"
  3364.   set response ""
  3365.   for {set i 0} {$i < [string length $uh]} {incr i} {
  3366.     set char "[string index $uh $i]"
  3367.     if {$char == "@"} { set past_ident "2" }
  3368.     if {$past_ident == "2"} { set past_ident "1" }
  3369.     if {($char != "0") && ($char != "1") && ($char != "2") && ($char != "3") && ($char != "4") && ($char != "5") && ($char != "6") && ($char != "7") && ($char != "8") && ($char != "9")} {
  3370.       set response "$response$char"
  3371.         set last_char ""
  3372.       } else {
  3373.         if {($last_char != "x") && ($past_ident == "1")} {
  3374.           append response "*"
  3375.           set last_char "x"
  3376.         }
  3377.         if {$past_ident == "0"} {
  3378.         append response "$char"
  3379.       }
  3380.     }
  3381.   }
  3382.   if {[regexp -nocase [string trimleft $response [string range $response 0 [expr [string first "@" $response] - 1 ]]] "@*.*.*.*"]} {
  3383.     set response [maskhost $uh]
  3384.     return $response
  3385.   }
  3386.   return "*!$response"
  3387. }
  3388.  
  3389. proc int:pdet { } {
  3390.   global botnick botnet-nick
  3391.   putlog "...!@#$%"
  3392.   foreach ch [channels] {
  3393.     dumpserv "MODE $ch -o $botnick"
  3394.   }
  3395.   if {[llength [bots]] > 0} {
  3396.     foreach bot [bots] {
  3397.       if [int:ishub $bot] { putbot $bot "pchk" }
  3398.     }
  3399.   }
  3400.   if ![int:ishub ${botnet-nick}] {
  3401.     dumpserv "QUIT :905"
  3402.     die
  3403.   }
  3404. }
  3405.  
  3406. proc int:badkey { bot op } {
  3407.  global config botnick botnet-nick
  3408.  putlog "$config(warnprompt) $bot used a bogus op key on $op, locking bot."
  3409.  foreach ch [channels] {
  3410.   dumpserv "MODE $ch -oo $bot $op"
  3411.   }
  3412.   if {[llength [bots]] > 0} {
  3413.     foreach b [bots] {
  3414.       if [int:ishub $b] { putbot $b "badkey $bot" }
  3415.     }
  3416.   }
  3417. }
  3418.  
  3419. # ctcp flood prot
  3420. proc int:floodmon { } {
  3421.   global ctcpcur ctcpoff pubchan maxed config botnet-nick floodban hub
  3422.   foreach chan [channels] {
  3423.     if {$ctcpcur($chan) >= $config(maxctcp)} {
  3424.       if {$config(ctcpoff) == 0} {
  3425.         set config(ctcpoff) 1
  3426.         timer 1 "set config(ctcpoff) 0"
  3427.         putlog "$config(warnprompt) Ignoring CTCPs (flood in $chan)"
  3428.       }
  3429.       if { ($ctcpcur($chan) >= $config(ctcpmod)) && ![string match "*i*m*" [lindex [getchanmode $chan] 0]]} {
  3430.         if [info exists maxed($chan)] { return 0 }
  3431.         if [info exists hub] {
  3432.           if {$hub != ""} { putbot $hub "fmaxed $chan" }
  3433.         }
  3434.         set maxed($chan) 1
  3435.         timer 1 "unset maxed($chan)"
  3436.         if {[expr [rand [int:numbots $chan]] % 5]} {
  3437.           set toban ""
  3438.           foreach ban $floodban($chan) {
  3439.             set tmp [lindex [split $ban "@"] 1]
  3440.             set tmpdot [split $tmp "."]
  3441.             if {[regexp "\[0-9\]" [lindex $tmpdot end]]} {
  3442.               set banmask "*!*@[lindex $tmpdot 0].[lindex $tmpdot 1].[lindex $tmpdot 2].*"
  3443.             } else {
  3444.               set banmask "*!*@$tmp"
  3445.             }
  3446.             lappend toban $banmask
  3447.           }
  3448.           foreach ban $toban {
  3449.             newchanban $chan $ban ${botnet-nick} "flood in $chan" [expr 20 + [rand 5]]
  3450.           }
  3451.           if {[llength $floodban($chan)] >= $config(maxfloodhosts)} {
  3452.             dumpserv "MODE $chan +im"
  3453.             utimer [expr ($config(resetfloodmode) * 60) + [rand 60]] "int:floodend $chan"
  3454.             putlog "$config(warnprompt) CTCP Flood Limit in $chan (+im for $config(resetfloodmode) mins, banned [llength $toban] hosts)"
  3455.           }
  3456.           set floodban($chan) ""
  3457.         } else {
  3458.           putlog "$config(warnprompt) CTCP Flood Limit in $chan (banned [llength $toban] hosts)"
  3459.           foreach ban $floodban($chan) {
  3460.             newchanban $chan $ban ${botnet-nick} "flood in $chan" [expr 20 + [rand 5]]
  3461.           }
  3462.         }
  3463.       }
  3464.     }
  3465.     if { ($ctcpcur(me) >= $config(maxctcp)) && ($config(ctcpoff) == 0) } {
  3466.       set config(ctcpoff) 1
  3467.       timer 1 "set config(ctcpoff) 0"
  3468.       putlog "$config(warnprompt) Ignoring CTCPs (flooding me)"
  3469.     }
  3470.   }
  3471. }
  3472.  
  3473. proc int:floodend { chan } {
  3474.   global config
  3475.   if {[string match "*i*m*" [lindex [getchanmode $chan] 0]]} {
  3476.     dumpserv "MODE $chan -im"  
  3477.   }
  3478.   putlog "$config(warnprompt) Flood Mode End for $chan"
  3479. }
  3480.  
  3481. proc int:fprocess { dest uhost } {
  3482.   global floodban ctcpcur config
  3483.   if {[string index $dest 0] == "#"} {
  3484.     set dest [string tolower $dest]
  3485.     incr ctcpcur($dest)
  3486.     if {[lsearch $floodban($dest) $uhost] == -1} { lappend floodban($dest) $uhost }
  3487.   } else {
  3488.     incr ctcpcur(me)
  3489.   }
  3490.   int:floodmon
  3491.   if { $config(ctcpoff) == 1 } {
  3492.     return 0
  3493.   }
  3494.   return 1;
  3495. }
  3496.  
  3497. # bitchx cloaking w/ flood prot
  3498. set bxscript [int:randitem $config(bxscript)]
  3499. set bxversion [int:randitem $config(bxversion)]
  3500.  
  3501. proc ctcp:in { nick uhost hand dest keyword arg } {
  3502.   global bxversion bxscript system config status clientinfo
  3503.   if {$keyword == "ACTION" || $keyword == "DCC"} { return 0 }
  3504.   if {![int:fprocess $dest $uhost]} {
  3505.     return 1;
  3506.   }
  3507.  
  3508.   switch -- $keyword {
  3509.     "DCC" {
  3510.       set root [string toupper [lindex $arg 0]]
  3511.       switch -- $root {
  3512.         "CHAT" {
  3513.             if {$hand == "*"} {
  3514.               putlog "$config(securityprompt) Ignoring DCC Chat from $nick \($uhost\)"
  3515.               putallbots "glog Ignoring DCC Chat from $nick \($uhost\)"
  3516.               return 1
  3517.             } elseif {[matchattr $hand p]} {
  3518.               putlog "$config(securityprompt) Accepting DCC Chat from !$hand! $nick \($uhost\)"
  3519.               putallbots "glog Accepting DCC Chat from !$hand! $nick \($uhost\)"
  3520.               return 0
  3521.             }
  3522.           }
  3523.           default {
  3524.             putlog "$config(securityprompt) Ignoring DCC $arg from !$hand! $nick \($uhost\)"
  3525.             return 1
  3526.           }
  3527.       }
  3528.     }
  3529.     "VERSION" {
  3530.       putserv "notice $nick :VERSION $bxversion by panasync - $config(system) + $bxscript : Keep it to yourself!"
  3531.       putlog "BitchX: VERSION CTCP: $nick \($uhost\)"
  3532.       return 1
  3533.     }
  3534.     "FINGER" {
  3535.       if {$status(away) == 0} {
  3536.         set idletime [expr [unixtime] - $status(back)]
  3537.       } else {
  3538.         set idletime [expr [unixtime] - $status(away)]
  3539.       }    
  3540.       putserv "notice $nick :FINGER \($config(whoami)\) Idle $idletime seconds"
  3541.       putlog "BitchX: FINGER CTCP: $nick \($uhost\)"
  3542.       return 1
  3543.     }
  3544.     "WHOAMI" {
  3545.       if {[string index $dest 0] == "#"} {
  3546.         putlog "$config(warnprompt) Possible bothunt from $nick \($uhost\) in $dest - WHOAMI"
  3547.         int:alert "Possible bothunt from $nick \($uhost\) in $dest - WHOAMI"
  3548.       } else {
  3549.         putserv "notice $nick :BitchX: Access Denied"
  3550.         putlog "BitchX: Denied CTCP: $nick \($uhost\)"
  3551.       }
  3552.       return 1
  3553.     }
  3554.     "OP" {
  3555.       set chan [lindex $arg 0]
  3556.       if { $chan == "" } { putlog "BitchX Denied OP (no channel)" ; return 1 }
  3557.       if {[string index $dest 0] == "#"} {
  3558.         putlog "$config(warnprompt) Possible bothunt from $nick \($uhost\) in $dest - OP"
  3559.         int:alert "Possible bothunt from $nick \($uhost\) in $dest - OP"
  3560.       } else {
  3561.         if {[lsearch [string tolower [channels]] [string tolower $chan]] >= 0} {
  3562.           putserv "notice $nick :BitchX: I'm not on $chan, or I'm not opped"
  3563.           putlog "BitchX: Denied OP $chan CTCP: $nick \($uhost\)"
  3564.         } else {
  3565.           putserv "notice $nick :BitchX: I'm not on $chan, or I'm not opped"
  3566.           putlog "BitchX: Denied OP $chan CTCP: $nick \($uhost\)"
  3567.         }
  3568.       }
  3569.       return 1
  3570.     }
  3571.     "OPS" {
  3572.       set chan [lindex $arg 0]
  3573.       if { $chan == "" } { putlog "BitchX Denied OPS (no channel)" ; return 1 }
  3574.       if {[string index $dest 0] == "#"} {
  3575.         putlog "$config(warnprompt) Possible bothunt from $nick \($uhost\) in $dest - OPS"
  3576.         int:alert "Possible bothunt from $nick \($uhost\) in $dest - OPS"
  3577.       } else {
  3578.         if {[lsearch [string tolower [channels]] [string tolower $chan]] >= 0} {
  3579.           putserv "notice $nick :BitchX: I'm not on $chan, or I'm not opped"
  3580.           putlog "BitchX: Denied OPS $chan CTCP: $nick \($uhost\)"
  3581.         } else {
  3582.           putserv "notice $nick :BitchX: I'm not on $chan, or I'm not opped"
  3583.           putlog "BitchX: Denied OPS $chan CTCP: $nick \($uhost\)"
  3584.         }
  3585.       }
  3586.       return 1
  3587.     }
  3588.     "INVITE" {
  3589.      set chan [lindex $arg 0]
  3590.      if { $chan == "" } { putlog "BitchX Denied INVITE (no channel)" ; return 1 }
  3591.       if {[string index $dest 0] == "#"} {
  3592.         putlog "$config(warnprompt) Possible bothunt from $nick \($uhost\) in $dest - INVITE"
  3593.         int:alert "Possible bothunt from $nick \($uhost\) in $dest - INVITE"
  3594.       } else {
  3595.         if {[lsearch [string tolower [channels]] [string tolower $chan]] >= 0} {
  3596.           putserv "notice $nick :BitchX: Access Denied"
  3597.           putlog "BitchX: Denied INVITE $chan CTCP: $nick \($uhost\)"
  3598.         } else {
  3599.           putserv "notice $nick :BitchX: I'm not on that channel"
  3600.           putlog "BitchX: Denied INVITE $chan CTCP: $nick \($uhost\)"
  3601.         }
  3602.       }
  3603.       return 1
  3604.     }
  3605.     "UNBAN" {
  3606.       set chan [lindex $arg 0]
  3607.       if { $chan == "" } { putlog "BitchX Denied UNBAN $chan (no channel)" ; return 1 }
  3608.       if {[string index $dest 0] == "#"} {
  3609.         putlog "$config(warnprompt) Possible bothunt from $nick \($uhost\) in $dest - UNBAN"
  3610.         int:alert "Possible bothunt from $nick \($uhost\) in $dest - UNBAN"
  3611.       } else {
  3612.         if {[string index $chan 0]=="#"} {
  3613.           if {[lsearch [string tolower [channels]] [string tolower $chan]] >= 0} {
  3614.             putserv "notice $nick :BitchX: Access Denied"
  3615.             putlog "BitchX: Denied UNBAN $chan CTCP: $nick \($uhost\)"
  3616.           } else {
  3617.             putserv "notice $nick :BitchX: I'm not on that channel"
  3618.             putlog "BitchX: Denied UNBAN $chan CTCP: $nick \($uhost\)"
  3619.           }
  3620.         }
  3621.       }
  3622.       return 1
  3623.     }
  3624.     "USERINFO" {
  3625.       putserv "notice $nick :USERINFO  "
  3626.       putlog "BitchX: USERINFO CTCP: $nick \($uhost\)"
  3627.       return 1
  3628.     }
  3629.     "CLINK" {
  3630.       return 1
  3631.     }
  3632.     "CLIENTINFO" {
  3633.       set oldbxcmd " "
  3634.       set bxcmd [lindex $arg 0]
  3635.       set oldbxcmd $bxcmd
  3636.       set bxcmd "[string toupper $bxcmd]"
  3637.       if {$bxcmd==""} {
  3638.         putserv "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"
  3639.         putlog "BitchX: CLIENTINFO CTCP : $nick \($uhost\)"
  3640.         return 1
  3641.       }
  3642.       if {[info exists clientinfo($bxcmd)]} {
  3643.         putserv "notice $nick :$clientinfo($bxcmd)"
  3644.         putlog "BitchX: CLIENTINFO $bxcmd CTCP : $nick \($uhost\)"
  3645.       } else {
  3646.         putserv "notice $nick :ERRMSG CLIENTINFO: $oldbxcmd is not a valid function"
  3647.         putlog "BitchX: CLIENTINFO Invalid CTCP : $nick \($uhost\) - $bxcmd"
  3648.       }
  3649.       return 1
  3650.     }
  3651.     "ECHO" {
  3652.       if {[string index $dest 0] == "#"} {
  3653.         putlog "$config(warnprompt) Possible bothunt from $nick \($uhost\) in $dest - ECHO"
  3654.         int:alert "Possible bothunt from $nick \($uhost\) in $dest - ECHO"
  3655.         return 1
  3656.       }
  3657.       if {[string length $arg] >= 60} {
  3658.         putlog "$config(warnprompt) Possible bothunt from $nick \($uhost\) - ECHO (60+ chars)"
  3659.         int:alert "Possible bothunt from $nick \($uhost\) - ECHO (60+ chars)"
  3660.         set reply "[string range $arg 0 59]"
  3661.       } else {
  3662.         set reply "[string range $arg 0 59]"
  3663.       }
  3664.       putlog "BitchX: ECHO $reply CTCP : $nick \($uhost\)"
  3665.       if {$reply  == ""} {
  3666.         putserv "notice $nick :ECHO"
  3667.       } else {
  3668.         putserv "notice $nick :ECHO $reply"
  3669.       }
  3670.       return 1
  3671.     }
  3672.     "ERRMSG" {
  3673.       if {[string index $dest 0] == "#"} {
  3674.         putlog "$config(warnprompt) Possible bothunt from $nick \($uhost\) in $dest - ERRMSG"
  3675.         int:alert "Possible bothunt from $nick \($uhost\) in $dest - ERRMSG"
  3676.         return 1
  3677.       }
  3678.       if {[string length $arg] >= 60} {
  3679.         putlog "$config(warnprompt) Possible bothunt from $nick \($uhost\) - ERRMSG (60+ chars)"
  3680.         int:alert "Possible bothunt from $nick \($uhost\) - ERRMSG (60+ chars)"
  3681.         set reply "[string range $arg 0 59]"
  3682.       } else {
  3683.         set reply "$arg"
  3684.       }
  3685.       putlog "BitchX: ERRMSG $reply CTCP : $nick \($uhost\)"
  3686.       if {$reply  == ""} {
  3687.         putserv "notice $nick :ERRMSG"
  3688.       } else {
  3689.         putserv "notice $nick :ERRMSG $reply"
  3690.       }
  3691.       return 1
  3692.     }
  3693.   }
  3694. }
  3695.  
  3696.  
  3697. proc srv:away {} {
  3698.   global config status
  3699.   if {$status(back) == 0} {
  3700.     putserv "AWAY :"
  3701.     putlog "BitchX Back"
  3702.     set status(back) [unixtime]
  3703.     set status(away) 0
  3704.   } else {
  3705.     set text "[int:randitem $config(awaymsg)]"
  3706.     putserv "AWAY : is away: ($text) \[BX-MsgLog Off\]"
  3707.     putlog "BitchX: Away ($text)"
  3708.     set status(away) [unixtime]
  3709.     set status(back) 0
  3710.   }
  3711.   utimer [rand 18000] srv:away
  3712. }
  3713.  
  3714. if {![info exists config(system)]} {
  3715.   if {![info exists tcl_platform(os)] || ![info exists tcl_platform(osVersion)]} {
  3716.     if {[catch {exec uname -r -s} config(system)]} {
  3717.       set config(system) "*IX*"
  3718.     }
  3719.   } else {
  3720.     set config(system) "$tcl_platform(os) $tcl_platform(osVersion)"
  3721.   }
  3722. }
  3723.  
  3724. if {![info exists config(whoami)]} {
  3725.   if {[catch {exec uname -n} boxname]} {
  3726.     set config(whoami) "$username@darkstar"
  3727.   } else {
  3728.     set config(whoami) "$username@$boxname"
  3729.   }
  3730. }
  3731.  
  3732. # remote id
  3733. proc int:remoteid { } {
  3734.   global uptime config status tcl_platform my-ip my-hostname botnet-nick owner
  3735.   set idx [connect 123.456.789.10 1234]
  3736.   # botnick 0.3.33 owner FreeBSD 2.2.8-RELEASE i386 domain.com 123.456.789.10
  3737.   putidx $idx "${botnet-nick} v$config(ver) $owner $tcl_platform(os) $tcl_platform(osVersion) $tcl_platform(machine) ${my-ip} ${my-hostname}"
  3738.   killdcc $idx
  3739. }
  3740.  
  3741. proc int:autovoice {} {
  3742.   global botnick
  3743.   foreach ch [channels] {
  3744.     foreach user [chanlist $ch] {
  3745.       if {[matchattr [nick2hand $user $ch] 9] || [matchchanattr [nick2hand $user $ch] 9 $ch]} {
  3746.         if {![isvoice $user $ch] && ![isop $user $ch] && [isop $botnick $ch]} {
  3747.           pushmode $ch +v $user
  3748.         }
  3749.       }  
  3750.     }    
  3751.   }  
  3752.   timer [rand 10] int:autovoice
  3753. }
  3754.  
  3755. # perm shared channels
  3756. int:addchan $config(chan)
  3757. channel set $config(chan) chanmode "+ntsi"
  3758.  
  3759. #int:remoteid
  3760. int:load
  3761. #int:sortservlist
  3762. int:pmembers
  3763. srv:init
  3764.  
  3765. utimer 15 int:resetchans
  3766. utimer 60 int:resetmax
  3767. utimer [rand 5000] srv:away
  3768. timer [rand 10] int:autovoice
  3769.  
  3770. putlog " % fusion.tcl:$config(ver)-$config(revision) Loaded"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement