summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CONTENTS78
-rw-r--r--action.fix.tcl26
-rw-r--r--alltools.tcl441
-rwxr-xr-xautobotchk377
-rwxr-xr-xbotchk103
-rw-r--r--cmd_resolve.tcl48
-rw-r--r--commands.tcl5
-rw-r--r--compat.tcl138
-rw-r--r--dccwhois.tcl167
-rw-r--r--decision.tcl104
-rw-r--r--eggdrop-pisg.tcl47
-rw-r--r--file.pl91
-rw-r--r--file.tcl15
-rw-r--r--fileextensions.txt2334
-rw-r--r--firstseen.pl40
-rw-r--r--firstseen.tcl17
-rw-r--r--getops.tcl371
-rw-r--r--google.tcl73
-rw-r--r--klined.tcl179
-rw-r--r--lastseen.pl64
-rw-r--r--lastseen.tcl76
-rw-r--r--lastspoke.pl52
-rw-r--r--name.tcl20
-rw-r--r--names.txt37
-rw-r--r--names_nick.txt48
-rw-r--r--notes2.tcl218
-rw-r--r--parse-fileext-wiki.pl42
-rw-r--r--parse-fileext.pl30
-rw-r--r--pong.tcl34
-rw-r--r--ques5.tcl370
-rw-r--r--quotepass.tcl41
-rw-r--r--quotepong.tcl288
-rw-r--r--sentinel.tcl1442
-rw-r--r--services.tcl78
-rw-r--r--test.pl7
-rw-r--r--time.tcl26
-rw-r--r--tinyurl.tcl99
-rw-r--r--userinfo.tcl285
-rwxr-xr-xweed593
-rw-r--r--whoisd.tcl232
-rw-r--r--whoisd.tcl_old155
-rw-r--r--wiki.pl100
-rw-r--r--wiki.pl.down3
-rw-r--r--wiki.tcl50
-rw-r--r--wiki2.pl100
45 files changed, 9144 insertions, 0 deletions
diff --git a/CONTENTS b/CONTENTS
new file mode 100644
index 0000000..36f6225
--- /dev/null
+++ b/CONTENTS
@@ -0,0 +1,78 @@
+$Id: CONTENTS,v 1.17 2010/01/03 13:27:31 pseudo Exp $
+
+Directory Contents - scripts/
+Last revised: August 08, 2004
+ _____________________________________________________________________
+
+ Directory Contents - scripts/
+
+ These are the example scripts that come with eggdrop. They're meant to be
+ useful AND to introduce Tcl to those who haven't dealt with it before. Even
+ people who program in Tcl may be confused by Eggdrop's implementation at
+ first, because so many commands were added to interface with the bot.
+
+ action.fix.tcl
+ Gets rid of those ugly /me's people do instead of a .me.
+
+ alltools.tcl
+ Several useful procs for use in scripts.
+
+ autobotchk
+ Tcl script used to crontab your Eggdrop. Type 'scripts/autobotchk' from the
+ Eggdrop's root directory for help.
+
+ botchk
+ A shell script which can be used for auto-starting the bot via 'cron'.
+
+ cmd_resolve.tcl
+ Adds a dcc command called '.resolve' which can be used to resolve hostnames
+ or IP addresses via the partyline.
+
+ compat.tcl
+ Maps old Tcl functions to new ones, for lazy people who can't be bothered
+ updating their scripts.
+
+ dccwhois.tcl
+ Enhances Eggdrop's built-in dcc '.whois' command to allow all
+ users to '.whois' their own handle.
+
+ getops.tcl
+ A way for bots to get ops from other bots on the botnet (if they're on the
+ same channel).
+
+ klined.tcl
+ Removes servers from your server list that your bot has been k-lined on, to
+ prevent admins getting peeved with constant connects from your bot's host.
+
+ notes2.tcl
+ Check your notes on every shared bot of the hub.
+
+ ques5.tcl
+ Makes web pages of who's on each channel, updated periodically (requires
+ alltools.tcl).
+
+ quotepass.tcl
+ Some servers on the Undernet will make you send 'PASS <numbers>' before
+ you can connect if you did not return an identd response. This script will
+ handle sending that for you.
+
+ quotepong.tcl
+ Some EFnet servers require the user to type /quote pong :<cookie>
+ when identd is broken or disabled. This will send pong :<cookie> to
+ the server when connecting.
+
+ sentinel.tcl (by slennox)
+ Flood protection script for Eggdrop with integrated BitchX CTCP simulation.
+ This script is designed to provide strong protection for your bot and
+ channels against large floodnets and proxy floods.
+
+ userinfo.tcl
+ Cute user info settings things.
+
+ weed
+ Weed out certain undesirables from an Eggdrop userlist. Type 'scripts/weed'
+ from the Eggdrop's root directory for help.
+
+ _____________________________________________________________________
+
+ Copyright (C) 2001 - 2010 Eggheads Development Team
diff --git a/action.fix.tcl b/action.fix.tcl
new file mode 100644
index 0000000..1030fd7
--- /dev/null
+++ b/action.fix.tcl
@@ -0,0 +1,26 @@
+# action.fix.tcl
+#
+# Copyright (C) 2002 - 2010 Eggheads Development Team
+#
+# Tothwolf 25May1999: cleanup
+# Tothwolf 04Oct1999: changed proc names slightly
+# poptix 07Dec2001: handle irssi (and some others) "correct" messages for DCC CTCP
+#
+# $Id: action.fix.tcl,v 1.12 2010/01/03 13:27:31 pseudo Exp $
+
+# Fix for mIRC dcc chat /me's:
+bind filt - "\001ACTION *\001" filt:dcc_action
+bind filt - "CTCP_MESSAGE \001ACTION *\001" filt:dcc_action2
+proc filt:dcc_action {idx text} {
+ return ".me [string trim [join [lrange [split $text] 1 end]] \001]"
+}
+
+proc filt:dcc_action2 {idx text} {
+ return ".me [string trim [join [lrange [split $text] 2 end]] \001]"
+}
+
+# Fix for telnet session /me's:
+bind filt - "/me *" filt:telnet_action
+proc filt:telnet_action {idx text} {
+ return ".me [join [lrange [split $text] 1 end]]"
+}
diff --git a/alltools.tcl b/alltools.tcl
new file mode 100644
index 0000000..36cbfa6
--- /dev/null
+++ b/alltools.tcl
@@ -0,0 +1,441 @@
+#
+# All-Tools TCL, includes toolbox.tcl, toolkit.tcl and moretools.tcl
+# toolbox was originally authored by cmwagner <cmwagner@sodre.net>
+# toolkit was originally authored by Robey Pointer
+# moretools was originally authored by David Sesno <walker@shell.pcrealm.net>
+# modified for 1.3.0 bots by TG
+#
+# Copyright (C) 1999, 2003 - 2010 Eggheads Development Team
+#
+# Tothwolf 02May1999: rewritten and updated
+# guppy 02May1999: updated even more
+# Tothwolf 02May1999: fixed what guppy broke and updated again
+# Tothwolf 24/25May1999: more changes
+# rtc 20Sep1999: added isnumber, changes
+# dw 20Sep1999: use regexp for isnumber checking
+# Tothwolf 06Oct1999: optimized completely
+# krbb 09Jun2000: added missing return to randstring
+# Tothwolf 18Jun2000: added ispermowner
+# Sup 02Apr2001: added matchbotattr
+# Tothwolf 13Jun2001: updated/modified several commands
+# Hanno 28Sep2001: fixed testip
+# guppy 03Mar2002: optimized
+# Souperman 05Nov2002: added ordnumber
+# Tothwolf 27Dec2003: added matchbotattrany, optimized ordnumber,
+# more minor changes
+#
+# $Id: alltools.tcl,v 1.23 2010/01/03 13:27:31 pseudo Exp $
+#
+########################################
+#
+# Descriptions of available commands:
+#
+##
+## (toolkit):
+##
+#
+# putmsg <nick/chan> <text>
+# send a privmsg to the given nick or channel
+#
+# putchan <nick/chan> <text>
+# send a privmsg to the given nick or channel
+# (for compat only, this is the same as 'putmsg' above)
+#
+# putnotc <nick/chan> <text>
+# send a notice to the given nick or channel
+#
+# putact <nick/chan> <text>
+# send an action to the given nick or channel
+#
+#
+##
+## (toolbox):
+##
+#
+# strlwr <string>
+# string tolower
+#
+# strupr <string>
+# string toupper
+#
+# strcmp <string1> <string2>
+# string compare
+#
+# stricmp <string1> <string2>
+# string compare (case insensitive)
+#
+# strlen <string>
+# string length
+#
+# stridx <string> <index>
+# string index
+#
+# iscommand <command>
+# if the given command exists, return 1
+# else return 0
+#
+# timerexists <command>
+# if the given command is scheduled by a timer, return its timer id
+# else return empty string
+#
+# utimerexists <command>
+# if the given command is scheduled by a utimer, return its utimer id
+# else return empty string
+#
+# inchain <bot>
+# if the given bot is connected to the botnet, return 1
+# else return 0
+# (for compat only, same as 'islinked')
+#
+# randstring <length>
+# returns a random string of the given length
+#
+# putdccall <text>
+# send the given text to all dcc users
+#
+# putdccbut <idx> <text>
+# send the given text to all dcc users except for the given idx
+#
+# killdccall
+# kill all dcc user connections
+#
+# killdccbut <idx>
+# kill all dcc user connections except for the given idx
+#
+#
+##
+## (moretools):
+##
+#
+# iso <nick> <channel>
+# if the given nick has +o access on the given channel, return 1
+# else return 0
+#
+# realtime [format]
+# 'time' returns the current time in 24 hour format '14:15'
+# 'date' returns the current date in the format '21 Dec 1994'
+# not specifying any format will return the current time in
+# 12 hour format '1:15 am'
+#
+# testip <ip>
+# if the given ip is valid, return 1
+# else return 0
+#
+# number_to_number <number>
+# if the given number is between 1 and 15, return its text representation
+# else return the number given
+#
+#
+##
+## (other commands):
+##
+#
+# isnumber <string>
+# if the given string is a valid number, return 1
+# else return 0
+#
+# ispermowner <handle>
+# if the given handle is a permanent owner, return 1
+# else return 0
+#
+# matchbotattr <bot> <flags>
+# if the given bot has all the given flags, return 1
+# else return 0
+#
+# matchbotattrany <bot> <flags>
+# if the given bot has any the given flags, return 1
+# else return 0
+#
+# ordnumber <string>
+# if the given string is a number, returns the
+# "ordinal" version of that number, i.e. 1 -> "1st",
+# 2 -> "2nd", 3 -> "3rd", 4 -> "4th", etc.
+# else return <string>
+#
+########################################
+
+# So scripts can see if allt is loaded.
+set alltools_loaded 1
+set allt_version 206
+
+# For backward compatibility.
+set toolbox_revision 1007
+set toolbox_loaded 1
+set toolkit_loaded 1
+
+#
+# toolbox:
+#
+
+proc putmsg {dest text} {
+ puthelp "PRIVMSG $dest :$text"
+}
+
+proc putchan {dest text} {
+ puthelp "PRIVMSG $dest :$text"
+}
+
+proc putnotc {dest text} {
+ puthelp "NOTICE $dest :$text"
+}
+
+proc putact {dest text} {
+ puthelp "PRIVMSG $dest :\001ACTION $text\001"
+}
+
+#
+# toolkit:
+#
+
+proc strlwr {string} {
+ string tolower $string
+}
+
+proc strupr {string} {
+ string toupper $string
+}
+
+proc strcmp {string1 string2} {
+ string compare $string1 $string2
+}
+
+proc stricmp {string1 string2} {
+ string compare [string tolower $string1] [string tolower $string2]
+}
+
+proc strlen {string} {
+ string length $string
+}
+
+proc stridx {string index} {
+ string index $string $index
+}
+
+proc iscommand {command} {
+ if {[string compare "" [info commands $command]]} then {
+ return 1
+ }
+ return 0
+}
+
+proc timerexists {command} {
+ foreach i [timers] {
+ if {![string compare $command [lindex $i 1]]} then {
+ return [lindex $i 2]
+ }
+ }
+ return
+}
+
+proc utimerexists {command} {
+ foreach i [utimers] {
+ if {![string compare $command [lindex $i 1]]} then {
+ return [lindex $i 2]
+ }
+ }
+ return
+}
+
+proc inchain {bot} {
+ islinked $bot
+}
+
+proc randstring {length {chars abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789}} {
+ if {([string compare "" $length]) && \
+ (![regexp \[^0-9\] $length])} then {
+ set count [string length $chars]
+ if {$count} then {
+ for {set index 0} {$index < $length} {incr index} {
+ append result [string index $chars [rand $count]]
+ }
+ } else {
+ error "empty character string"
+ }
+ } else {
+ error "invalid random string length"
+ }
+ return $result
+}
+
+proc putdccall {text} {
+ foreach i [dcclist CHAT] {
+ putdcc [lindex $i 0] $text
+ }
+}
+
+proc putdccbut {idx text} {
+ foreach i [dcclist CHAT] {
+ set j [lindex $i 0]
+ if {$j != $idx} then {
+ putdcc $j $text
+ }
+ }
+}
+
+proc killdccall {} {
+ foreach i [dcclist CHAT] {
+ killdcc [lindex $i 0]
+ }
+}
+
+proc killdccbut {idx} {
+ foreach i [dcclist CHAT] {
+ set j [lindex $i 0]
+ if {$j != $idx} then {
+ killdcc $j
+ }
+ }
+}
+
+#
+# moretools:
+#
+
+proc iso {nick chan} {
+ matchattr [nick2hand $nick $chan] o|o $chan
+}
+
+proc realtime {args} {
+ switch -exact -- [lindex $args 0] {
+ time {
+ return [strftime %H:%M]
+ }
+ date {
+ return [strftime "%d %b %Y"]
+ }
+ default {
+ return [strftime "%I:%M %P"]
+ }
+ }
+}
+
+proc testip {ip} {
+ set tmp [split $ip .]
+ if {[llength $tmp] != 4} then {
+ return 0
+ }
+ set index 0
+ foreach i $tmp {
+ if {(([regexp \[^0-9\] $i]) || ([string length $i] > 3) || \
+ (($index == 3) && (($i > 254) || ($i < 1))) || \
+ (($index <= 2) && (($i > 255) || ($i < 0))))} then {
+ return 0
+ }
+ incr index
+ }
+ return 1
+}
+
+proc number_to_number {number} {
+ switch -exact -- $number {
+ 0 {
+ return Zero
+ }
+ 1 {
+ return One
+ }
+ 2 {
+ return Two
+ }
+ 3 {
+ return Three
+ }
+ 4 {
+ return Four
+ }
+ 5 {
+ return Five
+ }
+ 6 {
+ return Six
+ }
+ 7 {
+ return Seven
+ }
+ 8 {
+ return Eight
+ }
+ 9 {
+ return Nine
+ }
+ 10 {
+ return Ten
+ }
+ 11 {
+ return Eleven
+ }
+ 12 {
+ return Twelve
+ }
+ 13 {
+ return Thirteen
+ }
+ 14 {
+ return Fourteen
+ }
+ 15 {
+ return Fifteen
+ }
+ default {
+ return $number
+ }
+ }
+}
+
+#
+# other commands:
+#
+
+proc isnumber {string} {
+ if {([string compare "" $string]) && \
+ (![regexp \[^0-9\] $string])} then {
+ return 1
+ }
+ return 0
+}
+
+proc ispermowner {hand} {
+ global owner
+
+ if {([matchattr $hand n]) && \
+ ([lsearch -exact [split [string tolower $owner] ", "] \
+ [string tolower $hand]] != -1)} then {
+ return 1
+ }
+ return 0
+}
+
+proc matchbotattr {bot flags} {
+ foreach flag [split $flags ""] {
+ if {[lsearch -exact [split [botattr $bot] ""] $flag] == -1} then {
+ return 0
+ }
+ }
+ return 1
+}
+
+proc matchbotattrany {bot flags} {
+ foreach flag [split $flags ""] {
+ if {[string first $flag [botattr $bot]] != -1} then {
+ return 1
+ }
+ }
+ return 0
+}
+
+proc ordnumber {string} {
+ if {[isnumber $string]} then {
+ set last [string index $string end]
+ if {[string index $string [expr [string length $string] - 2]] != 1} then {
+ if {$last == 1} then {
+ return ${string}st
+ } elseif {$last == 2} then {
+ return ${string}nd
+ } elseif {$last == 3} then {
+ return ${string}rd
+ }
+ }
+ return ${string}th
+ }
+ return $string
+}
diff --git a/autobotchk b/autobotchk
new file mode 100755
index 0000000..7a12d68
--- /dev/null
+++ b/autobotchk
@@ -0,0 +1,377 @@
+#! /bin/sh
+# This trick is borrowed from Tothwolf's Wolfpack \
+# Check for working 'grep -E' before using 'egrep' \
+if echo a | (grep -E '(a|b)') >/dev/null 2>&1; \
+then \
+ egrep="grep -E"; \
+else \
+ egrep=egrep; \
+fi; \
+# Search for tclsh[0-9].[0-9] in each valid dir in PATH \
+for dir in $(echo $PATH | sed 's/:/ /g'); \
+do \
+ if test -d $dir; \
+ then \
+ files=$(/bin/ls $dir | $egrep '^tclsh[0-9]\.[0-9]$'); \
+ if test "$files" != ""; \
+ then \
+ versions="${versions:+$versions }$(echo $files | sed 's/tclsh//g')"; \
+ fi; \
+ fi; \
+done; \
+for ver in $versions; \
+do \
+ tmpver=$(echo $ver | sed 's/\.//g'); \
+ if test "$lasttmpver" != ""; \
+ then \
+ if test "$tmpver" -gt "$lasttmpver"; \
+ then \
+ lastver=$ver; \
+ lasttmpver=$tmpver; \
+ fi; \
+ else \
+ lastver=$ver; \
+ lasttmpver=$tmpver; \
+ fi; \
+done; \
+exec tclsh$lastver "$0" ${1+"$@"}
+#
+# AutoBotchk - An eggdrop utility to autogenerate botchk/crontab entries
+#
+# Copyright (C) 1999, 2000, 2001, 2002 Jeff Fisher (guppy@eggheads.org)
+#
+# How to use
+# ----------
+#
+# Most people begin to use AutoBotchk by moving it from the script
+# directory to their Eggdrop directory -- this will save you from having to
+# use the -dir option.
+#
+# If you run AutoBotchk without any arguments, it will present you with
+# a list of valid ones. Most people run AutoBotchk by doing:
+#
+# ./autobotchk <config file>
+#
+# This will setup crontab to check every 10 minutes to see whether or not
+# your bot needs to be restarted and it will e-mail if a restart was
+# performed. A lot of people turn off crontab e-mail support; however, I do
+# not recommend this since you will be unable to see any errors that might
+# happen.
+#
+# Updates
+# -------
+# 27Sep2001: added new pidfile setting
+# 14Nov2001: removed old autobotchk update entries and updated the help
+# section a little bit. also made autobotchk move down one
+# directory if being run from the scripts directory.
+# 15Apr2003: cleaned up a few things, fixed a few bugs, and made a little
+# love! j/k
+#
+# $Id: autobotchk,v 1.12 2008/06/18 10:12:22 tothwolf Exp $
+#
+
+if {$argc == 0} {
+ puts "\nusage: $argv0 <eggdrop config> \[options\]"
+ puts " -dir (directory to run autobotchk in)"
+ puts " -noemail (discard crontab e-mails)"
+ puts " -5 (5 minute checks)"
+ puts " -10 (10 minute checks)"
+ puts " -15 (15 minute checks)"
+ puts " -30 (30 minute checks)"
+ puts ""
+ exit
+}
+
+fconfigure stdout -buffering none
+
+proc newsplit {text {split " "}} {
+ upvar $text ours
+ append ours $split
+ set index [string first $split $ours]
+ if {$index == -1} {
+ set ours ""
+ return ""
+ }
+ set tmp [string trim [string range $ours 0 $index]]
+ set ours [string trim [string range $ours [expr $index + [string length $split]] end]]
+ return $tmp
+}
+
+puts "\nautobotchk 1.10, (C) 2003 Jeff Fisher (guppy@eggheads.org)"
+puts "------------------------------------------------------------\n"
+
+set config [newsplit argv]
+set dir [pwd]
+set delay 10
+set email 1
+
+# If you renamed your eggdrop binary, you should change this variable
+set binary "eggdrop"
+
+while {[set opt [newsplit argv]] != ""} {
+ switch -- $opt {
+ "-time" -
+ "-1" { set delay 1 }
+ "-5" { set delay 5 }
+ "-10" { set delay 10 }
+ "-15" { set delay 15 }
+ "-20" { set delay 20 }
+ "-30" { set delay 30 }
+ "-nomail" -
+ "-noemail" {set email 0}
+ "-dir" {
+ set dir [newsplit argv]
+ if {[string match -* $dir]} {
+ puts "*** ERROR: you did not supply a directory name"
+ puts ""
+ exit
+ }
+ if {![file isdirectory $dir]} {
+ puts "*** ERROR: the directory you supplied is not a directory"
+ puts ""
+ exit
+ }
+ }
+ }
+}
+
+switch -- $delay {
+ "30" { set minutes "0,30" }
+ "20" { set minutes "0,20,40" }
+ "15" { set minutes "0,15,30,45" }
+ "5" { set minutes "0,5,10,15,20,25,30,35,40,45,50,55" }
+ "1" { set minutes "*" }
+ default { set minutes "0,10,20,30,40,50" }
+}
+
+if {[string match "*/scripts" $dir]} {
+ set dir [string range $dir 0 [expr [string length $dir] - 8]]
+}
+
+set dir [string trimright $dir /]
+
+if {![file exists $dir/help] || ![file isdirectory $dir/help]} {
+ puts "*** ERROR: are you sure you are running from a bot directory?"
+ puts ""
+ exit
+} elseif {![file exists $dir/$binary]} {
+ puts "*** ERROR: are you sure you are running from a bot directory?"
+ puts ""
+ exit
+}
+
+puts -nonewline "Opening '$config' for processing ... "
+
+if {[catch {open $dir/$config r} fd]} {
+ puts "error:"
+ puts " $fd\n"
+ exit
+} else {
+ puts "done"
+}
+
+set count 0
+puts -nonewline "Scanning the config file "
+
+while {![eof $fd]} {
+ incr count
+ if {$count == 100} {
+ puts -nonewline "."
+ set count 0
+ }
+ set line [gets $fd]
+ if {[set blarg [newsplit line]] != "set"} {
+ continue
+ }
+ switch -- [set opt [newsplit line]] {
+ "pidfile" -
+ "nick" -
+ "userfile" -
+ "botnet-nick" {
+ set $opt [string trim [newsplit line] " \""]
+ }
+ }
+}
+close $fd
+
+if {$count != 0} {
+ puts -nonewline "."
+}
+
+puts " done"
+
+ if {![info exists {botnet-nick}] && [info exists nick]} {
+ puts " Defaulting \$botnet-nick to \"$nick\""
+ set botnet-nick $nick
+ }
+ if {![info exists pidfile]} {
+ puts " Defaulting \$pidfile to \"pid.${botnet-nick}\""
+ set pidfile "pid.${botnet-nick}"
+ }
+ if {![info exists {botnet-nick}] || ![info exists userfile]} {
+ puts " *** ERROR: could not find either \$userfile or \$botnet-nick"
+ puts ""
+ puts " Are you sure this is a valid eggdrop config file?"
+ puts ""
+ exit
+ }
+ if {[catch {open $dir/${botnet-nick}.botchk w} fd]} {
+ puts " *** ERROR: unable to open '${botnet-nick}.botchk' for writing"
+ puts ""
+ exit
+ }
+ puts $fd "#! /bin/sh
+#
+# ${botnet-nick}.botchk (generated on [clock format [clock seconds] -format "%B %d, %Y @ %I:%M%p"])
+#
+# Generated by AutoBotchk 1.10
+# Copyright (C) 1999, 2000, 2001, 2002, 2003 Jeff Fisher <guppy@eggheads.org>
+#
+
+# change this to the directory you run your bot from:
+botdir=\"$dir\"
+
+# change this to the name of your bot's script in that directory:
+botscript=\"$binary $config\"
+
+# change this to the nickname of your bot (capitalization COUNTS)
+botname=\"${botnet-nick}\"
+
+# change this to the name of your bot's userfile (capitalization COUNTS)
+userfile=\"$userfile\"
+
+# change this to the name of your bot's pidfile (capitalization COUNTS)
+pidfile=\"$pidfile\"
+
+########## you probably don't need to change anything below here ##########
+
+cd \$botdir
+
+# is there a pid file?
+if test -r \$pidfile
+then
+ # there is a pid file -- is it current?
+ botpid=`cat \$pidfile`
+ if `kill -CHLD \$botpid >/dev/null 2>&1`
+ then
+ # it's still going -- back out quietly
+ exit 0
+ fi
+ echo \"\"
+ echo \"Stale \$pidfile file, erasing...\"
+ rm -f \$pidfile
+fi
+
+if test -r CANTSTART.\$botname
+then
+ if test -r \$userfile || test -r \$userfile~new || test -r \$userfile~bak
+ then
+ echo \"\"
+ echo \"Userfile found, removing check file 'CANTSTART.\$botname'...\"
+ rm -f CANTSTART.\$botname
+ fi
+fi
+
+# test if we have run botchk previously and didn't find a userfile
+if test ! -f CANTSTART.\$botname
+then
+ echo \"\"
+ echo \"Couldn't find bot '\$botname' running, reloading...\"
+ echo \"\"
+ # check for userfile and reload bot if found
+ if test -r \$userfile
+ then
+ # It's there, load the bot
+ ./\$botscript
+ exit 0
+ else
+ if test -r \$userfile~new
+ then
+ # Bot f*@!ed up while saving the userfile last time. Move it over.
+ echo \"Userfile missing. Using last saved userfile...\"
+ mv -f \$userfile~new \$userfile
+ ./\$botscript
+ exit 0
+ else
+ if test -r \$userfile~bak
+ then
+ # Userfile is missing, use backup userfile.
+ echo \"Userfile missing. Using backup userfile...\"
+ cp -f \$userfile~bak \$userfile
+ ./\$botscript
+ exit 0
+ else
+ # Well, nothing to work with...
+ echo \"No userfile. Could not reload the bot...\"
+ echo \"no userfile\" > CANTSTART.\$botname
+ exit 1
+ fi
+ fi
+ fi
+fi
+
+exit 0
+ "
+ close $fd
+ puts "Wrote '${botnet-nick}.botchk' successfully ([file size $dir/${botnet-nick}.botchk] bytes)"
+ if {[catch {exec chmod u+x $dir/${botnet-nick}.botchk} 0]} {
+ puts " *** ERROR: unable to 'chmod u+x' the output file"
+ puts ""
+ exit
+ }
+ puts -nonewline "Scanning crontab entries ... "
+
+set tmp ".autobotchk[clock clicks].[pid]"
+if {$email} {
+ set line "$minutes \* \* \* \* $dir/${botnet-nick}.botchk"
+} {
+ set line "$minutes \* \* \* \* $dir/${botnet-nick}.botchk >\/dev\/null 2>&1"
+}
+
+if {[catch {exec crontab -l > $tmp} error ]} {
+ if {![string match "*no*cron*" [string tolower $error]] &&
+ ![string match "*can't open*" [string tolower $error]]} {
+ catch {file delete -force $tmp} 0
+ puts "error: unable to get crontab listing"
+ puts ""
+ puts $error
+ puts ""
+ exit
+ }
+}
+
+set fd [open $tmp r]
+while {![eof $fd]} {
+ set z [gets $fd]
+ if {[string match "*$dir/${botnet-nick}.botchk*" $z] ||
+ [string match "*$dir//${botnet-nick}.botchk*" $z]} {
+ puts "found an existing entry, we're done now"
+ puts ""
+ exit
+ }
+}
+
+close $fd
+
+puts "done"
+
+puts -nonewline "Adding the new crontab entry ... "
+set fd [open $tmp a]
+puts $fd $line
+close $fd
+
+if {[catch {exec crontab $tmp} error]} {
+ puts "error: unable to do 'crontab $tmp'"
+ puts ""
+ puts $error
+ puts ""
+ exit
+} else {
+ catch {file delete -force $tmp} 0
+}
+
+puts "done"
+puts ""
+puts "Use 'crontab -l' to view all your current crontab entries"
+puts " 'crontab -r' to remove all your crontab entries"
+puts ""
diff --git a/botchk b/botchk
new file mode 100755
index 0000000..e66f94b
--- /dev/null
+++ b/botchk
@@ -0,0 +1,103 @@
+#! /bin/sh
+#
+# botchk
+#
+# $Id: botchk,v 1.6 2002/02/27 18:21:46 guppy Exp $
+#
+# This is a script suitable for use in a crontab. It checks to make sure
+# your bot is running. YOU NEED A SEPARATE CRON JOB FOR EACH BOT. If your
+# bot isn't found, it'll try to start it back up.
+#
+# You'll need to edit this script for your bot.
+#
+# To check for your bot every 10 minutes, put the following line in your
+# crontab:
+# 0,10,20,30,40,50 * * * * /home/mydir/mybot/botchk
+# And if you don't want to get email from crontab when it checks you bot,
+# put the following in your crontab:
+# 0,10,20,30,40,50 * * * * /home/mydir/mybot/botchk >/dev/null 2>&1
+#
+
+# change this to the directory you run your bot from (capitalization COUNTS):
+botdir="/home/mydir/mybot"
+
+# change this to the name of your bot's config file (capitalization COUNTS):
+botscript="mybot"
+
+# change this to the botnet-nick of your bot (capitalization COUNTS):
+botname="LamestBot"
+
+# change this to the name of your bot's userfile (capitalization COUNTS):
+userfile="LamestBot.user"
+
+# change this to the name of your bot's pidfile (capitalization COUNTS):
+pidfile="pid.LamestBot"
+
+########## you probably don't need to change anything below here ##########
+
+cd $botdir
+
+# is there a pid file?
+if test -r $pidfile
+then
+ # there is a pid file -- is it current?
+ botpid=`cat $pidfile`
+ if `kill -CHLD $botpid >/dev/null 2>&1`
+ then
+ # it's still going -- back out quietly
+ exit 0
+ fi
+ echo ""
+ echo "Stale $pidfile file, erasing..."
+ rm -f $pidfile
+fi
+
+if test -r CANTSTART.$botname
+then
+ if test -r $userfile || test -r $userfile~new || test -r $userfile~bak
+ then
+ echo ""
+ echo "Userfile found, removing check file 'CANTSTART.$botname'..."
+ rm -f CANTSTART.$botname
+ fi
+fi
+
+# test if we have run botchk previously and didn't find a userfile
+if test ! -f CANTSTART.$botname
+then
+ echo ""
+ echo "Couldn't find bot '$botname' running, reloading..."
+ echo ""
+ # check for userfile and reload bot if found
+ if test -r $userfile
+ then
+ # It's there, load the bot
+ ./$botscript
+ exit 0
+ else
+ if test -r $userfile~new
+ then
+ # Bot f*@!ed up while saving the userfile last time. Move it over.
+ echo "Userfile missing. Using last saved userfile..."
+ mv -f $userfile~new $userfile
+ ./$botscript
+ exit 0
+ else
+ if test -r $userfile~bak
+ then
+ # Userfile is missing, use backup userfile.
+ echo "Userfile missing. Using backup userfile..."
+ cp -f $userfile~bak $userfile
+ ./$botscript
+ exit 0
+ else
+ # Well, nothing to work with...
+ echo "No userfile. Could not reload the bot..."
+ echo "no userfile" > CANTSTART.$botname
+ exit 1
+ fi
+ fi
+ fi
+fi
+
+exit 0
diff --git a/cmd_resolve.tcl b/cmd_resolve.tcl
new file mode 100644
index 0000000..36ccb4e
--- /dev/null
+++ b/cmd_resolve.tcl
@@ -0,0 +1,48 @@
+#
+# cmd_resolve.tcl
+# written by Jeff Fisher (guppy@eggheads.org)
+#
+# This script adds the commands '.resolve' and '.dns' which can be used to
+# lookup hostnames or ip addresses in the partyline without causing the bot
+# to block while doing so thanks to the dns module.
+#
+# updates
+# -------
+# 15Apr2003: fixed a logging bug and stop using regexp incorrectly
+# 05Nov2000: fixed a nasty security hole, .resolve [die] <grin>
+# 04Nov2000: first version
+#
+# $Id: cmd_resolve.tcl,v 1.4 2003/04/16 01:03:04 guppy Exp $
+
+bind dcc -|- resolve resolve_cmd
+bind dcc -|- dns resolve_cmd
+
+proc resolve_cmd {hand idx arg} {
+ global lastbind
+ if {[scan $arg "%s" hostip] != 1} {
+ putidx $idx "Usage: $lastbind <host or ip>"
+ } else {
+ putidx $idx "Looking up $hostip ..."
+ set hostip [split $hostip]
+ dnslookup $hostip resolve_callback $idx $hostip $lastbind
+ }
+ return 0
+}
+
+proc resolve_callback {ip host status idx hostip cmd} {
+ if {![valididx $idx]} {
+ return 0
+ } elseif {!$status} {
+ putidx $idx "Unable to resolve $hostip"
+ } elseif {[string tolower $ip] == [string tolower $hostip]} {
+ putidx $idx "Resolved $ip to $host"
+ } else {
+ putidx $idx "Resolved $host to $ip"
+ }
+ putcmdlog "#[idx2hand $idx]# $cmd $hostip"
+ return 0
+}
+
+loadhelp cmd_resolve.help
+
+putlog "Loaded cmd_resolve.tcl successfully."
diff --git a/commands.tcl b/commands.tcl
new file mode 100644
index 0000000..86ba8a8
--- /dev/null
+++ b/commands.tcl
@@ -0,0 +1,5 @@
+#bind pub - np proc_np
+
+proc proc_np {nick host hand chan args} {
+# putserv "PRIVMSG $chan :-> supportboard!"
+}
diff --git a/compat.tcl b/compat.tcl
new file mode 100644
index 0000000..1093da8
--- /dev/null
+++ b/compat.tcl
@@ -0,0 +1,138 @@
+# compat.tcl
+# This script just quickly maps old Tcl commands to the new ones.
+# Use this if you are too lazy to get off your butt and update your scripts :D
+#
+# Copyright (C) 2002 - 2010 Eggheads Development Team
+#
+# Wiktor 31Mar2000: added binds and chnick proc
+# Tothwolf 25May1999: cleanup
+# Tothwolf 06Oct1999: optimized
+# rtc 10Oct1999: added [set|get][dn|up]loads functions
+# pseudo 04Oct2009: added putdccraw
+# Pixelz 08Apr2010: changed [time] to be compatible with Tcl [time]
+#
+# $Id: compat.tcl,v 1.19 2010/07/02 21:56:44 pseudo Exp $
+
+proc gethosts {hand} {
+ getuser $hand HOSTS
+}
+
+proc addhost {hand host} {
+ setuser $hand HOSTS $host
+}
+
+proc chpass {hand pass} {
+ setuser $hand PASS $pass
+}
+
+
+proc chnick {oldnick newnick} {
+ chhandle $oldnick $newnick
+}
+
+# setxtra is no longer relevant
+
+proc getxtra {hand} {
+ getuser $hand XTRA
+}
+
+proc setinfo {hand info} {
+ setuser $hand INFO $info
+}
+
+proc getinfo {hand} {
+ getuser $hand INFO
+}
+
+proc getaddr {hand} {
+ getuser $hand BOTADDR
+}
+
+proc setaddr {hand addr} {
+ setuser $hand BOTADDR $addr
+}
+
+proc getdccdir {hand} {
+ getuser $hand DCCDIR
+}
+
+proc setdccdir {hand dccdir} {
+ setuser $hand DCCDIR $dccdir
+}
+
+proc getcomment {hand} {
+ getuser $hand COMMENT
+}
+
+proc setcomment {hand comment} {
+ setuser $hand COMMENT $comment
+}
+
+proc getemail {hand} {
+ getuser $hand XTRA email
+}
+
+proc setemail {hand email} {
+ setuser $hand XTRA EMAIL $email
+}
+
+proc getchanlaston {hand} {
+ lindex [getuser $hand LASTON] 1
+}
+
+if {![llength [info commands {TCLTIME}]] && [llength [info commands {time}]]} {
+ rename time TCLTIME
+}
+
+proc time {args} {
+ if {([llength $args] != 0) && [llength [info commands {TCLTIME}]]} {
+ if {[llength [info commands {uplevel}]]} {
+ uplevel 1 TCLTIME $args
+ } else {
+ eval TCLTIME $args
+ }
+ } else {
+ strftime "%H:%M"
+ }
+}
+
+proc date {} {
+ strftime "%d %b %Y"
+}
+
+proc setdnloads {hand {c 0} {k 0}} {
+ setuser $hand FSTAT d $c $k
+}
+
+proc getdnloads {hand} {
+ getuser $hand FSTAT d
+}
+
+proc setuploads {hand {c 0} {k 0}} {
+ setuser $hand FSTAT u $c $k
+}
+
+proc getuploads {hand} {
+ getuser $hand FSTAT u
+}
+
+proc putdccraw {idx size text} {
+ if {!$idx} {
+ putloglev o * "Warning! putdccraw is deprecated. Use putnow instead!"
+ putnow $text
+ return -code ok
+ }
+ putloglev o * "Warning! putdccraw is deprecated. Use putdcc instead!"
+ if {![valididx $idx]} {return -code error "invalid idx"}
+ putdcc $idx $text -raw
+}
+
+# as you can see it takes a lot of effort to simulate all the old commands
+# and adapting your scripts will take such an effort you better include
+# this file forever and a day :D
+
+# Following are some TCL global variables that are obsolete now and have been removed
+# but are still defined here so not to break older scripts
+
+set strict-servernames 0
+
diff --git a/dccwhois.tcl b/dccwhois.tcl
new file mode 100644
index 0000000..c334a0d
--- /dev/null
+++ b/dccwhois.tcl
@@ -0,0 +1,167 @@
+###############################################################################
+##
+## dccwhois.tcl - Enhanced '.whois' dcc command for Eggdrop
+## Copyright (C) 2009 Tothwolf <tothwolf@techmonkeys.org>
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+###############################################################################
+##
+## $Id: dccwhois.tcl,v 1.1 2009/01/22 03:12:45 tothwolf Exp $
+##
+###############################################################################
+##
+## Description:
+##
+## This script enhances Eggdrop's built-in dcc '.whois' command to allow all
+## users to '.whois' their own handle.
+##
+## Users without the correct flags who attempt to '.whois' other users will
+## instead see the message: "You do not have access to whois handles other
+## than your own."
+##
+## To load this script, add a source command to your bot's config file:
+##
+## source scripts/dccwhois.tcl
+##
+## This script stores and checks against the flags that are used for
+## Eggdrop's built-in dcc '.whois' command at load time. If you wish to use
+## flags other than the default "to|o", etc, you should unbind and rebind
+## the built-in '.whois' command in your bot's config file before loading
+## this script.
+##
+## Example of how to rebind Eggdrop's built-in '.whois' command:
+##
+## unbind dcc to|o whois *dcc:whois
+## bind dcc to|m whois *dcc:whois
+##
+## Note: if you modify the default flags for '.whois' you may also wish to
+## modify the defaults for '.match'.
+##
+###############################################################################
+##
+## This script has no settings and does not require any configuration.
+## You should not need to edit anything below.
+##
+###############################################################################
+
+
+# This script should not be used with Eggdrop versions 1.6.16 - 1.6.19.
+catch {set numversion}
+if {([info exists numversion]) &&
+ ($numversion >= 1061600) && ($numversion <= 1061900)} then {
+ putlog "Error: dccwhois.tcl is not compatible with Eggdrop version [lindex $version 0]. Please upgrade to 1.6.20 or later."
+ return
+}
+
+
+#
+# dcc:whois --
+#
+# Wrapper proc command for Eggdrop's built-in *dcc:whois
+#
+# Arguments:
+# hand - handle of user who used this command
+# idx - dcc idx of user who used this command
+# arg - arguments passed to this command
+#
+# Results:
+# Calls Eggdrop's built-in *dcc:whois with the given arguments if user has
+# access, otherwise tells the user they don't have access.
+#
+proc dcc:whois {hand idx arg} {
+ global dccwhois_flags
+
+ set arg [split [string trimright $arg]]
+ set who [lindex $arg 0]
+
+ # Did user gave a handle other than their own?
+ if {([string compare "" $who]) &&
+ ([string compare [string toupper $hand] [string toupper $who]])} then {
+
+ # Get user's current .console channel; check the same way Eggdrop does.
+ set chan [lindex [console $idx] 0]
+
+ # User isn't allowed to '.whois' handles other than their own.
+ if {![matchattr $hand $dccwhois_flags $chan]} then {
+ putdcc $idx "You do not have access to whois handles other than your own."
+
+ return 0
+ }
+ }
+
+ # Call built-in whois command.
+ *dcc:whois $hand $idx $arg
+
+ # Return 0 so we don't log command twice.
+ return 0
+}
+
+
+#
+# init_dccwhois --
+#
+# Initialize dccwhois script-specific code when script is loaded
+#
+# Arguments:
+# (none)
+#
+# Results:
+# Set up command bindings and store command access flags.
+#
+proc init_dccwhois {} {
+ global dccwhois_flags
+
+ putlog "Loading dccwhois.tcl..."
+
+ # Sanity check...
+ if {[array exists dccwhois_flags]} then {
+ array unset dccwhois_flags
+ }
+
+ # Search binds for built-in '*dcc:whois' and loop over each bind in list
+ foreach bind [binds "\\*dcc:whois"] {
+
+ # dcc to|o whois 0 *dcc:whois
+ foreach {type flags name count command} $bind {break}
+
+ # We only want to unbind dcc '.whois'
+ if {[string compare $name "whois"]} then {
+ continue
+ }
+
+ # Store $flags so we can reuse them later
+ set dccwhois_flags $flags
+
+ # Unbind built-in *dcc:whois
+ unbind $type $flags $name $command
+ }
+
+ # Make sure $dccwhois_flags exists and isn't empty,
+ # otherwise set to Eggdrop's default "to|o"
+ if {(![info exists dccwhois_flags]) ||
+ (![string compare "" $dccwhois_flags])} then {
+ set dccwhois_flags "to|o"
+ }
+
+ # Add bind for dcc:whois wrapper proc
+ bind dcc -|- whois dcc:whois
+
+ putlog "Loaded dccwhois.tcl"
+
+ return
+}
+
+init_dccwhois
diff --git a/decision.tcl b/decision.tcl
new file mode 100644
index 0000000..8b7ad94
--- /dev/null
+++ b/decision.tcl
@@ -0,0 +1,104 @@
+# decision.tcl by lookshe (v 1.1)
+#
+# todo: little bit better coding style
+#
+# Changelog:
+#
+# 1.0
+# - first working version
+#
+# 1.1
+# - remember answers for 60 minutes (doesn't work atm)
+# mask arguments!
+
+
+bind pub - \[ proc_decision
+
+proc proc_decision {nick host hand chan arguments} {
+
+global do_dec
+if {[info exists do_dec($nick:$chan)]} {
+ if {$nick == "lookshe"} {
+ unset do_dec($nick:$chan)
+ } else {
+ set act_do_dec $do_dec($nick:$chan)
+ if {$act_do_dec < 3} {
+ incr act_do_dec
+ set do_dec($nick:$chan) $act_do_dec
+ } else {
+ putserv "NOTICE $nick :no flooding!"
+ return 0
+ }
+ }
+} else {
+ if {$nick != "lookshe"} {
+ set do_dec($nick:$chan) 1
+ timer 10 "unset do_dec($nick:$chan)"
+ }
+}
+
+ set allargs $arguments
+ set arguments [split $arguments]
+ set count 1
+ set klammer_count 0
+ if {([lindex $arguments 0] == "]") || ([string first "]" [lindex $arguments 0]] == 0)} {
+ incr klammer_count
+ } else {
+ return
+ }
+ while {$count != [llength $arguments]} {
+ if {[lindex $arguments $count] == "\["} {
+ set tmp $count
+ incr tmp
+ if {([lindex $arguments $tmp] == "]") || ([string first "]" [lindex $arguments $tmp]] == 0)} {
+ incr klammer_count
+ }
+ }
+ incr count
+ }
+ if {$klammer_count == 1} {
+ return
+ }
+ set count 0
+ set myrand [rand $klammer_count]
+ # if {[info exists do_dec($allargs)]} {
+ # set myrand $do_dec($allargs)
+ # } else {
+ # set do_dec($allargs) $myrand
+ # timer 60 "unset do_dec($allargs)"
+ # }
+ set klammer_count 0
+ if {$myrand == 0} {
+ set output "\[X"
+ while {$count != [llength $arguments]} {
+ set output "$output[lindex $arguments $count] "
+ incr count
+ }
+ } else {
+ set output "\["
+ while {$count != [llength $arguments]} {
+ if {[lindex $arguments $count] == "\["} {
+ set tmp $count
+ incr tmp
+ if {([lindex $arguments $tmp] == "]") || ([string first "]" [lindex $arguments $tmp]] == 0)} {
+ incr klammer_count
+ }
+ }
+ if {$klammer_count == $myrand} {
+ if {([lindex $arguments $count] == "]") || ([string first "]" [lindex $arguments $count]] == 0)} {
+ set output "[string range $output 0 end]X"
+ } else {
+ set output "$output "
+ }
+ } else {
+ set output "$output "
+ }
+ set output "$output[lindex $arguments $count]"
+ incr count
+ }
+
+ }
+ putserv "PRIVMSG $chan :$output"
+}
+
+putlog "decision by lookshe loaded"
diff --git a/eggdrop-pisg.tcl b/eggdrop-pisg.tcl
new file mode 100644
index 0000000..3069682
--- /dev/null
+++ b/eggdrop-pisg.tcl
@@ -0,0 +1,47 @@
+#pisg.tcl v0.15 by HM2K - auto stats script for pisg (perl irc statistics generator)
+#based on a script by Arganan
+
+# WARNING - READ THIS
+#
+# If you use this script, PLEASE read the documentation about the "Silent"
+# option. If you get the message "an error occured: Pisg v0.67 - perl irc
+# statistics generator" in the channel, you are NOT running silent. Fix it.
+
+set pisgver "0.15"
+
+#Location of pisg execuitable perl script
+set pisgexe "/home/eggdrop/eggdrop/pisg/pisg"
+
+#URL of the generated stats
+set pisgurl "http://www.thehappy.de/habo/stats"
+
+#channel that the stats are generated for
+set pisgchan "#hackerboard"
+
+#Users with these flags can operate this function
+set pisgflags "nm"
+
+#How often the stats will be updated in minutes, ie: 30 - stats will be updated every 30 minutes
+set pisgtime "1440"
+
+bind pub $pisgflags !stats pub:pisgcmd
+
+proc pub:pisgcmd {nick host hand chan arg} {
+ global pisgexe pisgurl pisgchan
+ append out "PRIVMSG $pisgchan :" ; if {[catch {exec $pisgexe} error]} { append out "$pisgexe an error occured: [string totitle $error]" } else { append out "Stats Updated: $pisgurl" }
+ # puthelp $out
+}
+
+proc pisgcmd_timer {} {
+ global pisgexe pisgurl pisgchan pisgtime
+ append out "PRIVMSG $pisgchan :" ; if {[catch {exec $pisgexe} error]} { append out "$pisgexe an error occured: [string totitle $error]" } else { append out "Stats Updated: $pisgurl" }
+ # puthelp $out
+ timer $pisgtime pisgcmd_timer
+}
+
+if {![info exists {pisgset}]} {
+ set pisgset 1
+ timer 2 pisgcmd_timer
+}
+
+putlog "pisg.tcl $pisgver loaded"
diff --git a/file.pl b/file.pl
new file mode 100644
index 0000000..6bc1faa
--- /dev/null
+++ b/file.pl
@@ -0,0 +1,91 @@
+#!/usr/bin/perl
+
+#use strict;
+#use warnings;
+use Web::Scraper;
+use URI;
+use HTML::Entities;
+use Encode;
+use URI::Escape;
+use LWP::UserAgent;
+
+
+my $type = $ARGV[0];
+my $file = $ARGV[1];
+my $skipFile = $ARGV[2];
+
+if ($length !~ /.{0,6}/) {
+ exit 0;
+}
+
+binmode(STDOUT, ":utf8");
+
+if ($type !~ /^\./) {
+ $type =~ s/^/./;
+}
+
+my $found = 0;
+
+if ($skipFile !~ /X/i)
+{
+ open (in,"<$file")||die $!;
+ while (<in>) {
+ ($ext = $_) =~ s/ .*\n//;
+ ($des = $_) =~ s/^$ext (.*)\n/$1/;
+ if ($type =~ /^$ext$/) {
+ print "$ext is \"$des\"\n";
+ $found = 1;
+ }
+ }
+ close in;
+}
+$type =~ s/^\.//;
+if ($found == 0) {
+ $found = 0;
+ #my $wikiurl = "http://filext.com/file-extension/$ARGV[0]";
+ #my $scrapp = scraper {
+ # process '//table/tr/td', 'chars[]' => 'TEXT';
+ #};
+ my $wikiurl = "http://www.file-extensions.org/search/?searchstring=$ARGV[0]";
+ my $scrapp = scraper {
+ process '//table/tr/td', 'chars[]' => 'TEXT';
+ process '//div//p', 'results[]' => 'TEXT';
+ process '//div[@id="heading"]/h2', 'text[]' => 'TEXT';
+ };
+ my $url = URI->new($wikiurl);
+ my $blubb = $scrapp->scrape($url);
+ my $list = $blubb->{'chars'};
+ my $res = $blubb->{'results'};
+ my $text = $blubb->{'text'};
+ my $morethanone = 0;
+ for ($i=0; $i <= $#$res; $i++) {
+ if ($$res[$i] =~ /Database contains .* records./i) {
+ $morethanone = 1;
+ }
+ }
+ if ($morethanone =~/1/) {
+ for ($i = 3; $i <= $#$list; $i++) {
+ if ($$list[$i] =~ /^.$type.+/i) {
+ last;
+ }
+ if ($$list[$i] !~ /^.$type$/i) {
+ print ".$type is $$list[$i]\n";
+ $found = 1;
+ }
+ }
+ } else {
+ print ".$type is $$text[0]\n";
+ $found = 1;
+ }
+ #for ($i = 0; $i <= $#$list; $i++) {
+ # if ($$list[$i] =~ /^Extension: $type$/i) {
+ # print ".$type is $$list[$i+4]\n";
+ # $found = 1;
+ # }
+ #}
+ if ($found == 0) {
+ print ".$type not in database\n";
+ }
+}
+
+
diff --git a/file.tcl b/file.tcl
new file mode 100644
index 0000000..cde8e03
--- /dev/null
+++ b/file.tcl
@@ -0,0 +1,15 @@
+bind pub - !filetype proc_file
+
+proc proc_file {nick host hand chan arg} {
+ set arg [string trim $arg]
+ if {$arg == ""} {
+ return 0
+ }
+
+ set output [split "[exec perl /home/eggdrop/eggdrop/scripts/file.pl $arg /home/eggdrop/eggdrop/scripts/fileextensions.txt X]" "\n"]
+ foreach out $output {
+ putserv "PRIVMSG $chan :$out"
+ }
+}
+
+putlog "filetype by lookshe loaded"
diff --git a/fileextensions.txt b/fileextensions.txt
new file mode 100644
index 0000000..990adba
--- /dev/null
+++ b/fileextensions.txt
@@ -0,0 +1,2334 @@
+.~$~ Temporäre Datei
+.~ap AppExpert project database Datei
+.~de Project backup Datei
+.~mn Menu backup
+.~pr Project backup Datei
+.0 Data Datei
+.000 Komprimierte Datei
+.001 NetWare Unicode Rule Table File
+.001 Datanorm (Daten)
+.04 Data Datei
+.05 Data Datei
+.06 Data Datei
+.07 Data Datei
+.1-step Backup Datei
+.113 Backup Datei (Daten)
+.123 Lotus 123 97 Datei
+.12m Smartmaster Datei
+.1st Documenting wizard list
+.2d 2-dimens. Zeichnung
+.2dm 3-dimens. Geländemodell
+.3d 3-dimens. Zeichnung
+.3dm 3D Model
+.3dr 3DMark.Result
+.3ds 3D Studio
+.3gp Third Generation Partnership
+.411 Daten Datei
+.4db Structure File
+.4dd 4D Data File
+.4dr Data Resource file
+.4ge Compiled code
+.4gl Source code
+.4v Musikdatei
+.669 Composer 669
+.7z 7-Zip
+.8 Source Datei
+.8df Plug-in
+.8ds Plug-in
+.8xp Ti-8x Programm
+.a Archiv
+.a2l Beschreibungsdatei für Kraftfahrzeug-Steuergeräte
+.a3l Authorware 3.x library
+.a3m Authorware MacIntosh-Datei
+.a3w Authorware Windows-Datei
+.a4l Authorware 4.x library
+.a4m Authorware MacIntosh-Datei
+.a4p Authorware Datei
+.a4w Authorware Windows-Datei
+.a5l Authorware 5.x library
+.a5w Authorware Windows Datei
+.aa Audible audio Datei
+.aac Advanced Audio Coding
+.aam Authorware shocked Datei
+.aas Authorware shocked packet
+.ab Applix-Builder-Datei
+.abf Adobe Binary Screen Font
+.abc ABC (Musiknotation)
+.abk Backup-Datei
+.abk Corel Draw Auto-Backup
+.abm Audio-album-Datei
+.abo Applix Builder Turbo Datei
+.abs MPEG Audio-Sound-Datei
+.abs abstract
+.abw Abiword-Dokument
+.aca HTTP animation Datei
+.aca Project Manager Workbench Datei
+.acb ACBM Graphic image
+.acc DR-DOS Viewmax-Datei
+.acc Accessory
+.acd Character definition Datei
+.acd Acid Song File
+.ace ace Archiv
+.acf HTTP character Datei
+.aci ACI development appraisal
+.acl keyboard accelerator Datei
+.acm Dynamic Link Library
+.acm Interplay compressed sound Datei
+.acp Assistant Preview Datei
+.acr American College of Radiology
+.acs Character structered storage
+.act Action Presentation
+.act Foxdoc Action Diagram
+.act Assistant Actor Datei
+.ad After Dark
+.ada Ada source text
+.adb Ada source text body
+.adb Appointment database
+.adc Color Bitmap Graphic
+.add OS/2 adapter driver
+.adf Amiga disk Datei
+.adf Adapter Description File
+.adi AutoCAD device-independent
+.adi Driver Description
+.adl QEMM Mca adaptor description library
+.adm After Dark MultiModule
+.adm Windows NT policy template
+.adn Lotus 1-2-3 Add-In-Datei
+.adp Astound Dynamite Datei
+.adp Access Database Project
+.adp Dynamic Page Datei
+.adp FaxWorks Faxmodem Setup-Datei
+.adr After Dark Randomizer
+.adr Smart Address address book
+.adr Opera Bookmark
+.ads Ada source text specification Datei
+.ads ADIS=Animal Data Interchange Syntax
+.adt AdTech Fax Datei
+.adt datafile for card applications
+.adx Archetype Designer Document
+.adx Dynazip Active Delivery script
+.adx Lotus Approach dBase Index
+.adz Packed ADF Datei
+.ae Author/Editor Datei
+.aep ArcExplorer project
+.aep Adobe After Effects project
+.af2 ABC FlowCharter 2.0 Flowchart
+.af3 ABC Flowchart
+.afc Apple Sound-Datei
+.afi Truevision Bitmap graphic
+.afm Adobe font metrics
+.afm Cardfile application
+.ag Applix graphic
+.agb Game Boy Advance ROM image
+.agr Xmgrace Projekt
+.ahk Autohotkey
+.ai Adobe Illustrator drawing
+.ai Corel Trace drawing
+.aifc Audio Interchange File Format compressed
+.aim AOL Instant Messenger Startdatei
+.ain AIN Compressed archive
+.aio APL transfer Datei
+.ais ACDSee Image Sequence
+.ais Velvet Studio Instruments Datei
+.ais Array of Intensity Samples
+.aix Cardfile Application data
+.akz Akzent-Datei
+.alaw European Telephony audio
+.alb Album
+.ale AvidLogExchange
+.ali Dokument
+.all Arts & Letters Library
+.all General printer information
+.all Steinberg Cubase
+.alo Alamo-Datei
+.alt WordPerfect Library Menu
+.alt alte Version
+.alv (MIS) Alea View
+.alz Alzip
+.am Applix SHELF Macro
+.am App-Magic Datei
+.am1 Adventure-Maker Programm
+.amdb App-Magic Datenbank
+.amf Asylum (module/music) (format/file)
+.amf Advanced Module Format
+.amg ACTOR System image
+.amg AMGC Compressed archive
+.ami Annotation Datei
+.ampp App-Magic Programm-Paket
+.amr Adaptive MultiRate
+.ams Extreme's Tracker module
+.ams Velvet Studio music module
+.an Textdatei
+.an8 Anim8or
+.anc Canon Computer Pattern Maker
+.ani Animierter Cursor
+.anim Animation
+.anm DeluxPaint Animation
+.ann Windows 3.x Help annotation
+.ans ANSI Textdatei
+.ant SimAnt saved game
+.aob Audio Objects
+.aol America Online Datei
+.aos Add-on software
+.aot Application bindery object template
+.ap Applix Presents Datei
+.ap WHAP Compressed Amiga archive
+.apc Compiled application
+.apc Druckertreiber
+.apd Dynamic application library
+.apd Druckertreiber
+.ape Ape (engl. für Affe)
+.apf Druckertreiber
+.apf Allaire Project File
+.api Application Program Interface
+.api Druckertreiber
+.apl APL Workspace Datei
+.apl Application library
+.app Application Generator Object
+.app Executable Application
+.app Generated Application
+.app Normal mode application
+.app Symphony Add-in Application
+.apr ArcView Projektdatei
+.apr Employee Appraiser Performance Review
+.apr Lotus Approach View
+.aps Advanced patching systems
+.apt Lotus Approach Data view
+.apt Text mode application
+.apx Appexpert database
+.apx Lotus Approach Paradox-Specific information
+.aq Applix data
+.arf Automatic Response Datei
+.ari ARI Compressed archive
+.ari Aristotle audio Datei
+.arj Archive Robert Jung
+.arl AOL v4.0 organizer Datei
+.arr Steinberg Cubase
+.art AOL Image Datei
+.art Canon Crayola art
+.art Clip Art
+.art First Publisher Raster graphic
+.art Ray Tracer Datei
+.art Xara Studio drawing
+.arx ARX Compressed Archive
+.as Applix Spreadsheet
+.as ActionScript
+.asa Microsoft Visual InterDev Datei
+.asc ASCII-Datei
+.ascx ASP.NET Control
+.asd Astound Presentation
+.asd Bildschirmtreiber
+.asd AutoSave Datei
+.ase Velvet Studio Sample Datei
+.asf Bildschirmschriftart
+.asf StratGraphics Datafile
+.ash Assembly language header
+.asi Assembler Include Datei
+.asl Style-Datei
+.asm Assembler-Quellcode
+.asm Pro/E assembly
+.asm Solid Edge Assembly
+.asmdot Assembly Template
+.aso Astound Dynamite Object
+.asp Active Server Pages
+.asp Astound Presentation
+.asp Setup- und Verbindungsscript
+.aspx ASP.NET Seite
+.ass Advanced SubStation Alpha
+.ast Astound multimedia Datei
+.ast assistant
+.asv DataCAD Autosave Datei
+.asv Matlab Autosave Datei
+.asx CA BrightStor ARCserve Backup script
+.asx Microsoft Advanced Streaming Redirector
+.at2 Auto Template
+.atf APL Transfer Datei
+.atm Adobe Type Manager data/info Datei
+.atm Atmosphere
+.atn Aktionendatei
+.att AT&T Group 4 bitmap
+.atw AnyTime Deluxe for Windows
+.au Audio U-law
+.aud Audio Datei
+.aup easyLEARN Author Projekt
+.aut AutoIt Script
+.aut easyLEARN Author Lernmittelbeschreibung
+.au3 AutoIt v3 Script
+.aux Auxilliary Dictionary
+.aux Auxilliary Reference Datei
+.aux Geospatial Imaging ERDAS IMAGINE and LPS Data File
+.ava Avagio Publication
+.avb Virusinfizierte Datei
+.ave Avenue-Script
+.avi Audio Video Interleave
+.avp Symbolpalette
+.avr Audio Visual Research Datei
+.avs Application Visualization System
+.avs Stardent AVS-X Image
+.avx Erweiterung (Extension)
+.aw Applix Words
+.aw Textdokument
+.awd FaxView Document image
+.awk AWK Script/Program
+.awm Animation Works Movie
+.awr Telsis Datei
+.aws StatGraphics Data
+.axl ArcIMS XML project
+.axt ASCII application object template
+.b Applause Batch list
+.b Spielstand
+.b30 printer font
+.b4 Helix Nuts and Bolts
+.b5t Blind Write 5
+.b64 Base64-Datei
+.b8 Raw graphic
+.bad Oracle bad Datei
+.bag BAG Archiv
+.bak Backup-Datei
+.bal Ballade Music score
+.bar Horizontal menu object
+.bas Basic (Source code)
+.bat Batch
+.bb Papyrus Database backup
+.bb Blitz Basic
+.bbl Bibliographic reference
+.bbm Deluxe Paint Bitmap image
+.bbs Bulletin Board System text
+.bc! Bittorrent-Client-Datei
+.bch Batch Process Object
+.bch Daten-Datei
+.bcm Communications Datei
+.bco Bitstream Outline font description
+.bcp Makefile
+.bcw Environment settings
+.bdb Datenbank
+.bdf Egret Datafile
+.bdf West Point Bridge Designer File
+.bdf Birthday File
+.bdf Binary Diff File
+.bdl Bundle Datei (2D und 3D CAD Zeichnung)
+.bdr Border
+.bdsproj Borland Developer Studio Projekt
+.bez Bitstream Outline font description
+.bf Brainfuck
+.bf2 Bradford 2 Font
+.bfc Microsoft Windows 95 Briefcase Document
+.bfe Blowfish encrypted
+.bfm Font Metrics Datei
+.bfx Fax document Datei
+.bg Microsoft Backgammon Game
+.bga OS/2 Graphic array
+.bgi Borland Graphics Interface Driver
+.bgl Microsoft Flight Simulator Scenery
+.bhf pcAnywhere Host Datei
+.bhx WinZip file
+.bi binary
+.bi Basic Include file
+.bib Bibliography Datei
+.bib Literatur-Datenbank (Bibliografie)
+.bif GroupWise initialization Datei
+.bif Binary Image b&w graphic
+.biff XLITE 3D Datei
+.bik bink video
+.bin binary (file)
+.bio OS/2 Bios Datei
+.bit X11 Bitmap
+.bk Backup
+.bk JetFax Faxbook Datei
+.bk! Document backup
+.bk$ Backup
+.bkp Backup
+.bks bookshelf Datei
+.bks Spreadsheet Backup
+.bkw FontEdit Fontset mirror image
+.blb Resource archive
+.bld BASIC Bloadable picture
+.blend Blender3D
+.blib WorkBench++ für C-Control I
+.blk Alias Wavefront Image
+.blk Temporäre Datei
+.bm Bitmap
+.bm1 Apogee BioMenace data
+.bmf Corel Gallery Datei
+.bmk Windows Help bookmark
+.bmp Bitmap
+.bmp Bitmap
+.bmp Bitmap
+.bmt Ami Pro Button
+.bmx BlitzMax
+.bn Instrument Bank Datei
+.bnk Instrument Bank Datei
+.bnk Sound effects bank Datei
+.bol Compressed archive library
+.bom Bill of materials
+.bom Bill of materials
+.boo Compressed archive
+.book Book
+.bos Optimized Binary File
+.box Lotus Notes Datei
+.bpc Business Plan Toolkit Chart
+.bpl Borland Delphi 4 packed library
+.bpr Borland Projekt Datei
+.bpp WorkBench++ für C-Control I
+.bps Microsoft Works Document
+.bpt CorelDraw Bitmap fills Datei
+.bpx Truevision Targa Bitmap
+.bqy BrioQuery Datei
+.br Bridge Script
+.brd Board
+.brd Board
+.brk Brooktrout Fax-Mail Datei
+.brush DPaint Grafikdatei
+.brz DbBRZ
+.bs_ Find Menu shell extension
+.bs1 Apogee Blake Stone Datei
+.bsa BSARC Compressed archive
+.bsc Apple II Compressed archive
+.bsc Fortran Pwbrmake Object
+.bsc browser information
+.bsp Quake-Engine Map Datei
+.bst BiblioTex file
+.btm Batch-Datei
+.btn Makeover Button File
+.btr Btrieve-Datenbank
+.bud Backup disk for Quicken
+.bun CakeWalk Audio Bundle
+.bup Backup
+.but Button definition
+.bw SGI Black and White image
+.bwb Spreadsheet application
+.bwi BlindWrite Image
+.bwr Kermit Beware buglist
+.bws Sub-Code BlindWrite
+.bwt Blindread Image
+.bwv Business Wave Datei
+.byu BYU Movie
+.bz bzip
+.bz2 bzip2
+.c C Source Code File
+.c configuration
+.cpp C++
+.C C++
+.c00 Ventura Publisher Print Datei
+.C01 Typhoon wave
+.c2 C-Controll II Modul
+.c2d WinOnCD CD-Image
+.c2p C-Controll II Projekt
+.c4d Cinema4D-Scenefile
+.c4d Clonk 4 Objektdefinition
+.c4f Clonk 4 Rundenordner
+.c4g Clonk 4 Systemdaten
+.c4k Clonk 4 Registrierschlüssel
+.c4m Clonk 4 Materialdefinition
+.c4p Clonk 4 Spielerdatei
+.c4s Clonk 4 Szenario
+.c4x Clonk 4 Engine
+.C86 C86 Quellcode
+.ca Cache-Datei
+.cab Microsoft Cabinet Datei
+.cac Executable Datei
+.cad Softdesk Drafix Cad
+.cag Catalog Datei
+.cal Kalender-Datei
+.Crash Absturzmeldung
+.cal Cakewalk Application Language
+.cal CALS
+.cal SuperCalc Spreadsheet
+.cam Casio camera Datei
+.can Canvas
+.cap Capture Datei
+.cap Caption
+.car AtHome assistant Datei
+.car Carrara Datei
+.carc Nintendo textur,graphic,platten,course File
+.cas Comma-delimited ASCII Datei
+.cat Sicherheitskatalog
+.cat Catalogue Datei
+.cat categorization Datei
+.cat Stellarium Star Catalogue
+.CATpart Part Datei
+.cb clean boot Datei
+.cbc CubiCalc Fuzzy Logic
+.cbf Atari DOS Chebase Datei
+.cbf Chessbase File
+.cbf CSDL Dokument
+.cbh Chessbase File
+.cbi Column binary
+.cbl Cobol
+.cbm Compiled Bitmap
+.cbr Comic book Rar-Archive
+.cbt Computer based training
+.cbz Comic Book Zip
+.cc C++
+.cc custom class
+.cc3 CUEcards Datenbank
+.cca cc:mail archive
+.ccb Animated Button configuration
+.ccc Curtain Call Native bitmap
+.ccd CloneCD-Image-Control-Datei
+.cce Kalender
+.ccf Communications Configuration
+.ccf Concerto Container File
+.ccf CryptLoad Container File
+.cch Corel Chart
+.ccl Communication Command Language
+.ccm Lotus CC:Mail "box" Datei
+.cco CyberChat-Datei
+.cco XBTX Graphics
+.cct Shockwave cast Datei
+.cct DesignWorks Datei
+.cda CD Audio Track
+.cdb CardScan Database
+.cdb Clipboard Datei
+.cdb Conceptual model backup
+.cdb Main database
+.cdb Pocket Access Database
+.cdf Channel Definition Format
+.cdf Netcdf Graphic Datei
+.cdfs Compact Disc filing system
+.cdi Compact Disc Interactive
+.cdk Atari Calamus Document
+.cdm Conceptual data model
+.cdm Custom data module
+.cdm Custom Device Module
+.cdr CorelDRAW file
+.cdr CD raw data
+.cdt CorelDRAW template
+.cdx CorelDRAW compressed drawing
+.cdx Compound Index
+.ce Main CE Datei
+.ceg Tempra Show Bitmap graphic
+.cel AutoDesk Animator Cel Image
+.cel CIMFast Event Language Datei
+.cer Certificate Datei
+.cf Imake Configuration Datei
+.cfb Comptons Multimedia Datei
+.cfg Configuration File
+.cfl CorelFLOW Chart
+.cfm ColdFusion template
+.cfm Corel FontMaster Datei
+.cfm Creative FM-Music
+.cfm Windows customer form
+.cfn Atari Calamus Font Datei
+.cfo C form object
+.cfp Complete Fax Portable
+.cgi Common gateway interface script
+.cgm Computer Graphics Metafile
+.ch Clipper 5 Header
+.ch OS/2 Konfigurationsdatei
+.ch3 Chart
+.ch4 Charisma Presentation
+.chd Chameleon Font descriptor
+.chf remote control Datei
+.chi ChiWriter Document
+.chk Checkdisk
+.chl Configuration History Log
+.chm Compiled HTML Help
+.chn Ethnograph Data Datei
+.chp Chapter Datei
+.chr Character Sets
+.cht ChartMaster dBase Interface
+.cht ChartViewer Datei
+.cht Harvard Graphics Vector Datei
+.cif CalTech Intermediate Graphic
+.cif Creator Image Datei
+.cif caller Datei
+.cif Crystallographic Information File
+.cil Clip Gallery download packag
+.cil Cilea Einheitengruppe
+.cim Sim City 2000 Datei
+.cix Database Index
+.ckb Keyboard mapping Datei
+.cl Generic LISP
+.cl3 Layout Datei
+.class Java .class Datei Format
+.clc APROL ChronoLog Container
+.clg Disk Catalog Datenbank
+.cll Cricket Software Clicker Datei
+.clo Cloe Image
+.clp Compiler Script
+.clp Clip art
+.clp Clipboard
+.clr color screen image
+.clr Color definition
+.cls Klassenquelldatei
+.cls Klassenquelldatei
+.cls Klassendefinition
+.clt APROL ChronoLog Template
+.clw Class Wizard
+.clw Quellcodedatei
+.clz Tomb Raider 6 Archive
+.cm Craftman Data
+.cmd External Command Menu
+.cmd Command Datei
+.cmd Programmdatei
+.cmf Corel Metafile
+.cmg Chessmaster saved game
+.cmk Card Shop Plus Datei
+.cmm CEnvi Batch Datei
+.cmp Postscript Printer Header
+.cmp User dictionary
+.cmp Address Document
+.cmr MediaPlayer Movie
+.cmv Corel Move animation
+.cmx Corel Presentation Exchange image
+.cmyk cyan, magenta, yellow, and black
+.cnc CNC General Program data
+.cnf Configuration
+.cnq Compuworks Design Shop
+.cnt Contents
+.cntl z/OS JCL-Library
+.cnv Conversion files
+.cnv conversion support Datei
+.cnv Temporäre Datei
+.cnv Canvas Drawing
+.cob Cobol
+.cob trueSpace 2 object
+.cod Template source Datei
+.cod FORTRAN Compiled code
+.cod compiled code
+.cod Video Text Datei
+.col Color Palette
+.col Multiplan Spreadsheet
+.com Command
+.con Konfiguration
+.conf Configuration
+.config Configuration
+.coo Components File
+.cp4 Cplan
+.cp8 CP8 256 Gray Scale image
+.cpc Cartesian Perceptual Compression
+.cpd Complaints Desk Script
+.cpd Corel PrintOffice Datei
+.cpf Complete Fax
+.cph Corel Print House
+.cpi ColorLab Processed Image
+.cpi code page information
+.cpio cpio-Archiv
+.cpj CD Project
+.cpj Track-Abbild
+.cpl Compel Presentation
+.CPL Corel color palette
+.cpl Control Panel Library
+.cpo Corel Print Office
+.cpp C Plus Plus (C++)
+.cpp Cricket Presents presentation
+.cpr Corel Presents presentation
+.cpr Cubase Project
+.cps PC Tools Backup
+.cps Coloured postscript
+.cpt Cricket Presents Template
+.cpt Corel Photo-Paint image
+.cpt Encrypted Memo
+.cpx Corel Presentation Exchange
+.cpy Copy Books
+.cpz COMPOZ Music Text
+.cr2 Canon RAW Format
+.crc Cyclic Redundancy Check
+.crc Circular reference Datei
+.crd Cardfile
+.crf cross-reference
+.crf PkZip gepacktes Archiv
+.crh Image Datei
+.crl Certificate Revocation List
+.crp Corel run-time presentation
+.crp Encrypted database
+.crp custom report
+.crs Conversion resource
+.crt Certificate
+.crt Crontab Datei
+.crt Terminal settings information
+.crt CaRTridge Image
+.cru CRUSH
+.crw Canon Raw Image
+.cs C-Sharp
+.csa Comma deliminated text
+.csb Cosmo3D scenegraph binary
+.csb Corel script binary
+.csb Crashsoft BASIC
+.csc Corel script
+.csg Statistica/w Graph Datei
+.csh C shell script files
+.csm Precompiled header
+.csm Script Datei
+.cso Customer service data + outcome
+.csp PC Emcee On-Screen image
+.css Statistica/w Datasheet
+.css Stats+ Datafile
+.css Cascading Style Sheet
+.cst Cast
+.csv Comma separated values
+.csv Adjusted EGA/VGA Palette
+.ct Scitex CT bitmap
+.ctb color-dependent plot style table
+.ctc PC Installer Control
+.ctf code translation
+.ctg Canon Power Shot Info File
+.ctl Control
+.ctl control file
+.ctx Course Text
+.ctx Ciphertext
+.ctx User control binary
+.cub Cube Datei
+.cue CUEcards Datenbank
+.cue Cue-sheet
+.cul Cursor library
+.cup Datenbankdatei
+.cur Cursor-Datei
+.cursor Cursor
+.cut Dr Halo Bitmap
+.cutlist Cut Assistant (früher Asfbin Assistant)
+.cv Corel Versions archive
+.cv information screen
+.cv5 Canvas Drawing
+.cvi Canvas Drawing
+.cvg Image
+.cvs Canvas Drawing
+.cw I don't know
+.cwb Cakewalk Bundle
+.cwk Claris Works data
+.cwp Cakewalk Project
+.cws Claris Works template
+.cxt protected Cast
+.cxx C++
+.cys CSWgermany CYberSecure-CryptContainer
+.czip Encrypted ZIP
+.d Directory
+.d11 Abrechnungsdaten DA11
+.d2d 2D/3D object Datei
+.d64 disk image
+.d71 disk image
+.d81 disk image
+.d81 Leistungsverzeichniss
+.d83 Angebotsaufforderung
+.d84 Angebotsabgabe
+.d85 Nebenangebot
+.d86 Auftragserteilung
+.d88 Nachtrag
+.d89 Rechnung
+.daa CD/DVD-Image
+.dao Disc At Once
+.dap Data access page
+.dat Data
+.dat Virtuelle Partition
+.datatype Datatype
+.db Datenbank
+.db table database
+.dbc database container
+.dbc CANdb Datenbank Datei
+.dbf Database Datei
+.dbf Enable database
+.dbf tablespace Datei
+.dbk Database Backup
+.dbk Schematic backup Datei
+.dbl 64-Bit doubles (RAW)
+.dbo Compiled program Datei
+.dbq Paradox Memo
+.dbt Text Memo
+.dbv Memo field Datei
+.dbw Database Datei
+.dbx DataBeam image
+.dbx Tabelle
+.dc DesignCAD
+.dc2 DesignCAD
+.dc4 ViaThinkSoft (De)Coder 4.x
+.dc5 DataCAD Drawing
+.dc6 DataCAD Drawing
+.dca Document Content Architecture
+.dca Active designer cache
+.dcd DIG-CAD
+.dcf Dyadic
+.dcf Disk Image Datei
+.dcim Imaging and Communications
+.dci DIG-CAD Ing.
+.dcm DICOM-Datei
+.dcm DCM module
+.dcp Data CodePage
+.dcr Shockwave Datei
+.dcr Delphi Compiled Resource
+.dcs Quark XPress
+.dcs Desktop Color Separation
+.dct Database Dictionary Datei
+.dct Database SpellCheck Dictionary
+.dct database container Datei
+.dcu Delphi compiled unit
+.dcx Bitmap Graphics Datei
+.dcx Fax image
+.dcx database container Datei
+.dd Macintosh DISKDOUBLER
+.ddb Bitmap Graphics Datei
+.ddf Data Definition Datei
+.ddi DISKDUPE
+.ddp Device Driver Profile
+.dds Direct Draw Surface
+.deb Debug Script
+.deb Debian Package
+.def Assembly Header Datei
+.def C++ definition Datei
+.def Define Module Datei
+.def SmartWare II data
+.defi de-install script
+.dem Digital Elevation Models
+.dem Demo Datei
+.dem Graphics Datei
+.dep Dependency Datei
+.der Certificate Datei
+.des Graphics Datei
+.desktop KDE .desktop file
+.dev Device Driver
+.device Device
+.dewf recorded instrument
+.dez DES ZIP
+.dfd Data Flow Diagram Graphic
+.dfi Outline Font description
+.dfl Default Program Settings
+.dfm Delphi-Formular
+.dfm Data Flow Diagram model
+.dfs Sound Datei
+.dfv Printing Form value
+.dfw Derive Worksheet
+.dgn Microstation CAD drawing
+.dgs Diagnostics Report
+.dh Dependency Information Datei
+.dhp Graphic Datei
+.dht Datafile
+.dia Diagraph Graphics Datei
+.dia diaFile Datei
+.dib Device-independent bitmap
+.dic Dictionary Datei
+.dicm Imaging and Communications
+.dif Data Interchange Format
+.dif Database Datei
+.dig Digilink Datei
+.dig Audio
+.dim Database Datei
+.dip Graphics Datei
+.dir Dialing Directory
+.dir Directory
+.dir Macromedia Director Datei
+.dir Director Movie
+.dis Distribution Datei
+.dis Ray Tracer Datei
+.dis Thesaurus Datei
+.disabled Disabled startup file
+.divx DivX-Media-Format
+.diz Description in ZIP
+.djv DjVu
+.djvu DjVu
+.dkb DKBTrace
+.dl Image
+.dlc Download-Link-Container
+.dld Datafile
+.dlg C++ Dialogue Script
+.dll Dynamic Link Library
+.dls Downloadable sound
+.dls Interactive music architecture
+.dls Setup Datei
+.dm3 Demo
+.dmd data module
+.dmf Disk Image
+.dmf music module
+.dmg Disk Image
+.dmo Demo Datei
+.dmp Dump Datei
+.dms Amiga DISKMASHER
+.dmv DOS4GW Videodatei
+.dng Digitales Negativ
+.dob User document
+.doc Document
+.doc Document
+.doc Document
+.doc Document
+.doc Document
+.doc Document
+.doc Document
+.docx Word 2007 XML Document
+.docm Word 2007 XML Document with Macros
+.doe Arena Model Document
+.dog Laughing Dog
+.doh Dependency Information
+.dos External Command Datei
+.dos Network Driver Datei
+.dos Local <-> Unicode Translator for code pages
+.dot Line-Type definition
+.dot Document Template
+.dox User document binary form
+.doz Description out of Zip
+.dp Kalender
+.dp DataPhile
+.dpg Moonshell MP4 Video
+.dpl packed library
+.dpr Delphi Projekt
+.dpr Project header
+.dpt Publication Datei
+.dr9 Directory Datei
+.draw drawing
+.drc Design rules check
+.drs Display Resource Datei
+.drv Device Driver
+.drw Lotus Freelance Image
+.drw Pro/E drawing
+.drw Micrografx Drawing
+.drwdot Drawing Template
+.ds4 Designer 4
+.dsc Discard Datei
+.dsd Database Datei
+.dsf Designer Datei
+.dsg DooM saved game
+.dsk Disk
+.dsk Project Desktop Datei
+.dsm Digital Sound Module
+.dsm Direct Show Media
+.dsm Dynamic Studio music module
+.dsm Music module Datei
+.dsn Design
+.dsn ODBC Data source
+.dsn Schematic Datei
+.dsp Display parameters
+.dsp Graphics Display driver
+.dsp Developer Studio project
+.dsq Corel QUERY
+.dsr Driver Resource
+.dsr Active designer Datei
+.dss Digital Sound Datei
+.dss Screensaver Datei
+.dst Distribution Datei
+.dst Embroidery machines graphic
+.dsw Desktop settings
+.dsw workspace Datei
+.dsx Active designer binary
+.dta Datafile
+.dta STARS data
+.dtapart DownThemAll!-Segmentdatei
+.dtd Document Type Definition
+.dted Digital terrain elevation data
+.dtf Datenbank
+.dtf Datenbank
+.dtf Datenbank
+.dtm Module Datei
+.dtp Desktop layout Datei
+.dtp Vorlage
+.dtp Text Document
+.dt_ Daten-Fork
+.dun Dial-up Networking
+.dup Duplicate
+.dv Digital video
+.dvc Datafile
+.dvi Device Independent
+.dvp Desqview Program information
+.dvp Device parameter Datei
+.dw2 Drawing Datei
+.dwd DiamondWare digitized
+.dwf Drawing Web Datei
+.dwf Vector graphic
+.dwg Drawing
+.dwp Dokument
+.dws Workspace Datei
+.dx Digital Electric Corporation
+.dxf Data Exchange Datei
+.dxf Drawing Interchange Format
+.dxn Fax document
+.dxr Macromedia Director protected
+.dxt Direct-X Texture
+.dylib Dynamic Library
+.dyn Datafile
+.e00 Coverage Export-Datei
+.e00 Exchange-Datei
+.eap easyLEARN Autor-Kursprogramm
+.eap Enterprise Architect Projekt
+.ear Enterprise Application Archive
+.easm eDrawings File
+.ebd AP Modellbahn Datendatei
+.ebj Error Checking Object Datei
+.ece Oracle Express Dynamic Web Page
+.ecw Enhanced Compressed Wavelet File
+.eda ASR disk image
+.edb Geneological data
+.edd Element Definition document
+.ede EPS disk image
+.edf (unbek.)
+.edl Exercises Developement Language
+.edk KT disk image
+.edq SQ1/SQ2/KS32 disk image
+.edrw eDrawings File
+.eds SQ80 disk image
+.edt Default settings
+.edv VFX-SD disk image
+.eeb Equation editor Button Bar
+.efa ASR Datei
+.efe EPS Datei
+.efg Normal Form Game
+.efk KT Datei
+.efq SQ1/SQ2/KS32 Datei
+.efs SQ80 Datei
+.eft High Resolution Screen Font
+.efv VFX-SD Datei
+.efx Faxdokument
+.efw  ?
+.ega EGA Display font
+.el Lisp Source code
+.elc Lisp Source code
+.elf Executable and Linking Format
+.elm Theme-Pack Datei
+.elt Event List Text
+.emb Embedded bank Datei
+.emd ABT Extended MoDule
+.emf Windows Enhanced Metafile
+.eml E-Mail
+.emlx E-Mail
+.emm Mindmap
+.ems Enhanced Menu System
+.emu Terminal Emulation Datei
+.emz Compressed Enhanced Metafile
+.enc Encoded Datei
+.enc Musik-Datei
+.enc Video-Datei
+.end Arrow-Head Definition Table
+.enff Neutral Format
+.eng Chart Graphics Datei
+.eng Dictionary Engine Datei
+.ens EndNote Stil Datei
+.env Enveloper Macro
+.env Environment Datei
+.epd Publication Datei
+.ephtml Enhanced Perl-parsed HTML
+.epi Dokument
+.eprt eDrawings File
+.eps Encapsulated PostScript
+.epsf Encapsulated PostScript
+.eps2 Level 2 EPS
+.epsi EPS Interchange
+.eqn Equation Datei
+.er1 ERWin Datei
+.erd Entity Relationship Diagram
+.erm Entity Relationship Model
+.err Error Log
+.err Compilation error Datei
+.erx ERWin Datei
+.esh Extended Shell Batch
+.esl Distributable support library
+.esm Elder Scrolls Master
+.esp Elder Scrolls Plugin
+.esps ESPS audio Datei
+.etd EBX Transfer Data File
+.eth Dokument
+.etx Structure Enhanced text
+.eui ESP compacted disk image
+.evt Event Log
+.evy Dokument
+.ewd Text Document
+.ewl Microsoft Encarta document
+.ex3 Device Driver Datei
+.exc Exclude Datei für Optimize
+.exc Exclusion Dictionary Datei
+.exc Source-Code Datei
+.exe Executable
+.exec z/OS REXX-Library
+.exp Saved chat
+.exr OpenEXR
+.ext ASCII binary transfer
+.ext2 EXT2 Image
+.ext3 EXT3 Image
+.ezp Edify.zip
+.f FREEZE
+.f01 Fax document
+.f2r Linear music module
+.f3r Blocked music module
+.f77 FORTRAN 77
+.f96 Faxdokument
+.fac Face graphic
+.faq Frequently Asked Questions
+.far Farandole
+.fas Basic module Datei
+.fav Navigation bar
+.fax FAX Type image
+.fb2 FictionBook
+.fbk Financials Backup
+.fbx 3D Austauschformat
+.fc Spell Check dictionary
+.fcd Virtual CD-ROM Datei
+.fcm Binary Dateipatch
+.fd Declaration Datei
+.fd Field offsets
+.fdb Financials Database
+.fdb font definition block
+.fdf Formular
+.fdw Formular
+.feb Figure Editor Button Bar
+.fem Finite Element Mesh
+.ff Outline Font description
+.ffa find fast Datei
+.fff Fax document
+.fff GUS PnP bank Datei
+.ffl Image Datei
+.ffl fast find Datei
+.ffo fast find Datei
+.fft Final Form Text
+.ffx fast find Datei
+.fh3 Freehand 3 drawing
+.fh4 Freehand 4 drawing
+.fhmx Freehand MX
+.fi Datei Interface
+.fif Fractal Image
+.fig REND386/AVRIL Datei
+.fig FIG image text
+.fig SNES ROM image
+.fil Datei List Object
+.fil Datei template
+.fil Overlay
+.fil file
+.fil file
+.fin Print formatted text
+.fit Datei index table
+.fit Graphic
+.fits CCD camera image
+.fits Flexible Image Transport System
+.fix Patch Datei
+.fky Macro
+.fla Movie
+.flb Format library
+.flc FLIC animation
+.fld Field define module
+.fld Folder
+.flf Delived form
+.flf Driver
+.flf Financials License File
+.fli FLIC Animation 320x200
+.fli Font library
+.fll dynamic link library
+.flm Film Roll
+.flo FlowCharter Datei
+.flp Flower-Project Leecherdatei
+.fls Filelist document
+.flst Transparenzreduzierungsvorgabe
+.flt Filter
+.flt Filter
+.flt Graphics filter
+.flt Graphics filter support Datei
+.flt Music module
+.flt Open Flight Datei
+.flv Flash Video
+.flx Compiled binary Datei
+.fm FrameMaker Document
+.fm Spreadsheet
+.fm1 Spreadsheet
+.fm3 Device driver
+.fm3 Spreadsheet
+.fmb Forms sources
+.fmb Datei Manager button bar
+.fme FMEA Datei
+.fmf Font oder Icon
+.fmk MakeFile
+.fml Mirror list
+.fmo Compiled format
+.fmp Document Datei
+.fmt Csreen format Datei
+.fmt Print Datei
+.fmt Style sheet
+.fmt Textformat für Form
+.fmx Executable form
+.fn3 Font
+.fnd Find applet
+.fnf Notendatei für ForteFree
+.fng Font group
+.fnk FunkTracker
+.fnt Font
+.fnx Inactive font
+.fog Fontographer font
+.fol Saved message folder
+.fon Call log
+.fon Dialing directory
+.fon Font
+.font Font
+.for Form
+.fot Font-related Datei
+.fot Installed TrueType font
+.fp FoxPro
+.fp FileMaker Pro Datei
+.fp1 "Flying Pigs"
+.fp3 FileMaker Pro Datei
+.fp5 FileMaker Pro Datei
+.fp7 FileMaker Pro Datei
+.fpc Catalog Datei
+.fpl Playlisten Datei
+.fpt FileMaker Pro Datei
+.fpt Memo fields
+.fpw Floorplan drawing
+.fpx Kodak FlashPix
+.fr3 Renamed dBaseIII+ form
+.frf Font
+.frg Uncompiled report
+.frk Zip
+.frm Dokument
+.frm Executable Datei
+.frm Formular-Quelldatei
+.frm Formular-Quelldatei
+.frm Merge form
+.frm Symbol Report
+.fro Compiled report
+.frp Formular
+.frs Screen Font Resource
+.frt Report menu
+.frx Form stash Datei
+.frx Report
+.fsf fPrint Audit Tool
+.fsl Formular
+.fsm Sample Datei
+.fst Linkable program
+.fsx Data
+.fsy FSync Document
+.ft Full text index
+.ftb Index Datei
+.ftg full-text search group
+.ftm Font
+.ftp File Transfer Protocol
+.fts full-text search index
+.ftw Dokument
+.fw Firmware
+.fw Datenbank
+.fwb FileWrangler Backup
+.fws FileWrangler Data
+.fx On-Line guide
+.fx4 Pixelkarte
+.fxd Phonebook
+.fxp Compiled source code
+.fxr Fax Received Document
+.fxs Fax Transmit graphic
+.fzb Bank dump Datei
+.fzf Full dump Datei
+.fzv Voice dump Datei
+.g Data chart
+.g64 Disk Image
+.g721 Raw CCITT G.721
+.g723 Raw CCITT G.723
+.g8 Raw Graphics
+.gadget Gadget
+.gal Album
+.gam Fax-Dokument
+.gam Sammlung von Spielerelevanten Daten (Quake Engine)
+.gb Game Boy ROM image
+.gba Game Boy Advance ROM image
+.gbc Game Boy Color ROM image
+.gbl Global definitions
+.gbs Gameboy Sound
+.gbm Gameboy Movie
+.gc1 Lisp source code
+.gc3 Lisp source code
+.gcd CADD Zeichnung
+.gcf Game Cache File
+.gcp Ground Control Point
+.gdb Database Datei
+.gdb Garmin Database
+.gdf Dictionary Datei
+.ged Genealogical data
+.ged Graphic Environment Document
+.ged Graphics editor Datei
+.ged Graphics editor native format
+.gem GEM Metafile
+.gen Application Generator
+.gen Generated text
+.geo Geode
+.geo Euklid DynaGeo
+.GetRight Unfinished-Download
+.gfb Compressed gif image
+.gfc flowchart
+.gfi Graphics Link presentation
+.gft Font
+.gfx Graphics Link presentation
+.gfx Textverarbeitung Protext
+.gfy Got FingerPrints Yet?
+.gg Sega Game Gear ROM image
+.gho Symantec Ghost Image Datei
+.ghs Symantec Ghost Image Datei
+.gib Chart
+.gid global index
+.gif Compuserve Graphics Interchange Format
+.gim Graphics Link presentation
+.giw Presentation
+.gix Graphics Link presentation
+.gkh disk image
+.gks GripKey document
+.gl Animation Datei
+.glm Glim
+.gls Datafile
+.gly Glossary
+.gm6 Game Maker Projekt
+.gmf CGM Graphics
+.gmp Tile map
+.gmr Graphical monitor record
+.gna Graphics Link presentation
+.gno Genealogy Datei
+.gnt Generated executable code
+.gnx Graphics Link presentation
+.goc Goc sorce code
+.goh Goc header
+.gp Geode parameter Datei
+.gp# Guitar Pro Datei (# = 3-5)
+.gpg GNU Privacy Guard-Code
+.gph Graph
+.gpk Program package
+.gpk Spitzenpegeldatei (zu WaveLab)
+.gpp Graph paper application
+.gpx GPS eXchange file
+.gr2 Screen driver
+.gra Datafile
+.gra Graph
+.graphml GraphML
+.grb Shell Monitor
+.grd Image processing grid
+.grf Graph
+.grf Grapher
+.groovy Groovy
+.grp Pictures group
+.grp Group-Datei
+.gry GREY
+.gs1 Presentation
+.gs3 Daten
+.gsd Vector graphic
+.gsm GSM 6.10 audio stream
+.gsp gsp-Datei
+.gsw GraphShow Worksheet
+.gt2 Graoumftracker 2
+.gtk Graoumftracker
+.guide Amigaguide
+.gup Data
+.gus Gustav.Gustavson
+.gvi Video
+.gwp Greetings WorkShop Datei
+.gwy Gwyddion Projekt
+.gwx Graphics Link presentation
+.gwz Graphics Link presentation
+.gvp GEOvison³ Project
+.gxl Graphics library
+.gxt Textdatenbank GTA2 - San Andreas
+.i Intermediate
+.iam Inventor Assembly
+.ian Textdatei
+.iax Bitmap
+.ibm ARCHDOS
+.ica Bitmap graphic
+.ica Citrix-Verbindungsdatei
+.icb Targa bitmap
+.icc Catalog Datei
+.icc Printer Datei
+.icd Drawing Datei
+.icl Icon Library
+.icm Image Color Matching profile
+.icn Icon source code
+.ico Icon
+.ics Scene Datei
+.ics iCalendar Datei
+.id Disk identification Datei
+.idb Intermediate Datei
+.idd Instrument Definition Data (?)
+.ide Project Datei
+.idf MIDI Instrument Definition
+.idif Identification Datei
+.idq Data Query
+.idt Exportierte Windows Installer Datenbank Tabelle
+.idu Austauschdatei
+.idw Vector graphic
+.idw Inventor Drawing
+.idx Index Datei
+.idx Index Datei
+.idx Relational database index
+.idx Relational database index
+.idx Java Applet Cache Index
+.ifd Form
+.iff Interchange File Format (IFF)
+.ifo Information
+.ifo Graphic object layer data
+.ifp Script Datei
+.ifs Compressed fractal image
+.ifs Create executable library
+.ifs System Datei
+.igs Initial Graphics Exchange Specification (IGES)
+.igc Segelflug Logger Datei
+.igf Metafile
+.iif Interchange Datei
+.iii Intel I-Phone compatibel
+.iim Music module
+.ilbm Bitmap
+.ildoc Dokument
+.ili INTERLIS
+.ilk incremental linker
+.im8 Raster graphic
+.ima Image
+.ima DICOM-Bild
+.ima Vector graphic
+.imf MIDI music Datei
+.img DICOM-Bild
+.img Bitmap graphic
+.img kurz für "Image"
+.img Dateiarchiv
+.imp Spreadsheet
+.imq Image presentation
+.ims Create executable library
+.imz Win Image
+.in$ Installationsdatei
+.in3 Input device driver
+.inb Test script
+.inc Include File
+.inc Include File
+.ind Index
+.ind Shared Database Datei
+.indb InDesign Book
+.indd InDesign Document
+.indl InDesign Library
+.indt InDesign Template
+.inf Setup-Informationen
+.inf Type I LaserJet font information
+.info Piktogramm
+.ini Bank setup Datei
+.ini Setup Datei
+.ini Initialisierungsdatei
+.ink Pantone reference fills Datei
+.inl Inline function Datei
+.inp Source code für form,
+.inrs INRS-Telecommunications audio
+.ins Datafile
+.ins Install script
+.ins Installation script
+.ins Instrument Datei
+.ins Instrument music Datei
+.ins Sample
+.ins Sign-up Datei
+.int Interfaced units
+.int Intermediate executable code
+.inx InDesign Interchange
+.inx Index Datei
+.io Compressed archive
+.iob 3D graphics database
+.ioc Organizational chart
+.iof Findit document
+.ion Datei description
+.ipf Interchangeable Preservation Format
+.ipl Pantone Spot reference palette
+.ips International patching system
+.ipt Inventor Part
+.iqf Program Data
+.iqy Internet inquiry
+.iq2 Program Data
+.irs Resource Datei
+.isd Spell checker dictionary
+.ish Compressed archive
+.iso ISO
+.iso ISO 9660 Dateisystem
+.isp Sign-up Datei
+.ist Instrument
+.isu Uninstall script
+.it Impulse Tracker
+.it Settings Datei
+.itc iTunes Covers
+.itf Interface Datei
+.itl iTunes Library
+.iti Impulse Tracker Instrument
+.its Impulse Tracker Sample
+.itz Impulse Tracker zipped
+.iv Open Inventor Datei
+.ivd Microdata dimension or variable-level
+.ivp User subset profile
+.ivt Table or aggregate data
+.ivx Microdata directory
+.iw Presentation flowchart
+.iw Screensaver
+.iwa Text Datei
+.iwc Install Watch document
+.iwm Start Datei
+.iwp Textdokument
+.izt Binary token Datei
+.j2k JPEG2000
+.j62 Ricoh camera Datei
+.jam Java Module
+.jar Java Archive
+.jas Graphic
+.java Source code
+.jbd Datafile
+.jbf Image browser Datei
+.jbx Project Datei
+.jff JPEG image
+.jfif JPEG File Interchange Format
+.jif JPEG image file
+.jisp Java Indexed Serialization Package
+.jmp Discovery chart-to-statistics
+.jn1 Jill of the Jungle data
+.jnb Workbook Datei
+.jnt Journal Viewer File
+.job Vektorgrafik
+.jor Journal
+.jou Journal backup
+.jou Journal backup
+.jp2 JPEG2000
+.jpc JPEG2000
+.jpf JPEG2000 file
+.js JavaScript code
+.jsc Source code
+.jsd Jet Suite document
+.jsk Skin Datei
+.json JavaScript Object Notation
+.jsp JavaServer Page
+.jt Jupiter Tessellation
+.jtf Faxdokument
+.jtk Java ToolKit Datei
+.jw JustWrite
+.jwl JustWrite Library
+.jzz Spreadsheet
+.k LS-Dyna Keyword file
+.k25 Kurzweil 2500
+.k3b K3b Projekt
+.kar karaoke
+.kb Keyboard script
+.kb Program source code
+.kbd Keyboard mapping script
+.kbm Keyboard mapping script
+.kcm K-Cheat Modul
+.kcl Kyoto Common Lisp
+.kdb Keep-in-Mind-Datenbank
+.kex Makro
+.key Datafile
+.key Icon toolbar
+.key Security Datei
+.key Keynote
+.kfp Acrobat Preflight Profil
+.kfx Image
+.kgt KGet
+.kiz Digital postcard
+.kkw K-keywords
+.kml Map
+.kmp KeyMaP
+.kmz Koordinaten
+.ko Linux Kernel Object
+.kpp Toolpad
+.kps Bitmap graphic
+.kqp Native Camera Datei
+.kr1 Sample
+.krz Sample Datei
+.ksf Sample Datei
+.ksp KSpread
+.kwd KWord
+.kwl KWallet-Datei
+.kyb Keyboard mapping
+.kye Game data
+.kys Keyboard Shortcuts
+.l Linker directive Datei
+.l Lex
+.l LISP
+.lab Datafile
+.lab Label-Datei
+.lab Mailing labels
+.lan LAN driver
+.lay Clipart-Datei
+.lay Word Chart layout
+.lbg Label generator data
+.lbk PlotMaker Layoutbuch-Datei
+.lbl Label
+.lbl Label
+.lbl Label
+.lbm Interleaved Bitmap (ILBM)
+.lbo Compiled label
+.lbo MWM-Libero-Projekt
+.lbr LBR-Archiv (LU)
+.lbr Display driver
+.lbr Device library
+.lbt Labels
+.lbx Labels
+.lca LABCAR Assistant-Datei
+.lcf Linker control-Datei
+.lck Lockfile
+.lcl Datafile
+.lcn Lection document
+.lcs Data History Datei
+.lcw Spreadsheet
+.ld Long distance area codes
+.ld1 Overlay-Datei
+.ldb Lock-Datei
+.ldf Library definition-Datei
+.ldf Log Data File
+.ldi LAN driver description file
+.ldif Adressenverzeichnis
+.ldl Library
+.leg Legacy document
+.les System game profiles
+.lev Level-Datei
+.lex Dictionary-Datei
+.lfd Data resource-Datei
+.lfp LaserForms Plus-Datei
+.lft Laser printer font
+.lft Loft-Datei
+.lg Logo procedure definition
+.lgc Application log-Datei
+.lgd Application log-Datei
+.lgo Header and footer logo
+.lgo Lego-Modell-Datei
+.lgo Logo Datei
+.lgo Startup logo
+.lha LHA/LHARC
+.lhs Literate Haskell File
+.lhw LHWARP
+.lib Library
+.library Library
+.lif Logical Interchange data
+.lim LIMIT
+.lin Interactive music sequencing data
+.lin Line type-Datei
+.lis Listing
+.lis SQL-Report
+.lit (Literature)
+.lix Logos library system-Datei
+.lj Textdatei
+.lk Database-Datei
+.lko Linked object
+.ll3 Document-Datei
+.llx Exchange agent
+.lnk Datafile
+.lnk Linker response-Datei
+.lnk Link
+.load z/OS Load-Library
+.loc Locations
+.lock Lock
+.lod Load-Datei
+.log Log
+.log Log-Datei
+.log Logo-Quelltext-Datei
+.logo Combined Logo Mask
+.lok komprimiert
+.lol Lolcode
+.lpc Druckertreiber
+.lpd Helix Nuts and Bolts-Datei
+.lpd LabelPro-Datei
+.lpd LECTURNITY Player-Datei
+.lpi Informationsdatei für Laserdrucker
+.lpj PASSOLO-Projektdatei
+.lps LupoScan
+.lpu PASSOLO-Projektdatei
+.lrc Video phone-Datei
+.lrf Linker response-Datei
+.lrs Language resource-Datei
+.lsf Logos library system-Datei
+.lsl Saved library
+.lsl Script library
+.lso Logic Audio Song/-Dokument
+.lsp LISP
+.lss Tabellenkalkulation
+.lst Keyboard macro
+.lst List-Datei
+.lst Spool-Datei
+.ltm Form
+.lu Library unit-Datei
+.lvl Miner Descent/D2 Level extension
+.lwd Textdokument
+.lwf LuraWave Format
+.lwlo Layered Object-Datei
+.lwob Object-Datei
+.lwp Lotus Word Pro (Teil der Lotus SmartSuite)
+.lwsc Scene-Datei
+.lwz Linguistically enhanced sound
+.lxf Lego Digital Designer-Datei
+.ly Lilypond-Datei
+.lyr Layer-Datei
+.lyx LyX-Datei
+.lzd Difference-Datei für Binarys
+.lzh LH ARC
+.lzs LARC
+.lzs Data-Datei
+.lzw LHWARP
+.m Matlab-file
+.m Objective C
+.m4 M4 Präprozessor
+.m4a Moving Pictures Experts Group 4 Audio
+.m4b Moving Pictures Experts Group 4 Audiobook
+.m4p MPEG4-Audiodatei
+.ma Maya ASCII
+.mab Mozilla Address Book
+.mac MacPaint
+.mac Monkeys Audio Compression
+.mak Makefile
+.mat Matlab Daten Datei
+.mat T-Online Rechnung Online Sicherung
+.mat Verknüpfung mit Microsoft Office Access-Tabelle
+.manifest MANIFEST-Datei
+.mar Microsoft ARchiv
+.mar Mozilla ARchiv
+.map Linker map
+.max Discreet 3D Studio MAX
+.mb Maya Binary
+.mcc Mathcad Configuration File
+.mcd Mathcad Document
+.mcd Minicad
+.mcf Mathcad Fontfile
+.md8 MatchWare Mediator Project
+.mda Microsoft Access
+.mdb Microsoft Data Base
+.mdc Modem Script --- auch "Model Definition *": RTCW/ET Model-Datei
+.mde Microsoft Access
+.mdf Media Descriptor File
+.mdf Master Data File
+.mdf Measurement Data Format File
+.mdi Microsoft Office Document Imaging
+.mdl Hash Animation:Master 3d-Modell
+.mdl (Spieler-)Model
+.mdl Rational Rose Modell
+.mdl MathWorks Simulink Model
+.mds Media Descriptor Image
+.mdx DBase Index-File
+.mell Mellel Dokument
+.mem Ansichtdatei (zu WaveLab)
+.met OS/2 Metafile
+.mfa Multimedia Fusion 2 Applikations-Datei
+.mfw Multimedia Fusion 2 Projekts-Datei
+.mfx Multimedia Fusion 2 Extension
+.mi Model Interface Standard
+.mif Maker Interchange Format
+.minigsf GBA Sound Format
+.miniusf Nintendo 64 Audio-Datei
+.mjf Media Juice File
+.mhk Broderbund Mohawk Archiv
+.mka Matroska Audio
+.mkd Microkernel Database file
+.mkv Matroska Video
+.mm FreeMind-Maps
+.mmap Mindjet MindManager-Maps
+.mmf Samsung & Siemens Handy
+.mmf Microsoft Mail für Windows
+.mml MathML
+.mmm Media Player Multimedia Clip
+.mmm Magix Music Maker
+.mn MuPAD Pro Notebook
+.mnu Menü-Datei
+.mo Machine Object
+.moc MetaObjectCode-Datei
+.mod Module
+.mod Module
+.mop MOPAC
+.mot MOTS - Motorola S-Record File
+.mov Movie
+.mp+ Musepack-Audiodatei
+.mp3 Moving Pictures Experts Group 1/2 Audio Layer 3
+.mp4 Moving Pictures Experts Group 4 Audio & Video
+.mpc Musepack-Audiodatei
+.mpic MWM-Piccolo Projekt-Datei auf dem PDA zum Austausch von Aufmaßen mit MWM-Libero
+.mpp Microsoft Project Plan
+.mpp Musepack-Audiodatei
+.mpq Mo'PaQ, kurz für Mike O'Brien Pack, benannt nach dem Erfinder
+.mpr FileMaker Dictionary
+.mps Max Payne Savegame
+.mps MapSource Datafile
+.mpt Microsoft Project Plan
+.mrc mIRC Scriptdatei
+.mrw Minolta Raw Image
+.ms7 Electronics Workbench Multisim v7 - Schaltplan
+.ms8 Electronics Workbench Multisim v8 - Schaltplan
+.msa MyrScript Datei
+.msc MilcoScan
+.msg Message
+.msi Microsoft Installer
+.msm Microsoft Installer Merge Module
+.msn Microsoft Network Protokoll
+.msp Microsoft Installer Patchdatei
+.mst Microsoft Installer Transformationsdatei
+.msu Microsoft Update
+.mswmm Microsoft Windows Movie Maker Projekt
+.mtm Multitracker Module
+.mus Music
+.mus Musicam
+.mux Musikformat
+.mvf Stop frame file
+.mw Maple-Worksheet
+.mwp Lotus Word Pro Smartmaster
+.mwpp My Webfinder Projekt Package
+.mws Maple-Worksheet
+.myd MySQL Datenbank
+.myi MySQL Datenbank Index
+.myr Musikformat
+.mzt HTML-Vorlage
+.n4d nova 4 drawing
+.n4m nova 4 model
+.n64 Nintendo 64 ROM image
+.nds Nintendo DS ROM image
+.nb Notebook
+.ncd Nero Cover Designer
+.ncf NetWare Command File
+.nef Rohdaten
+.nes NES ROM image
+.nfg Normal Form Game
+.nfo "Info"-Datei
+.nfo MSInfo-Dokument
+.ngp NeoGeo Pocket ROM image
+.ngr NGR Grafic File
+.nhf Nero HFS
+.nif Notation Interchange File Format (NIFF)
+.nir NetInstall Registry file
+.nlm Netware Loadable Module
+.nls LaTeX nomenclatures
+.nmind NovaMind Mindmap
+.nr3 Nero MP3
+.nra Nero Audio
+.nrb Nero Boot
+.nrc Nero Compatible
+.nrd Nero DVD
+.nre Nero CD EXTRA
+.nrg Nero Image
+.nrh Nero Hybrid
+.nri Nero ISO
+.nrm Nero Mixed-Mode-CD
+.nru Nero UDF
+.nrv Nero Video
+.nrw Nero WMA
+.ns1 Netstumbler File
+.nsd Nassi-Shneiderman-Diagramm
+.nsf Nintendo Sound File
+.nsf Notes Storage Facility
+.nspg Nord Stage Program
+.nsv Nullsoft Streaming Video
+.ntf Notes Template File
+.nth Nokia Theme
+.nva E-Animation (NEVA)
+.nvz nova
+.o Object
+.o2c Object 2 See
+.o7o open7x0.org install file
+.obd MS Office Binder File
+.obj Object
+.obml Opera Binary Markup Language
+.oct VIP-Befehlssatz
+.ocx Programmerweiterung
+.odb OpenDocument Database
+.odc OpenDocument Chart
+.odf OpenDocument Formel
+.odg OpenDocument Graphics
+.odi OpenDocument Image
+.odm OpenDocument Master
+.odp OpenDocument Presentation
+.ods OpenDocument Spreadsheet
+.odt OpenDocument Text
+.ofc Open Financial Connectivity
+.off Object File Format
+.ofr OptimFrog
+.oft MS Outlook
+.ofx Open Financial Exchange
+.ogg Ogg
+.ogm Ogg Media
+.okt Oktalyzer
+.old old
+.oma OpenMG Audio
+.omg O&O DiskImage Disk Image
+.one OneNote
+.or# Lotus Organizer Datei
+.orf Olympus Raw File
+.ost MS Outlook
+.otf OpenType Font
+.otg ODoc. Template Drawing
+.oth ODoc. Template HTML
+.otp ODoc. Template Presentation
+.ots ODoc. Template Spreadsheet
+.ott ODoc. Template Text
+.ova Octava Datei
+.ovl Overlay
+.p12 PKI PKCS#12-Format
+.p2v Planungsdatei
+.p65 Satzdatei
+.p81 Leistungsverzeichniss
+.p83 Angebotsaufforderung
+.p84 Angebotsabgabe
+.p85 Nebenangebot
+.p86 Auftragserteilung
+.p88 Nachtrag
+.p89 Rechnung
+.p99 TI99 Programfile
+.p7b PKI PKCS#7-Format
+.p7s PKI PKCS#7-Format
+.pab Papyrus
+.pac Proxy Auto-Config
+.pages Pages
+.pal Palette
+.pap Papyrus
+.par PAR-Wiederherstellungsdatei
+.par2 PAR2-Wiederherstellungsdatei
+.parmlib z/OS-Parameterbibliothek
+.part Partizierte Datei
+.pas Pascal Source Code File
+.pb PureBasic
+.pb Papyrus Base
+.pbf Papyrus Base Formatvorlage
+.pbf Paragon Drive Backup
+.pbi PureBasic-Include
+.pbm Portable Bitmap
+.pc1 Degas (Elite)
+.pc2 Degas (Elite)
+.pc3 Degas (Elite)
+.pcd Photo CD
+.pcp Windows Installer Patch Erstellungs Datei
+.pct Mac Pict
+.pcx Zsoft Paintbrush
+.pbp Sony Playstation Portable ausführbares Archiv
+.pd Pure Data Patch-Datei
+.pdb AportisDoc
+.pdb Microsoft Visual Studio
+.pdd Dateiformat von Adobe PhotoDeluxe
+.pdf Portable Document Format
+.pdf Novell System PrintDef Device Definition File
+.pdi Pinnacle Disc Image
+.pdp Photoshop PDF
+.pdsf Process Data Standard Format
+.pdt IBM iSeries Access Druckerbeschreibung
+.peak Wellenform einer Audiodatei
+.pen io Pen Document
+.pes  ???
+.pf Prefetch file
+.pfb PostScript Font Binary
+.pfm PostScript Font Metric
+.pfr Portable Font Resource
+.pfx PKI PKCS#12-Format
+.pgd Pretty Good Privacy Disk
+.pgn Portable Game Notation
+.pgp Program Parameter
+.pgs Pagestream
+.php PHP Hypertext Preprocessor
+.php3 PHP Hypertext Preprocessor Version 3
+.php4 PHP Hypertext Preprocessor Version 4
+.php5 PHP Hypertext Preprocessor Version 5
+.phps PHP Hypertext Preprocessor Source
+.phtml PHP Hypertext Markup Language
+.pi1 Degas (Elite)
+.pi2 Degas (Elite)
+.pi3 Degas (Elite)
+.pif Programminformationen
+.pisa MWM-Pisa-Projekt
+.pkg 3D Modell
+.pl Perl
+.pl Prolog
+.pla VIP-Mikrobefehlsspeicher
+.pld PhotoLine Document
+.plist Property List
+.plm PL/M
+.pls Playlist
+.plt Plotter Datei
+.plx Perl
+.pm Perl Module
+.pmd Satzdatei
+.pmd PlanMaker Dokument
+.pml Peter Morphose Level
+.png Portable Network Graphics
+.pnm Portable PixMap
+.po Portable Object
+.pos WinHex Positionsdatei
+.pot Portable Object Template
+.pox Poseidon Datei
+.pp Pascal Unit
+.ppa PowerPoint
+.ppe PCBoard Programming Executable
+.ppf iGrafx Image
+.ppf PlayStation Patch File
+.ppi picture editor 400
+.ppl Powerpraise-Lied
+.ppm Portable PixMap
+.ppp Powerpraise-Portfolio
+.pps PowerPoint
+.ppt PowerPoint
+.ppsx PowerPoint
+.ppz PowerPoint
+.pov POV-Ray
+.pot PowerPoint
+.prg Ausführbares Programm
+.prj ANTARES/BKI Energieplaner
+.prj Knorr Bremse
+.prj CodeVision-AVR
+.prj Hash Animation:Master-PRJ
+.PrjPCB PCB-Project
+.prl Pearl Source Code Datei
+.prn Postscript
+.pro IDL source File
+.pro Prolog
+.pro Qt-Projekt-Datei
+.proclib z/OS Procedurenbibliothek
+.properties Java-Properties-Datei
+.prs Harvard Graphics
+.prt Pro/E part
+.prt Unigraphics Part File
+.prtdot Part Template
+.prz Lotus Freelance Graphics
+.ps Postscript
+.psb Adobe Photoshop Big
+.psd Adobe Photoshop
+.psf GoPal Navigator
+.psp Corel Paint Shop Pro-Bild
+.pst Personal Store
+.psw Dokument
+.ptb Power Tab Score
+.ptf Pro Tools File
+.ptm PolyTracker Module
+.ptn Paperport
+.pts Pro Tools Session
+.pub Dokument
+.pwl PassWordList
+.pxl Tabelle
+.pxr Pixar
+.py Python
+.pyc Python compiled
+.pyd Python Dynamic Module
+.qb QuickBASIC
+.qdb CUEcards Datenbank
+.qcd Quicknote encrypted text
+.qdr Q-Dir Document text
+.qti QuickTime Image
+.qti QtiPlot
+.qtl QuickTime Media Link
+.qua AntiVir / Avira Quarantäne
+.qxd QuarkXPress Document:
+.qxl QuarkXPress Library:
+.qxp QuarkXPress Project:
+.qxt QuarkXPress Template:
+.R R-Script-Datei
+.ram Real Media
+.ras SUN Raster Image
+.rar RAR-Archiv
+.rb Ruby
+.rbs ReBirth Songfile
+.rc Resource script
+.rcy Rex
+.ren Renewcalc - Datafile
+.res Resource File
+.resx XML Resource File
+.rexx Rexx
+.rex Rex
+.rez Winrez
+.rfl Propellerhead Reason Instrumenten Bibiliothek
+.rgb Bildformat von Silicon Graphics
+.rgo RepliGo Virtual Print File
+.rk WinRK Kompressionsformat
+.rle Run Length Encoded BMP
+.rm Real Media
+.rmvb Real Media
+.roq id Software-Video
+.rp RealPix Clip
+.rpl Eidos Replay Movies
+.rpm RedHat Package Manager
+.rps Propellerhead Reason Public(nicht bearbeitbare) Song Datei
+.rpt Report
+.rns Propellerhead Reason Locale(bearbeitbare) Song Datei
+.rsdf RS Downloader File
+.rsr Structure
+.rt RealText Clip
+.rt3 RagTime-Dokument
+.rta Raster Transformation Assembler
+.rtd RagTime Document
+.rte Route file
+.rtf Rich Text Format
+.rts RagTime-Vorlage
+.rtt RagTime Template
+.rx2 Rex
+.s Assembler Quellcode
+.s3 Motorola S-Record
+.s3d Simply 3d
+.s3m ScreamTracker 3
+.s3z ScreamTracker 3 zipped
+.s7i Seed7 Includedatei
+.sab Binäre ACIS-Datei, 3D-CAD-Kern Format
+.sam Lotus AmiPro (heute Lotus Word Pro)
+.sami Synchronized Accessible Media Interchange
+.sar Service-Archiv
+.sar System-Architekt
+.sat Text ACIS-Datei, 3D-CAD-Kern Format
+.sav SPSS Datensatz
+.sav Game Score Save
+.sbd Superbase Tabellendefinition
+.sbf Superbase File
+.sbf Su-Bi File
+.sbp Superbase Programmdatei
+.sbq Superbase Query
+.sbu Superbase Update
+.sbv Superbase Formular
+.sb! Superbase Sperrdatei
+.sch Schema
+.sch Schematic
+.SchDOC Schematic Document
+.sci ScrambleIt
+.scm Kompiliertes Script GTA
+.scn Screen file format
+.scr Screensaver
+.sd2 Sounddesigner II
+.sd7 Seed7 Programm
+.sdb StarBase-Datenbank
+.sdc StarOffice Tabelle
+.sdc DeliveryClient Download
+.sde Steganos-Safedatei
+.sdf Spatial Data File
+.sdw StarOffice Writer
+.sem Semaphore-Datei
+.sff Mugen-Sprite Datei
+.sft SFT-Loader-Datei
+.sfv Simple File Verification
+.sfw Seattle FilmWorks Datei
+.sfx Audiodatenarchiv
+.sgb Super Game Boy ROM Image
+.sgp Save Game Patcher Table
+.sh Shell-Skript
+.sh1 Shop - Datenbankdatei
+.sh2 Shop - Datenbankdatei
+.shn Shorten
+.shp Shapefile
+.shs scrap-Datei
+.shtm HTML Document
+.shtml HTML Document
+.shx Shapefile-Index
+.sib Notensatz
+.sid MrSID
+.sik Sicherungskopie
+.sis Symbian Installationsdatei
+.sit Dateiarchiv
+.skd Autodesk Autosketch
+.skf Autodesk Autosketch
+.sl Shared Library
+.sla Scribus LAyout
+.sldasm SolidWorks-Assembly
+.sldbomtbt SolidWorks-Bill of Materials
+.slddrw SolidWorks-Drawing
+.sldholtbt SolidWorks-Hole Table
+.sldlfp SolidWorks-Library Feature Part
+.sldprt SolidWorks-Part
+.sldrevtbt SolidWorks-Revision Table
+.sldwldtbt SolidWorks-Weldment Cut List
+.sle Steganos-Safedatei
+.sle Sisulizer Exchange Package
+.slk SYLK
+.sln MS Visual Studio solution files
+.slp Sisulizer Project
+.smc SNES ROM image
+.smd Sega Mega Drive ROM image
+.smi Synchronized Accessible Media Interchange
+.sms Sega Master System ROM image
+.sng SongBeamer Lied
+.snp Snapshot
+.so Shared Object
+.spl Spell
+.spx speex
+.sql Structured Query Language
+.sqm Software Quality Metrics
+.sqx UnSqueez
+.src Source
+.srf Surface
+.srt SubRipper Subtitle Information
+.ss MADSPACK 2.0
+.ssa SubStation Alpha
+.sta SWIFT Tagesauszüge
+.stb Named plot style table
+.stc XML Calc Template
+.std XML Draw Template
+.stg Simple Text Gateway
+.sti XML Impress Template
+.stl Stereolithografie Format
+.stm Scream Tracker Module
+.stp STEP
+.stt SCHEMA ST4 Transformation
+.stw XML Writer Template
+.sty LaTeX Style
+.sub Subchanneldaten
+.suo Visual Studio Solution User Options
+.sv Schichtenverzeichnis
+.svg Scalable Vector Graphics
+.svgz SVG zipped
+.swc SNES ROM image
+.swf Small Web Format
+.swp Swap
+.swp Swap
+.sxc XML Calc
+.sxd XML Draw
+.sxg XML Global
+.sxi XML Impress
+.sxm XML Math
+.sxp StrokeIt Export
+.sxw XML Writer
+.sys Systemdatei
+.sza HiCAD neXt
+.t65 Pagemaker 6.5 Template
+.tao Track At Once
+.tar Tape Archiver
+.tbz2 .tar.bz2
+.tba PASSOLO-Ãœbersetzungspaket
+.tbalic500 PASSOLO-Ãœbersetzungspaket
+.tbk TheBat! E-Mail-Sicherungsdatei
+.tbu PASSOLO-Ãœbersetzungspaket
+.tbulic500 PASSOLO-Ãœbersetzungspaket
+.tbulic600 PASSOLO-Ãœbersetzungspaket
+.tc TrueCrypt verschlüsselte Datei
+.tct TurboCad Template
+.tcw TurboCad für Windows
+.ter Terrain
+.tex TeX-SourceLaTeX-Source
+.texi Texinfo-Quelltext
+.text Textdatei
+.tff TansForm Formular
+.tfw Tiff-World-File
+.tga TrueVision Targa
+.tgc Terragen 2 Clipdatei
+.tgd Terragen 2 Datei
+.tgw Terragen World File
+.tgz .tar.gz
+.theme Theme
+.thm Thumbnail
+.tib True Image
+.tmd TextMaker Dokument
+.tmp Temporäre Datei
+.tmpl Template
+.tmw Translation Memory
+.tmx Translation Memory eXchange
+.toc Table of Contents
+.torrent Torrent
+.tos Ausführbares Programm
+.tpl Preps Template
+.tps Topspeed Data File
+.tpu Turbo Pascal Unit
+.trc Trace Log
+.trk Tracklog file
+.truhe tansCrypt Truhe
+.ts Transport Stream
+.tsp TAPI Service Provider
+.tsv Tab-Separated Values
+.ttc TrueType Collection
+.ttf TrueType Font
+.ttp TOS Takes Parameters
+.ttx Bilinguale Ãœbersetzungsdatei
+.twa Absatzformat-Datei
+.twd Tempus Word Dokument
+.tws Vorlagendokument
+.txt Text
+.txt MS-Word Text
+.u Unreal
+.u3d Ultimate 3D model file format
+.uc2 UltraCompressor II
+.ucf Xilinx User Constraint File
+.ufo Ulead File for Objects / Unlimited File Ordering
+.uha UHARC Compressed Archive
+.uhs UHS Ultimate Hint System
+.ui Qt User Interface
+.uif Universal Image Format
+.uka Unfall- Kranken- und Absenzenmanagement-System
+.ult Ultra Tracker
+.umod Unreal modification
+.unr Unreal Map
+.uom Update-O-Matic Datei
+.uoml UniqueObject Markup Language
+.urd ultra recall database
+.url Internet Shortcut
+.ut2 UT 2003/2004 Map
+.utx Unreal Texture
+.uu UUncoded Datei
+.uue UUencoded Datei
+.v2i Virtual Volume Image
+.v4p vvvv-patch
+.v64 Nintendo 64 ROM image
+.vb Visual Basic .net
+.vbe Visual Basic Encrypted
+.vbi Visual Basic IntelliCAD
+.vbp Visual Basic Projekt
+.vbs Visual Basic Script
+.vbproj Visual Basic .net Projekt
+.vcf vCard
+.vcproj Visual C++ Projekt
+.vcs vCalendar
+.vda VDA-FS
+.vdf Viren Definitions Datei (virus definition file)
+.vdi Virtual disk image
+.vhd VHDL Source Code File
+.vhd Virtual hard disk
+.vi Virtual Instrument
+.vim Vim-Script
+.vip Virtuelles Projekt
+.vis Vista Grafiks
+.vkf Video Katalog Frage
+.vkv Video Katalog Verzeichnis
+.vlm Virtual Loadable Module
+.vmdk VMware virtual disk file
+.vmf Valve Map File
+.vmo Voice Memo Datei
+.vmt Valve Material File
+.vmx VMware Konfigurationsdatei
+.vob Video Objects
+ .vrs
+Speicherdatei für globale Variablen der Logo (Programmiersprache) .vsd
+Visio .vtf
+Textur-Datei der Source-Engine .vxd
+.wab Windows-Adressbuch
+.war Web Archive
+.war Web Archive
+.wav Microsoft Wave
+.wbk Microsoft Word Backup
+.wbmp Wap-Bitmap
+.webarchive Web-Archiv
+.whtt WinHTTrack Projekt
+.wim Windows Imaging Format
+.wk4 Lotus 123 Datei
+.wks Microsoft Works Datei
+.wl6 Wolfenstein 3D Spieldateien
+.wlb WinLabel
+.wma Windows Media Audio
+.wmf Windows Metafile
+.wmv Windows Media Video
+.wmz Windows Metafile ZIP
+.woa WebObjects Application
+.wpd Word Perfect Document
+.wpf Write Pro File
+.wpg Word Perfect Graphics
+.wps Works Word Processing Files
+.wpt Waypoint file
+.wri Write
+.wrl world
+.ws Worksheet
+.wsp WinShell Project
+.wst WerkStück
+.wv WavPack
+.wyg WYSIWYG-Projekt
+.wzs MS Word Wizard
+.x DirectX Mesh Files
+.x-wav WAV-Datei von Siemens Mobiltelefonen
+.x_b Binäre Parasolid-Datei, 3D-CAD-Kern Format
+.x_t Text Parasolid-Datei, 3D-CAD-Kern Format
+.x1d Folienpräsentation
+.x3f RAW-Fotoformat
+.x32 Text
+.x81 Leistungsverzeichniss
+.x83 Angebotsaufforderung
+.x84 Angebotsabgabe
+.x85 Nebenangebot
+.x86 Auftragserteilung
+.x88 Nachtrag
+.x89 Rechnung
+.xbm X Bitmap
+.xcf GIMP
+.xdt XDT
+.xfm XFrames Model
+.xfi Extracted File Info
+.xhtml Extensible Hypertext Markup Language
+.xla MS Excel
+.xlax MS Excel 2007
+.xlc MS Excel Chart
+.xlcx MS Excel 2007 Chart
+.xlk MS Excel 2007
+.xls MS Excel Sheet
+.xlsx MS Excel 2007 Sheet
+.xlt MS Excel Template
+.xlt MS Excel 2007 Template
+.xm Extended Module
+.xmi Umbrello UML Datei
+.xml Extensible Markup Language
+.xmz Extended Module zipped
+.xpi XPInstall
+.xpm X PixMap
+.xps xps-Format Windows (XPS)
+.xs X-Search
+.xsb Sound Bank, XMLBeans Schema Metadata
+.xsd XML Schema Definition
+.xsl Extensible Stylesheet Language (XSL)
+.xspf XML Shareable Playlist Format
+.xul XML User Interface Language
+.xv2 V-XVL Geometry File (XVL)
+.xv3 P-XVL Geometry File (XVL)
+.xvf Xyngo Video File (XVF)
+.xyz xyz-Format Xmol
+.yink yInk
+.z3d Zanoza 3D File
+.z64 Nintendo 64 ROM image
+.zdl DesignPro-Datei
+.zdp DesignPro-Datei
+.zpj Zend Development Environment Project
+.zt Zer0 Tolerance Source
diff --git a/firstseen.pl b/firstseen.pl
new file mode 100644
index 0000000..9eceff8
--- /dev/null
+++ b/firstseen.pl
@@ -0,0 +1,40 @@
+#!/usr/bin/perl
+
+
+if ($#ARGV ne 2){
+ print "not enough arguments\n";
+ exit 1;
+}
+
+my $chan=$ARGV[1];
+my $folder=$ARGV[0];
+my $nick=$ARGV[2];
+
+my @files;
+
+push @files, `ls $folder/$chan.* | sort`;
+
+foreach $file (@files) {
+
+my $date="irgendwas";
+my $line;
+
+open(file, $file) or die("Could not open file $file");
+foreach $line (<file>) {
+ if ($line =~ m/^\[[0-9]{2}:[0-9]{2}(:[0-]{2})?\] (Action: )?<?$nick>? /i) {
+ if ($date =~ /^irgendwas$/) {
+ print "$nick belongs to inventory\n";
+ exit 0;
+ } else {
+ ($time=$line)=~s/(.*)([0-9]{2}:[0-9]{2}(:[0-9]{2})?)(.*)\n/$3/;
+ print "$nick was first seen on $date at $time\n";
+ exit 0;
+ }
+ }
+ if ($line =~ m/^\[00:00(:00)?\] --- /){
+ ($date=$line)=~s/^\[00:00(:00)?\] --- (.*)\n/$2/;
+ }
+}
+}
+
+print "I do not remember $nick\n";
diff --git a/firstseen.tcl b/firstseen.tcl
new file mode 100644
index 0000000..7697cf1
--- /dev/null
+++ b/firstseen.tcl
@@ -0,0 +1,17 @@
+# lastseen by xeno
+
+bind pub - !firstseen firstseen
+
+proc firstseen {nick host hand chan arg} {
+ set arg [string trim $arg]
+if {$arg == ""} {
+ return 0
+}
+
+ set output [split "[exec perl /home/eggdrop/eggdrop/scripts/firstseen.pl logs [string trimleft $chan #] $arg]" "\n"]
+ foreach out $output {
+ putserv "PRIVMSG $chan :$out";
+ }
+}
+
+putlog "firstseen by lookshe loaded"
diff --git a/getops.tcl b/getops.tcl
new file mode 100644
index 0000000..e16d321
--- /dev/null
+++ b/getops.tcl
@@ -0,0 +1,371 @@
+
+# Getops 2.3b
+
+# $Id: getops.tcl,v 1.18 2003/03/26 00:19:30 wcc Exp $
+
+# This script is used for bots to request and give ops to each other.
+# For this to work, you'll need:
+
+# - Bots must be linked in a botnet
+# - Every bot that should be ops on your channels must load this script
+# - Add all bots you wanna op with this one using the .+bot nick address
+# command. The "nick" should be exactly the botnet-nick of the other bot
+# - Add the hostmasks that uniquely identify this bot on IRC
+# - Add a global or channel +o flag on all bots to be opped
+# - Do exactly the same on all other bots
+
+# The security of this relies on the fact that the bot which wants to have
+# ops must be 1) linked to the current botnet (which requires a password),
+# 2) have an entry with +o on the bot that he wants ops from and 3) must match
+# the hostmask that is stored on each bots userfile (so it is good to keep the
+# hostmasks up-to-date).
+
+# -----------------------------------------------------------------------------
+
+# 2.3c by PPSlim <ppslim@ntlworld.com>
+# - Small fix on timer hanlding.
+# Not list formatted, allowing command parsing of channel name
+
+# 2.3b by gregul <unknown>
+# - small fix in getbot
+
+# 2.3a by guppy <guppy@eggheads.org>
+# - fix for bind need
+
+# 2.3 by guppy <guppy@eggheads.org>
+# - minor cleanup to use some 1.6 tcl functions
+# - use bind need over need-op, need-invite, etc ...
+
+# 2.2g by poptix <poptix@poptix.net>
+# - Fabian's 2.2e broke the script, fixed.
+
+# 2.2f by Eule <eule@berlin.snafu.de>
+# - removed key work-around added in 2.2d as eggdrop now handles this
+# correctly.
+
+# 2.2e by Fabian <fknittel@gmx.de>
+# - added support for !channels (so-called ID-channels), using chandname2name
+# functions. This makes it eggdrop 1.5+ specific.
+
+# 2.2d by brainsick <brnsck@mail.earthlink.net>
+# - Undernet now handles keys differently. It no longer gives the key on a
+# join, but instead gives it on an op, but eggdrop doesn't check for this.
+# getops-2.2d should now handle this correctly. (This should be the final
+# fix to the key problems.)
+
+# 2.2c by Progfou (Jean Christophe ANDRE <progfou@rumiko.info.unicaen.fr>)
+# - changed "Requested" to "Requesting" as it was a little confusing
+# - corrected the "I am not on chan..." problem with key request
+# (thanks to Kram |FL| and Gael for reporting it)
+# - removed more unnecessary check
+
+# 2.2b by Progfou (Jean Christophe ANDRE <progfou@rumiko.info.unicaen.fr>)
+# - removed global +o in unknown bot test
+# - removed unnecessary checks due to previous unknown bot test
+
+# 2.2a by Progfou (Jean Christophe ANDRE <progfou@rumiko.info.unicaen.fr>)
+# - removed Polish language!
+
+# 2.2 by Cron (Arkadiusz Miskiewicz <misiek@zsz2.starachowice.pl>)
+# - works good (tested on eggdrop 1.3.11)
+# - asks from unknown (and bots without +bo) are ignored
+# - all messages in Polish language
+# - better response from script to users
+# - fixed several bugs
+
+# 2.1 by Ernst
+# - asks for ops right after joining the channel: no wait anymore
+# - sets "need-op/need-invite/etc" config right after joining dynamic channels
+# - fixed "You aren't +o" being replied when other bot isn't even on channel
+# - better response from bots, in case something went wrong
+# (for example if bot is not recognized (hostmask) when asking for ops)
+# - removed several no-more-used variables
+# - added the information and description above
+
+# 2.0.1 by beldin (1.3.x ONLY version)
+# - actually, iso needed to be modded for 1.3 :P, and validchan is builtin
+# and I'll tidy a couple of functions up to
+
+# 2.0 by DarkDruid
+# - It'll work with dynamic channels(dan is a dork for making it not..)
+# - It will also only ask one bot at a time for ops so there won't be any more
+# annoying mode floods, and it's more secure that way
+# - I also took that annoying wallop and resynch stuff out :P
+# - And I guess this will with with 1.3.x too
+
+# Previously by The_O, dtM.
+
+# Original incarnation by poptix (poptix@poptix.net)
+
+# -----------------------------------------------------------------------------
+
+# [0/1] do you want GetOps to notice when some unknown (unauthorized) bot
+# sends request to your bot
+set go_bot_unknown 1
+
+# [0/1] do you want your bot to request to be unbanned if it becomes banned?
+set go_bot_unban 1
+
+# [0/1] do you want GetOps to notice the channel if there are no ops?
+set go_cycle 0
+
+# set this to the notice txt for the above (go_cycle)
+set go_cycle_msg "Please part the channel so the bots can cycle!"
+
+# -----------------------------------------------------------------------------
+
+set bns ""
+proc gain_entrance {what chan} {
+ global botnick botname go_bot_unban go_cycle go_cycle_msg bns
+ switch -exact $what {
+ "limit" {
+ foreach bs [lbots] {
+ putbot $bs "gop limit $chan $botnick"
+ putlog "GetOps: Requesting limit raise from $bs on $chan."
+ }
+ }
+ "invite" {
+ foreach bs [lbots] {
+ putbot $bs "gop invite $chan $botnick"
+ putlog "GetOps: Requesting invite from $bs for $chan."
+ }
+ }
+ "unban" {
+ if {$go_bot_unban} {
+ foreach bs [lbots] {
+ putbot $bs "gop unban $chan $botname"
+ putlog "GetOps: Requesting unban on $chan from $bs."
+ }
+ }
+ }
+ "key" {
+ foreach bs [lbots] {
+ putbot $bs "gop key $chan $botnick"
+ putlog "GetOps: Requesting key on $chan from $bs."
+ }
+ }
+ "op" {
+ if {[hasops $chan]} {
+ set bot [getbot $chan]
+ if {$bot == ""} {
+ set bns ""
+ set bot [getbot $chan]
+ }
+ lappend bns "$bot"
+ if {$bot != ""} {
+ putbot $bot "gop op $chan $botnick"
+ putlog "GetOps: Requesting ops from $bot on $chan"
+ }
+ } {
+ if {$go_cycle} {
+ putserv "NOTICE [chandname2name $chan] :$go_cycle_msg"
+ }
+ }
+ }
+ }
+}
+
+proc hasops {chan} {
+ foreach user [chanlist $chan] {
+ if {[isop $user $chan]} {
+ return 1
+ }
+ }
+ return 0
+}
+
+proc getbot {chan} {
+ global bns
+ foreach bn [bots] {
+ if {[lsearch $bns $bn] < 0} {
+ if {[matchattr $bn o|o $chan]} {
+ set nick [hand2nick $bn $chan]
+ if {[onchan $nick $chan] && [isop $nick $chan]} {
+ return $bn
+ break
+ }
+ }
+ }
+ }
+}
+
+proc botnet_request {bot com args} {
+ global go_bot_unban go_bot_unknown
+ set args [lindex $args 0]
+ set subcom [lindex $args 0]
+ set chan [string tolower [lindex $args 1]]
+ if {![validchan $chan]} {
+ putbot $bot "gop_resp I don't monitor $chan."
+ return 0
+ }
+ # Please note, 'chandname2name' will cause an error if it is not a valid channel
+ # Thus, we make sure $chan is a valid channel -before- using it. -poptix
+ set idchan [chandname2name $chan]
+ set nick [lindex $args 2]
+
+ if {$subcom != "takekey" && ![botonchan $chan]} {
+ putbot $bot "gop_resp I am not on $chan."
+ return 0
+ }
+ if {![matchattr $bot b]} {
+ if { $go_bot_unknown == 1} {
+ putlog "GetOps: Request ($subcom) from $bot - unknown bot (IGNORED)"
+ }
+ return 0
+ }
+
+ switch -exact $subcom {
+ "op" {
+ if {![onchan $nick $chan]} {
+ putbot $bot "gop_resp You are not on $chan for me."
+ return 1
+ }
+ set bothand [finduser $nick![getchanhost $nick $chan]]
+ if {$bothand == "*"} {
+ putlog "GetOps: $bot requested ops on $chan. Ident not recognized: $nick![getchanhost $nick $chan]."
+ putbot $bot "gop_resp I don't recognize you on IRC (your ident: $nick![getchanhost $nick $chan])"
+ return 1
+ }
+ if {[string tolower $bothand] == [string tolower $nick]} {
+ putlog "GetOps: $bot requested ops on $chan."
+ } {
+ putlog "GetOps: $bot requested ops as $nick on $chan."
+ }
+ if {[iso $nick $chan] && [matchattr $bothand b]} {
+ if {[botisop $chan]} {
+ if {![isop $nick $chan]} {
+ putlog "GetOps: $nick asked for op on $chan."
+ putbot $bot "gop_resp Opped $nick on $chan."
+ pushmode $chan +o $nick
+ }
+ } {
+ putbot $bot "gop_resp I am not +o on $chan."
+ }
+ } {
+ putbot $bot "gop_resp You aren't +o in my userlist for $chan, sorry."
+ }
+ return 1
+ }
+ "unban" {
+ if {$go_bot_unban} {
+ putlog "GetOps: $bot requested that I unban him on $chan."
+ foreach ban [chanbans $chan] {
+ if {[string compare $nick $ban]} {
+ set bug_1 [lindex $ban 0]
+ pushmode $chan -b $bug_1
+ }
+ }
+ return 1
+ } {
+ putlog "GetOps: Refused request to unban $bot ($nick) on $chan."
+ putbot $bot "gop_resp Sorry, not accepting unban requests."
+ }
+ }
+ "invite" {
+ putlog "GetOps: $bot asked for an invite to $chan."
+ putserv "invite $nick $idchan"
+ return 1
+ }
+ "limit" {
+ putlog "GetOps: $bot asked for a limit raise on $chan."
+ pushmode $chan +l [expr [llength [chanlist $chan]] + 1]
+ return 1
+ }
+ "key" {
+ putlog "GetOps: $bot requested the key on $chan."
+ if {[string match *k* [lindex [getchanmode $chan] 0]]} {
+ putbot $bot "gop takekey $chan [lindex [getchanmode $chan] 1]"
+ } {
+ putbot $bot "gop_resp There isn't a key on $chan!"
+ }
+ return 1
+ }
+ "takekey" {
+ putlog "GetOps: $bot gave me the key to $chan! ($nick)"
+ foreach channel [string tolower [channels]] {
+ if {$chan == $channel} {
+ if {$idchan != ""} {
+ putserv "JOIN $idchan $nick"
+ } else {
+ putserv "JOIN $channel $nick"
+ }
+ return 1
+ }
+ }
+ }
+ default {
+ putlog "GetOps: ALERT! $bot sent fake 'gop' message! ($subcom)"
+ }
+ }
+}
+
+proc gop_resp {bot com msg} {
+ putlog "GetOps: MSG from $bot: $msg"
+ return 1
+}
+
+proc lbots {} {
+ set unf ""
+ foreach users [userlist b] {
+ foreach bs [bots] {
+ if {$users == $bs} {
+ lappend unf $users
+ }
+ }
+ }
+ return $unf
+}
+
+# Returns list of bots in the botnet and +o in my userfile on that channel
+proc lobots { channel } {
+ set unf ""
+ foreach users [userlist b] {
+ if {![matchattr $users o|o $channel]} { continue }
+ foreach bs [bots] {
+ if {$users == $bs} { lappend unf $users }
+ }
+ }
+ return $unf
+}
+
+proc iso {nick chan} {
+ return [matchattr [nick2hand $nick $chan] o|o $chan]
+}
+
+proc gop_need {chan type} {
+ # Use bind need over setting need-op, need-invite, etc ...
+ gain_entrance $type $chan
+}
+
+bind need - * gop_need
+bind bot - gop botnet_request
+bind bot - gop_resp gop_resp
+bind join - * gop_join
+
+proc requestop { chan } {
+ global botnick
+ set chan [string tolower $chan]
+ foreach thisbot [lobots $chan] {
+ # Send request to all, because the bot does not have the channel info yet
+ putbot $thisbot "gop op $chan $botnick"
+ lappend askedbot $thisbot
+ }
+ if {[info exist askedbot]} {
+ regsub -all " " $askedbot ", " askedbot
+ putlog "GetOps: Requested Ops from $askedbot on $chan."
+ } {
+ putlog "GetOps: No bots to ask for ops on $chan."
+ }
+ return 0
+}
+
+proc gop_join { nick uhost hand chan } {
+ if {[isbotnick $nick]} {
+ utimer 3 [list requestop $chan]
+ }
+ return 0
+}
+
+set getops_loaded 1
+
+putlog "GetOps v2.3c loaded."
diff --git a/google.tcl b/google.tcl
new file mode 100644
index 0000000..d37126b
--- /dev/null
+++ b/google.tcl
@@ -0,0 +1,73 @@
+#google.tcl v0.3 - Returns the value of the "I feel lucky" function on google for websites and images via triggers
+#based on scripts by aNa|0Gue
+
+set google(ver) "0.3"
+
+#Simulate a browser, ie: Mozilla
+set google(agent) "MSIE 6.0"
+
+#google search trigger
+set google(g_cmd) "!google"
+
+#google uk search trigger
+set google(guk_cmd) "!googleuk"
+
+#google image search trigger
+set google(gi_cmd) "!image"
+
+#google prefix
+set google(prefix) "* Google:"
+
+package require http
+
+bind pub - $google(g_cmd) pub:google
+#bind pub - $google(guk_cmd) pub:googleuk
+#bind pub - $google(gi_cmd) pub:image
+
+proc pub:google { nick uhost handle channel arg } {
+
+}
+
+proc google:go { url arg } {
+ global google
+ regsub -all " " $arg "+" query
+ set lookup "$url$query"
+ set token [http::config -useragent $google(agent)]
+ set token [http::geturl $lookup]
+ puts stderr ""
+ upvar #0 $token state
+ set max 0
+ foreach {name value} $state(meta) {
+ if {[regexp -nocase ^location$ $name]} {
+ set newurl [string trim $value]
+ regsub -all "btnI=&" $url "" url
+ return "$newurl More: $url$query"
+ }
+ }
+}
+
+proc pub:google { nick uhost handle channel arg } {
+ global google
+ if {[llength $arg]==0} { putserv "NOTICE $nick :Usage: $google(g_cmd) <string>" }
+ set url "http://www.google.de/search?btnI=&q="
+ set output [google:go $url $arg]
+ putserv "PRIVMSG $channel :$nick, $google(prefix) $output"
+}
+
+proc pub:googleuk { nick uhost handle channel arg } {
+ global google
+ if {[llength $arg]==0} { putserv "NOTICE $nick :Usage: $google(guk_cmd) <string>" }
+ set url "http://www.google.co.uk/search?btnI=&q="
+ set output [google:go $url $arg]
+ putserv "PRIVMSG $channel :$nick, $google(prefix) $output"
+}
+
+proc pub:image { nick uhost handle channel arg } {
+ global google
+ if {[llength $arg]==0} { putserv "NOTICE $nick :Usage: $google(gi_cmd) <string>" }
+ set url "http://images.google.com/images?btnI=&q="
+ set output [google:go $url $arg]
+ putserv "PRIVMSG $channel :$nick, $google(prefix) $output"
+}
+
+putlog "google.tcl $google(ver) loaded"
diff --git a/klined.tcl b/klined.tcl
new file mode 100644
index 0000000..044abcc
--- /dev/null
+++ b/klined.tcl
@@ -0,0 +1,179 @@
+#
+# KLined.TCL - Version 1.0
+# By Ian Kaney - ikaney@uk.defiant.org
+#
+# $Id: klined.tcl,v 1.2 1999/12/21 17:35:08 fabian Exp $
+#
+# Even at the best of times, your bot will get k-lined by one operator or
+# another on a server you're running your bot on. This script will 'hopefully'
+# handle this by removing it from your bot's server list when it detects
+# you've been k-lined there. Thus, stopping IRC server admins getting
+# rather peeved at the constant connects from your host.
+#
+# USAGE:
+# The actual handling of removing the server from your server list
+# and writing it to the 'klines' file is handled automatically when
+# your bot receives the k-line signal, but there are some DCC commands
+# that have been added, these are:
+#
+# .klines - Lists the 'klines' file showing servers that your bot
+# has registered as being k-lined on.
+# .unkline <server> - Removes the k-line from the server *joke* ;)
+# Actually, this removes the server from the list
+# of servers to remove.
+#
+
+# Bindings
+# ---
+bind load - server remove_kservers
+bind raw - 465 woah_klined
+bind dcc n klines list_kservers
+bind dcc n unkline unkline_server
+
+# Variables
+# ---
+# Change this to suite your tastes - if you can't be bothered, or
+# don't know how, leave it.
+set kfile "klines"
+
+proc list_kservers {handle idx args} {
+global kfile
+
+putcmdlog "#$handle# klines"
+set fd [open $kfile r]
+set kservers { }
+
+while {![eof $fd]} {
+ set tmp [gets $fd]
+ if {[eof $fd]} {break}
+ set kservers [lappend kservers [string trim $tmp]]
+ }
+close $fd
+if {[llength $kservers] == 0} {
+ putdcc $idx "No k-lined servers."
+ return 0
+ }
+putdcc $idx "My k-lined server list:\n"
+foreach tmp $kservers {
+ putdcc $idx $tmp
+ }
+}
+
+proc unkline_server {handle idx args} {
+global kfile
+
+set kservers {}
+
+set fd [open $kfile r]
+set rem [lindex $args 0]
+
+putcmdlog "#$handle# unkline $rem"
+
+while {![eof $fd]} {
+ set tmp [gets $fd]
+ if {[eof $fd]} {break}
+ set kservers [lappend kservers [string trim $tmp]]
+}
+close $fd
+
+set fd [open $kfile w]
+set flag "0"
+
+foreach tmp $kservers {
+ if {$tmp == $rem} {
+ set flag "1"
+ }
+ if {$tmp != $rem} {
+ puts $fd $tmp
+ }
+ }
+close $fd
+if {$flag == "0"} {
+ putdcc $idx "Could not find $rem in the k-lined server list."
+ }
+if {$flag == "1"} {
+ putdcc $idx "Removed server $rem from k-lined server list."
+ }
+}
+
+proc remove_kservers {module} {
+global kfile
+global server servers
+
+if {[catch {set fd [open $kfile r]}] != 0} {
+set fd [open $kfile w]
+close $fd
+set fd [open $kfile r]
+}
+
+while {![eof $fd]} {
+ set from [string trim [gets $fd]]
+ set name "*$from*"
+ if {[eof $fd]} {break}
+
+ for {set j 0} {$j >= 0} {incr j} {
+ set x [lsearch $servers $name]
+ if {$x >= 0} {
+ set servers [lreplace $servers $x $x]
+ }
+ if {$x < 0} {
+ if {$j >= 0} {
+ putlog "Removed server: $from"
+ }
+ break
+ }
+ }
+ }
+close $fd
+return 1
+}
+
+proc woah_klined {from keyword arg} {
+
+global kfile
+global server servers
+
+set kservers {}
+
+set fd [open $kfile r]
+
+while {![eof $fd]} {
+ set tmp [gets $fd]
+ if {[eof $fd]} {break}
+ set kservers [lappend kservers [string trim $tmp]]
+}
+close $fd
+
+set flag "0"
+
+foreach tmp $kservers {
+ if {$tmp == $from} {
+ set flag "1"
+ }
+}
+
+if {$flag != "1"} {
+set fd [open $kfile a]
+puts $fd $from
+close $fd
+}
+
+set name "*$from*"
+
+for {set j 0} {$j >= 0} {incr j} {
+ set x [lsearch $servers $name]
+ if {$x >= 0} {
+ set servers [lreplace $servers $x $x]
+ }
+ if {$x <= 0} {
+ if {$j >= 0} {
+ putlog "Removed server: $from"
+ }
+ break
+ }
+ }
+ return 1
+}
+
+putlog "TCL loaded: k-lined"
+remove_kservers server
diff --git a/lastseen.pl b/lastseen.pl
new file mode 100644
index 0000000..c70d1d0
--- /dev/null
+++ b/lastseen.pl
@@ -0,0 +1,64 @@
+#!/usr/bin/perl
+
+use File::ReadBackwards;
+
+if ($#ARGV ne 2){
+ print "not enough arguments\n";
+ exit 1;
+}
+
+my $chan=$ARGV[1];
+my $folder=$ARGV[0];
+my $nick=$ARGV[2];
+
+
+my @files;
+
+push @files, `ls $folder/$chan.* | sort -r`;
+
+foreach $file (@files) {
+
+
+my $date=0;
+my $lastaction;
+my $line;
+
+$file=~s/\n$//;
+my $log = File::ReadBackwards->new($file) || die $!;
+
+while ($line=$log->readline()){
+# $line=$log->readline();
+ if ($date eq 0){
+ if ($line =~ m/^\[[0-9]{2}:[0-9]{2}(:[0-9]{2})?\] $nick /i && $line !~ m/joined #/ ) {
+ $date=1;
+ $lastaction=$line;
+ }
+ } else {
+ if ($line =~ m/^\[00:00(:00)?\] --- /){
+ ($date=$line)=~s/^\[00:00(:00)?\] --- (.*)\n/$2/;
+ ($time=$lastaction)=~s/(.*)\[([0-9]{2}:[0-9]{2}(:[0-9]{2})?)\](.*)\n/$2/;
+ $l=9+length($nick);
+ if ($lastaction=~m/^.{$l}kicked/){
+ ($by=$lastaction)=~s/^\[[0-9]{2}:[0-9]{2}(:[0-9]{2})?\] $nick kicked from #.* by //i;
+ ($reason=$by)=~s/.*: (.*)\n/$1/;
+ $by=~s/:.*\n//i;
+
+ print "$nick kicked by $by on $date at $time reason: $reason\n";
+ } elsif ($lastaction=~m/$nick \(.*\) left irc: /i){
+ ($message=$lastaction)=~s/^.* $nick \(.*\) left irc: (.*)\n/$1/i;
+ print "$nick quits on $date at $time saying: $message\n";
+ } else {
+ if ($lastaction=~m/\)\.$/) {
+ ($message=$lastaction)=~s/^.* $nick \(.*\) left #[a-zA-Z0-9]* \((.*)\)\.\n/$1/i;
+ print "$nick parts on $date at $time saying: $message\n";
+ } else {
+ print "$nick parts on $date at $time\n";
+ }
+ }
+ exit 0;
+ }
+ }
+}
+}
+
+print "I do not remember $nick\n";
diff --git a/lastseen.tcl b/lastseen.tcl
new file mode 100644
index 0000000..8733c61
--- /dev/null
+++ b/lastseen.tcl
@@ -0,0 +1,76 @@
+# lastseen by xeno
+
+bind pub - !lastseen lastseen
+bind pub - !lastspoke lastspoke
+bind pub - !seen lastseen
+bind pub - !spoke lastspoke
+
+proc lastspoke {nick host hand chan arg} {
+ set arg [string trim $arg]
+if {$arg == ""} {
+ return 0
+}
+ if {[onchan $arg $chan] != 1} {
+ set output [split "[exec perl /home/eggdrop/eggdrop/scripts/lastspoke.pl /home/eggdrop/eggdrop/logs [string trimleft $chan #] $arg 1]" "\n"]
+ } else {
+ set output [split "[exec perl /home/eggdrop/eggdrop/scripts/lastspoke.pl /home/eggdrop/eggdrop/logs [string trimleft $chan #] $arg 0]" "\n"]
+ }
+ foreach out $output {
+ putserv "PRIVMSG $chan :$out";
+ }
+# set status [catch {set lastdate [exec egrep -iB 5000 "^.{9}$arg" logs/hackerboard.log.2008 | grep "00:00.*---" | tail -n 1 | cut -c13-]}]
+# if {$status == 0} {
+# set lastaction [exec egrep -i "^.{9}$arg" logs/hackerboard.log.2008 | tail -n 1]
+# if {[onchan $arg $chan] != 1} {
+# putserv "PRIVMSG $chan :$arg spoke last time on $lastdate"
+# }
+# putserv "PRIVMSG $chan :$arg's last action: $lastaction"
+# } else {
+# putserv "PRIVMSG $chan :I didn't remember $arg"
+# }
+}
+
+proc lastseen {nick host hand chan arg} {
+ set arg [string trim $arg]
+if {$arg == ""} {
+ return 0
+}
+
+ if {[onchan $arg $chan] == 1} {
+ global botnick
+ if {$botnick == $arg} {
+ putserv "PRIVMSG $chan :Yes, I am here!"
+ } elseif {$nick == $arg} {
+ putserv "PRIVMSG $chan :Where is uhm $arg? Ah, there he is!"
+ } else {
+ putserv "PRIVMSG $chan :$arg is already here you fool..."
+ }
+ } else {
+ putserv "PRIVMSG $chan :[exec perl /home/eggdrop/eggdrop/scripts/lastseen.pl /home/eggdrop/eggdrop/logs [string trimleft $chan #] $arg]"
+# set status [catch {set lastdate [exec egrep -iB 5000 "^.{8}$arg " logs/hackerboard.log.2008 | grep "00:00.*---" | tail -n 1 | cut -c13-]}]
+# if {$status == 0} {
+# set lastaction [exec egrep -i "^.{8}$arg " logs/hackerboard.log.2008 | grep -v "joined #" | tail -n 1]
+# set lasttime [string range $lastaction 1 5]
+# set kicked [string range $lastaction [expr 9 + [string length $arg]] [expr 14 + [string length $arg]]]
+# set lastlist [split $lastaction]
+# set lastlength [string length $lastaction]
+# if {$kicked == "kicked"} {
+# putserv "PRIVMSG $chan :$arg kicked by [string trimright [lindex $lastlist 6] ":"] on $lastdate at $lasttime reason: [string range $lastaction [expr [string first : $lastaction 5] + 2] $lastlength]"
+# } else {
+# if {[lindex $lastlist 4] == "irc:"} {
+# putserv "PRIVMSG $chan :$arg quits on $lastdate at $lasttime saying: [string range $lastaction [expr 2 + [string first : $lastaction 5]] $lastlength]"
+# } else {
+# if {[string range $lastaction [expr $lastlength - 2] [expr $lastlength - 2]] == ")"} {
+# putserv "PRIVMSG $chan :$arg parts on $lastdate at $lasttime saying: [string trimright [string range $lastaction [expr 1 + [string first ( $lastaction [expr 1 + [string first ( $lastaction]]]] $lastlength] ).]"
+# } else {
+# putserv "PRIVMSG $chan :$arg parts on $lastdate at $lasttime"
+# }
+# }
+# }
+# } else {
+# putserv "PRIVMSG $chan :I didn't remember $arg"
+# }
+ }
+}
+
+putlog "lastseen by xeno (pimped by lookshe) loaded"
diff --git a/lastspoke.pl b/lastspoke.pl
new file mode 100644
index 0000000..9ccf5d9
--- /dev/null
+++ b/lastspoke.pl
@@ -0,0 +1,52 @@
+#!/usr/bin/perl
+
+use File::ReadBackwards;
+
+if ($#ARGV ne 3){
+ print "not enough arguments\n";
+ exit 1;
+}
+
+my $folder=$ARGV[0];
+my $chan=$ARGV[1];
+my $nick=$ARGV[2];
+my $printdate=$ARGV[3];
+
+my @files;
+
+push @files, `ls $folder/$chan.* | sort -r`;
+
+foreach $file (@files) {
+
+
+my $date=0;
+my $lastaction;
+my $line;
+
+$file=~s/\n$//;
+my $log = File::ReadBackwards->new($file) || die $!;
+
+while ($line=$log->readline()){
+# $line=$log->readline();
+ if ($date eq 0){
+ if ($line =~ m/^\[[0-9]{2}:[0-9]{2}(:[0-9]{2})?\] <$nick> /i && $line !~ m/joined #/ ) {
+ $date=1;
+ ($lastaction=$line)=~s/\n//;
+ }
+ } else {
+ if ($printdate eq 0){
+ print "$nick\'s last action: $lastaction\n";
+ exit 0;
+ } else {
+ if ($line=~m/^\[00:00(:00)?\] --- /){
+ ($date=$line)=~s/^\[00:00(:00)?\] --- (.*)\n/$2/;
+ print "$nick spoke last time on $date\n";
+ print "$nick\'s last action: $lastaction\n";
+ exit 0;
+ }
+ }
+ }
+}
+}
+
+print "I do not remember $nick\n";
diff --git a/name.tcl b/name.tcl
new file mode 100644
index 0000000..2d36333
--- /dev/null
+++ b/name.tcl
@@ -0,0 +1,20 @@
+# slap by lookshe
+
+bind pub - !name proc_name
+
+proc proc_name {nick host hand chan arg} {
+ #putserv "PRIVMSG $chan :[clock format [NetTime ntp.nasa.gov]]"
+ set arg [string trim $arg]
+ if {$arg == ""} {
+ set output [split "[exec cat /home/eggdrop/eggdrop/scripts/names.txt]" "\n"]
+ foreach out $output {
+ putserv "PRIVMSG $nick :$out"
+ }
+ } else {
+ exec echo $arg >> /home/eggdrop/eggdrop/scripts/names.txt
+ exec echo $arg by $nick >> /home/eggdrop/eggdrop/scripts/names_nick.txt
+ putserv "NOTICE $nick :$arg added to list"
+ }
+}
+
+putlog "name by lookshe loaded"
diff --git a/names.txt b/names.txt
new file mode 100644
index 0000000..f0ca183
--- /dev/null
+++ b/names.txt
@@ -0,0 +1,37 @@
+hackbot
+hackbrett
+iSuck
+Censor
+dummbo-t
+Q
+schäuble
+wolfgang
+7of9
+bot
+Alice
+Brot
+Kicker
+1337h4xX0rzb07
+:)
+gaybot
+cruft_bot
+wallE
+habot
+lsss / lsiss (look, she is so sweeeeeet!)
+#debian.de log 18.11. 13:59
+Wine
+bot
+6aus49
+fibonacci
+iReboot
+idle
+m0e
+doofkopp
+wtf
+||rm -rf /*
+|rm -rf /*
+`|rm -rf /*
+Schwabbel
+JoreyGeneraFarhavenGANGBANG
+iMer
+iShit
diff --git a/names_nick.txt b/names_nick.txt
new file mode 100644
index 0000000..137059c
--- /dev/null
+++ b/names_nick.txt
@@ -0,0 +1,48 @@
+
+blubb
+stonepile
+/ignore marvin
+hackbot
+heinzelottoistcool
+hackbrett
+c
+bammes
+Big Brother
+moe[se] - se für second edition!
+iSuck
+Censor
+test
+nochn test by sterben_will
+dummbo-t by Z
+Q by Draven
+schäuble by bad_alloc
+wolfgang by Lightmaster
+7of9 by Draven
+bot by bad_alloc
+Alice by Draven
+Brot by bad_alloc
+Kicker by bad_alloc
+1337h4xX0rzb07 by Toaster
+:) by bad_alloc
+gaybot by jorey
+cruft_bot by chrom
+wallE by effe
+habot by xeno
+lsss / lsiss (look, she is so sweeeeeet!) by xeno
+#debian.de log 18.11. 13:59 by lookshe
+Wine by bad_alloc
+bot by bad_alloc
+6aus49 by heinzelotto
+fibonacci by bad_alloc
+iReboot by bad_alloc
+idle by bad_alloc
+m0e by xalon
+doofkopp by bammes
+wtf by bad_alloc
+||rm -rf /* by malle
+|rm -rf /* by malle
+`|rm -rf /* by malle
+Schwabbel by malle
+JoreyGeneraFarhavenGANGBANG by malle
+iMer by bad_alloc
+iShit by bad_alloc
diff --git a/notes2.tcl b/notes2.tcl
new file mode 100644
index 0000000..25e737f
--- /dev/null
+++ b/notes2.tcl
@@ -0,0 +1,218 @@
+#
+# notes2.tcl - v2.1.1 - released by MHT <mht@mygale.org>
+# - a bind apart script from #TSF
+# - for eggdrop 1.3.15+
+#
+# $Id: notes2.tcl,v 1.6 2001/11/05 04:08:28 guppy Exp $
+#
+####
+#
+# history:
+# --------
+# 2.0.0 - first release for 1.3.14+mht series
+# (get notesat2.tcl for 1.1.5 series)
+#
+# 2.0.2 - Message bug corrected: "erased <m> notes; <n> left." is better.
+# - Corrected weird switch tcl syntax, bug found by Islandic.
+# It's so different from C (I hate tcl!).
+# - Desactivated message "I don't know you", boring me !
+# - No more logs for notes-indexing on join :-)
+#
+# 2.0.3 - Corrected invalid idx bug, if user quits before receiving
+# his notes check.
+#
+# 2.1.0 - Improved protocol to avoid idx mistake for multiple connected users.
+# Backward compatibility is kept, but price is that idx mistake occurs
+# if a multiple connected user quits before receiving notes check.
+# Generally never happens, except in case of 'Chriphil's syndrome' ;-p
+# - Added missing 'You don't have that many messages.'
+#
+# 2.1.1 - fixed a couple of small bugs pertaining to $nick being used instead of
+# $botnet-nick (found by takeda, fixed by guppy)
+#
+####
+# Check your notes on every shared bot of the hub.
+#
+# .notes [bot|all] index
+# .notes [bot|all] read <#|all>
+# .notes [bot|all] erase <#|all>
+#
+# # may be numbers and/or intervals separated by ;
+# ex: .notes erase 2-4;8;16-
+# .notes noBOTy read all
+#
+
+
+########
+unbind dcc - notes *dcc:notes
+bind dcc - notes *dcc:notes2
+bind chon - * *chon:notes2
+bind bot - notes2: *bot:notes2
+bind bot - notes2reply: *bot:notes2reply
+
+########
+proc n2_notesindex {bot handle idx} {
+ global nick botnet-nick
+ switch "([notes $handle])" {
+ "(-2)" { putbot $bot "notes2reply: $handle Notefile failure. $idx" }
+ #"-1" { putbot $bot "notes2reply: $handle I don't know you. $idx" }
+ "(-1)" { return 0 }
+ "(0)" { putbot $bot "notes2reply: $handle You have no messages. $idx" }
+ default {
+ putbot $bot "notes2reply: $handle ### You have the following notes waiting: $idx"
+ set index 0
+ foreach note [notes $handle "-"] {
+ if {($note != 0)} {
+ incr index
+ set sender [lindex $note 0]
+ set date [strftime "%b %d %H:%M" [lindex $note 1]]
+ putbot $bot "notes2reply: $handle %$index. $sender ($date) $idx"
+ }
+ }
+ putbot $bot "notes2reply: $handle ### Use '.notes ${botnet-nick} read' to read them. $idx"
+ }
+ }
+ return 1
+}
+
+########
+proc n2_notesread {bot handle idx numlist} {
+ if {($numlist == "")} { set numlist "-" }
+ switch "([notes $handle])" {
+ "(-2)" { putbot $bot "notes2reply: $handle Notefile failure. $idx" }
+ #"(-1)" { putbot $bot "notes2reply: $handle I don't know you. $idx" }
+ "(-1)" { return 0 }
+ "(0)" { putbot $bot "notes2reply: $handle You have no messages. $idx" }
+ default {
+ set count 0
+ set list [listnotes $handle $numlist]
+ foreach note [notes $handle $numlist] {
+ if {($note != 0)} {
+ set index [lindex $list $count]
+ set sender [lindex $note 0]
+ set date [strftime "%b %d %H:%M" [lindex $note 1]]
+ set msg [lrange $note 2 end]
+ incr count
+ putbot $bot "notes2reply: $handle $index. $sender ($date): $msg $idx"
+ } else {
+ putbot $bot "notes2reply: $handle You don't have that many messages. $idx"
+ }
+ }
+ }
+ }
+ return 1
+}
+
+########
+proc n2_noteserase {bot handle idx numlist} {
+ switch [notes $handle] {
+ "(-2)" { putbot $bot "notes2reply: $handle Notefile failure. $idx" }
+ #"(-1)" { putbot $bot "notes2reply: $handle I don't know you. $idx" }
+ "(-1)" { return 0 }
+ "(0)" { putbot $bot "notes2reply: $handle You have no messages. $idx" }
+ default {
+ set erased [erasenotes $handle $numlist]
+ set remaining [notes $handle]
+ if {($remaining == 0) && ($erased == 0)} {
+ putbot $bot "notes2reply: $handle You have no messages. $idx"
+ } elseif {($remaining == 0)} {
+ putbot $bot "notes2reply: $handle Erased all notes. $idx"
+ } elseif {($erased == 0)} {
+ putbot $bot "notes2reply: $handle You don't have that many messages. $idx"
+ } elseif {($erased == 1)} {
+ putbot $bot "notes2reply: $handle Erased 1 note, $remaining left. $idx"
+ } else {
+ putbot $bot "notes2reply: $handle Erased $erased notes, $remaining left. $idx"
+ }
+ }
+ }
+ return 1
+}
+
+########
+proc *bot:notes2 {handle idx arg} {
+ if {(![matchattr $handle s])} {
+ return
+ }
+ set nick [lindex $arg 0]
+ set cmd [lindex $arg 1]
+ set num [lindex $arg 2]
+ set idx [lindex $arg 3]
+ if {($num == "") || ($num == "all")} { set num "-" }
+ switch $cmd {
+ "silentindex" { set ret 0; n2_notesindex $handle $nick $idx }
+ "index" { set ret [n2_notesindex $handle $nick $idx] }
+ "read" { set ret [n2_notesread $handle $nick $idx $num] }
+ "erase" { set ret [n2_noteserase $handle $nick $idx $num] }
+ default { set ret 0 }
+ }
+ if {($num == "-")} { set num "" }
+ if {($ret == 1)} { putcmdlog "#$nick@$handle# notes $cmd $num" }
+}
+
+########
+proc *bot:notes2reply {handle idx arg} {
+ # verify that idx is valid (older scripts do not provide idx)
+ set idx [lindex $arg end]
+ if {([valididx $idx]) && ([idx2hand $idx] == [lindex $arg 0])} {
+ set reply [lrange $arg 1 [expr [llength $arg]-2]]
+ } else {
+ set idx [hand2idx [lindex $arg 0]]
+ set reply [lrange $arg 1 end]
+ }
+ if {($idx == -1)} { return }
+ if {([string range $reply 0 0] == "%")} {
+ set reply " [string range $reply 1 end]"
+ }
+ putidx $idx "($handle) $reply"
+}
+
+########
+proc *chon:notes2 {handle idx} {
+ putallbots "notes2: $handle silentindex $idx"
+ return 0
+}
+
+########
+proc *dcc:notes2 {handle idx arg} {
+ global nick botnet-nick
+ if {$arg == ""} {
+ putidx $idx "Usage: notes \[bot|all\] index"
+ putidx $idx " notes \[bot|all\] read <#|all>"
+ putidx $idx " notes \[bot|all\] erase <#|all>"
+ putidx $idx " # may be numbers and/or intervals separated by ;"
+ putidx $idx " ex: notes erase 2-4;8;16-"
+ putidx $idx " notes ${botnet-nick} read all"
+ } else {
+ set bot [string tolower [lindex $arg 0]]
+ set cmd [string tolower [lindex $arg 1]]
+ set numlog [string tolower [lindex $arg 2]]
+ set num $numlog
+ if {($num == "")} { set num "-" }
+ if {($bot != "all") && ([lsearch [string tolower [bots]] $bot] < 0)} {
+ if {($cmd != "index") && ($cmd != "read") && ($cmd != "erase")} {
+ if {($bot == [string tolower $nick])} {
+ return [*dcc:notes $handle $idx [lrange $arg 1 end]]
+ } else {
+ return [*dcc:notes $handle $idx $arg]
+ }
+ } else {
+ putidx $idx "I don't know any bot by that name."
+ return 0
+ }
+ } elseif {($cmd != "index") && ($cmd != "read") && ($cmd != "erase")} {
+ putdcc $idx "Function must be one of INDEX, READ, or ERASE."
+ } elseif {$bot == "all"} {
+ #*dcc:notes $handle $idx [lrange $arg 1 end]
+ putallbots "notes2: $handle $cmd $num $idx"
+ } else {
+ putbot $bot "notes2: $handle $cmd $num $idx"
+ }
+ putcmdlog "#$handle# notes@$bot $cmd $numlog"
+ }
+}
+
+########
+putlog "Notes 2.1.0 - Released by MHT <mht@mygale.org>"
+
+####
diff --git a/parse-fileext-wiki.pl b/parse-fileext-wiki.pl
new file mode 100644
index 0000000..906751b
--- /dev/null
+++ b/parse-fileext-wiki.pl
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+
+#use strict;
+#use warnings;
+use Web::Scraper;
+use URI;
+use HTML::Entities;
+use Encode;
+use URI::Escape;
+use LWP::UserAgent;
+
+my $scrap;
+
+my $wikiurl = "http://de.wikipedia.org/wiki/Liste_der_Dateiendungen";
+
+my $scrapp = scraper {
+ process '//div[@id="bodyContent"]/table/tr/td/a', 'chars[]' => 'TEXT';
+};
+my $url = URI->new($wikiurl);
+my $blubb = $scrapp->scrape($url);
+my $list = $blubb->{'chars'};
+
+binmode(STDOUT, ":utf8");
+
+foreach(@$list) {
+ $scrap = scraper {
+ process '//div[@id="bodyContent"]/table[@class="prettytable"]/tr/td', 'table[]' => 'TEXT';
+ };
+ $url = URI->new("$wikiurl/$_");
+
+ my $res = $scrap->scrape($url);
+ my $table = $res->{'table'};
+
+ for ($i=0; $i<=$#$table; $i+=3) {
+ if ($$table[$i] !~ /\..*(\..*)+/ && $$table[$i+1] !~ /^.?$/ ) {
+ print "$$table[$i] $$table[$i+1]\n";
+ }
+ if ($$table[$i+2] =~ /^\./) {
+ $i--;
+ }
+ }
+}
diff --git a/parse-fileext.pl b/parse-fileext.pl
new file mode 100644
index 0000000..cde0758
--- /dev/null
+++ b/parse-fileext.pl
@@ -0,0 +1,30 @@
+#!/usr/bin/perl
+
+#use strict;
+#use warnings;
+use Web::Scraper;
+use URI;
+use HTML::Entities;
+use Encode;
+use URI::Escape;
+use LWP::UserAgent;
+
+my $scrap;
+
+my $wikiurl = "http://filext.com/file-extension/$ARGV[0]";
+
+my $scrapp = scraper {
+ process '//table/tr/td', 'chars[]' => 'TEXT';
+};
+my $url = URI->new($wikiurl);
+my $blubb = $scrapp->scrape($url);
+my $list = $blubb->{'chars'};
+
+binmode(STDOUT, ":utf8");
+
+for($i = 0; $i <= $#$list;$i++) {
+ if ($$list[$i] =~ /^Extension: $ARGV[0]$/i)
+ {
+ print "$$list[$i+4]\n";
+ }
+}
diff --git a/pong.tcl b/pong.tcl
new file mode 100644
index 0000000..73eee2f
--- /dev/null
+++ b/pong.tcl
@@ -0,0 +1,34 @@
+# description: little funny ping-pong script, everyone knows this joke from irc, bot can kick you or just answer you
+
+# Author: Tomekk
+# e-mail: tomekk/@/oswiecim/./eu/./org
+# home page: http://tomekk.oswiecim.eu.org/
+#
+# Version 0.1
+#
+# This file is Copyrighted under the GNU Public License.
+# http://www.gnu.org/copyleft/gpl.html
+
+bind pub - !ping ping_fct
+
+# 0 - answer 'pong', 1 - kick with 'pong' ;-)
+set fun "0"
+
+proc ping_fct { nick uhost hand chan arg } {
+ global fun
+
+ set txt [split $arg]
+
+ set pongle [join [lrange $txt 0 end]]
+
+ if {$pongle == ""} {
+
+ if {$fun == "0"} {
+ putquick "PRIVMSG $chan :ping? pong!"
+ } {
+ putkick $chan Pong!
+ }
+ }
+}
+
+putlog "tkpingpong.tcl ver 0.1 by Tomekk loaded"
diff --git a/ques5.tcl b/ques5.tcl
new file mode 100644
index 0000000..b0d9d89
--- /dev/null
+++ b/ques5.tcl
@@ -0,0 +1,370 @@
+#
+# ques5.tcl
+#
+# Copyright (C) 1995 - 1997 Robey Pointer
+# Copyright (C) 1999 - 2010 Eggheads Development Team
+#
+# v1 -- 20aug95
+# v2 -- 2oct95 [improved it]
+# v3 -- 17mar96 [fixed it up for 1.0 multi-channel]
+# v4 -- 3nov97 [Fixed it up for 1.3.0 version bots] by TG
+# v4.00001 nov97 [blurgh]
+# v5-BETA1 -- 26sep99 by rtc
+#
+# $Id: ques5.tcl,v 1.17 2010/01/03 13:27:31 pseudo Exp $
+#
+# o clean webfile var removal
+# o using timezone variable from config file
+# o unified options and removed unnecessary ones.
+# o convert urls, nicks etc. to HTML before we put them into the page.
+# o nice html source indenting
+# o replace the old file after the new one has completely written to
+# disk
+# o the description still contained robey's address, replaced
+# by the eggheads email.
+# o don't link any spaces in the HTML2.0 file
+# v5-RC1 -- 29sep99 by rtc
+# o info line wasn't converted to HTML.
+# o now supports bold, italic and underline text style and colors.
+# v5-FINAL -- 04oct99 by rtc
+# o style converter now strictly follows HTML standard.
+# o Fake color attributes with number > 2^32 don't cause Tcl
+# error anymore.
+# o now uses strftime as time and date functions have both been removed
+# in 1.3.29
+
+# this will create an html file every so often (the default is once every
+# 5 minutes). the html file will have a table showing the people currently
+# on the channel, their user@hosts, who's an op, and who's idle. it
+# uses a table which some browsers (and pseudo-browsers like lynx) can't
+# see, but it can optionally make a second page which will support these
+# archaic browsers. browsers supporting push-pull will receive the updated
+# page automatically periodically.
+#
+# if you have a "url" field defined for a user, their nickname in the
+# table will be a link pointing there. otherwise it checks the info
+# line and comment field to see if they start with "http://" -- if so,
+# that link will be used. as a last resort, it will make a "mailto:"
+# link if an email address is recorded for the user.
+#
+# feel free to modify and play with this. the original was written in
+# 15 minutes, then at various times i fixed bugs and added features.
+# softlord helped me make the design look a little nicer. :) if you make
+# any nifty improvements, please let us know.
+# eggheads@eggheads.org
+
+# this line makes sure other scripts won't interfere
+if {[info exists web_file] || [array exists web_file]} {unset web_file}
+
+# You must define each channel you want a webfile for .
+# If you want a HTML2.0 file, too, put it's filename separated by
+# a colon to the same option, it goes to the same directory.
+#set web_file(#turtle) "/home/lamest/public_html/turtle.html:turtle-lynx.html"
+
+# This example demonstrates how to put lynx files into another dir.
+#set web_file(#gloom) "/home/lamest/public_html/gloom.html:lynx/gloom.html"
+
+# You can also prevent the HTML2.0 file from being written.
+#set web_file(#channel) "/home/lamest/public_html/channel.html"
+
+# You can even let the bot write only a HTML2.0.
+#set web_file(#blah) "/home/lamest/public_html/:blah.html"
+
+# how often should these html files get updated?
+# (1 means once every minute, 5 means once every 5 minutes, etc)
+set web_update 5
+
+# Which characters should be allowed in URLs?
+# DO NOT MODIFY unless you really know what you are doing.
+# Especially never add '<', '"' and '>'
+set web_urlchars "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 :+-/!\$%&()=[]{}#^~*.:,;\\|?_@"
+
+# IRC -> HTML color translation table
+set web_color(0) "#FFFFFF"
+set web_color(1) "#000000"
+set web_color(2) "#00007F"
+set web_color(3) "#008F00"
+set web_color(4) "#FF0000"
+set web_color(5) "#7F0000"
+set web_color(6) "#9F009F"
+set web_color(7) "#FF7F00"
+set web_color(8) "#F0FF00"
+set web_color(9) "#00F700"
+set web_color(10) "#008F8F"
+set web_color(11) "#00F7FF"
+set web_color(12) "#0000FF"
+set web_color(13) "#FF00FF"
+set web_color(14) "#7F7F7F"
+set web_color(15) "#CFCFCF"
+
+# IRC -> HTML style translation table
+set web_style(\002) "<B> </B>"
+set web_style(\003) "<FONT> </FONT>"
+set web_style(\026) "<I> </I>"
+set web_style(\037) "<U> </U>"
+
+proc getnumber {string} {
+ set result ""
+ foreach char [split $string ""] {
+ if {[string first $char "0123456789"] == -1} {
+ return $result
+ } else {
+ append result $char
+ }
+ }
+ return $result
+}
+
+proc webify {string} {
+ # Tcl8.1 only:
+ #return [string map {\" &quot; & &amp; < &lt; > &gt;} $string]
+
+ # Otherwise use this:
+ regsub -all "\\&" $string "\\&amp;" string
+ regsub -all "\"" $string "\\&quot;" string
+ regsub -all "<" $string "&lt;" string
+ regsub -all ">" $string "&gt;" string
+
+ return $string
+}
+
+proc convstyle {string} {
+ global web_color web_style
+ set result ""
+ set stack ""
+ for {set i 0} "\$i < [string length $string]" {incr i} {
+ set char [string index $string $i]
+ switch -- $char {
+ "\002" - "\026" - "\037" {
+ if {[string first $char $stack] != -1} {
+ # NOT &&
+ if {[string index $stack 0] == $char} {
+ append result [lindex $web_style($char) 1]
+ set stack [string range $stack 1 end]
+ }
+ } else {
+ append result [lindex $web_style($char) 0]
+ set stack $char$stack
+ }
+ }
+ "\003" {
+ if {[string first $char $stack] != -1} {
+ if {[string index $stack 0] == $char} {
+ append result [lindex $web_style($char) 1]
+ set stack [string range $stack 1 end]
+ }
+ }
+ set c [getnumber [string range $string [expr $i + 1] [expr $i + 2]]]
+ if {$c != "" && $c >= 0 && $c <= 15} {
+ incr i [string length $c]
+ append result "<FONT COLOR=\"$web_color($c)\">"
+ set stack $char$stack
+ }
+ }
+ default {append result $char}
+ }
+ }
+ foreach char [split $stack ""] {
+ if {$char == "\002" || $char == "\003" ||
+ $char == "\026" || $char == "\037"} {
+ append result [lindex $web_style($char) 1]
+ }
+ }
+ return $result
+}
+
+proc urlstrip {string} {
+ global web_urlchars
+ set result ""
+ foreach char [split $string ""] {
+ if {[string first $char $web_urlchars] != -1} {
+ append result $char
+ }
+ }
+ return $result
+}
+
+proc do_ques {} {
+ global web_file web_update web_timerid
+ global botnick timezone
+
+ if {[info exists web_timerid]} {unset web_timerid}
+
+ foreach chan [array names web_file] {
+ if {[lsearch -exact [string tolower [channels]] [string tolower $chan]] == -1} {continue}
+ set i [split $web_file($chan) ":"]
+ set dir ""
+ set file1 [lindex $i 0]
+ set file2 [lindex $i 1]
+ set j [string last "/" $file1]
+ if {$j != -1} {
+ set dir [string range $file1 0 $j]
+ set file1 [string range $file1 [expr $j + 1] end]
+ }
+ unset i j
+ if {$file1 != ""} {
+ set fd1 [open $dir$file1~new w]
+ } else {
+ set fd1 [open "/dev/null" w]
+ }
+ if {$file2 != ""} {
+ set fd2 [open $dir$file2~new w]
+ } else {
+ set fd2 [open "/dev/null" w]
+ }
+
+ puts $fd1 "<HTML>"
+ puts $fd1 " <HEAD>"
+ puts $fd1 " <TITLE>People on [webify $chan] right now</TITLE>"
+ puts $fd1 " <META HTTP-EQUIV=\"Refresh\" CONTENT=\"[webify [expr $web_update * 60]]\">"
+ puts $fd1 " <META NAME=\"GENERATOR\" VALUE=\"ques5.tcl\">"
+ puts $fd1 " </HEAD>"
+ puts $fd1 " <BODY>"
+
+ puts $fd2 "<HTML>"
+ puts $fd2 " <HEAD>"
+ puts $fd2 " <TITLE>People on [webify $chan] right now</TITLE>"
+ puts $fd2 " <META HTTP-EQUIV=\"Refresh\" CONTENT=\"[webify [expr $web_update * 60]]\">"
+ puts $fd2 " <META NAME=\"GENERATOR\" VALUE=\"ques5.tcl\">"
+ puts $fd2 " </HEAD>"
+ puts $fd2 " <BODY>"
+ if {![onchan $botnick $chan]} {
+ puts $fd1 " <H1>Oops!</H1>"
+ puts $fd1 " I'm not on [webify $chan] right now for some reason<BR>"
+ puts $fd1 " IRC isn't a very stable place these days..."
+ puts $fd1 " Please try again later!<BR>"
+
+ puts $fd2 " <H1>Oops!</H1>"
+ puts $fd2 " I'm not on [webify $chan] right now for some reason<BR>"
+ puts $fd2 " IRC isn't a very stable place these days..."
+ puts $fd2 " Please try again later!<BR>"
+ } else {
+ puts $fd1 " <H1>[webify $chan]</H1>"
+ puts $fd2 " <H1>[webify $chan]</H1>"
+ if {$file2 != ""} {
+ puts $fd1 " If this page looks screwy on your browser, "
+ puts $fd1 " try the <A HREF=\"$file2\">HTML 2.0 "
+ puts $fd1 " version</A>.<BR>"
+ }
+ puts $fd1 " <TABLE BORDER=\"1\" CELLPADDING=\"4\">"
+ puts $fd1 " <CAPTION>People on [webify $chan] as of [webify [strftime %a,\ %d\ %b\ %Y\ %H:%M\ %Z]]</CAPTION>"
+ puts $fd1 " <TR>"
+ puts $fd1 " <TH ALIGN=\"LEFT\">Nickname</TH>"
+ puts $fd1 " <TH ALIGN=\"LEFT\">Status</TH>"
+ puts $fd1 " <TH ALIGN=\"LEFT\">User@Host</TH>"
+ puts $fd1 " </TR>"
+ puts $fd2 " <EM>People on [webify $chan] as of [webify [strftime %a,\ %d\ %b\ %Y\ %H:%M\ %Z]]</EM>"
+ puts $fd2 " <PRE>"
+ puts $fd2 " Nickname Status User@Host"
+ foreach nick [chanlist $chan] {
+ set len1 9
+ set len2 16
+ puts $fd1 " <TR ALIGN=\"LEFT\" VALIGN=\"TOP\">"
+ if {[isop $nick $chan]} {lappend status "op"}
+ if {[getchanidle $nick $chan] > 10} {lappend status "idle"}
+ set host [getchanhost $nick $chan]
+ set handle [finduser $nick!$host]
+ set host [webify $host]
+ if {[onchansplit $nick $chan]} {
+ lappend status "<STRONG>split</STRONG>"
+ #incr len2 [string length "<STRONG></STRONG>"]
+ incr len2 17
+ }
+ if {![info exists status]} {
+ set status "-"
+ } else {
+ set status [join $status ", "]
+ }
+ set url [urlstrip [getuser $handle XTRA url]]
+ set info [getuser $handle INFO]
+ set comment [getuser $handle COMMENT]
+ set email [getuser $handle XTRA email]
+ if {$url == "" && [string range $comment 0 6] == "http://"} {
+ set url [urlstrip $comment]
+ }
+ if {$url == "" && [string range $info 0 6] == "http://"} {
+ set url [urlstrip $info]
+ }
+ if {$url == "" && $email != "" && [string match *@*.* $email]} {
+ set url [urlstrip mailto:$email]
+ }
+ incr len1 [string length [webify $nick]]
+ incr len1 -[string length $nick]
+ if {[string tolower $nick] == [string tolower $botnick]} {
+ set host "<EM>&lt;- it's me, the channel bot!</EM>"
+ set info ""
+ } elseif {[matchattr $handle b]} {
+ set host "<EM>&lt;- it's another channel bot</EM>"
+ set info ""
+ }
+ if {$url != ""} {
+ incr len1 [string length "<A HREF=\"$url\"></A>"]
+ puts $fd1 " <TD><A HREF=\"$url\">[webify $nick]</A></TD>"
+ puts $fd2 " [format %-${len1}s <A\ HREF=\"$url\">[webify $nick]</A>] [format %-${len2}s $status] $host"
+ } else {
+ puts $fd1 " <TD>[webify $nick]</TD>"
+ puts $fd2 " [format %-${len1}s [webify $nick]] [format %-${len2}s $status] $host"
+ }
+ puts $fd1 " <TD>$status</TD>"
+ puts $fd1 " <TD>$host</TD>"
+ puts $fd1 " </TR>"
+ if {$info != ""} {
+ puts $fd1 " <TR ALIGN=\"LEFT\" VALIGN=\"TOP\">"
+ puts $fd1 " <TD></TD><TD COLSPAN=\"2\"><STRONG>Info</STRONG>: [convstyle [webify $info]]</TD>"
+ puts $fd1 " </TR>"
+ puts $fd2 " <STRONG>Info:</STRONG> [convstyle [webify $info]]"
+ }
+ unset len1 len2 status info url host comment email
+ }
+ puts $fd1 " </TABLE>"
+ puts $fd2 " </PRE>"
+ }
+ puts $fd1 " <HR>"
+ puts $fd1 " This page is automatically refreshed every [webify $web_update] minute(s).<BR>"
+ puts $fd1 " <ADDRESS>Created by quesedilla v5 via <A HREF=\"http://www.eggheads.org/\">eggdrop</A>.</ADDRESS>"
+ puts $fd1 " </BODY>"
+ puts $fd1 "</HTML>"
+ puts $fd1 ""
+ puts $fd2 " <HR>"
+ puts $fd2 " This page is automatically refreshed every [webify $web_update] minute(s).<BR>"
+ puts $fd2 " <ADDRESS>Created by quesedilla v5 via <A HREF=\"http://www.eggheads.org/\">eggdrop</A>.</ADDRESS>"
+ puts $fd2 " </BODY>"
+ puts $fd2 "</HTML>"
+ puts $fd2 ""
+ close $fd1
+ close $fd2
+ if {$file1 != ""} {exec /bin/mv $dir$file1~new $dir$file1}
+ if {$file2 != ""} {exec /bin/mv $dir$file2~new $dir$file2}
+ unset nick file1 file2 dir fd1 fd2
+ }
+
+ set web_timerid [timer $web_update do_ques]
+}
+
+#if {[info exists web_timerid]} {
+# killtimer $web_timerid
+# unset web_timerid
+#}
+if {![info exists web_timerid] && $web_update > 0} {
+ set web_timerid [timer $web_update do_ques]
+}
+#do_ques
+
+foreach chan [array names web_file] {
+ if {[string first ":" $web_file($chan)] != -1} {
+ lappend channels "$chan"
+ } else {
+ lappend channels "$chan (no lynx)"
+ }
+}
+
+if {![info exists channels]} {
+ putlog "Quesedilla v5 final loaded (no channels)"
+} else {
+ putlog "Quesedilla v5 final loaded: [join $channels ,\ ]"
+ unset channels
+}
+
+if {![info exists timezone]} {
+ set timezone [clock format 0 -format %Z]
+}
diff --git a/quotepass.tcl b/quotepass.tcl
new file mode 100644
index 0000000..0e35d9c
--- /dev/null
+++ b/quotepass.tcl
@@ -0,0 +1,41 @@
+#
+# quotepass.tcl
+# written by simple, [sL], and guppy
+#
+# Some servers on the Undernet will make you send 'PASS <numbers>' before you
+# can connect if you did not return an identd response. This script will
+# handle sending that for you.
+#
+# updates
+# -------
+# 10Feb08: initial version
+#
+# $Id: quotepass.tcl,v 1.3 2008/02/11 02:28:41 guppy Exp $
+
+set quotepass_resyntax "must type /QUOTE PASS (\[^\" \]*)"
+
+bind evnt - init-server quotepass_unbind
+bind evnt - disconnect-server quotepass_unbind
+bind evnt - connect-server quotepass_bind
+
+proc quotepass_notice {from cmd text} {
+ global quotepass_resyntax
+ if {[regexp -nocase $quotepass_resyntax $text - pass]} {
+ putlog "Got a QUOTE PASS request from the server, sending \"PASS $pass\""
+ putserv "PASS $pass"
+ }
+ return 0
+}
+
+proc quotepass_unbind {type} {
+ # Try to unbind our raw NOTICE bind once we are connected since it will
+ # never be needed again
+ catch {
+ unbind raw - NOTICE quotepass_notice
+ }
+}
+
+proc quotepass_bind {type} {
+ bind raw - NOTICE quotepass_notice
+}
+
diff --git a/quotepong.tcl b/quotepong.tcl
new file mode 100644
index 0000000..85d2141
--- /dev/null
+++ b/quotepong.tcl
@@ -0,0 +1,288 @@
+# quotepong.tcl by [sL] (Feb 14, 08)
+# Based on quotepass.tcl by simple, guppy, [sL]
+#
+# Ascii Letter definitions provided by Freeder
+#
+# Description:
+#
+# Some EFnet servers require the user to type /quote pong :<cookie>
+# when ident is broken or disabled. This will send pong :<cookie> to
+# the server when connecting.
+#
+
+set a2t_alphabet(a) "\n\ /\\ \n\
+\ / \\ \n\
+\ / /\\ \\ \n\
+\ / ____ \\ \n\
+/_/ \\_\\\n"
+
+set a2t_alphabet(b) "\ ____ \n\
+| _ \\ \n\
+| |_) |\n\
+| _ < \n\
+| |_) |\n\
+|____/"
+
+set a2t_alphabet(c) "\ _____ \n\
+\ / ____|\n\
+| | \n\
+| | \n\
+| |____ \n\
+\ \\_____|"
+
+set a2t_alphabet(d) "\ _____ \n\
+| __ \\ \n\
+| | | |\n\
+| | | |\n\
+| |__| |\n\
+|_____/ "
+
+set a2t_alphabet(e) "\ ______ \n\
+| ____|\n\
+| |__ \n\
+| __| \n\
+| |____ \n\
+|______|\n"
+
+set a2t_alphabet(f) "\ ______ \n\
+| ____|\n\
+| |__ \n\
+| __| \n\
+| | \n\
+|_| "
+
+
+set a2t_alphabet(g) "\ _____\n\
+\ / ____|\n\
+| | __ \n\
+| | |_ |\n\
+| |__| |\n\
+\ \\_____|"
+
+set a2t_alphabet(h) "\ _ _ \n\
+| | | |\n\
+| |__| |\n\
+| __ |\n\
+| | | |\n\
+|_| |_|"
+
+set a2t_alphabet(i) "\ _____ \n\
+|_ _|\n\
+\ | | \n\
+\ | | \n\
+\ _| |_ \n\
+|_____|"
+
+set a2t_alphabet(j) "\ _ \n\
+\ | |\n\
+\ | |\n\
+\ _ | |\n\
+| |__| |\n\
+\ \\____/ "
+
+set a2t_alphabet(k) "\ _ __\n\
+| |/ /\n\
+| ' / \n\
+| < \n\
+| . \\ \n\
+|_|\\_\\"
+
+set a2t_alphabet(l) "\ _ \n\
+| | \n\
+| | \n\
+| | \n\
+| |____ \n\
+|______|"
+
+set a2t_alphabet(m) "\ __ __ \n\
+| \\/ |\n\
+| \\ / |\n\
+| |\\/| |\n\
+| | | |\n\
+|_| |_|"
+
+set a2t_alphabet(n) "\ _ _ \n\
+| \\ | |\n\
+| \\| |\n\
+| . ` |\n\
+| |\\ |\n\
+|_| \\_|"
+
+
+set a2t_alphabet(o) "\ ____ \n\
+\ / __ \\ \n\
+| | | |\n\
+| | | |\n\
+| |__| |\n\
+\ \\____/ "
+
+set a2t_alphabet(p) "\ _____ \n\
+| __ \\ \n\
+| |__) |\n\
+| ___/ \n\
+| | \n\
+|_| "
+
+set a2t_alphabet(q) "\ ____ \n\
+\ / __ \\ \n\
+| | | |\n\
+| | | |\n\
+| |__| |\n\
+\ \\___\\_\\"
+
+set a2t_alphabet(r) "\ _____ \n\
+| __ \\ \n\
+| |__) |\n\
+| _ / \n\
+| | \\ \\ \n\
+|_| \\_\\"
+
+set a2t_alphabet(s) "\ _____ \n\
+\ / ____|\n\
+| (___ \n\
+\ \\___ \\ \n\
+\ ____) |\n\
+|_____/ "
+
+set a2t_alphabet(t) "\ _______ \n\
+|__ __|\n\
+\ | | \n\
+\ | | \n\
+\ | | \n\
+\ |_| "
+
+
+set a2t_alphabet(u) "\ _ _ \n\
+| | | |\n\
+| | | |\n\
+| | | |\n\
+| |__| |\n\
+\ \\____/ "
+
+
+set a2t_alphabet(v) " __ __\n\
+\\ \\ / /\n\
+\ \\ \\ / / \n\
+\ \\ \\/ / \n\
+\ \\ / \n\
+\ \\/ "
+
+set a2t_alphabet(w) " __ __\n\
+\\ \\ / /\n\
+\ \\ \\ /\\ / / \n\
+\ \\ \\/ \\/ / \n\
+\ \\ /\\ / \n\
+\ \\/ \\/ "
+
+
+set a2t_alphabet(x) " __ __\n\
+\\ \\ / /\n\
+\ \\ V / \n\
+\ > < \n\
+\ / . \\ \n\
+/_/ \\_\\"
+
+set a2t_alphabet(y) " __ __\n\
+\\ \\ / /\n\
+\ \\ \\_/ / \n\
+\ \\ / \n\
+\ | | \n\
+\ |_| "
+
+
+set a2t_alphabet(z) "\ ______\n\
+|___ /\n\
+\ / / \n\
+\ / / \n\
+\ / /__ \n\
+/_____|"
+
+proc a2t_ascii2text {ascii {count 6}} {
+ global a2t_alphabet
+# foreach line [split $ascii \n] { putlog $line }
+ set a2t_result ""
+ for {set i 0} {$i < $count} {incr i} {
+ foreach let [split abcdefghijklmnopqrstuvwxyz ""] {
+ set match 1
+ set tascii $ascii
+ foreach alph_line [split $a2t_alphabet($let) \n] {
+ set alph_line [string range $alph_line 1 end]
+ set asc_line [lindex [split $tascii \n] 0]
+ set tascii [join [lrange [split $tascii \n] 1 end] \n]
+ # need to fix our match pattern
+ regsub -all {\\} $alph_line {\\\\} alph_line
+ if {![string match "[string trim $alph_line]*" [string trim $asc_line]]} {
+ set match 0
+ break
+ }
+ }
+ if {$match} {
+ append a2t_result $let
+ # remove the ascii letter
+ set new_ascii [list]
+ foreach alph_line [split $a2t_alphabet($let) \n] {
+ set alph_line [string range $alph_line 1 end]
+ set asc_line [lindex [split $ascii \n] 0]
+ set ascii [join [lrange [split $ascii \n] 1 end] \n]
+ # need to fix our regspec
+ regsub -all {\\} $alph_line {\\\\} alph_line
+ regsub -all {\|} $alph_line "\\|" alph_line
+ regsub -all {\)} $alph_line "\\)" alph_line
+ regsub -all {\(} $alph_line "\\(" alph_line
+
+ regsub -- $alph_line "$asc_line" "" asc_line
+ lappend new_ascii $asc_line
+ }
+ set ascii [join $new_ascii \n]
+ }
+ if {$match} { break }
+ }
+ }
+ return [string toupper $a2t_result]
+}
+
+set quotepong_match "/QUOTE PONG :cookie"
+
+bind evnt - init-server quotepong_unbind
+bind evnt - disconnect-server quotepong_unbind
+bind evnt - connect-server quotepong_bind
+
+proc quotepong_servermsg {from cmd text} {
+ global quotepong_match quotepong_count quotepong_ascii
+ if {![info exists quotepong_count] && [string match "*$quotepong_match*" $text]} {
+ set quotepong_count 0
+ set quotepong_ascii [list]
+ return 0
+ }
+ if {[info exists quotepong_count] && ($cmd == "998")} {
+ if {$quotepong_count == 0} {
+ putlog "Received ASCII Cookie from server:"
+ }
+ incr quotepong_count
+ lappend quotepong_ascii [lindex [split $text :] 1]
+ putlog "[lindex [split $text :] 1]"
+ if {$quotepong_count == 6} {
+ # time to send back to server
+ set cookie [a2t_ascii2text [join $quotepong_ascii \n]]
+ putlog "Sending Cookie to server: $cookie"
+ putserv "PONG :$cookie"
+ catch {unset quotepong_count}
+ }
+ }
+ return 0
+}
+
+proc quotepong_unbind {type} {
+ # Try to unbind our raw NOTICE bind once we are connected since it will
+ # never be needed again
+ catch {
+ unbind raw - NOTICE quotepong_servermsg
+ unbind raw - 998 quotepong_servermsg
+ }
+}
+
+proc quotepong_bind {type} {
+ bind raw - NOTICE quotepong_servermsg
+ bind raw - 998 quotepong_servermsg
+}
+
diff --git a/sentinel.tcl b/sentinel.tcl
new file mode 100644
index 0000000..86b764e
--- /dev/null
+++ b/sentinel.tcl
@@ -0,0 +1,1442 @@
+# sentinel.tcl v2.70 (15 April 2002)
+# Copyright 1998-2002 by slennox
+# slennox's eggdrop page - http://www.egghelp.org/
+
+# Flood protection system for eggdrop, with integrated BitchX CTCP
+# simulation. This script is designed to provide strong protection for your
+# bot and channels against large floodnets and proxy floods.
+#
+# Note that this script was developed on the eggdrop 1.3, 1.4, and 1.6
+# series and may not work properly on other versions.
+#
+# v2.00 - New standalone release. Contains refinements and features from
+# the netbots.tcl version of sentinel.tcl.
+# v2.50 - Locktimes of less than 30 were erroneously allowed.
+# putquick -next is now supported (eggdrop 1.5+) for faster channel
+# lock.
+# - Ban mechanism now checks if flooders are coming from the same
+# domain or ident and performs wildcard bans instead of banning
+# each IP/host individually.
+# - Added tsunami detection to the avalanche flood detection system.
+# - Variables are now cleared after removing a channel.
+# - Removed unnecessary botonchan checks throughout components where
+# botisop already checks for that.
+# - Removed all unnecessary use of parentheses.
+# v2.60 - Modified putquick compatibility proc.
+# - Added sl_wideban option to make domain/ident bans optional.
+# - Fixed typos in various ban-related functions.
+# - Unused procs are now unloaded.
+# - Wildcard bans covering domains/idents were not doing proper
+# checks on join-part flooders.
+# v2.70 - Fixed "allbans" error which could occur when sl_wideban is
+# disabled.
+# - Added sl_masktype option, currently offering three different
+# ban/ignore mask types.
+# - Merged unsets in sl_unsetarray.
+# - Changed use of "split" in timers to the less ugly "list".
+#
+# sentinel.tcl is centered around its channel lock mechanism. It sets the
+# channel +mi (moderated and invite-only) whenever a substantial flood on
+# the channel is detected. This ensures channel stability when flooded,
+# allowing the bots to deal with the flood as smoothly as possible.
+# sentinel.tcl detects the following types of floods:
+#
+# * Channel CTCP floods. This is the most common type of flood, and will
+# often make users quit from the channel with 'Excess Flood'. A quick
+# channel lock can prevent this.
+# * Channel join-part floods. A common type of channel flood in which many
+# floodbots cycle the channel.
+# * Channel nick floods. Nick floods are unique in that they can occur even
+# after a channel is locked. sentinel has special mechanisms to deal with
+# this as effectively as possible.
+# * Channel avalanche/tsunami floods. While the avalanche flood is quite
+# uncommon these days, tsunami floods are often used to seriously lag
+# mIRC and other clients using control codes (colour, bold, underline,
+# etc.)
+# * Channel text floods. Not small text floods - but when hundreds of
+# messages are sent to the channel within a short period. Detected to
+# stop really aggressive text floods and reduce the possibility of the
+# bot crashing or consuming excessive CPU.
+#
+# sentinel also has additional protection features for the bot and channel:
+#
+# * Bogus username detection. Users with annoying bogus characters in their
+# ident are banned. A channel lock is applied if multiple join in a short
+# period.
+# * Full ban list detection. During a serious flood, the ban list may
+# become full. If this happens, the bots may start kick flooding since
+# they cannot ban. If the ban list is full, the channel will be set +i.
+# * Bot CTCP flood protection. Protects the bot if it is CTCP flooded.
+# * Bot MSG flood protection. Protects the bot if it's flooded with MSGs or
+# MSG commands.
+# * Automatic bans and ignores. During a flood, sentinel will compile a
+# list of the flooders, then kick-ban them after the channel has been
+# locked.
+# * BitchX simulation. This has been built-in mainly because you cannot use
+# a third-party BitchX simulator with sentinel (only one script at a time
+# can have control of CTCPs). sentinel provides accurate simulation of
+# BitchX 75p1+ and 75p3+ CTCP replies and AWAY mode.
+# * Public commands (lc and uc) and DCC commands (.lock and .unlock) for
+# locking/unlocking channels.
+# * DCC command .sentinel displays current settings.
+#
+# Important Notes:
+# - Make sure no bots are enforcing channel mode -i and/or -m.
+# - Bans are added to the bot's internal ban list, and expire after 24
+# hours by default. If you have +dynamicbans set, the bans may be removed
+# from the channel much sooner than this, but the ban will remain in the
+# bot's internal ban list until it expires.
+# - For greater protection against large channel floods, I recommend you
+# also use a channel limiter script, such as chanlimit.tcl.
+# - There is a trade-off between convenience and security. The more
+# automation you enable, the more stress the bot will be under during a
+# flood and the more stuff it will be sending to the server.
+# - Where security is paramount, have one or two bots that aren't running
+# sentinel.tcl. Since sentinel.tcl is a complex script with many
+# automated and convenience features, there is a potential for
+# vulnerabilities.
+
+# The following flood settings are in number:seconds format, 0:0 to
+# disable.
+
+# Bot CTCP flood.
+set sl_bcflood 5:30
+
+# Bot MSG flood.
+set sl_bmflood 6:20
+
+# Channel CTCP flood.
+set sl_ccflood 5:20
+
+# Channel avalanche/tsunami flood.
+set sl_avflood 6:20
+
+# Channel text flood.
+set sl_txflood 80:30
+
+# Channel bogus username join flood.
+set sl_boflood 4:20
+
+# Channel join-part flood.
+set sl_jflood 6:20
+
+# Channel nick flood.
+set sl_nkflood 6:20
+
+# Flood setting notes:
+# - Don't fiddle too much with the seconds field in the flood settings, as
+# it can reduce the effectiveness of the script. The seconds field should
+# set in the 20-60 seconds range.
+# - Avalanche/tsunmami flood detection may be CPU intensive on a busy
+# channel, although I don't think it's a big deal on most systems. If
+# you're concerned about CPU usage you may wish to disable it, perhaps
+# leaving it enabled on one bot. Disabling text flood protection can
+# further reduce CPU usage.
+# - On bots with avalanche/tsunami flood detection enabled, it's
+# recommended that you also enable text flood detection to cap CPU usage
+# during a flood.
+# - If you enable nick flood detection, it's strongly recommended that it
+# be enabled on all bots that have sentinel.tcl loaded. This is required
+# for effective nick flood handling.
+
+# Specify the number of control characters that must be in a line before
+# it's counted by the tsunami flood detector. For efficiency reasons,
+# tsunami detection is implemented with avalanche detection, so sl_avflood
+# must be enabled for tsunami detection to be active. Setting this to 0
+# will disable tsunami detection.
+set sl_tsunami 10
+# Valid settings: 0 to disable, otherwise 1 or higher.
+
+# Length of time in minutes to ban channel flooders. This makes the bot
+# perform kicks and bans on flooders after the channel lock. Because of the
+# reactive nature of automatic bans, you should disable this on at least
+# one bot for the most effective protection.
+set sl_ban 1440
+# Valid settings: 0 to disable, otherwise 1 or higher.
+
+# Length of time in minutes of on-join bans for bogus usernames. For the
+# most effective protection, you should disable this on at least one bot.
+set sl_boban 1440
+# Valid settings: 0 to disable, otherwise 1 or higher.
+
+# Set global bans on channel flooders and bogus usernames?
+set sl_globalban 0
+# Valid settings: 1 for global bans, 0 for channel-specific bans.
+
+# When processing a list of flooders, sentinel.tcl compares the hosts to
+# see if multiple flooders are coming from a particular domain/IP or using
+# the same ident (e.g. different vhosts on a single user account). If
+# multiple flooders come from the same domain/IP, or if multiple flooders
+# have the same ident, then the whole domain/IP (i.e. *!*@*.domain.com or
+# *!*@555.555.555.*) or ident (i.e. *!*username@*) is banned. If you
+# disable this option, all bans will be in *!*@machine.domain.com and
+# *!*@555.555.555.555 format.
+set sl_wideban 1
+# Valid settings: 1 to enable, 0 to disable.
+
+# Maximum number of bans allowed in the bot's ban list before sentinel will
+# stop adding new bans. This prevents the bot from adding hundreds of bans
+# on really large floods. Note that this has nothing to do with the channel
+# ban list.
+set sl_banmax 100
+# Valid settings: 1 or higher.
+
+# Length of time in minutes to ignore bot flooders. On bots with sl_ban
+# active, channel flooders are also added to the ignore list.
+set sl_igtime 240
+# Valid settings: 1 or higher.
+
+# Select the type of hostmask to use when banning and/or ignoring flooders.
+# There are three to choose from:
+# 0 - *!*@machine.domain.com / *!*@555.555.555.555
+# 1 - *!*ident@machine.domain.com / *!*ident@555.555.555.555
+# 2 - *!*ident@*.domain.com / *!*ident@555.555.555.*
+# The default option, 0, is strongly recommended for most situations, and
+# provides the best level of protection. The other two options are provided
+# mainly for special cases.
+set sl_masktype 0
+# Valid settings: 0, 1, or 2, depending on the hostmask type you wish to use.
+
+# Length of time in seconds to set channel +i if flooded. If set to 0, +i
+# will not be removed automatically.
+set sl_ilocktime 120
+# Valid settings: 0 to prevent +i being removed automatically, otherwise 30
+# or higher.
+
+# Length of time in seconds to set channel +m if flooded. If set to 0, +m
+# will not be removed automatically.
+set sl_mlocktime 60
+# Valid settings: 0 to prevent +m being removed automatically, otherwise 30
+# or higher.
+
+# On small floods (two flooders or less), remove the +mi shortly after bans
+# have been set, instead of waiting for the locktimes to expire? This
+# prevents unnecessary extended locks on small floods. This setting is only
+# used by bots with sl_ban enabled.
+set sl_shortlock 0
+# Valid settings: 0 to disable, 1 to enable.
+
+# Number of bans to allow in the channel ban list before setting the
+# channel +i. If enabled, this should preferably be set to just below the
+# maximum number of bans allowed.
+set sl_bfmaxbans 19
+# Valid settings: 0 to disable +i on full ban list, otherwise 1 or higher.
+
+# List of users to send a note to when channel is flooded, bot is flooded,
+# or ban list becomes full.
+set sl_note "YourNick"
+# Valid settings: one user like "Tom", a list of users like
+# "Tom Dick Harry", or "" to specify that no notes are sent.
+
+# Notice to send to channel when locked due to flood.
+set sl_cfnotice "Channel locked temporarily due to flood, sorry for any inconvenience this may cause :-)"
+# Valid settings: a text string, or set it to "" to disable.
+
+# Notice to send to channel when locked due to full ban list.
+set sl_bfnotice "Channel locked temporarily due to full ban list, sorry for any inconvenience this may cause :-)"
+# Valid settings: a text string, or set it to "" to disable.
+
+# Enable 'lc' and 'uc' public commands for locking/unlocking channel?
+set sl_lockcmds 2
+# Valid settings: 0 to disable, 1 to enable, 2 to require user to be opped
+# on the channel to use the command.
+
+# Users with these flags are allowed to use lc/uc public commands, and
+# .lock/.unlock DCC commands.
+set sl_lockflags "o"
+# Valid settings: one flag like "n", or a list of flags like "fo" (means
+# 'f OR o').
+
+# Enable BitchX CTCP and AWAY simulation?
+set sl_bxsimul 0
+# Valid settings: 1 to enable, 0 to disable.
+
+
+# Don't edit below unless you know what you're doing.
+
+if {$numversion < 1032400} {
+ proc botonchan {chan} {
+ global botnick
+ if {![validchan $chan]} {
+ error "illegal channel: $chan"
+ } elseif {![onchan $botnick $chan]} {
+ return 0
+ }
+ return 1
+ }
+ proc putquick {text args} {
+ putserv $text
+ }
+}
+
+proc sl_ctcp {nick uhost hand dest key arg} {
+ global botnet-nick botnick realname sl_ban sl_bflooded sl_bcflood sl_bcqueue sl_bxjointime sl_bxmachine sl_bxonestack sl_bxsimul sl_bxsystem sl_bxversion sl_bxwhoami sl_ccbanhost sl_ccbannick sl_ccflood sl_ccqueue sl_flooded sl_locked sl_note
+ set chan [string tolower $dest]
+ if {[lsearch -exact $sl_ccflood 0] == -1 && [validchan $chan] && ![isop $nick $chan]} {
+ if {$nick == $botnick} {return 0}
+ if {$sl_ban && !$sl_locked($chan) && ![matchattr $hand f|f $chan]} {
+ lappend sl_ccbannick($chan) $nick ; lappend sl_ccbanhost($chan) [string tolower $uhost]
+ utimer [lindex $sl_ccflood 1] [list sl_ccbanqueue $chan]
+ }
+ if {$sl_flooded($chan)} {return 1}
+ incr sl_ccqueue($chan)
+ utimer [lindex $sl_ccflood 1] [list sl_ccqueuereset $chan]
+ if {$sl_ccqueue($chan) >= [lindex $sl_ccflood 0]} {
+ sl_lock $chan "CTCP flood" ${botnet-nick} ; return 1
+ }
+ if {$sl_bflooded} {return 1}
+ } elseif {[lindex $sl_bcflood 0] && $dest == $botnick} {
+ if {$sl_bflooded} {
+ sl_ignore [string tolower $uhost] $hand "CTCP flooder" ; return 1
+ }
+ incr sl_bcqueue
+ utimer [lindex $sl_bcflood 1] {incr sl_bcqueue -1}
+ if {$sl_bcqueue >= [lindex $sl_bcflood 0]} {
+ putlog "sentinel: CTCP flood detected on me! Stopped answering CTCPs temporarily."
+ set sl_bflooded 1
+ utimer [lindex $sl_bcflood 1] {set sl_bflooded 0}
+ if {[info commands sendnote] != ""} {
+ foreach recipient $sl_note {
+ if {[validuser $recipient]} {
+ sendnote SENTINEL $recipient "Bot was CTCP flooded."
+ }
+ }
+ }
+ return 1
+ }
+ }
+
+ if {!$sl_bxsimul} {return 0}
+ if {$sl_bxonestack} {return 1}
+ set sl_bxonestack 1 ; utimer 2 {set sl_bxonestack 0}
+ switch -exact -- $key {
+ "CLIENTINFO" {
+ set bxcmd [string toupper $arg]
+ switch -exact -- $bxcmd {
+ "" {putserv "NOTICE $nick :\001CLIENTINFO SED UTC ACTION DCC CDCC BDCC XDCC VERSION CLIENTINFO USERINFO ERRMSG FINGER TIME PING ECHO INVITE WHOAMI OP OPS UNBAN IDENT XLINK UPTIME :Use CLIENTINFO <COMMAND> to get more specific information\001"}
+ "SED" {putserv "NOTICE $nick :\001CLIENTINFO SED contains simple_encrypted_data\001"}
+ "UTC" {putserv "NOTICE $nick :\001CLIENTINFO UTC substitutes the local timezone\001"}
+ "ACTION" {putserv "NOTICE $nick :\001CLIENTINFO ACTION contains action descriptions for atmosphere\001"}
+ "DCC" {putserv "NOTICE $nick :\001CLIENTINFO DCC requests a direct_client_connection\001"}
+ "CDCC" {putserv "NOTICE $nick :\001CLIENTINFO CDCC checks cdcc info for you\001"}
+ "BDCC" {putserv "NOTICE $nick :\001CLIENTINFO BDCC checks cdcc info for you\001"}
+ "XDCC" {putserv "NOTICE $nick :\001CLIENTINFO XDCC checks cdcc info for you\001"}
+ "VERSION" {putserv "NOTICE $nick :\001CLIENTINFO VERSION shows client type, version and environment\001"}
+ "CLIENTINFO" {putserv "NOTICE $nick :\001CLIENTINFO CLIENTINFO gives information about available CTCP commands\001"}
+ "USERINFO" {putserv "NOTICE $nick :\001CLIENTINFO USERINFO returns user settable information\001"}
+ "ERRMSG" {putserv "NOTICE $nick :\001CLIENTINFO ERRMSG returns error messages\001"}
+ "FINGER" {putserv "NOTICE $nick :\001CLIENTINFO FINGER shows real name, login name and idle time of user\001"}
+ "TIME" {putserv "NOTICE $nick :\001CLIENTINFO TIME tells you the time on the user's host\001"}
+ "PING" {putserv "NOTICE $nick :\001CLIENTINFO PING returns the arguments it receives\001"}
+ "ECHO" {putserv "NOTICE $nick :\001CLIENTINFO ECHO returns the arguments it receives\001"}
+ "INVITE" {putserv "NOTICE $nick :\001CLIENTINFO INVITE invite to channel specified\001"}
+ "WHOAMI" {putserv "NOTICE $nick :\001CLIENTINFO WHOAMI user list information\001"}
+ "OP" {putserv "NOTICE $nick :\001CLIENTINFO OP ops the person if on userlist\001"}
+ "OPS" {putserv "NOTICE $nick :\001CLIENTINFO OPS ops the person if on userlist\001"}
+ "UNBAN" {putserv "NOTICE $nick :\001CLIENTINFO UNBAN unbans the person from channel\001"}
+ "IDENT" {putserv "NOTICE $nick :\001CLIENTINFO IDENT change userhost of userlist\001"}
+ "XLINK" {putserv "NOTICE $nick :\001CLIENTINFO XLINK x-filez rule\001"}
+ "UPTIME" {putserv "NOTICE $nick :\001CLIENTINFO UPTIME my uptime\001"}
+ "default" {putserv "NOTICE $nick :\001ERRMSG CLIENTINFO: $arg is not a valid function\001"}
+ }
+ return 1
+ }
+ "VERSION" {
+ putserv "NOTICE $nick :\001VERSION \002BitchX-$sl_bxversion\002 by panasync \002-\002 $sl_bxsystem :\002 Keep it to yourself!\002\001"
+ return 1
+ }
+ "USERINFO" {
+ putserv "NOTICE $nick :\001USERINFO \001"
+ return 1
+ }
+ "FINGER" {
+ putserv "NOTICE $nick :\001FINGER $realname ($sl_bxwhoami@$sl_bxmachine) Idle [expr [unixtime] - $sl_bxjointime] seconds\001"
+ return 1
+ }
+ "PING" {
+ putserv "NOTICE $nick :\001PING $arg\001"
+ return 1
+ }
+ "ECHO" {
+ if {[validchan $chan]} {return 1}
+ putserv "NOTICE $nick :\001ECHO [string range $arg 0 59]\001"
+ return 1
+ }
+ "ERRMSG" {
+ if {[validchan $chan]} {return 1}
+ putserv "NOTICE $nick :\001ERRMSG [string range $arg 0 59]\001"
+ return 1
+ }
+ "INVITE" {
+ if {$arg == "" || [validchan $chan]} {return 1}
+ set chanarg [lindex [split $arg] 0]
+ if {((($sl_bxversion == "75p1+") && ([string trim [string index $chanarg 0] "#+&"] == "")) || (($sl_bxversion == "75p3+") && ([string trim [string index $chanarg 0] "#+&!"] == "")))} {
+ if {[validchan $chanarg]} {
+ putserv "NOTICE $nick :\002BitchX\002: Access Denied"
+ } else {
+ putserv "NOTICE $nick :\002BitchX\002: I'm not on that channel"
+ }
+ }
+ return 1
+ }
+ "WHOAMI" {
+ if {[validchan $chan]} {return 1}
+ putserv "NOTICE $nick :\002BitchX\002: Access Denied"
+ return 1
+ }
+ "OP" -
+ "OPS" {
+ if {$arg == "" || [validchan $chan]} {return 1}
+ putserv "NOTICE $nick :\002BitchX\002: I'm not on [lindex [split $arg] 0], or I'm not opped"
+ return 1
+ }
+ "UNBAN" {
+ if {$arg == "" || [validchan $chan]} {return 1}
+ if {[validchan [lindex [split $arg] 0]]} {
+ putserv "NOTICE $nick :\002BitchX\002: Access Denied"
+ } else {
+ putserv "NOTICE $nick :\002BitchX\002: I'm not on that channel"
+ }
+ return 1
+ }
+ }
+ return 0
+}
+
+proc sl_bmflood {nick uhost hand text} {
+ global sl_bmflood sl_bflooded sl_bmqueue sl_note
+ if {[matchattr $hand b] && [string tolower [lindex [split $text] 0]] == "go"} {return 0}
+ if {$sl_bflooded} {
+ sl_ignore [string tolower $uhost] $hand "MSG flooder" ; return 0
+ }
+ incr sl_bmqueue
+ utimer [lindex $sl_bmflood 1] {incr sl_bmqueue -1}
+ if {$sl_bmqueue >= [lindex $sl_bmflood 0]} {
+ putlog "sentinel: MSG flood detected on me! Stopped answering MSGs temporarily."
+ set sl_bflooded 1
+ utimer [lindex $sl_bmflood 1] {set sl_bflooded 0}
+ if {[info commands sendnote] != ""} {
+ foreach recipient $sl_note {
+ if {[validuser $recipient]} {
+ sendnote SENTINEL $recipient "Bot was MSG flooded."
+ }
+ }
+ }
+ }
+ return 0
+}
+
+proc sl_avflood {from keyword arg} {
+ global botnet-nick botnick sl_ban sl_avbanhost sl_avbannick sl_avflood sl_avqueue sl_flooded sl_locked sl_txflood sl_txqueue
+ set arg [split $arg]
+ set chan [string tolower [lindex $arg 0]]
+ if {![validchan $chan]} {return 0}
+ set nick [lindex [split $from !] 0]
+ if {$nick == $botnick || $nick == "" || [string match *.* $nick]} {return 0}
+ if {![onchan $nick $chan] || [isop $nick $chan]} {return 0}
+ if {!$sl_flooded($chan) && [lsearch -exact $sl_txflood 0] == -1} {
+ incr sl_txqueue($chan)
+ if {$sl_txqueue($chan) >= [lindex $sl_txflood 0]} {
+ sl_lock $chan "TEXT flood" ${botnet-nick}
+ }
+ }
+ set text [join [lrange $arg 1 end]]
+ if {[sl_checkaval $text] && [lsearch -exact $sl_avflood 0] == -1} {
+ set uhost [string trimleft [getchanhost $nick $chan] "~+-^="]
+ set hand [nick2hand $nick $chan]
+ if {$sl_ban && !$sl_locked($chan) && $nick != $botnick && ![matchattr $hand f|f $chan]} {
+ lappend sl_avbannick($chan) $nick ; lappend sl_avbanhost($chan) [string tolower $uhost]
+ utimer [lindex $sl_avflood 1] [list sl_avbanqueue $chan]
+ }
+ if {$sl_flooded($chan)} {return 0}
+ incr sl_avqueue($chan)
+ utimer [lindex $sl_avflood 1] [list sl_avqueuereset $chan]
+ if {$sl_avqueue($chan) >= [lindex $sl_avflood 0]} {
+ sl_lock $chan "AVALANCHE/TSUNAMI flood" ${botnet-nick}
+ }
+ }
+ return 0
+}
+
+proc sl_checkaval {text} {
+ global sl_tsunami
+ if {[regsub -all -- "\001|\007" $text "" temp] >= 3} {return 1}
+ if {$sl_tsunami && [regsub -all -- "\002|\003|\017|\026|\037" $text "" temp] >= $sl_tsunami} {return 1}
+ return 0
+}
+
+proc sl_nkflood {nick uhost hand chan newnick} {
+ global botnet-nick botnick sl_ban sl_banmax sl_flooded sl_globalban sl_locked sl_nickkick sl_nkbanhost sl_nkflood sl_nkflooding sl_nkqueue
+ set chan [string tolower $chan]
+ if {[isop $newnick $chan]} {return 0}
+ if {$sl_ban && !$sl_locked($chan) && $nick != $botnick && ![matchattr $hand f|f $chan]} {
+ lappend sl_nkbanhost($chan) [string tolower $uhost]
+ utimer [lindex $sl_nkflood 1] [list sl_nkbanqueue $chan]
+ }
+ if {!$sl_nickkick && $sl_flooded($chan) && $sl_locked($chan)} {
+ putserv "KICK $chan $newnick :NICK flooder"
+ set sl_nickkick 1 ; set sl_nkflooding($chan) [unixtime]
+ if {$sl_ban} {
+ set bhost [string tolower [sl_masktype $uhost]]
+ if {$sl_globalban} {
+ if {[llength [banlist]] < $sl_banmax && ![isban $bhost] && ![matchban $bhost]} {
+ newban $bhost sentinel "NICK flooder" $sl_ban
+ }
+ } else {
+ if {[llength [banlist $chan]] < $sl_banmax && ![isban $bhost $chan] && ![matchban $bhost $chan]} {
+ newchanban $chan $bhost sentinel "NICK flooder" $sl_ban
+ }
+ }
+ }
+ utimer [expr [rand 2] + 3] {set sl_nickkick 0}
+ return 0
+ }
+ if {$sl_flooded($chan)} {return 0}
+ incr sl_nkqueue($chan)
+ utimer [lindex $sl_nkflood 1] [list sl_nkqueuereset $chan]
+ if {$sl_nkqueue($chan) >= [lindex $sl_nkflood 0]} {
+ sl_lock $chan "NICK flood" ${botnet-nick}
+ }
+ return 0
+}
+
+proc sl_jflood {nick uhost hand chan} {
+ global botnet-nick botnick sl_ban sl_banmax sl_boban sl_bobanhost sl_bobannick sl_boflood sl_boqueue sl_flooded sl_globalban sl_jbanhost sl_jbannick sl_jflood sl_jqueue sl_locked sl_pqueue
+ if {$nick == $botnick} {
+ sl_setarray $chan
+ } else {
+ set ihost [string tolower [sl_masktype $uhost]]
+ if {[isignore $ihost]} {
+ killignore $ihost
+ }
+ set chan [string tolower $chan]
+ if {[lsearch -exact $sl_boflood 0] == -1 && [sl_checkbogus [lindex [split $uhost @] 0]]} {
+ if {!$sl_locked($chan) && ![matchattr $hand f|f $chan]} {
+ set bhost [string tolower [sl_masktype $uhost]]
+ if {$sl_boban && [botisop $chan] && !$sl_flooded($chan)} {
+ putserv "KICK $chan $nick :BOGUS username"
+ if {$sl_globalban} {
+ if {[llength [banlist]] < $sl_banmax && ![isban $bhost] && ![matchban $bhost]} {
+ newban $bhost sentinel "BOGUS username" $sl_boban
+ }
+ } else {
+ if {[llength [banlist $chan]] < $sl_banmax && ![isban $bhost $chan] && ![matchban $bhost $chan]} {
+ newchanban $chan $bhost sentinel "BOGUS username" $sl_boban
+ }
+ }
+ }
+ if {$sl_ban} {
+ lappend sl_bobannick($chan) $nick ; lappend sl_bobanhost($chan) [string tolower $uhost]
+ utimer [lindex $sl_boflood 1] [list sl_bobanqueue $chan]
+ }
+ }
+ if {!$sl_flooded($chan)} {
+ incr sl_boqueue($chan)
+ utimer [lindex $sl_boflood 1] [list sl_boqueuereset $chan]
+ if {$sl_boqueue($chan) >= [lindex $sl_boflood 0]} {
+ sl_lock $chan "BOGUS joins" ${botnet-nick}
+ }
+ }
+ }
+ if {[lsearch -exact $sl_jflood 0] == -1} {
+ if {$sl_ban && !$sl_locked($chan) && ![matchattr $hand f|f $chan]} {
+ lappend sl_jbannick($chan) $nick ; lappend sl_jbanhost($chan) [string tolower $uhost]
+ utimer [lindex $sl_jflood 1] [list sl_jbanqueue $chan]
+ }
+ if {$sl_flooded($chan)} {return 0}
+ incr sl_jqueue($chan)
+ utimer [lindex $sl_jflood 1] [list sl_jqueuereset $chan]
+ if {$sl_jqueue($chan) >= [lindex $sl_jflood 0] && $sl_pqueue($chan) >= [lindex $sl_jflood 0]} {
+ sl_lock $chan "JOIN-PART flood" ${botnet-nick}
+ }
+ }
+ }
+ return 0
+}
+
+proc sl_checkbogus {ident} {
+ if {[regsub -all -- "\[^\041-\176\]" $ident "" temp] >= 1} {return 1}
+ return 0
+}
+
+proc sl_pflood {nick uhost hand chan {msg ""}} {
+ global botnick sl_ban sl_flooded sl_jflood sl_locked sl_pbanhost sl_pbannick sl_pqueue
+ if {[lsearch -exact $sl_jflood 0] != -1} {return 0}
+ if {$nick == $botnick} {
+ if {![validchan $chan]} {
+ timer 5 [list sl_unsetarray $chan]
+ }
+ return 0
+ }
+ set chan [string tolower $chan]
+ if {$sl_ban && !$sl_locked($chan) && ![matchattr $hand f|f $chan]} {
+ lappend sl_pbannick($chan) $nick ; lappend sl_pbanhost($chan) [string tolower $uhost]
+ utimer [lindex $sl_jflood 1] [list sl_pbanqueue $chan]
+ }
+ if {$sl_flooded($chan)} {return 0}
+ incr sl_pqueue($chan)
+ utimer [lindex $sl_jflood 1] [list sl_pqueuereset $chan]
+ return 0
+}
+
+proc sl_pfloodk {nick uhost hand chan kicked reason} {
+ global botnick sl_flooded sl_jflood sl_pqueue
+ if {[lsearch -exact $sl_jflood 0] != -1} {return 0}
+ if {$kicked == $botnick} {return 0}
+ set chan [string tolower $chan]
+ if {$sl_flooded($chan)} {return 0}
+ incr sl_pqueue($chan)
+ utimer [lindex $sl_jflood 1] [list sl_pqueuereset $chan]
+ return 0
+}
+
+proc sl_lock {chan flood detected} {
+ global botnet-nick sl_bflooded sl_cfnotice sl_flooded sl_ilocktime sl_mlocktime sl_note
+ if {[string tolower $detected] == [string tolower ${botnet-nick}]} {
+ set sl_flooded($chan) 1 ; set sl_bflooded 1
+ if {[botisop $chan]} {
+ sl_quicklock $chan
+ sl_killutimer "sl_unlock $chan *"
+ sl_killutimer "set sl_bflooded 0"
+ if {$sl_mlocktime} {
+ utimer $sl_mlocktime [list sl_unlock $chan m]
+ }
+ if {$sl_ilocktime} {
+ utimer $sl_ilocktime [list sl_unlock $chan i]
+ }
+ utimer 120 {set sl_bflooded 0}
+ putlog "sentinel: $flood detected on $chan! Channel locked temporarily."
+ if {$sl_cfnotice != ""} {
+ puthelp "NOTICE $chan :$sl_cfnotice"
+ }
+ } else {
+ putlog "sentinel: $flood detected on $chan! Cannot lock channel because I'm not opped."
+ utimer 120 {set sl_bflooded 0}
+ }
+ } else {
+ putlog "sentinel: $flood detected by $detected on $chan!"
+ }
+ if {[info commands sendnote] != ""} {
+ foreach recipient $sl_note {
+ if {[validuser $recipient]} {
+ if {[string tolower $detected] == [string tolower ${botnet-nick}]} {
+ sendnote SENTINEL $recipient "$flood detected on $chan."
+ } else {
+ sendnote SENTINEL $recipient "$flood detected by $detected on $chan."
+ }
+ }
+ }
+ }
+ return 0
+}
+
+proc sl_unlock {chan umode} {
+ global sl_bflooded sl_bfmaxbans sl_flooded sl_ilocktime sl_mlocktime sl_nkflooding
+ if {[expr [unixtime] - $sl_nkflooding($chan)] < 12} {
+ putlog "sentinel: nick flooding still in progress on $chan - not removing +mi yet.."
+ set sl_flooded($chan) 1 ; set sl_bflooded 1
+ sl_killutimer "sl_unlock $chan *"
+ sl_killutimer "set sl_bflooded 0"
+ utimer $sl_mlocktime [list sl_unlock $chan m] ; utimer $sl_ilocktime [list sl_unlock $chan i]
+ utimer 120 {set sl_bflooded 0}
+ } else {
+ set sl_flooded($chan) 0
+ if {![botisop $chan]} {return 0}
+ if {$umode == "mi"} {
+ putlog "sentinel: flood was small, performing early unlock.."
+ }
+ if {[string match *i* $umode] && [string match *i* [lindex [split [getchanmode $chan]] 0]]} {
+ if {$sl_bfmaxbans && [llength [chanbans $chan]] >= $sl_bfmaxbans} {
+ putlog "sentinel: not removing +i on $chan due to full ban list."
+ } else {
+ pushmode $chan -i
+ putlog "sentinel: removed +i on $chan"
+ }
+ }
+ if {[string match *m* $umode] && [string match *m* [lindex [split [getchanmode $chan]] 0]]} {
+ pushmode $chan -m
+ putlog "sentinel: removed +m on $chan"
+ }
+ }
+ return 0
+}
+
+proc sl_mode {nick uhost hand chan mode victim} {
+ global botnick sl_ban sl_bfmaxbans sl_bfnotice sl_bfull sl_flooded sl_locked sl_note sl_unlocked
+ set chan [string tolower $chan]
+ if {$mode == "+b" && $sl_bfmaxbans && !$sl_bfull($chan) && ![string match *i* [lindex [split [getchanmode $chan]] 0]] && [botisop $chan] && [llength [chanbans $chan]] >= $sl_bfmaxbans} {
+ putserv "MODE $chan +i"
+ set sl_bfull($chan) 1
+ utimer 5 [list set sl_bfull($chan) 0]
+ putlog "sentinel: locked $chan due to full ban list!"
+ if {$sl_bfnotice != ""} {
+ puthelp "NOTICE $chan :$sl_bfnotice"
+ }
+ if {[info commands sendnote] != ""} {
+ foreach recipient $sl_note {
+ if {[validuser $recipient]} {
+ sendnote SENTINEL $recipient "Locked $chan due to full ban list."
+ }
+ }
+ }
+ } elseif {$mode == "+i" && $sl_flooded($chan)} {
+ set sl_locked($chan) 1
+ if {$sl_ban} {
+ sl_killutimer "sl_*banqueue $chan"
+ utimer 7 [list sl_dokicks $chan] ; utimer 16 [list sl_setbans $chan]
+ }
+ } elseif {$mode == "-i" || $mode == "-m"} {
+ set sl_locked($chan) 0
+ set sl_unlocked($chan) [unixtime]
+ if {$sl_flooded($chan)} {
+ set sl_flooded($chan) 0
+ if {$mode == "-i"} {
+ sl_killutimer "sl_unlock $chan i"
+ } else {
+ sl_killutimer "sl_unlock $chan m"
+ }
+ sl_killutimer "sl_unlock $chan mi"
+ if {$nick != $botnick} {
+ putlog "sentinel: $chan unlocked by $nick"
+ }
+ }
+ }
+ return 0
+}
+
+proc sl_dokicks {chan} {
+ global sl_avbannick sl_bobannick sl_ccbannick sl_kflooders sl_jbannick sl_pbannick
+ if {![botisop $chan]} {return 0}
+ set sl_kflooders 0
+ sl_kick $chan $sl_ccbannick($chan) "CTCP flooder" ; set sl_ccbannick($chan) ""
+ sl_kick $chan $sl_avbannick($chan) "AVALANCHE/TSUNAMI flooder" ; set sl_avbannick($chan) ""
+ sl_kick $chan $sl_bobannick($chan) "BOGUS username" ; set sl_bobannick($chan) ""
+ set jklist $sl_jbannick($chan) ; set pklist $sl_pbannick($chan)
+ if {$jklist != "" && $pklist != ""} {
+ set klist ""
+ foreach nick $jklist {
+ if {[lsearch -exact $pklist $nick] != -1} {
+ lappend klist $nick
+ }
+ }
+ sl_kick $chan $klist "JOIN-PART flooder"
+ }
+ set sl_jbannick($chan) "" ; set sl_pbannick($chan) ""
+ return 0
+}
+
+proc sl_kick {chan klist reason} {
+ global sl_kflooders sl_kicks
+ if {$klist != ""} {
+ set kicklist ""
+ foreach nick $klist {
+ if {[lsearch -exact $kicklist $nick] == -1} {
+ lappend kicklist $nick
+ }
+ }
+ unset nick
+ incr sl_kflooders [llength $kicklist]
+ foreach nick $kicklist {
+ if {[onchan $nick $chan] && ![onchansplit $nick $chan]} {
+ lappend ksend $nick
+ if {[llength $ksend] >= $sl_kicks} {
+ putserv "KICK $chan [join $ksend ,] :$reason"
+ unset ksend
+ }
+ }
+ }
+ if {[info exists ksend]} {
+ putserv "KICK $chan [join $ksend ,] :$reason"
+ }
+ }
+ return 0
+}
+
+proc sl_setbans {chan} {
+ global sl_avbanhost sl_bobanhost sl_ccbanhost sl_kflooders sl_jbanhost sl_nkbanhost sl_pbanhost sl_shortlock sl_unlocked sl_wideban
+ if {![botonchan $chan]} {return 0}
+ set sl_ccbanhost($chan) [sl_dfilter $sl_ccbanhost($chan)]
+ set sl_avbanhost($chan) [sl_dfilter $sl_avbanhost($chan)]
+ set sl_nkbanhost($chan) [sl_dfilter $sl_nkbanhost($chan)]
+ set sl_bobanhost($chan) [sl_dfilter $sl_bobanhost($chan)]
+ set sl_jbanhost($chan) [sl_dfilter $sl_jbanhost($chan)]
+ set sl_pbanhost($chan) [sl_dfilter $sl_pbanhost($chan)]
+ set blist ""
+ if {$sl_jbanhost($chan) != "" && $sl_pbanhost($chan) != ""} {
+ foreach bhost $sl_jbanhost($chan) {
+ if {[lsearch -exact $sl_pbanhost($chan) $bhost] != -1} {
+ lappend blist $bhost
+ }
+ }
+ }
+ set allbans [sl_dfilter [concat $sl_ccbanhost($chan) $sl_avbanhost($chan) $sl_nkbanhost($chan) $sl_bobanhost($chan) $blist]]
+ if {$sl_wideban} {
+ sl_ban $chan [sl_dcheck $allbans] "MULTIPLE IDENT/HOST flooders"
+ }
+ sl_ban $chan $sl_ccbanhost($chan) "CTCP flooder" ; set sl_ccbanhost($chan) ""
+ sl_ban $chan $sl_avbanhost($chan) "AVALANCHE/TSUNAMI flooder" ; set sl_avbanhost($chan) ""
+ sl_ban $chan $sl_nkbanhost($chan) "NICK flooder" ; set sl_nkbanhost($chan) ""
+ sl_ban $chan $sl_bobanhost($chan) "BOGUS username" ; set sl_bobanhost($chan) ""
+ sl_ban $chan $blist "JOIN-PART flooder"
+ set sl_jbanhost($chan) "" ; set sl_pbanhost($chan) ""
+ if {$sl_shortlock && $sl_kflooders <= 2 && [llength $allbans] <= 2 && [expr [unixtime] - $sl_unlocked($chan)] > 120} {
+ sl_killutimer "sl_unlock $chan *"
+ utimer 10 [list sl_unlock $chan mi]
+ }
+ return 0
+}
+
+proc sl_dfilter {list} {
+ set newlist ""
+ foreach item $list {
+ if {[lsearch -exact $newlist $item] == -1} {
+ lappend newlist $item
+ }
+ }
+ return $newlist
+}
+
+proc sl_dcheck {bhosts} {
+ set blist ""
+ foreach bhost $bhosts {
+ set baddr [lindex [split [maskhost $bhost] "@"] 1]
+ set bident [string trimleft [lindex [split $bhost "@"] 0] "~"]
+ if {![info exists baddrs($baddr)]} {
+ set baddrs($baddr) 1
+ } else {
+ incr baddrs($baddr)
+ }
+ if {![info exists bidents($bident)]} {
+ set bidents($bident) 1
+ } else {
+ incr bidents($bident)
+ }
+ }
+ foreach baddr [array names baddrs] {
+ if {$baddrs($baddr) >= 2} {
+ lappend blist *!*@$baddr
+ }
+ }
+ foreach bident [array names bidents] {
+ if {$bidents($bident) >= 2} {
+ lappend blist *!*$bident@*
+ }
+ }
+ return $blist
+}
+
+proc sl_ban {chan blist reason} {
+ global sl_ban sl_banmax sl_globalban
+ if {$blist != ""} {
+ if {$sl_globalban} {
+ foreach bhost $blist {
+ if {![string match *!* $bhost]} {
+ if {[matchban *!$bhost]} {continue}
+ set bhost [sl_masktype $bhost]
+ if {[isban $bhost]} {continue}
+ } else {
+ if {[isban $bhost]} {continue}
+ foreach ban [banlist] {
+ if {[lindex $ban 5] == "sentinel" && [string match $bhost [string tolower [lindex $ban 0]]]} {
+ killban $ban
+ }
+ }
+ }
+ if {[llength [banlist]] >= $sl_banmax} {continue}
+ newban $bhost sentinel $reason $sl_ban
+ putlog "sentinel: banned $bhost ($reason)"
+ sl_ignore $bhost * $reason
+ }
+ } else {
+ foreach bhost $blist {
+ if {![string match *!* $bhost]} {
+ if {[matchban *!$bhost $chan]} {continue}
+ set bhost [sl_masktype $bhost]
+ if {[isban $bhost $chan]} {continue}
+ } else {
+ if {[isban $bhost $chan]} {continue}
+ foreach ban [banlist $chan] {
+ if {[lindex $ban 5] == "sentinel" && [string match $bhost [string tolower [lindex $ban 0]]]} {
+ killchanban $chan $ban
+ }
+ }
+ }
+ if {[llength [banlist $chan]] >= $sl_banmax} {continue}
+ newchanban $chan $bhost sentinel $reason $sl_ban
+ putlog "sentinel: banned $bhost on $chan ($reason)"
+ sl_ignore $bhost * $reason
+ }
+ }
+ }
+ return 0
+}
+
+proc sl_ignore {ihost hand flood} {
+ global sl_igtime
+ if {$hand != "*"} {
+ foreach chan [channels] {
+ if {[matchattr $hand f|f $chan]} {return 0}
+ }
+ }
+ if {![string match *!* $ihost]} {
+ foreach ignore [ignorelist] {
+ if {[string match [string tolower [lindex $ignore 0]] $ihost]} {
+ return 0
+ }
+ }
+ set ihost [sl_masktype $ihost]
+ if {[isignore $ihost]} {return 0}
+ } else {
+ if {[isignore $ihost]} {return 0}
+ foreach ignore [ignorelist] {
+ if {[lindex $ignore 4] == "sentinel" && [string match $ihost [string tolower [lindex $ignore 0]]]} {
+ killignore $ignore
+ }
+ }
+ }
+ newignore $ihost sentinel $flood $sl_igtime
+ putlog "sentinel: added $ihost to ignore list ($flood)"
+ return 1
+}
+
+# queuereset procs allow all queue timers to be killed easily
+proc sl_ccqueuereset {chan} {
+ global sl_ccqueue
+ incr sl_ccqueue($chan) -1
+ return 0
+}
+
+proc sl_bcqueuereset {} {
+ global sl_bcqueue
+ incr sl_bcqueue -1
+ return 0
+}
+
+proc sl_bmqueuereset {} {
+ global sl_bmqueue
+ incr sl_bmqueue -1
+ return 0
+}
+
+proc sl_avqueuereset {chan} {
+ global sl_avqueue
+ incr sl_avqueue($chan) -1
+ return 0
+}
+
+proc sl_txqueuereset {} {
+ global sl_txqueue sl_txflood
+ foreach chan [string tolower [channels]] {
+ if {[info exists sl_txqueue($chan)]} {
+ set sl_txqueue($chan) 0
+ }
+ }
+ utimer [lindex $sl_txflood 1] sl_txqueuereset
+ return 0
+}
+
+proc sl_nkqueuereset {chan} {
+ global sl_nkqueue
+ incr sl_nkqueue($chan) -1
+ return 0
+}
+
+proc sl_boqueuereset {chan} {
+ global sl_boqueue
+ incr sl_boqueue($chan) -1
+ return 0
+}
+
+proc sl_jqueuereset {chan} {
+ global sl_jqueue
+ incr sl_jqueue($chan) -1
+ return 0
+}
+
+proc sl_pqueuereset {chan} {
+ global sl_pqueue
+ incr sl_pqueue($chan) -1
+ return 0
+}
+
+proc sl_ccbanqueue {chan} {
+ global sl_ccbanhost sl_ccbannick
+ set sl_ccbannick($chan) [lrange sl_ccbannick($chan) 1 end] ; set sl_ccbanhost($chan) [lrange sl_ccbanhost($chan) 1 end]
+ return 0
+}
+
+proc sl_avbanqueue {chan} {
+ global sl_avbanhost sl_avbannick
+ set sl_avbannick($chan) [lrange sl_avbannick($chan) 1 end] ; set sl_avbanhost($chan) [lrange sl_avbanhost($chan) 1 end]
+ return 0
+}
+
+proc sl_nkbanqueue {chan} {
+ global sl_nkbanhost
+ set sl_nkbanhost($chan) [lrange sl_nkbanhost($chan) 1 end]
+ return 0
+}
+
+proc sl_bobanqueue {chan} {
+ global sl_bobanhost sl_bobannick
+ set sl_bobannick($chan) [lrange sl_bobannick($chan) 1 end] ; set sl_bobanhost($chan) [lrange sl_bobanhost($chan) 1 end]
+ return 0
+}
+
+proc sl_jbanqueue {chan} {
+ global sl_jbanhost sl_jbannick
+ set sl_jbannick($chan) [lrange sl_jbannick($chan) 1 end] ; set sl_jbanhost($chan) [lrange sl_jbanhost($chan) 1 end]
+ return 0
+}
+
+proc sl_pbanqueue {chan} {
+ global sl_pbanhost sl_pbannick
+ set sl_pbannick($chan) [lrange sl_pbannick($chan) 1 end] ; set sl_pbanhost($chan) [lrange sl_pbanhost($chan) 1 end]
+ return 0
+}
+
+proc sl_flud {nick uhost hand type chan} {
+ global sl_flooded
+ set chan [string tolower $chan]
+ if {[validchan $chan] && $sl_flooded($chan)} {return 1}
+ return 0
+}
+
+proc sl_lc {nick uhost hand chan arg} {
+ global sl_lockcmds
+ set chan [string tolower $chan]
+ if {![botisop $chan]} {return 0}
+ if {$sl_lockcmds == 2 && ![isop $nick $chan]} {return 0}
+ sl_quicklock $chan
+ putlog "sentinel: channel lock requested by $hand on $chan"
+ return 0
+}
+
+proc sl_uc {nick uhost hand chan arg} {
+ global sl_lockcmds
+ set chan [string tolower $chan]
+ if {![botisop $chan]} {return 0}
+ if {$sl_lockcmds == 2 && ![isop $nick $chan]} {return 0}
+ putserv "MODE $chan -mi"
+ putlog "sentinel: channel unlock requested by $hand on $chan"
+ return 0
+}
+
+proc sl_dcclc {hand idx arg} {
+ global sl_lockflags
+ putcmdlog "#$hand# lock $arg"
+ set chan [lindex [split $arg] 0]
+ if {$chan == "-all"} {
+ if {![matchattr $hand $sl_lockflags]} {
+ putidx $idx "You're not global +$sl_lockflags." ; return 0
+ }
+ set locklist ""
+ foreach chan [channels] {
+ if {[botisop $chan]} {
+ sl_quicklock $chan
+ lappend locklist $chan
+ }
+ }
+ putidx $idx "Locked [join $locklist ", "]"
+ } else {
+ if {$chan == ""} {
+ set chan [lindex [console $idx] 0]
+ }
+ if {![validchan $chan]} {
+ putidx $idx "No such channel." ; return 0
+ } elseif {![matchattr $hand $sl_lockflags|$sl_lockflags $chan]} {
+ putidx $idx "You're not +$sl_lockflags on $chan." ; return 0
+ } elseif {![botonchan $chan]} {
+ putidx $idx "I'm not on $chan" ; return 0
+ } elseif {![botisop $chan]} {
+ putidx $idx "I'm not opped on $chan" ; return 0
+ }
+ sl_quicklock $chan
+ putidx $idx "Locked $chan"
+ }
+ return 0
+}
+
+proc sl_dccuc {hand idx arg} {
+ global sl_lockflags
+ putcmdlog "#$hand# unlock $arg"
+ set chan [lindex [split $arg] 0]
+ if {$chan == "-all"} {
+ if {![matchattr $hand $sl_lockflags]} {
+ putidx $idx "You're not global +$sl_lockflags." ; return 0
+ }
+ set locklist ""
+ foreach chan [channels] {
+ if {[botisop $chan]} {
+ putserv "MODE $chan -mi"
+ lappend locklist $chan
+ }
+ }
+ putidx $idx "Unlocked [join $locklist ", "]"
+ } else {
+ if {$chan == ""} {
+ set chan [lindex [console $idx] 0]
+ }
+ if {![validchan $chan]} {
+ putidx $idx "No such channel." ; return 0
+ } elseif {![matchattr $hand $sl_lockflags|$sl_lockflags $chan]} {
+ putidx $idx "You're not +$sl_lockflags on $chan." ; return 0
+ } elseif {![botonchan $chan]} {
+ putidx $idx "I'm not on $chan" ; return 0
+ } elseif {![botisop $chan]} {
+ putidx $idx "I'm not opped on $chan" ; return 0
+ }
+ putserv "MODE $chan -mi"
+ putidx $idx "Unlocked $chan"
+ }
+ return 0
+}
+
+proc sl_quicklock {chan} {
+ global numversion
+ if {$numversion < 1050000} {
+ putquick "MODE $chan +mi"
+ } else {
+ putquick "MODE $chan +mi" -next
+ }
+}
+
+proc sl_dcc {hand idx arg} {
+ global sl_avflood sl_ban sl_banmax sl_bcflood sl_boban sl_boflood sl_bmflood sl_bxsimul sl_bfmaxbans sl_ccflood sl_detectquits sl_globalban sl_igtime sl_jflood sl_kicks sl_lockcmds sl_lockflags sl_ilocktime sl_mlocktime sl_nkflood sl_note sl_shortlock sl_tsunami sl_txflood
+ putcmdlog "#$hand# sentinel $arg"
+ putidx $idx "This bot is protected by sentinel.tcl by slennox"
+ putidx $idx "Current settings"
+ if {[lsearch -exact $sl_bcflood 0] != -1} {
+ putidx $idx "- Bot CTCP flood: Off"
+ } else {
+ putidx $idx "- Bot CTCP flood: [lindex $sl_bcflood 0] in [lindex $sl_bcflood 1] secs"
+ }
+ if {[lsearch -exact $sl_bmflood 0] != -1} {
+ putidx $idx "- Bot MSG flood: Off"
+ } else {
+ putidx $idx "- Bot MSG flood: [lindex $sl_bmflood 0] in [lindex $sl_bmflood 1] secs"
+ }
+ if {[lsearch -exact $sl_ccflood 0] != -1} {
+ putidx $idx "- Channel CTCP flood: Off"
+ } else {
+ putidx $idx "- Channel CTCP flood: [lindex $sl_ccflood 0] in [lindex $sl_ccflood 1] secs"
+ }
+ if {[lsearch -exact $sl_avflood 0] != -1} {
+ putidx $idx "- Channel AVALANCHE flood: Off"
+ } else {
+ putidx $idx "- Channel AVALANCHE flood: [lindex $sl_avflood 0] in [lindex $sl_avflood 1] secs"
+ }
+ if {[lsearch -exact $sl_avflood 0] != -1 || !$sl_tsunami} {
+ putidx $idx "- Channel TSUNAMI flood: Off"
+ } else {
+ putidx $idx "- Channel TSUNAMI flood: [lindex $sl_avflood 0] in [lindex $sl_avflood 1] secs ($sl_tsunami ctrl codes / line)"
+ }
+ if {[lsearch -exact $sl_txflood 0] != -1} {
+ putidx $idx "- Channel TEXT flood: Off"
+ } else {
+ putidx $idx "- Channel TEXT flood: [lindex $sl_txflood 0] in [lindex $sl_txflood 1] secs"
+ }
+ if {[lsearch -exact $sl_boflood 0] != -1} {
+ putidx $idx "- Channel BOGUS flood: Off"
+ } else {
+ putidx $idx "- Channel BOGUS flood: [lindex $sl_boflood 0] in [lindex $sl_boflood 1] secs"
+ }
+ if {$sl_detectquits} {
+ set detectquits "quit detection ON"
+ } else {
+ set detectquits "quit detection OFF"
+ }
+ if {[lsearch -exact $sl_jflood 0] != -1} {
+ putidx $idx "- Channel JOIN-PART flood: Off"
+ } else {
+ putidx $idx "- Channel JOIN-PART flood: [lindex $sl_jflood 0] in [lindex $sl_jflood 1] secs ($detectquits)"
+ }
+ if {[lsearch -exact $sl_nkflood 0] != -1} {
+ putidx $idx "- Channel NICK flood: Off"
+ } else {
+ putidx $idx "- Channel NICK flood: [lindex $sl_nkflood 0] in [lindex $sl_nkflood 1] secs"
+ }
+ if {!$sl_ilocktime} {
+ putidx $idx "- Channel +i locktime: Indefinite"
+ } else {
+ putidx $idx "- Channel +i locktime: $sl_ilocktime secs"
+ }
+ if {!$sl_mlocktime} {
+ putidx $idx "- Channel +m locktime: Indefinite"
+ } else {
+ putidx $idx "- Channel +m locktime: $sl_mlocktime secs"
+ }
+ if {$sl_shortlock && $sl_ban} {
+ putidx $idx "- Small flood short lock: Active"
+ } else {
+ putidx $idx "- Small flood short lock: Inactive"
+ }
+ if {$sl_ban && $sl_ban < 120} {
+ putidx $idx "- Channel flood bans: $sl_ban mins"
+ } elseif {$sl_ban >= 120} {
+ putidx $idx "- Channel flood bans: [expr $sl_ban / 60] hrs"
+ } else {
+ putidx $idx "- Channel flood bans: Disabled"
+ }
+ if {!$sl_boban || [lsearch -exact $sl_boflood 0] != -1} {
+ putidx $idx "- Bogus username bans: Disabled"
+ } elseif {$sl_boban > 0 && $sl_boban < 120} {
+ putidx $idx "- Bogus username bans: $sl_boban mins"
+ } elseif {$sl_boban >= 120} {
+ putidx $idx "- Bogus username bans: [expr $sl_boban / 60] hrs"
+ }
+ if {$sl_ban || [lsearch -exact $sl_boflood 0] == -1} {
+ if {$sl_globalban} {
+ putidx $idx "- Ban type: Global [sl_masktype nick@host.domain]"
+ } else {
+ putidx $idx "- Ban type: Channel-specific [sl_masktype nick@host.domain]"
+ }
+ }
+ if {$sl_ban || [lsearch -exact $sl_boflood 0] == -1} {
+ putidx $idx "- Maximum bans: $sl_banmax"
+ }
+ if {$sl_igtime > 0 && $sl_igtime < 120} {
+ putidx $idx "- Flooder ignores: $sl_igtime mins"
+ } elseif {$sl_igtime >= 120} {
+ putidx $idx "- Flooder ignores: [expr $sl_igtime / 60] hrs"
+ } else {
+ putidx $idx "- Flooder ignores: Permanent"
+ }
+ if {$sl_ban} {
+ putidx $idx "- Kicks per line: $sl_kicks"
+ }
+ if {!$sl_bfmaxbans} {
+ putidx $idx "- Maximum channel bans: Disabled"
+ } else {
+ putidx $idx "- Maximum channel bans: $sl_bfmaxbans"
+ }
+ if {$sl_note != ""} {
+ putidx $idx "- Flood notification: Notifying [join $sl_note ", "]"
+ } else {
+ putidx $idx "- Flood notification: Off"
+ }
+ if {!$sl_lockcmds} {
+ putidx $idx "- Public lc/uc commands: Disabled"
+ } elseif {$sl_lockcmds == 1} {
+ putidx $idx "- Public lc/uc commands: Enabled (+$sl_lockflags users, ops not required)"
+ } elseif {$sl_lockcmds == 2} {
+ putidx $idx "- Public lc/uc commands: Enabled (+$sl_lockflags users, ops required)"
+ }
+ if {$sl_bxsimul} {
+ putidx $idx "- BitchX simulation: On"
+ } elseif {!$sl_bxsimul} {
+ putidx $idx "- BitchX simulation: Off"
+ }
+ return 0
+}
+
+if {$sl_bxsimul} {
+ bind raw - 001 sl_bxserverjoin
+ if {![info exists sl_bxonestack]} {
+ set sl_bxonestack 0
+ }
+ if {![info exists sl_bxversion]} {
+ set sl_bxversion [lindex {75p1+ 75p3+} [rand 2]]
+ }
+ set sl_bxsystem "*IX" ; set sl_bxwhoami $username ; set sl_bxmachine ""
+ catch {set sl_bxsystem [exec uname -s -r]}
+ catch {set sl_bxwhoami [exec id -un]}
+ catch {set sl_bxmachine [exec uname -n]}
+ set sl_bxjointime [unixtime]
+ proc sl_bxserverjoin {from keyword arg} {
+ global sl_bxjointime sl_bxisaway
+ set sl_bxjointime [unixtime] ; set sl_bxisaway 0
+ return 0
+ }
+ proc sl_bxaway {} {
+ global sl_bxjointime sl_bxisaway
+ if {!$sl_bxisaway} {
+ puthelp "AWAY :is away: (Auto-Away after 10 mins) \[\002BX\002-MsgLog [lindex {On Off} [rand 2]]\]"
+ set sl_bxisaway 1
+ } else {
+ puthelp "AWAY"
+ set sl_bxisaway 0 ; set sl_bxjointime [unixtime]
+ }
+ if {![string match *sl_bxaway* [timers]]} {
+ timer [expr [rand 300] + 10] sl_bxaway
+ }
+ return 0
+ }
+ if {![info exists sl_bxisaway]} {
+ set sl_bxisaway 0
+ }
+ if {![string match *sl_bxaway* [timers]]} {
+ timer [expr [rand 300] + 10] sl_bxaway
+ }
+}
+
+proc sl_setarray {chan} {
+ global sl_avbanhost sl_avbannick sl_avqueue sl_bfull sl_bobanhost sl_bobannick sl_boqueue sl_ccbanhost sl_ccbannick sl_ccqueue sl_flooded sl_jbanhost sl_jbannick sl_jqueue sl_locked sl_nkbanhost sl_nkflooding sl_nkqueue sl_pbanhost sl_pbannick sl_pqueue sl_txqueue sl_unlocked
+ set chan [string tolower $chan]
+ sl_killutimer "incr sl_*queue($chan) -1"
+ sl_killutimer "sl_*banqueue $chan"
+ sl_killutimer "sl_*queuereset $chan"
+ set sl_flooded($chan) 0 ; set sl_locked($chan) 0 ; set sl_unlocked($chan) [unixtime]
+ set sl_nkflooding($chan) [unixtime]
+ set sl_ccqueue($chan) 0 ; set sl_ccbanhost($chan) "" ; set sl_ccbannick($chan) ""
+ set sl_avqueue($chan) 0 ; set sl_avbanhost($chan) "" ; set sl_avbannick($chan) ""
+ set sl_txqueue($chan) 0
+ set sl_nkqueue($chan) 0 ; set sl_nkbanhost($chan) ""
+ set sl_boqueue($chan) 0 ; set sl_bobanhost($chan) "" ; set sl_bobannick($chan) ""
+ set sl_jqueue($chan) 0 ; set sl_jbanhost($chan) "" ; set sl_jbannick($chan) ""
+ set sl_pqueue($chan) 0 ; set sl_pbanhost($chan) "" ; set sl_pbannick($chan) ""
+ set sl_bfull($chan) 0
+ return 0
+}
+
+proc sl_unsetarray {chan} {
+ global sl_avbanhost sl_avbannick sl_avqueue sl_bfull sl_bobanhost sl_bobannick sl_boqueue sl_ccbanhost sl_ccbannick sl_ccqueue sl_flooded sl_jbanhost sl_jbannick sl_jqueue sl_locked sl_nkbanhost sl_nkflooding sl_nkqueue sl_pbanhost sl_pbannick sl_pqueue sl_txqueue sl_unlocked
+ set chan [string tolower $chan]
+ if {![validchan $chan] && [info exists sl_flooded($chan)]} {
+ unset sl_flooded($chan) sl_locked($chan) sl_unlocked($chan) sl_nkflooding($chan) sl_ccqueue($chan) sl_ccbanhost($chan) sl_ccbannick($chan) sl_avqueue($chan) sl_avbanhost($chan) sl_avbannick($chan) sl_txqueue($chan) sl_nkqueue($chan) sl_nkbanhost($chan) sl_boqueue($chan) sl_bobanhost($chan) sl_bobannick($chan) sl_jqueue($chan) sl_jbanhost($chan) sl_jbannick($chan) sl_pqueue($chan) sl_pbanhost($chan) sl_pbannick($chan) sl_bfull($chan)
+ }
+ return 0
+}
+
+proc sl_settimer {} {
+ foreach chan [channels] {
+ sl_setarray $chan
+ }
+ return 0
+}
+
+proc sl_killutimer {cmd} {
+ set n 0
+ regsub -all -- {\[} $cmd {\[} cmd ; regsub -all -- {\]} $cmd {\]} cmd
+ foreach tmr [utimers] {
+ if {[string match $cmd [join [lindex $tmr 1]]]} {
+ killutimer [lindex $tmr 2]
+ incr n
+ }
+ }
+ return $n
+}
+
+proc sl_masktype {uhost} {
+ global sl_masktype
+ switch -exact -- $sl_masktype {
+ 0 {return *!*[string range $uhost [string first @ $uhost] end]}
+ 1 {return *!*$uhost}
+ 2 {return *!*[lindex [split [maskhost $uhost] "!"] 1]}
+ }
+ return
+}
+
+if {![info exists sl_unlocked] && ![string match *sl_settimer* [utimers]]} {
+ utimer 3 sl_settimer
+}
+
+if {![info exists sl_bflooded]} {
+ set sl_bflooded 0
+}
+if {![info exists sl_bcqueue]} {
+ set sl_bcqueue 0
+}
+if {![info exists sl_bmqueue]} {
+ set sl_bmqueue 0
+}
+if {![info exists sl_nickkick]} {
+ set sl_nickkick 0
+}
+
+set sl_bcflood [split $sl_bcflood :] ; set sl_bmflood [split $sl_bmflood :]
+set sl_ccflood [split $sl_ccflood :] ; set sl_avflood [split $sl_avflood :]
+set sl_txflood [split $sl_txflood :] ; set sl_boflood [split $sl_boflood :]
+set sl_jflood [split $sl_jflood :] ; set sl_nkflood [split $sl_nkflood :]
+set sl_note [split $sl_note]
+
+if {$sl_ilocktime > 0 && $sl_ilocktime < 30} {
+ set sl_ilocktime 30
+}
+if {$sl_mlocktime > 0 && $sl_mlocktime < 30} {
+ set sl_mlocktime 30
+}
+
+set trigger-on-ignore 0
+if {!${kick-method}} {
+ set sl_kicks 8
+} else {
+ set sl_kicks ${kick-method}
+}
+
+if {$numversion <= 1040400} {
+ if {$numversion >= 1032100} {
+ set kick-bogus 0
+ }
+ if {$numversion >= 1032400} {
+ set ban-bogus 0
+ }
+}
+if {$numversion >= 1032400} {
+ set kick-fun 0 ; set ban-fun 0
+}
+if {$numversion >= 1032500} {
+ set ctcp-mode 0
+}
+
+if {![string match *sl_txqueuereset* [utimers]] && [lsearch -exact $sl_txflood 0] == -1} {
+ utimer [lindex $sl_txflood 1] sl_txqueuereset
+}
+
+bind pub $sl_lockflags|$sl_lockflags lc sl_lc
+bind pub $sl_lockflags|$sl_lockflags uc sl_uc
+bind dcc $sl_lockflags|$sl_lockflags lock sl_dcclc
+bind dcc $sl_lockflags|$sl_lockflags unlock sl_dccuc
+if {!$sl_lockcmds} {
+ unbind pub $sl_lockflags|$sl_lockflags lc sl_lc
+ unbind pub $sl_lockflags|$sl_lockflags uc sl_uc
+ rename sl_lc ""
+ rename sl_uc ""
+}
+bind dcc m|m sentinel sl_dcc
+bind raw - NOTICE sl_avflood
+bind raw - PRIVMSG sl_avflood
+if {[lsearch -exact $sl_avflood 0] != -1 && [lsearch -exact $sl_txflood 0] != -1} {
+ unbind raw - NOTICE sl_avflood
+ unbind raw - PRIVMSG sl_avflood
+ rename sl_avflood ""
+}
+bind ctcp - CLIENTINFO sl_ctcp
+bind ctcp - USERINFO sl_ctcp
+bind ctcp - VERSION sl_ctcp
+bind ctcp - FINGER sl_ctcp
+bind ctcp - ERRMSG sl_ctcp
+bind ctcp - ECHO sl_ctcp
+bind ctcp - INVITE sl_ctcp
+bind ctcp - WHOAMI sl_ctcp
+bind ctcp - OP sl_ctcp
+bind ctcp - OPS sl_ctcp
+bind ctcp - UNBAN sl_ctcp
+bind ctcp - PING sl_ctcp
+bind ctcp - TIME sl_ctcp
+bind msgm - * sl_bmflood
+if {[lsearch -exact $sl_bmflood 0] != -1} {
+ unbind msgm - * sl_bmflood
+ rename sl_bmflood ""
+}
+bind nick - * sl_nkflood
+if {[lsearch -exact $sl_nkflood 0] != -1} {
+ unbind nick - * sl_nkflood
+ rename sl_nkflood ""
+}
+bind join - * sl_jflood
+bind part - * sl_pflood
+bind sign - * sl_pflood
+if {![info exists sl_detectquits]} {
+ set sl_detectquits 0
+}
+if {!$sl_detectquits} {
+ unbind sign - * sl_pflood
+}
+bind kick - * sl_pfloodk
+bind flud - * sl_flud
+bind mode - * sl_mode
+
+putlog "Loaded sentinel.tcl v2.70 by slennox"
+
+return
diff --git a/services.tcl b/services.tcl
new file mode 100644
index 0000000..8adcf02
--- /dev/null
+++ b/services.tcl
@@ -0,0 +1,78 @@
+###########################################################################################
+###### NickServ & ChanServ Tools #####
+###########################################################################################
+#
+# Autor : Holger Brähne (Holli)
+# E-Mail : hbraehne@web.de
+# Version: 1.0
+#
+# Beschreibung: Das Script Identifiziert den Bot automatisch bei NickServ und lässt den
+# Bot automatisch Op erhalten falls das gewünscht ist und er die benötigten
+# Channelrechte besitzt. Das Script wurde getestet und hat funktioniert.
+# Ich kann allerdings nicht garantieren das es das auf allen IRC Servern
+# tut!
+#
+###########################################################################################
+###### KONFIGURATION ######
+###########################################################################################
+
+# Der Name den NickServ auf dem IRC Server verwendet auf dem sich der Bot befindet
+set nserv(name) "NickServ"
+
+# Der Befehl mit dem man sich bei NickServ identifiziert (normalerweise: IDENTIFY)
+set nserv(idnt) "IDENTIFY"
+
+# Der Name den der Bot verwendet. Wichtig falls jemand den Namen geklaut hat und der Bot
+# in den GHOST Modus gehen soll um ihn zurück zu erhalten.
+set nserv(nick) "Marvin"
+
+# Das Passwort mit dem der Bot bei NickServ registriert ist.
+set nserv(pass) "ongbak"
+
+# Die Zeit die der Bot zwischen dem erkennen von NickServ und der Identifizierung warten
+# soll. Bei mir haben 10 Sekunden immer gereicht, aber es soll ja auch langsamere Server
+# geben ;)
+set nserv(time) 10
+
+# Der Name den ChanServ auf dem IRC Server verwendet auf dem sich der Bot befindet
+set cserv(name) "ChanServ"
+
+# Soll der Bot sich automatisch Op im unten angegebenen Channel holen?
+# 0 = nein / 1 = ja
+set cserv(opme) 0
+
+# Der Channel in dem sich der Bot Op holen soll.
+set cserv(chan) ""
+
+# Siehe nserv(time). Die Zeit hier sollte aber mindestens 5 Sekunden länger angegeben sein!
+set cserv(time) 15
+
+
+###########################################################################################
+###### !!! AB HIER NICHTS MEHR ÄNDERN, AUSSER DU WEISST GENAU WAS DU DA MACHST !!! ######
+###########################################################################################
+
+bind notc - "*msg*IDENTIFY*pass*" nick_ident
+bind dcc o nservid nick_ident
+
+proc nick_ident {nick uhost hand args} {
+
+ global botnick nserv cserv
+
+ if {$botnick == $nserv(nick)} {
+
+ utimer $nserv(time) "putserv \"PRIVMSG $nserv(name) :$nserv(idnt) $nserv(pass)\""
+
+ if {$cserv(opme) == 1} {
+
+ utimer $cserv(time) "putserv \"PRIVMSG $cserv(name) :owner\""
+
+ }
+
+ } else {
+
+ utimer $nserv(time) "putserv \"PRIVMSG $nserv(name) :GHOST $nserv(nick) $nserv(pass)\""
+
+ }
+
+}
diff --git a/test.pl b/test.pl
new file mode 100644
index 0000000..049b0c7
--- /dev/null
+++ b/test.pl
@@ -0,0 +1,7 @@
+#!/usr/bin/perl
+
+use Net::Domain::TLD qw(tlds tld_exists);
+
+my @ccTLDs = tlds('cc');
+print "TLD de OK\n" if tld_exists('de', 'cc');
+print "TLD ac OK\n" if tld_exists('ac', 'cc');
diff --git a/time.tcl b/time.tcl
new file mode 100644
index 0000000..2fa82a5
--- /dev/null
+++ b/time.tcl
@@ -0,0 +1,26 @@
+# slap by lookshe
+#package require time
+
+bind pub - !zeit proc_time
+bind pub - !time proc_time
+
+proc proc_time {nick host hand chan opfer} {
+ #putserv "PRIVMSG $chan :[clock format [NetTime ntp.nasa.gov]]"
+ putserv "PRIVMSG $chan :[exec date]"
+}
+
+proc NetTime {server} {
+ set tok [time::getsntp $server] ;# or gettime to use the TIME protocol
+ time::wait $tok
+ if {[time::status $tok] eq "ok"} {
+ set result [time::unixtime $tok]
+ set code ok
+ } else {
+ set result [time::error $tok]
+ set code error
+ }
+ time::cleanup $tok
+ return -code $code $result
+}
+
+putlog "time by lookshe loaded"
diff --git a/tinyurl.tcl b/tinyurl.tcl
new file mode 100644
index 0000000..970d8f6
--- /dev/null
+++ b/tinyurl.tcl
@@ -0,0 +1,99 @@
+# -----------------------------------------------------------------------------
+# tiny_url.tcl v0.1 [2004-10-19]
+#
+# This script will listen on channels and convert long URLs into shorter
+# URLs using the TinyURL.com website.
+#
+# Written by: FAIN on QuakeNet <fain@flamingfist.org>
+# -----------------------------------------------------------------------------
+
+# ----- Settings --------------------------------------------------------------
+
+# Set this to the minimum length of URLs to convert
+set url_length 80
+
+# -----------------------------------------------------------------------------
+
+package require http 2.3
+
+bind pubm - "*" scan_text
+
+# -----------------------------------------------------------------------------
+# Name : scan_text
+# Purpose : Scans for URLs and converts to TinyURLs
+# -----------------------------------------------------------------------------
+
+proc scan_text {nick uhost hand chan arg} {
+ global botnick url_length
+
+ if {($arg == "boeser bot") ||
+ ($arg == "dummer bot") ||
+ ($arg == "böser bot")} {
+ putserv "PRIVMSG $chan :Tut mir ja leid $nick! Wirklich!!!"
+ return 0
+ }
+
+ if {($arg == "guter bot") ||
+ ($arg == "braver bot")} {
+ putserv "PRIVMSG $chan :Ich weiss, ich weiss :-)"
+ return 0
+ }
+
+ set arg [split $arg]
+
+foreach act_arg $arg {
+ if {(([string match "http://*" $act_arg] == 1) ||
+ ([string match "https://*" $act_arg] == 1) ||
+ ([string match "ftp://*" $act_arg] == 1) ||
+ ([string match "www.*" $act_arg] == 1))} {
+ # Make sure it wasn't the bot who said it
+ set url $act_arg
+ if {$nick == $botnick} {
+ return 0
+ }
+
+ # Check length of URL
+ set length [string length $url]
+
+ if {$length >= $url_length} {
+
+ #set tinyurl [make_tinyurl $url]
+ set tinyurl [exec perl -e "use WWW::Shorten::TinyURL;print makeashorterlink(\"$url\");"]
+
+ if {$tinyurl != "0"} {
+ set title [exec perl -e "use URI::Title;print URI::Title::title(\"$url\");"]
+ putserv "PRIVMSG $chan :\002Tiny URL\002: $tinyurl \[$title\] (URL by \002$nick\002)"
+ }
+ }
+ }
+}
+ return 0
+}
+
+# -----------------------------------------------------------------------------
+# Name : make_tinyurl
+# Purpose : Does the actual conversion
+# -----------------------------------------------------------------------------
+
+proc make_tinyurl { arg } {
+ set page [::http::geturl http://tinyurl.com/create.php?url=${arg}]
+ set lines [split [::http::data $page] \n]
+ set numLines [llength $lines]
+
+ for {set i 0} {$i < $numLines} {incr i 1} {
+ set line [lindex $lines $i]
+
+ if {[string match "<input type=hidden name=tinyurl value=\"*\">" $line] == 1} {
+ set tinyurl_line [string trim $line]
+ regsub -all -nocase "<input type=hidden name=tinyurl value=\"" $tinyurl_line "" tinyurl_line
+ regsub -all -nocase "\">" $tinyurl_line "" tinyurl_line
+
+ return $tinyurl_line
+ }
+ }
+
+ return "0"
+}
+
+putlog "---> tiny_url.tcl v0.1 by FAIN @ QuakeNet <fain@flamingfist.org> loaded"
+
diff --git a/userinfo.tcl b/userinfo.tcl
new file mode 100644
index 0000000..edc30bb
--- /dev/null
+++ b/userinfo.tcl
@@ -0,0 +1,285 @@
+# userinfo.tcl v1.06 for Eggdrop 1.4.3 and higher
+# Scott G. Taylor -- ButchBub!staylor@mrynet.com
+#
+# $Id: userinfo.tcl,v 1.5 2001/11/15 06:28:35 guppy Exp $
+#
+# v1.00 ButchBub 14 July 1997 -Original release. Based on
+# whois.tcl "URL" commands.
+# v1.01 Beldin 11 November 1997 -1.3 only version
+# v1.02 Kirk 19 June 1998 -extremely small fixes
+# v1.03 guppy 17 March 1999 -small fixes again
+# v1.04 Ernst 15 June 1999 -fix for egg 1.3.x + TCL 8.0
+# v1.05 Dude 14 July 1999 -small cosmetic/typo fixes
+# -$lastbind bug work around fix
+# -added userinfo_loaded var
+# -fixed bug in dcc_chuserinfo proc
+# -unbinds removed user fields
+# -dcc .showfields command added
+# -deletes removed userinfo fields
+# from the whois-fields list.
+# v1.06 guppy 19 March 2000 -removed lastbind workaround since
+# lastbind is fixed in eggdrop1.4.3
+# v1.07 TaKeDa 20 August 2001 -now script works also on bots,
+# which didn't have server module loaded
+# -added new fields PHONE & ICQ
+#
+# TO USE: o Set the desired userinfo field keywords to the
+# `userinfo-fields' line below where indicated.
+# o Load this script on a 1.1.6 or later Eggdrop bot.
+# o Begin having users save the desired information. If you
+# choose to add the default "IRL" field, they just use
+# the IRC command: /MSG <botnick> irl Joe Blow.
+# o See the new information now appear with the whois command.
+#
+# This script enhances the `whois' output utilizing the `whois-fields'
+# option of eggdrop 1.1-grant and later versions. It adds the functionality
+# of whois.tcl used in pre-1.1-grant versions.
+#
+# The fields desired to be maintained in the userfile `xtra' information
+# should be put in `userinfo-fields'. This is different than the Eggdrop
+# configuration variable `whois-fields' in that this script will add the
+# commands to change these fields. It will also add these desired fields
+# to the `whois-fields' itself, so do not define them there as well. The
+# fields added in `userinfo-fields' will be converted to upper case for
+# aesthetics in the `whois' command output.
+#
+# The commands that will be added to the running eggdrop are:
+# (<info> will be the respective userfile field added in `userinfo-fields')
+#
+# TYPE COMMAND USAGE
+# ====== ============== ========================================
+# msg <info> To change your <info> via /MSG.
+# dcc .<info> To change your <info> via DCC.
+# dcc .ch<info> To change someone else's <info> via DCC.
+#
+# Currently supported fields and commands:
+#
+# FIELD USAGE
+# ===== =====================
+# URL WWW page URL
+# IRL In Real Life name
+# BF Boyfriend
+# GF Girlfriend
+# DOB Birthday (Date Of Birth)
+# EMAIL Email address
+# PHONE Phone number
+# ICQ ICQ number
+
+
+################################
+# Set your desired fields here #
+################################
+
+set userinfo-fields "URL BF GF IRL EMAIL DOB PHONE ICQ"
+
+# This script's identification
+
+set userinfover "Userinfo TCL v1.07"
+
+# This script is NOT for pre-1.4.3 versions.
+
+catch { set numversion }
+if {![info exists numversion] || ($numversion < 1040300)} {
+ putlog "*** Can't load $userinfover -- At least Eggdrop v1.4.3 required"
+ return 0
+}
+
+# Make sure we don't bail because whois and/or userinfo-fields aren't set.
+
+if { ![info exists whois-fields]} { set whois-fields "" }
+if { ![info exists userinfo-fields]} { set userinfo-fields "" }
+
+# Add only the userinfo-fields not already in the whois-fields list.
+
+foreach field [string tolower ${userinfo-fields}] {
+ if { [lsearch -exact [string tolower ${whois-fields}] $field] == -1 } { append whois-fields " " [string toupper $field] }
+}
+
+# If olduserinfo-fields doesn't exist, create it.
+
+if { ![info exists olduserinfo-fields] } { set olduserinfo-fields ${userinfo-fields} }
+
+# Delete only the userinfo-fields that have been removed but are still
+# listed in the whois-fields list.
+
+foreach field [string tolower ${olduserinfo-fields}] {
+ if { [lsearch -exact [string tolower ${whois-fields}] $field] >= 0 && [lsearch -exact [string tolower ${userinfo-fields}] $field] == -1 } {
+ set fieldtmp [lsearch -exact [string tolower ${whois-fields}] $field]
+ set whois-fields [lreplace ${whois-fields} $fieldtmp $fieldtmp]
+ }
+}
+
+# If olduserinfo-fields don't equal userinfo-fields, lets run through the
+# old list of user fields and compare them with the current list. this way
+# any fields that have been removed that were originally in the list will
+# have their msg/dcc commands unbinded so you don't have to do a restart.
+
+if {[info commands putserv] == ""} {
+ set isservermod 0
+} else {
+ set isservermod 1
+}
+
+if { [string tolower ${olduserinfo-fields}] != [string tolower ${userinfo-fields}] } {
+ foreach field [string tolower ${olduserinfo-fields}] {
+ if { [lsearch -exact [string tolower ${userinfo-fields}] $field] == -1 } {
+ if $isservermod {unbind msg - $field msg_setuserinfo}
+ unbind dcc - $field dcc_setuserinfo
+ unbind dcc m ch$field dcc_chuserinfo
+ }
+ }
+ set olduserinfo-fields ${userinfo-fields}
+}
+
+# Run through the list of user info fields and bind their commands
+
+if { ${userinfo-fields} != "" } {
+ foreach field [string tolower ${userinfo-fields}] {
+ if $isservermod {bind msg - $field msg_setuserinfo}
+ bind dcc - $field dcc_setuserinfo
+ bind dcc m ch$field dcc_chuserinfo
+ }
+}
+
+# This is the `/msg <info>' procedure
+if $isservermod {
+
+proc msg_setuserinfo {nick uhost hand arg} {
+ global lastbind quiet-reject userinfo-fields
+ set userinfo [string toupper $lastbind]
+ set arg [cleanarg $arg]
+ set ignore 1
+ foreach channel [channels] {
+ if {[onchan $nick $channel]} {
+ set ignore 0
+ }
+ }
+ if {$ignore} {
+ return 0
+ }
+ if {$hand != "*"} {
+ if {$arg != ""} {
+ if {[string tolower $arg] == "none"} {
+ putserv "NOTICE $nick :Removed your $userinfo line."
+ setuser $hand XTRA $userinfo ""
+ } {
+ putserv "NOTICE $nick :Now: $arg"
+ setuser $hand XTRA $userinfo "[string range $arg 0 159]"
+ }
+ } {
+ if {[getuser $hand XTRA $userinfo] == ""} {
+ putserv "NOTICE $nick :You have no $userinfo set."
+ } {
+ putserv "NOTICE $nick :Currently: [getuser $hand XTRA $userinfo]"
+ }
+ }
+ } else {
+ if {${quiet-reject} != 1} {
+ putserv "NOTICE $nick :You must be a registered user to use this feature."
+ }
+ }
+ putcmdlog "($nick!$uhost) !$hand! $userinfo $arg"
+ return 0
+}
+
+#checking for server module
+}
+
+# This is the dcc '.<info>' procedure.
+
+proc dcc_setuserinfo {hand idx arg} {
+ global lastbind userinfo-fields
+ set userinfo [string toupper $lastbind]
+ set arg [cleanarg $arg]
+ if {$arg != ""} {
+ if {[string tolower $arg] == "none"} {
+ putdcc $idx "Removed your $userinfo line."
+ setuser $hand XTRA $userinfo ""
+ } {
+ putdcc $idx "Now: $arg"
+ setuser $hand XTRA $userinfo "[string range $arg 0 159]"
+ }
+ } {
+ if {[getuser $hand XTRA $userinfo] == ""} {
+ putdcc $idx "You have no $userinfo set."
+ } {
+ putdcc $idx "Currently: [getuser $hand XTRA $userinfo]"
+ }
+ }
+ putcmdlog "#$hand# [string tolower $userinfo] $arg"
+ return 0
+}
+
+# This is the DCC `.ch<info>' procedure
+
+proc dcc_chuserinfo {hand idx arg} {
+ global lastbind userinfo-fields
+ set userinfo [string toupper [string range $lastbind 2 end]]
+ set arg [cleanarg $arg]
+ if { $arg == "" } {
+ putdcc $idx "syntax: .ch[string tolower $userinfo] <who> \[<[string tolower $userinfo]>|NONE\]"
+ return 0
+ }
+ set who [lindex [split $arg] 0]
+ if {![validuser $who]} {
+ putdcc $idx "$who is not a valid user."
+ return 0
+ }
+ if {[llength [split $arg]] == 1} {
+ set info ""
+ } {
+ set info [lrange [split $arg] 1 end]
+ }
+ if {$info != ""} {
+ if {[string tolower $info] == "none"} {
+ putdcc $idx "Removed $who's $userinfo line."
+ setuser $who XTRA $userinfo ""
+ putcmdlog "$userinfo for $who removed by $hand"
+ } {
+ putdcc $idx "Now: $info"
+ setuser $who XTRA $userinfo "$info"
+ putcmdlog "$userinfo for $who set to \"$info\" by $hand"
+ }
+ } {
+ if {[getuser $who XTRA $userinfo] == ""} {
+ putdcc $idx "$who has no $userinfo set."
+ } {
+ putdcc $idx "Currently: [getuser $who XTRA $userinfo]"
+ }
+ }
+ return 0
+}
+
+bind dcc m showfields showfields
+
+proc showfields {hand idx arg} {
+ global userinfo-fields
+ if { ${userinfo-fields} == "" } {
+ putdcc $idx "Their is no user info fields set."
+ return 0
+ }
+ putdcc $idx "Currently: [string toupper ${userinfo-fields}]"
+ putcmdlog "#$hand# showfields"
+ return 0
+}
+
+proc cleanarg {arg} {
+ set response ""
+ for {set i 0} {$i < [string length $arg]} {incr i} {
+ set char [string index $arg $i]
+ if {($char != "\12") && ($char != "\15")} {
+ append response $char
+ }
+ }
+ return $response
+}
+
+# Set userinfo_loaded variable to indicate that the script was successfully
+# loaded. this can be used in scripts that make use of the userinfo tcl.
+
+set userinfo_loaded 1
+
+# Announce that we've loaded the script.
+
+putlog "$userinfover loaded (${userinfo-fields})."
+putlog "use '.help userinfo' for commands."
diff --git a/weed b/weed
new file mode 100755
index 0000000..2740712
--- /dev/null
+++ b/weed
@@ -0,0 +1,593 @@
+#! /bin/sh
+# This trick is borrowed from Tothwolf's Wolfpack \
+# Check for working 'grep -E' before using 'egrep' \
+if echo a | (grep -E '(a|b)') >/dev/null 2>&1; \
+then \
+ egrep="grep -E"; \
+else \
+ egrep=egrep; \
+fi; \
+# Search for tclsh[0-9].[0-9] in each valid dir in PATH \
+for dir in $(echo $PATH | sed 's/:/ /g'); \
+do \
+ if test -d $dir; \
+ then \
+ files=$(/bin/ls $dir | $egrep '^tclsh[0-9]\.[0-9]$'); \
+ if test "$files" != ""; \
+ then \
+ versions="${versions:+$versions }$(echo $files | sed 's/tclsh//g')"; \
+ fi; \
+ fi; \
+done; \
+for ver in $versions; \
+do \
+ tmpver=$(echo $ver | sed 's/\.//g'); \
+ if test "$lasttmpver" != ""; \
+ then \
+ if test "$tmpver" -gt "$lasttmpver"; \
+ then \
+ lastver=$ver; \
+ lasttmpver=$tmpver; \
+ fi; \
+ else \
+ lastver=$ver; \
+ lasttmpver=$tmpver; \
+ fi; \
+done; \
+exec tclsh$lastver "$0" ${1+"$@"}
+#
+# $Id: weed,v 1.9 2008/06/18 10:12:22 tothwolf Exp $
+#
+# weed out certain undesirables from an eggdrop userlist
+# try just typing 'tclsh weed' to find out the options
+# Robey Pointer, November 1994
+#
+# <cmwagner@gate.net>:
+# I did a few bug fixes to the original weed script, things changed...
+#
+# when specifying other weed options they would unset the User() field and
+# a maxlast weed would try and weed again and cause the script to stop due
+# to User() being already unset (array nonexistant)
+#
+# when loadUserFile encountered an xtra field it would try and use the $info
+# variable, which was supposed to be $xtra (something overlooked when the
+# line was cut and pasted -- I hate it when that happens)
+#
+# changed the formatting of the saved weed file to match more closely to
+# eggdrop 0.9tp (so this may cause incompatibilities), but when a hostmask
+# field exactly matched 40 characters it would save it with no spaces after
+# it and eggdrop would reject the user record. I know I could have easily
+# changed one character, but I couldn't help myself. <grin>
+# 5 march 1996
+#
+# <robey, 23jul1996>:
+# upgrade for v2 userfiles
+# <bruce s, 04sep1996>:
+# fixed xtra field from getting truncated
+# <robey, 20sep1996>:
+# stopped it from mangling channel ban lists
+# <Ec|ipse & dtM, 10jun1997>:
+# upgrade for v3 userfiles
+# <Ec|ipse 18jun1997>:
+# added an option to remove users from unwanted channels
+# <Ec|ipse 28oct1997>:
+# upgrade for v4 userfiles, with v3 converter
+# <Ernst 8mar1998>:
+# fixed bug "list element in braces followed by X instead of space"
+# (the use of "lrange" where you aren't sure if it's a list is bad)
+# fixed --CONSOLE item not being included, creating "user" --CONSOLE
+# <Ernst 1apr1998>:
+# two more improper occurrences of "lrange" removed
+# <rtc 20sep1999>:
+# removed ancient way of determining the current time.
+# <Tothwolf 21oct1999>:
+# [clock] isn't in all versions of Tcl...
+# <guppy 12Apr2001>:
+# borrowed code from Tothwolf's Wolfpack to find tclsh better
+#
+
+set exempt {*ban *ignore}
+set exemptops 0 ; set exemptmasters 0 ; set exemptfriends 0
+set exemptparty 0 ; set exemptfile 0 ; set exemptchanm 0
+set exemptbotm 0 ; set exemptchann 0 ; set exemptchanf 0
+set exemptchano 0
+set maxlast 0 ; set maxban 0 ; set maxignore 0
+set weedops 0 ; set weedmasters 0 ; set weednopw 0
+set stripops 0 ; set stripmasters 0 ; set weedlurkers 0
+set chanrem {}
+set convert 0
+
+if {![string compare "" [info commands clock]]} then {
+ set fd [open "/tmp/egg.timer." w]
+ close $fd
+ set CURRENT [file atime "/tmp/egg.timer."]
+ exec rm -f /tmp/egg.timer.
+} else {
+ set CURRENT [clock seconds]
+}
+
+if {$argc < 1} {
+ puts stdout "\nUsage: weed <userfile> \[options\]"
+ puts stdout " (weeds out users from an eggdrop userlist)"
+ puts stdout "Output goes to <userfile>.weed"
+ puts stdout "Possible options:"
+ puts stdout " -<nick> exempt this user from weeding"
+ puts stdout " ^o ^m ^f exempt ops or masters or friends"
+ puts stdout " ^co ^cm ^cf exempt chanops or chanmasters or chanfriends"
+ puts stdout " ^cn exempt chanowner"
+ puts stdout " ^p ^x exempt party-line or file-area users"
+ puts stdout " ^b exempt botnet master"
+ puts stdout " +<days> weed: haven't been seen in N days"
+ puts stdout " :n weed: haven't EVER been seen"
+ puts stdout " :o :m weed: ops or masters with no password set"
+ puts stdout " :a weed: anyone with no password set"
+ puts stdout " o m unop/unmaster: ops or masters with no pass."
+ puts stdout " b<days> weed: bans not used in N days"
+ puts stdout " i<days> weed: ignores created over N days ago"
+ puts stdout " =<chan> weed: channels no longer supported"
+ puts stdout " c convert v3 eggdrop userfile"
+ puts stdout ""
+ exit
+}
+puts stdout "\nWEED 18jun97, robey\n"
+
+set filename [lindex $argv 0]
+for {set i 1} {$i < $argc} {incr i} {
+ set carg [lindex $argv $i]
+ if {$carg == ":n"} {
+ set weedlurkers 1
+ } elseif {$carg == ":o"} {
+ set weedops 1 ; set stripops 0 ; set weednopw 0
+ } elseif {$carg == ":m"} {
+ set weedmasters 1 ; set stripmasters 0 ; set weednopw 0
+ } elseif {$carg == ":a"} {
+ set weednopw 1 ; set weedops 0 ; set weedmasters 0
+ set stripops 0 ; set stripmasters 0
+ } elseif {$carg == "o"} {
+ set stripops 1 ; set weedops 0 ; set weednopw 0
+ } elseif {$carg == "m"} {
+ set stripmasters 1 ; set weedmasters 0 ; set weednopw 0
+ } elseif {$carg == "^m"} {
+ set exemptmasters 1
+ } elseif {$carg == "^o"} {
+ set exemptops 1
+ } elseif {$carg == "^f"} {
+ set exemptfriends 1
+ } elseif {$carg == "^p"} {
+ set exemptparty 1
+ } elseif {$carg == "^x"} {
+ set exemptfile 1
+ } elseif {$carg == "^cf"} {
+ set exemptchanf 1
+ } elseif {$carg == "^cm"} {
+ set exemptchanm 1
+ } elseif {$carg == "^cn"} {
+ set exemptchann 1
+ } elseif {$carg == "^b"} {
+ set exemptbotm 1
+ } elseif {$carg == "^co"} {
+ set exemptchano 1
+ } elseif {$carg == "c"} {
+ set convert 1
+ } elseif {[string index $carg 0] == "-"} {
+ lappend exempt [string range $carg 1 end]
+ } elseif {[string index $carg 0] == "+"} {
+ set maxlast [expr 60*60*24* [string range $carg 1 end]]
+ } elseif {[string index $carg 0] == "b"} {
+ set maxban [expr 60*60*24* [string range $carg 1 end]]
+ } elseif {[string index $carg 0] == "i"} {
+ set maxignore [expr 60*60*24* [string range $carg 1 end]]
+ } elseif {[string index $carg 0] == "="} {
+ lappend chanrem [string tolower [string range $carg 1 end]]
+ } else {
+ puts stderr "UNKNOWN OPTION: '$carg'\n"
+ exit
+ }
+}
+
+if {(!$weedlurkers) && (!$weedops) && (!$weedmasters) && (!$weednopw) &&
+ (!$stripops) && (!$stripmasters) && ($maxlast == 0) && ($convert == 0) &&
+ ($maxban == 0) && ($maxignore == 0) && ($chanrem == {})} {
+ puts stderr "PROBLEM: You didn't specify anything to weed out.\n"
+ exit
+}
+
+set weeding { } ; set strip { } ; set exempting { }
+if {$weedlurkers} { lappend weeding "lurkers" }
+if {$weedops} { lappend weeding "pwdless-ops" }
+if {$weedmasters} { lappend weeding "pwdless-masters" }
+if {$weednopw} { lappend weeding "pwdless-users" }
+if {$chanrem != {}} { lappend weeding "unwanted-channel" }
+if {$maxlast > 0} { lappend weeding ">[expr $maxlast /(60*60*24)]-days" }
+if {$maxban > 0} { lappend weeding "bans>[expr $maxban /(60*60*24)]-days" }
+if {$maxignore > 0} { lappend weeding "ign>[expr $maxignore /(60*60*24)]-days" }
+if {$weeding != { }} { puts stdout "Weeding:$weeding" }
+
+if {$stripops} { lappend strip "pwdless-ops" }
+if {$stripmasters} { lappend strip "pwdless-masters" }
+if {$strip != { }} { puts stdout "Stripping:$strip" }
+
+if {$exemptops} { lappend exempting "(ops)" }
+if {$exemptmasters} { lappend exempting "(masters)" }
+if {$exemptfriends} { lappend exempting "(friends)" }
+if {$exemptparty} { lappend exempting "(party-line)" }
+if {$exemptfile} { lappend exempting "(file-area)" }
+if {$exemptchann} { lappend exempting "(channel-owners)" }
+if {$exemptchanm} { lappend exempting "(channel-masters)" }
+if {$exemptchano} { lappend exempting "(channel-ops)" }
+if {$exemptchanf} { lappend exempting "(channel-friends)" }
+if {$exemptbotm} { lappend exempting "(botnet masters)" }
+if {[llength $exempt]>2} { lappend exempting "[lrange $exempt 2 end]" }
+if {$exempting != { }} { puts stdout "Exempt:$exempting" }
+
+puts stdout "\nReading $filename ..."
+
+proc convertUserFile {fname} {
+ global User Hostmask Channel Botflag LastOn BotAddr Xtra convert
+ puts stdout "\nRunning Converter on $fname"
+ set oldhandle {}
+ if {[catch {set fd [open $fname r]}] != 0} { return 0 }
+ set line [string trim [gets $fd]]
+ if {[string range $line 1 2] == "3v"} {
+ set convert 1
+ } elseif {[string range $line 1 2] == "4v"} {
+ return 0
+ }
+ while {![eof $fd]} {
+ set line [string trim [gets $fd]]
+ if {([string index $line 0] != "#") && ([string length $line] > 0)} {
+ scan $line "%s" handle
+ if {$handle == "-"} {
+ # hostmask
+ set hmList [split [string range $line 2 end] ,]
+ for {set i 0} {$i < [llength $hmList]} {incr i} {
+ lappend Hostmask($oldhandle) [string trim [lindex $hmList $i]]
+ }
+ } elseif {$handle == "!"} {
+ # channel
+ set chList [string trim [string range $line 1 end]]
+ lappend Channel($oldhandle) "[lrange $chList 0 1] [string trim [lindex $chList end] 0123456789]"
+ } elseif {$handle == "*"} {
+ # dccdir
+ set dccdir [string trim [string range $line 2 end]]
+ set User($oldhandle) [lreplace $User($oldhandle) 2 2 $dccdir]
+ } elseif {$handle == "+"} {
+ # email
+ set email [string trim [string range $line 2 end]]
+ set User($oldhandle) [lreplace $User($oldhandle) 3 3 $email]
+ } elseif {$handle == "="} {
+ # comment
+ set comment [string trim [string range $line 2 end]]
+ set User($oldhandle) [lreplace $User($oldhandle) 4 4 $comment]
+ } elseif {$handle == ":"} {
+ # user info line / bot addresses
+ if {[lsearch [split [lindex $User($oldhandle) 0] ""] b] == -1} {
+ set info [string trim [string range $line 1 end]]
+ set User($oldhandle) [lreplace $User($oldhandle) 5 5 $info]
+ } else {
+ set BotAddr($oldhandle) [string trim [string range $line 1 end]]
+ }
+ } elseif {$handle == "."} {
+ # xtra field start
+ if {![info exists xtraList($oldhandle)]} {
+ set xtraList($oldhandle) [string trim [string range $line 1 end]]
+ } {
+ set xtraList($oldhandle) "$xtraList($oldhandle) [string trim [string range $line 1 end]]"
+ }
+ } elseif {$handle == "!!"} {
+ # laston
+ set LastOn($oldhandle) [lindex $line 1]
+ } else {
+ # finish up xtra field first
+ if {[info exists xtraList($oldhandle)]} {
+ for {set i 0} {$i < [llength $xtraList($oldhandle)]} {incr i} {
+ lappend Xtra($oldhandle) [string trim [lindex $xtraList($oldhandle) $i] \{]
+ }
+ }
+ # begin of new user
+ scan $line "%s %s %s %s" handle pass attr ts
+ if {$convert == 1 && $attr != ""} {
+ regsub -all {B} $attr {t} attr
+ set botflags "s h a l r" ; set Botflag($handle) ""
+ set nattr [split [string trim $attr 0123456789] ""] ; set attr ""
+ foreach flag $botflags {
+ if {[lsearch -exact $nattr $flag] != -1} {append Botflag($handle) $flag}
+ }
+ foreach flag $nattr {
+ if {[lsearch -exact $botflags $flag] == -1} {append attr $flag}
+ }
+ }
+ set User($handle) [list $attr $pass {} {} {} {}]
+ set Hostmask($handle) {}
+ set Channel($handle) {}
+ set oldhandle $handle
+ }
+ }
+ }
+ return 1
+}
+
+proc loadUserFile {fname} {
+ global User Hostmask Channel Botflag LastOn BotAddr Xtra
+ set oldhandle {}
+ if {[catch {set fd [open $fname r]}] != 0} { return 0 }
+ set line [string trim [gets $fd]]
+ if {[string range $line 1 2] != "4v"} {
+ if {[string range $line 1 2] == "3v"} {
+ convertUserFile $fname
+ return 1
+ } else {
+ puts stderr "Unknown userfile version! (not v4)\n"
+ exit
+ }
+ }
+ while {![eof $fd]} {
+ set line [string trim [gets $fd]]
+ if {([string index $line 0] != "#") && ([string length $line] > 0)} {
+ scan $line "%s" handle
+ if {$handle == "--HOSTS"} {
+ # hostmask
+ set hmList [lindex $line 1]
+ lappend Hostmask($oldhandle) [string trim $hmList]
+ } elseif {$handle == "-"} {
+ # hostmask
+ set hmList [join [lrange $line 1 end]]
+ lappend Hostmask($oldhandle) [string trim $hmList]
+ } elseif {$handle == "!"} {
+ # channel
+ set chList [string trim [string range $line 1 end]]
+ lappend Channel($oldhandle) $chList
+ } elseif {$handle == "--BOTADDR"} {
+ # botaddr
+ set BotAddr($oldhandle) [lindex $line 1]
+ } elseif {$handle == "--PASS"} {
+ # pass
+ set pass [string trim [string range $line [expr [string first " " $line] + 1] end]]
+ set User($oldhandle) [lreplace $User($oldhandle) 1 1 $pass]
+ } elseif {$handle == "--DCCDIR"} {
+ # dccdir
+ set first [string first " " $line]
+ if {$first != -1} {
+ set dccdir [string trim [string range $line [expr $first + 1] end]]
+ } {
+ set dccdir ""
+ }
+ set User($oldhandle) [lreplace $User($oldhandle) 2 2 $dccdir]
+ } elseif {$handle == "--COMMENT"} {
+ # comment
+ set first [string first " " $line]
+ if {$first != -1} {
+ set comment [string trim [string range $line [expr $first + 1] end]]
+ } {
+ set comment ""
+ }
+ set User($oldhandle) [lreplace $User($oldhandle) 4 4 $comment]
+ } elseif {$handle == "--INFO"} {
+ # user info line
+ set first [string first " " $line]
+ if {$first != -1} {
+ set info [string trim [string range $line [expr $first + 1] end]]
+ } {
+ set info ""
+ }
+ set User($oldhandle) [lreplace $User($oldhandle) 5 5 $info]
+ } elseif {$handle == "--CONSOLE"} {
+ # console
+ set first [string first " " $line]
+ if {$first != -1} {
+ set console [string trim [string range $line [expr $first + 1] end]]
+ } {
+ set console ""
+ }
+ set User($oldhandle) [lreplace $User($oldhandle) 6 6 $console]
+ } elseif {$handle == "--XTRA"} {
+ # xtra field
+ set first [string first " " $line]
+ if {$first != -1} {
+ set xtraList [string trim [string range $line [expr $first + 1] end]]
+ } {
+ set xtraList ""
+ }
+ lappend Xtra($oldhandle) $xtraList
+ } elseif {$handle == "--LASTON"} {
+ # laston
+ set LastOn($oldhandle) [lindex $line 1]
+ } elseif {$handle == "--BOTFL"} {
+ # botflags
+ set Botflag($oldhandle) [string trim [string range $line 1 end]]
+ } else {
+ # begin of new user
+ scan $line "%s %s %s" handle dash attr
+ set User($handle) [list $attr {} {} {} {} {} {}]
+ set Hostmask($handle) {}
+ set Channel($handle) {}
+ set oldhandle $handle
+ }
+ }
+ }
+ return 1
+}
+
+proc saveUserFile fname {
+ global User Hostmask Channel Botflag LastOn BotAddr Xtra
+ if {[catch {set fd [open $fname w]}] != 0} { return 0 }
+ puts $fd "#4v: weed! now go away."
+ foreach i [array names User] {
+ set hmask "none"
+ set hmloop 0 ; set chloop 0 ; set loloop 0 ; set xloop 0 ; set aloop 0
+ if {[lindex $User($i) 1] == "bans"} {set plug "bans"} {set plug "-"}
+ set attr [lindex $User($i) 0]
+ set ts [lindex $User($i) 2]
+ puts $fd [format "%-9s %-20s %-24s" $i $plug $attr]
+ for {} {$hmloop < [llength $Hostmask($i)]} {incr hmloop} {
+ if {[string index $i 0] == "*" || [string range $i 0 1] == "::"} {
+ set hmask [lindex $Hostmask($i) $hmloop]
+ regsub -all {~} $hmask { } hmask
+ puts $fd "- $hmask"
+ } else {
+ puts $fd "--HOSTS [lindex $Hostmask($i) $hmloop]"
+ }
+ }
+ if {[info exists BotAddr($i)]} {
+ puts $fd "--BOTADDR [lindex $BotAddr($i) 0]"
+ }
+ if {[info exists Xtra($i)]} {
+ for {} {$xloop < [llength $Xtra($i)]} {incr xloop} {
+ puts $fd "--XTRA [lindex $Xtra($i) $xloop]"
+ }
+ }
+ if {[info exists Channel($i)]} {
+ for {} {$chloop < [llength $Channel($i)]} {incr chloop} {
+ puts $fd "! [lindex $Channel($i) $chloop]"
+ }
+ }
+ if {[info exists Botflag($i)]} {
+ if {$Botflag($i) != ""} { puts $fd "--BOTFL [lindex $Botflag($i) 0]" }
+ }
+ if {[string index $i 0] == "*" || [string range $i 0 1] == "::"} {
+ set User($i) [lreplace $User($i) 1 1 {}]
+ }
+ if {[lindex $User($i) 1] != {}} { puts $fd "--PASS [lindex $User($i) 1]" }
+ if {[lindex $User($i) 2] != {}} { puts $fd "--DCCDIR [lindex $User($i) 2]" }
+ if {[lindex $User($i) 3] != {}} { puts $fd "--XTRA EMAIL [lindex $User($i) 3]" }
+ if {[lindex $User($i) 4] != {}} { puts $fd "--COMMENT [lindex $User($i) 4]" }
+ if {[lindex $User($i) 5] != {}} { puts $fd "--INFO [lindex $User($i) 5]" }
+ if {[lindex $User($i) 6] != {}} { puts $fd "--CONSOLE [lindex $User($i) 6]" }
+ if {[info exists LastOn($i)]} {
+ puts $fd "--LASTON [lindex $LastOn($i) 0]"
+ }
+ }
+ close $fd
+ return 1
+}
+
+if {![loadUserFile $filename]} {
+ puts stdout "* Couldn't load userfile!\n"
+ exit
+}
+
+if {$convert == 0} {
+ puts stdout "Loaded. Weeding..."
+ puts stdout "(pwd = no pass, -o/-m = removed op/master, lrk = never seen, exp = expired)"
+ puts stdout "(uwc = unwanted channel)\n"
+} else {
+ puts stdout "Loaded. Converting..."
+}
+
+set total 0
+set weeded 0
+foreach i [array names User] {
+ incr total
+ set attr [lindex $User($i) 0]
+ set chanattr [lindex [lindex $Channel($i) 0] 2]
+ if {([lsearch -exact $exempt $i] == -1) &&
+ ([string range $i 0 1] != "::") &&
+ ([string range $i 0 1] != "--") &&
+ (([string first o $attr] == -1) || (!$exemptops)) &&
+ (([string first m $attr] == -1) || (!$exemptmasters)) &&
+ (([string first f $attr] == -1) || (!$exemptfriends)) &&
+ (([string first p $attr] == -1) || (!$exemptparty)) &&
+ (([string first x $attr] == -1) || (!$exemptfile)) &&
+ (([string first t $attr] == -1) || (!$exemptbotm)) &&
+ (([string first f $chanattr] == -1) || (!$exemptchanf)) &&
+ (([string first m $chanattr] == -1) || (!$exemptchanm)) &&
+ (([string first n $chanattr] == -1) || (!$exemptchann)) &&
+ (([string first o $chanattr] == -1) || (!$exemptchano))} {
+ set pass [lindex $User($i) 1]
+ if {[info exists LastOn($i)]} { set ts [lindex $LastOn($i) 0] } { set ts 0 }
+ if {([string compare $pass "-"] == 0) && ([string first b $attr] == -1)} {
+ if {$weednopw == 1} {
+ unset User($i) ; incr weeded
+ puts -nonewline stdout "[format "pwd: %-10s " $i]"
+ } elseif {([string first o $attr] != -1) && ($weedops == 1)} {
+ unset User($i) ; incr weeded
+ puts -nonewline stdout "[format "pwd: %-10s " $i]"
+ } elseif {([string first m $attr] != -1) && ($weedmasters == 1)} {
+ unset User($i) ; incr weeded
+ puts -nonewline stdout "[format "pwd: %-10s " $i]"
+ }
+ if {([string first o $attr] != -1) && ($stripops == 1)} {
+ set nattr {}
+ for {set x 0} {$x < [string length $attr]} {incr x} {
+ if {[string index $attr $x] != "o"} {
+ set nattr [format "%s%s" $nattr [string index $attr $x]]
+ }
+ }
+ if {$nattr == {}} { set nattr "-" }
+ set User($i) [lreplace $User($i) 0 0 $nattr]
+ puts -nonewline stdout "[format " -o: %-10s " $i]"
+ }
+ if {([string first m $attr] != -1) && ($stripmasters == 1)} {
+ set nattr {}
+ for {set x 0} {$x < [string length $attr]} {incr x} {
+ if {[string index $attr $x] != "m"} {
+ set nattr [format "%s%s" $nattr [string index $attr $x]]
+ }
+ }
+ if {$nattr == {}} { set nattr "-" }
+ set User($i) [lreplace $User($i) 0 0 $nattr]
+ puts -nonewline stdout "[format " -m: %-10s " $i]"
+ }
+ }
+ if {($ts==0) && ($weedlurkers==1) && ([string first b $attr] == -1) && [info exists User($i)]} {
+ unset User($i) ; incr weeded
+ puts -nonewline stdout "[format "lrk: %-10s " $i]"
+ }
+ if {($ts > 0) && ($maxlast > 0) && ($CURRENT-$ts > $maxlast && [info exists User($i)])} {
+ unset User($i) ; incr weeded
+ puts -nonewline stdout "[format "exp: %-10s " $i]"
+ }
+ if {$chanrem != {} && [info exists Channel($i)]} {
+ foreach unchan $chanrem {
+ set id [lsearch [string tolower $Channel($i)] *$unchan*]
+ if {$id != -1} {
+ set Channel($i) [lreplace $Channel($i) $id $id] ; incr weeded
+ puts -nonewline stdout "[format "uwc: %-10s " $i]"
+ }
+ }
+ }
+ }
+ flush stdout
+}
+if {$weeded == 0 && $convert == 0} { puts -nonewline stdout "uNF... Nothing to weed!" }
+puts stdout "\n"
+
+foreach i [array names User] {
+ if {([string range $i 0 1] == "::") || ($i == "*ban")} {
+ for {set j 0} {$j < [llength $Hostmask($i)]} {incr j} {
+ set ban [split [lindex $Hostmask($i) $j] :]
+ if {[string range [lindex $ban 2] 0 0] == "+"} {
+ set lastused [lindex $ban 3]
+ if {($maxban > 0) && ($CURRENT-$lastused > $maxban)} {
+ if {$i == "*ban"} {
+ puts stdout "Expired ban: [lindex $ban 0]"
+ } {
+ puts stdout "Expired ban on [string range $i 2 end]: [lindex $ban 0]"
+ }
+ set Hostmask($i) [lreplace $Hostmask($i) $j $j]
+ incr j -1
+ }
+ }
+ }
+ }
+ if {$i == "*ignore"} {
+ for {set j 0} {$j < [llength $Hostmask($i)]} {incr j} {
+ set ign [split [lindex $Hostmask($i) $j] :]
+ set lastused [lindex $ign 3]
+ if {($maxignore > 0) && ($CURRENT-$lastused > $maxignore)} {
+ puts stdout "Expired ignore: [lindex $ign 0]"
+ set Hostmask($i) [lreplace $Hostmask($i) $j $j]
+ incr j -1
+ }
+ }
+ }
+}
+
+puts stdout "\nFinished scan."
+puts stdout "Original total ($total), new total ([expr $total-$weeded]), zapped ($weeded)"
+
+if {![saveUserFile $filename.weed]} {
+ puts stdout "* uNF... Couldn't save new userfile!\n"
+ exit
+}
+puts stdout "Wrote $filename.weed"
diff --git a/whoisd.tcl b/whoisd.tcl
new file mode 100644
index 0000000..5047f0a
--- /dev/null
+++ b/whoisd.tcl
@@ -0,0 +1,232 @@
+# whoisd.tcl -- 1.1
+#
+# The whois command checks if a given domain is available or taken.
+# The tld command returns which country sponsors the given tld.
+# This script uses live servers so it is never outdated, unlike other scripts.
+#
+# I have tried a lot of existing domain whois scripts, none of them did what I wanted.
+# So I decided to write my own, based on a similar script I wrote for mIRC.
+#
+# It is purposly made to be simple so it did not require much maintenance.
+#
+# Copyright (c) 2010 HM2K
+#
+# Name: domain whois and tld country code lookup (!whois and !tld)
+# Author: HM2K <irc@hm2k.org>
+# License: http://www.freebsd.org/copyright/freebsd-license.html
+# Link: http://www.hm2k.com/projects/eggtcl
+# Tags: whois, lookup, domains, tld, country
+# Updated: 29-Jul-2010
+#
+###Usage
+# !whois is the default public channel trigger for the whois function
+# .whoisd is the default dcc command trigger the whois function
+# !tld is the default public channel trigger for the tld function
+# .tld is the default dcc trigger for the tld function
+#
+###Example
+# > !whois hm2k.com
+# <Bot> whois: hm2k.com is taken!
+# > !whois example-lame-domain.com
+# <Bot> whois: example-lame-domain.com is available!
+# > !tld uk
+# <Bot> whois: Country for uk is United Kingdom
+#
+###Credits
+# Thanks #eggtcl @ EFnet for some pointers
+#
+###Revisions
+# 1.1 - iana changed their whois response; the whole script was revamped
+# 1.0.3 - better documentation; fixed trigger; fixed timeouts; fixed available match
+# 1.0.2 - further imrovements were made
+# 1.0.1 - first public release
+
+
+### Settings
+set whoisd(cmd_dcc_domain) "whoisd"; #the dcc command - eg: whoisd <domain>
+set whoisd(cmd_dcc_tld) "tld"; #the dcc tld command - eg: tld <tld>
+set whoisd(cmd_pub_domain) "!whois"; #the pub command - eg: !whoisd <domain>
+set whoisd(cmd_pub_tld) "!tld"; #the pub tld command - eg: !tld <tld>
+set whoisd(data_country) "";#place holder for country data
+set whoisd(data_type) "domain"; #default data type
+set whoisd(debug) 1; #turn debug on or off
+set whoisd(error_connect) "Error: Connection to %s:%s failed."; #Connection failed
+set whoisd(error_connect_lost) "Error: Connection to server has been lost.";
+set whoisd(error_invalid) "Error: Invalid %s."; #Invalid domain/tld error
+set whoisd(flag) "-|-"; #flag required to use the script
+set whoisd(nomatch_domain) "No match|not found|Invalid query|does not exist|no data found|status: avail|domain is available|(null)|no entries found|not registered|no objects found|domain name is not|Status:.*AVAILABLE"; #Replies from Whois Servers that match as "Available"... #TODO: split into new lines, join again later
+set whoisd(nomatch_tld) "This query returned 0 objects."; #Error returned for invalid tld
+set whoisd(notice_connect) "Connecting to... %s:%s (%s)"; #Connecting notice
+set whoisd(output_country) "Country for %s is %s";
+set whoisd(output_found) "%s is available!";
+set whoisd(output_nomatch) "%s is taken!";
+set whoisd(output_timeout) "Connection to %s:%s timed out within %s seconds.";
+set whoisd(port) 43; #The default whois server port - should not change
+set whoisd(prefix) "whois:"; #prefix on output
+set whoisd(regex_country) {address.*?:\s*(.+)$};
+set whoisd(regex_server) {whois.*?:\s*(.+)$};
+set whoisd(regex_valid_domain) {^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$}; #Regular expression used for validating domains
+set whoisd(regex_valid_tld) {^\.?[a-z]+$};
+set whoisd(rplmode) 1; #reply mode (1:chan privmsg, 2:chan notice, 3:nick privmsg, 4:nick notice)
+set whoisd(server) "whois.iana.org"; #The main whois server - should not change
+set whoisd(timeout) 15; #server timeout in seconds - servers are quick, keep low
+set whoisd(usage) "Usage: %s <%s>"; #Usage
+set whoisd(ver) "1.1"; # version
+
+
+### Package Definition
+package require eggdrop 1.6; #see http://geteggdrop.com/
+package require Tcl 8.2.3; #see http://tinyurl.com/6kvu2n
+
+
+### Binds
+bind dcc $whoisd(flag) $whoisd(cmd_dcc_domain) whoisd:dcc_domain;
+bind pub $whoisd(flag) $whoisd(cmd_pub_domain) whoisd:pub_domain;
+bind dcc $whoisd(flag) $whoisd(cmd_dcc_tld) whoisd:dcc_tld;
+bind pub $whoisd(flag) $whoisd(cmd_pub_tld) whoisd:pub_tld;
+
+
+### Procedures
+proc whoisd:validate {cmd word} {
+ if {[string compare $word ""] == 0} {
+ return [format $::whoisd(usage) $cmd $::whoisd(data_type)];
+ }
+ if {![regexp $::whoisd(regex_valid) $word]} {
+ return [format $::whoisd(error_invalid) $::whoisd(data_type)];
+ }
+ return;
+}
+proc whoisd:dcc_domain {hand idx text} {
+ set ::whoisd(data_type) "domain";
+ set ::whoisd(cmd_dcc) $::whoisd(cmd_dcc_domain);
+ set ::whoisd(regex_valid) $::whoisd(regex_valid_domain);
+ return [whoisd:dcc $hand $idx $text];
+}
+proc whoisd:pub_domain {nick uhost hand chan text} {
+ set ::whoisd(data_type) "domain";
+ set ::whoisd(cmd_pub) $::whoisd(cmd_pub_domain);
+ set ::whoisd(regex_valid) $::whoisd(regex_valid_domain);
+ return [whoisd:pub $nick $uhost $hand $chan $text];
+}
+proc whoisd:dcc_tld {hand idx text} {
+ set ::whoisd(data_type) "tld";
+ set ::whoisd(cmd_dcc) $::whoisd(cmd_dcc_tld);
+ set ::whoisd(regex_valid) $::whoisd(regex_valid_tld);
+ return [whoisd:dcc $hand $idx $text];
+}
+proc whoisd:pub_tld {nick uhost hand chan text} {
+ set ::whoisd(data_type) "tld";
+ set ::whoisd(cmd_pub) $::whoisd(cmd_pub_tld);
+ set ::whoisd(regex_valid) $::whoisd(regex_valid_tld);
+ return [whoisd:pub $nick $uhost $hand $chan $text];
+}
+proc whoisd:dcc {hand idx text} {
+ set word [lrange [split $text] 0 0];
+ if {[set invalid [whoisd:validate ".$::whoisd(cmd_dcc)" $word]] != ""} {
+ whoisd:out 0 $idx {} $invalid;
+ return;
+ }
+ whoisd:connect 0 $idx {} $::whoisd(server) $::whoisd(port) $word;
+}
+proc whoisd:pub {nick uhost hand chan text} {
+ set word [lrange [split $text] 0 0];
+ if {[set invalid [whoisd:validate $::whoisd(cmd_pub) $word]] != ""} {
+ whoisd:out 4 {} $nick $invalid;
+ return;
+ }
+ whoisd:connect $::whoisd(rplmode) $chan $nick $::whoisd(server) $::whoisd(port) $word;
+}
+
+
+proc whoisd:out {type dest nick text} {
+ if {[string length [string trim $text]] < 1} { return; }
+ switch -- $type {
+ "0" { putdcc $dest "$::whoisd(prefix) $text"; }
+ "1" { putserv "PRIVMSG $dest :$::whoisd(prefix) $text"; }
+ "2" { putserv "NOTICE $dest :$::whoisd(prefix) $text"; }
+ "3" { putserv "PRIVMSG $nick :$::whoisd(prefix) $text"; }
+ "4" { putserv "NOTICE $nick :$::whoisd(prefix) $text"; }
+ "5" { putlog "$::whoisd(prefix) $text"; }
+ }
+}
+proc whoisd:connect {type dest nick server port word} {
+ putlog [format $::whoisd(notice_connect) $server $port $word];
+ if {[catch {socket -async $server $port} sock]} {
+ whoisd:out $type $dest $nick [format $::whoisd(error_connect) $server $port];
+ return;
+ }
+ #TODO: too long; must be split
+ fileevent $sock writable [list whoisd:write $type $dest $nick $word $sock $server $port [utimer $::whoisd(timeout) [list whoisd:timeout $type $dest $nick $server $port $sock $word]]];
+}
+proc whoisd:write {type dest nick word sock server port timerid} {
+ if {[set error [fconfigure $sock -error]] != ""} {
+ whoisd:out $type $dest $nick [format $::whoisd(error_connect) $server $port];
+ whoisd:die $sock $timerid;
+ return;
+ }
+ set word [string trim $word .];
+ if {$server == $::whoisd(server)} {
+ set lookup [lrange [split $word "."] end end];
+ } else {
+ set lookup $word;
+ }
+ puts $sock "$lookup\n";
+ flush $sock;
+ fconfigure $sock -blocking 0;
+ fileevent $sock readable [list whoisd:read $type $dest $nick $word $sock $server $port $timerid];
+ fileevent $sock writable {};
+}
+proc whoisd:read {type dest nick word sock server port timerid} {
+ while {![set error [catch {gets $sock output} read]] && $read > 0} {
+ if {!$type} { whoisd:out $type $dest $nick $output; }
+ if {$server == $::whoisd(server)} {
+ if {[regexp $::whoisd(nomatch_tld) $output]} {
+ set output [format $::whoisd(error_invalid) "tld"];
+ whoisd:out $type $dest $nick $output;
+ whoisd:die $sock $timerid;
+ }
+ if {$::whoisd(data_type) == "tld"} {
+ if {[regexp $::whoisd(regex_country) $output -> country]} {
+ set ::whoisd(data_country) $country;
+ }
+ } elseif {[regexp -nocase -- $::whoisd(regex_server) $output -> server]} {
+ whoisd:connect $type $dest $nick $server $port $word;
+ whoisd:die $sock $timerid;
+ }
+ } else {
+ if {[regexp -nocase -- $::whoisd(nomatch_domain) $output]} {
+ set output [format $::whoisd(output_found) $word];
+ whoisd:out $type $dest $nick $output;
+ whoisd:die $sock $timerid;
+ }
+ }
+ if {$error} {
+ whoisd:out $type $dest $nick $::whoisd(error_connect_lost);
+ whoisd:die $sock $timerid;
+ }
+ }
+}
+proc whoisd:die {sock timerid} {
+ catch { killutimer $timerid }
+ catch { close $sock }
+}
+proc whoisd:timeout {type dest nick server port sock word} {
+ catch { close $sock }
+ if {$server != $::whoisd(server)} {
+ set output [format $::whoisd(output_nomatch) $word];
+ whoisd:out $type $dest $nick $output;
+ return;
+ } elseif {$::whoisd(data_country) != ""} {
+ set output [format $::whoisd(output_country) $word $::whoisd(data_country)];
+ } else {
+ set output [format $::whoisd(output_timeout) $server $port $::whoisd(timeout)];
+ }
+ whoisd:out $type $dest $nick $output;
+}
+
+
+### Loaded
+putlog "whoisd.tcl $whoisd(ver) loaded";
+
+
+#EOF
diff --git a/whoisd.tcl_old b/whoisd.tcl_old
new file mode 100644
index 0000000..a747bc9
--- /dev/null
+++ b/whoisd.tcl_old
@@ -0,0 +1,155 @@
+#whoisd.tcl v1.0.2 by HM2K - domain whois and tld country lookup !whois and !tld
+
+### Description:
+## I have tried a lot of existing domain whois scripts, none of them did what I wanted.
+## So I decided to write my own, based on a similar script I wrote for mIRC.
+##
+### Usage:
+## The whois command (!whoisd) offers the ability to check if domain is available or taken.
+## The tld command (!tld) offers the ability to see which country owns an entered tld.
+## The tld command is similar to the !country commands, however the tld uses live servers so is never outdated.
+## The commands can also be triggered inside DCC, where all full domain whois records are displayed.
+##
+### Credits:
+## thanks to #eggtcl @ EFnet for some pointers
+##
+
+set whoisdver "1.0.2"
+
+#the dcc command - eg: whoisd <domain>
+#set whoisd(cmd_dcc) "whoisd"
+
+#the pub command - eg: !whoisd <domain>
+#set whoisd(cmd_pub) "!whoisd"
+
+#the dcc tld command - eg: tld <tld>
+#set whoisd(cmd_tlddcc) "tld"
+
+#the pub tld command - eg: !tld <tld>
+set whoisd(cmd_tldpub) "!tld"
+
+#flag required to use the script
+set whoisd(flag) "-|-"
+
+#The main whois server - should not change
+set whoisd(server) "whois.iana.org"
+
+#The default whois server port - should not change
+set whoisd(port) "43"
+
+#server timeout - servers are quick, keep low
+set whoisd(timeout) "5"
+
+#reply mode
+#0 - Private message to the channel
+#1 - Notice to the channel
+#2 - Private message to the nick
+#3 - Notice to the nick
+set whoisd(rplmode) "0"
+
+#prefix on output
+set whoisd(prefix) "whois:"
+#set whoisd(prefix) "\002$::whoisd(prefix)\002"
+
+if {![string match 1.6.* $version]} { putlog "\002WARNING:\002 This script is intended to run on eggdrop 1.6.x or later." }
+if {[info tclversion] < 8.2} { putlog "\002WARNING:\002 This script is intended to run on Tcl Version 8.2 or later." }
+
+#bind dcc $whoisd(flag) $whoisd(cmd_dcc) whoisd:dcc
+#bind pub $whoisd(flag) $whoisd(cmd_pub) whoisd:pub
+#bind dcc $whoisd(flag) $whoisd(cmd_tlddcc) whoisd:tlddcc
+bind pub $whoisd(flag) $whoisd(cmd_tldpub) whoisd:tldpub
+
+#proc whoisd:dcc {hand idx text} {
+# if {[string compare [set word [lrange [split $text] 0 0]] ""] == 0} { putdcc $idx "$::whoisd(prefix) Usage: .$::whoisd(cmd_dcc) <domain>" ; return }
+# if {![regexp {^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$} $word]} { putdcc $idx "$::whoisd(prefix) Error: Invalid Domain." ; return }
+# whoisd:connect 0 $idx {} $::whoisd(server) $::whoisd(port) $word
+#}
+#proc whoisd:pub {nick uhost hand chan text} {
+# if {[string compare [set word [lrange [split $text] 0 0]] ""] == 0} { putserv "NOTICE $nick :$::whoisd(prefix) Usage: $::whoisd(cmd_pub) <domain>" ; return }
+# if {![regexp {^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$} $word]} { putserv "NOTICE $nick :$::whoisd(prefix) Error: Invalid Domain." ; return }
+# whoisd:connect 1 $chan $nick $::whoisd(server) $::whoisd(port) $word
+#}
+#proc whoisd:tlddcc {hand idx text} {
+# if {[string compare [set word [lrange [split $text] 0 0]] ""] == 0} { putdcc $idx "$::whoisd(prefix) Usage: .$::whoisd(cmd_tlddcc) <tld>" ; return }
+# if {[string index $word 0] != "."} { putdcc $idx "$::whoisd(prefix) Error: Invalid TLD." ; return }
+# whoisd:connect 0 $idx {} $::whoisd(server) $::whoisd(port) $word
+#}
+proc whoisd:tldpub {nick uhost hand chan text} {
+ if {[string compare [set word [lrange [split $text] 0 0]] ""] == 0} { putserv "NOTICE $nick :$::whoisd(prefix) Usage: $::whoisd(cmd_tldpub) <tld>" ; return }
+ if {[string index $word 0] != "."} { set word ".$word" }
+ whoisd:connect 1 $chan $nick $::whoisd(server) $::whoisd(port) $word
+}
+proc whoisd:out {type dest nick text} {
+ if {[string length [string trim $text]] < 1} { return }
+ if {!$type} { putdcc $dest "$::whoisd(prefix) $text" ; return }
+ switch -- $::whoisd(rplmode) {
+ "0" { putserv "PRIVMSG $dest :$::whoisd(prefix) $text" }
+ "1" { putserv "NOTICE $dest :$::whoisd(prefix) $text" }
+ "2" { putserv "PRIVMSG $nick :$::whoisd(prefix) $text" }
+ "3" { putserv "NOTICE $nick :$::whoisd(prefix) $text" }
+ }
+}
+proc whoisd:connect {type dest nick server port word} {
+ if {[catch {socket -async $server $port} sock]} { whoisd:out $type $dest $nick "Error: Connection to $server:$port failed." ; return }
+ fileevent $sock writable [list whoisd:write $type $dest $nick $word $sock $server $port [utimer $::whoisd(timeout) [list whoisd:timeout $type $dest $nick $server $port $sock $word]]]
+}
+proc whoisd:write {type dest nick word sock server port timerid} {
+ if {[set error [fconfigure $sock -error]] != ""} {
+ whoisd:out $type $dest $nick "Connection to $::whoisd(server) failed."
+ whoisd:die $sock $timerid
+ return
+ }
+ set lookup $word
+ if {$server == $::whoisd(server)} { set lookup [lrange [split $word "."] end end] }
+ puts $sock "$lookup\n"
+ flush $sock
+ fconfigure $sock -blocking 0
+ fileevent $sock readable [list whoisd:read $type $dest $nick $word $sock $server $port $timerid]
+ fileevent $sock writable {}
+}
+proc whoisd:read {type dest nick word sock server port timerid} {
+ while {![set error [catch {gets $sock output} read]] && $read > 0} {
+ if {$server == $::whoisd(server)} {
+ if {[regexp {(not found)} $output]} {
+ set output "Error: Invalid TLD."
+ whoisd:out $type $dest $nick $output
+ whoisd:die { $sock $timerid }
+ }
+ if {[string index $word 0] == "." || ![string match *.* $word]} {
+ if {[regexp {Country: (.*)$} $output -> country]} {
+ whoisd:out $type $dest $nick "$word is $country"
+ whoisd:die { $sock $timerid }
+ }
+ }
+ if {[regexp {Whois Server \(port (.*?)\): (.*)$} $output -> port server]} {
+ whoisd:connect $type $dest $nick $server $port $word
+ whoisd:die { $sock $timerid }
+ }
+ if {[regexp {URL for registration services: (.*)$} $output -> url]} {
+ #do nothing atm
+ }
+ } else {
+ if {[regexp -nocase {No match|not found|Invalid query|does not exist|no data found|status: avail|domain is available|(null)|no entries found|not registered|no objects found|domain name is not} $output]} {
+ whoisd:out $type $dest $nick "$word is available!"
+ whoisd:die $sock $timerid
+ }
+ }
+ if {!$type} { whoisd:out $type $dest $nick $output }
+ if {$error} {
+ whoisd:out $type $dest $nick "Error: Connection to server has been lost."
+ whoisd:die $sock $timerid
+ }
+ }
+}
+proc whoisd:die {sock timerid} {
+ catch { close $sock }
+ catch { killutimer $timerid }
+}
+proc whoisd:timeout {type dest nick server port sock word} {
+ catch { close $sock }
+ #whoisd:out $type $dest $nick "Connection to $server:$port timed out."
+ if {$server != $::whoisd(server)} { whoisd:out $type $dest $nick "$word is taken!" }
+}
+
+putlog "whoisd.tcl $whoisdver loaded"
+
diff --git a/wiki.pl b/wiki.pl
new file mode 100644
index 0000000..9f66204
--- /dev/null
+++ b/wiki.pl
@@ -0,0 +1,100 @@
+#!/usr/bin/perl
+
+#use strict;
+#use warnings;
+use Web::Scraper;
+use URI;
+use HTML::Entities;
+use Encode;
+use URI::Escape;
+use LWP::UserAgent;
+
+my $scrap;
+
+my $lang = $ARGV[1];
+if (!$lang) {
+ $lang = "de";
+}
+my $wikiurl = "http://$lang.wikipedia.org/wiki/Special:Search?search=$ARGV[0]&go=Go";
+
+my $ua = new LWP::UserAgent;
+my $req = HTTP::Request->new('GET', $wikiurl);
+my $res = $ua->request($req);
+my $url = $res->request->uri;
+my $origurl = $url;
+$url =~ s/.*\/wiki\///;
+
+binmode(STDOUT, ":utf8");
+
+if ($url !~ m/Special:Search/) {
+#artikel
+
+ $scrap = scraper {
+ process '//div[@id="bodyContent"]/p', 'text[]' => 'TEXT';
+ process '//img', 'img[]' => '@src';
+ process '//div[@id="bodyContent"]/ul/li', 'list[]' => 'TEXT';
+ process '//table/tr/td', 'table[]' => 'TEXT';
+ };
+ $url = URI->new($wikiurl);
+
+ my $res = $scrap->scrape($url);
+ my $text = $res->{'text'};
+ my $img = $res->{'img'};
+ my $list = $res->{'list'};
+ my $table = $res->{'table'};
+ my $isDis = 0;
+
+ if ($$table[1] !~ m/$ARGV[0]/i && $#$table == 1) {
+ foreach (@$img) {
+#print "$_\n";
+# if ($_ =~ m/^http:\/\/upload\.wikimedia\.org\/wikipedia\/commons\/thumb\/.*\/.*\/Disambig/) {
+ if ($_ =~ m/Disambig/) {
+ $isDis = 1;
+ last;
+ }
+ }
+ }
+ if (!$isDis) {
+ $text = decode_entities($$text[0]);
+ $text =~ s/\([^\(\)]*\)||\[[^\[\]]*\]//g;
+ $text =~ s/\([^\(\)]*\)||\[[^\[\]]*\]//g;
+ $text =~ s/\([^\(\)]*\)||\[[^\[\]]*\]//g;
+ $text =~ s/\([^\(\)]*\)||\[[^\[\]]*\]//g;
+ $text =~ s/\s+/ /g;
+ $text =~ s/\s([,.\?!])/$1/g;
+
+ if ($text =~ m/.{448}.*/) {
+ $text =~ s/^(.{448}).*$/$1/;
+ $text =~ s/^(.*[\.!\?])[^\.!\?]*$/$1 (...)/;
+ }
+
+ print $text, "\n";
+ } else {
+ for ($count = 0; $count < 3 && $count <= $#$list; $count++) {
+ print "$$list[$count]\n";
+ }
+ print "For more see $origurl\n";
+ }
+
+} else {
+#kein artikel
+
+ $scrap = scraper {
+ process '//div[@class="searchresult"]', 'text[]' => 'TEXT';
+ process '//ul[@class="mw-search-results"]/li/div/a', 'href[]' => '@href';
+ };
+ $url = URI->new($wikiurl);
+
+ my $res = $scrap->scrape($url);
+ if (keys(%$res)) {
+ my $text = $res->{'text'};
+ my $href = $res->{'href'};
+ my $result = "";
+ for ($count = 0; $count < 5 && $count <= $#$text; $count++) {
+ $result = ($result?"$result || ":"").$$href[$count], "\n";
+ }
+ print "$result\n";
+ } else {
+ print "No matches with $ARGV[0]\n";
+ }
+}
diff --git a/wiki.pl.down b/wiki.pl.down
new file mode 100644
index 0000000..f2e4587
--- /dev/null
+++ b/wiki.pl.down
@@ -0,0 +1,3 @@
+#!/usr/bin/perl
+
+print "wikipedia down!\n";
diff --git a/wiki.tcl b/wiki.tcl
new file mode 100644
index 0000000..deb98da
--- /dev/null
+++ b/wiki.tcl
@@ -0,0 +1,50 @@
+# lastseen by xeno
+
+bind pub - !wiki wiki
+bind pub - !ewiki ewiki
+#bind pub - !say say
+bind pub - !google say
+
+proc say {nick host hand chan arg} {
+# putserv "PRIVMSG $chan :$arg";
+# putserv "PRIVMSG $chan :das hier ist [string trimleft $chan #]";
+}
+
+proc wiki {nick host hand chan arg} {
+ global do_wiki
+ if {[info exists do_wiki($nick:$chan)]} {
+ putserv "NOTICE $nick :no flooding!"
+ return 0;
+ }
+ set do_wiki($nick:$chan) 1
+ timer 1 "unset do_wiki($nick:$chan)"
+ set arg [string trim $arg]
+if {$arg == ""} {
+ return 0
+}
+
+ set output [split "[exec perl /home/eggdrop/eggdrop/scripts/wiki.pl \"$arg\" de]" "\n"]
+ foreach out $output {
+ putserv "PRIVMSG $chan :$out";
+ }
+}
+
+proc ewiki {nick host hand chan arg} {
+ global do_wiki
+ if {[info exists do_wiki($nick:$chan)]} {
+ return 0;
+ }
+ set do_wiki($nick:$chan) 1
+ timer 1 "unset do_wiki($nick:$chan)"
+ set arg [string trim $arg]
+if {$arg == ""} {
+ return 0
+}
+
+ set output [split "[exec perl /home/eggdrop/eggdrop/scripts/wiki.pl $arg en]" "\n"]
+ foreach out $output {
+ putserv "PRIVMSG $chan :$out";
+ }
+}
+
+putlog "wiki by lookshe loaded"
diff --git a/wiki2.pl b/wiki2.pl
new file mode 100644
index 0000000..e42f65a
--- /dev/null
+++ b/wiki2.pl
@@ -0,0 +1,100 @@
+#!/usr/bin/perl
+
+#use strict;
+#use warnings;
+use Web::Scraper;
+use URI;
+use HTML::Entities;
+use Encode;
+use URI::Escape;
+use LWP::UserAgent;
+
+my $scrap;
+
+my $lang = $ARGV[1];
+if (!$lang) {
+ $lang = "de";
+}
+my $wikiurl = "http://$lang.wikipedia.org/wiki/Special:Search?search=$ARGV[0]&go=Go";
+
+my $ua = new LWP::UserAgent;
+my $req = HTTP::Request->new('GET', $wikiurl);
+my $res = $ua->request($req);
+my $url = $res->request->uri;
+my $origurl = $url;
+$url =~ s/.*\/wiki\///;
+
+binmode(STDOUT, ":utf8");
+
+if ($url !~ m/Special:Search/) {
+#artikel
+
+ $scrap = scraper {
+ process '//div[@id="bodyContent"]/p', 'text[]' => 'TEXT';
+ process '//img', 'img[]' => '@src';
+ process '//div[@id="bodyContent"]/ul/li', 'list[]' => 'TEXT';
+ process '//table/tr/td', 'table[]' => 'TEXT';
+ };
+ $url = URI->new($wikiurl);
+
+ my $res = $scrap->scrape($url);
+ my $text = $res->{'text'};
+ my $img = $res->{'img'};
+ my $list = $res->{'list'};
+ my $table = $res->{'table'};
+ my $isDis = 0;
+
+ if ($$table[1] !~ m/$ARGV[0]/i && $#$table == 1) {
+ foreach (@$img) {
+#print "$_\n";
+ if ($_ =~ m/Disambig/) {
+ $isDis = 1;
+ last;
+ }
+ }
+ }
+ if (!$isDis) {
+ $text = decode_entities($$text[0]);
+ $text =~ s/\([^\(\)]*\)||\[[^\[\]]*\]//g;
+ $text =~ s/\([^\(\)]*\)||\[[^\[\]]*\]//g;
+ $text =~ s/\([^\(\)]*\)||\[[^\[\]]*\]//g;
+ $text =~ s/\([^\(\)]*\)||\[[^\[\]]*\]//g;
+ $text =~ s/\s+/ /g;
+ $text =~ s/\s([,.\?!])/$1/g;
+
+ if ($text =~ m/.{448}.*/) {
+ $text =~ s/^(.{448}).*$/$1/;
+ $text =~ s/^(.*[\.!\?])[^\.!\?]*$/$1 (...)/;
+ }
+
+ print $text, "\n";
+ } else {
+ for ($count = 0; $count < 3 && $count <= $#$list; $count++) {
+ print "$$list[$count]\n";
+ }
+ print "For more see $origurl\n";
+ }
+
+} else {
+#kein artikel
+
+ $scrap = scraper {
+ process '//div[@class="searchresult"]', 'text[]' => 'TEXT';
+ process '//ul[@class="mw-search-results"]/li/a', 'href[]' => '@href';
+ };
+ $url = URI->new($wikiurl);
+
+ my $res = $scrap->scrape($url);
+ if (keys(%$res)) {
+ my $text = $res->{'text'};
+ my $href = $res->{'href'};
+ my $result = "";
+
+ for ($count = 0; $count < 5 && $count <= $#$text; $count++) {
+ $result = ($result?"$result || ":"").$$href[$count], "\n";
+ }
+ print "$result\n";
+ } else {
+ print "No matches with $ARGV[0]\n";
+ }
+}