Code: Select all
# exec tclsh "$0" ${1+"$@"}
# ipcheck.3.0.3.tcl
# arfer <arfer.minute@gmail.com>
# dalnet #BogOff
# ***************************************************************************************************************************** #
# ********** OPERATION ******************************************************************************************************** #
# this script detemines the geographical location of an ip/hostmask/nick
# a nick must be online but not necessarily in one of the bot's channels
# ***************************************************************************************************************************** #
# ********** LICENCE ********************************************************************************************************** #
# 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
# if you did not receive a copy of the GNU General Public License along with this program write ..
# .. to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
# ***************************************************************************************************************************** #
# ********** DEPENDENCIES ***************************************************************************************************** #
# this script requires eggdrop/windrop version 1.6.17 or later
# *** it will NOT work on older versions due to the inlusion of the eggdrop tcl command stripcodes ***
# this script requires tcl version 8.4 or later
# *** it will NOT work on older version due to changes in the core tcl command regsub ***
# to check, use '.tcl info tclversion' in the partyline if you have enabled tcl commands in the bot's configuration file
# this script was specifically designed for Eggdrop/Windrop on DalNet IRC network, ..
# .. it has not been tested and may or may not work on other networks
# ***************************************************************************************************************************** #
# ********** INSTALLATION ***************************************************************************************************** #
# *** DO NOT LOAD THE REGION FILES THROUGH THE .CONF -- READ BELOW ***
# 1. configure ipcheck.3.0.3.tcl in a suitable text editor - see configuration section below
# 2. create the directory scripts/ipcheck if it doesn't already exist
# 3. put the congigured ipcheck.3.0.3.tcl in the bot's scripts/ipcheck directory
# 4. ONLY use region files for ipcheck.3.0.3.tcl supplied WITH ipcheck.3.0.3.tcl
# 5. put any/all of the accompanying region files in the same scripts/ipcheck directory (they will be loaded automatically)
# 6. add a line to the bot's .conf file 'source scripts/ipcheck/ipcheck.3.0.3.tcl'
# 7. restart the bot (NOT rehash)
# 8. once the bot is online use '.chanset #channelname +ipcheck' in the partyline for each bot channel you wish to use the ..
# .. script in, unless this process is automated - see configuration section below
# editpad lite is recommended as a suitable text editor for configuring this script
# free download from http://www.editpadpro.com/editpadlite.html
# note that the accompanying region files are not essential but are needed if you wish to see region translation in the output
# setting the region translation variable to boolean true in the configuration section below but not having the appropriate ..
# .. region file loaded will not result in an error
# ***************************************************************************************************************************** #
# ********** CHANGELOG ******************************************************************************************************** #
# 1.0.0 [16/12/06] [448 lines]
# alpha code
# 2.0.0 [15/08/07] [671 lines]
# changed www.dnsstuff.com lookup to api.hostip.info lookup after the owners secured dnsstuff from unauthorised use
# added ability to do a network /whois for nicks not in a bot channel
# 2.1.0 [10/08/07] [687 lines]
# added latitude and longitude output
# 2.1.1 [18/08/07] [690 lines]
# minor bugfix to one of the colour outputs
# 3.0.0 [19/08/07] [860 lines]
# changed from api.hostip.info (poor results) to www.mynameserver.com which required major code changes
# downside seems to be that if the city isn't in the database then nothing is returned, also sometimes geographically inaccurate
# started building region translation information as independent files
# 3.0.1 [06/09/07] [864 lines]
# changed regsub & switch statements slightly, to more formally correct syntax
# typo in ipclear proc
# changed var names and proc names to look less confusing
# changed to more sensible user flags eg. channel op allows global op, channel master allows global master etc
# 3.0.2 [04/09/07] [898 lines]
# added ability to automate setting of channel flag +ipcheck to any channel the bot joins
# added more explanatory text to the dependencies section
# minor change to an error output for ipclear command
# 3.0.3 [20/09/07] [902 lines]
# fixed code to search for nick in $owner in the case of multiple owners
# ***************************************************************************************************************************** #
# ********** SYNTAX *********************************************************************************************************** #
# assuming the default trigger '.'
# .ip <hostname||nick||numeric>
# .ipclear
# if a nick is specified as the target as in the syntax .ip <nick>, the target need not be on a bot channel (a network /whois ..
# .. will be automatically sent in order to determine the target's hostname/ip)
# ***************************************************************************************************************************** #
# ********** CONFIGURATION **************************************************************************************************** #
# set here the single character command trigger
# ensure that it is set such that it does not interfere with similar commands on this or other bots in the same channel(s)
# allowed values are as follows (the existing settings are recommended)
# , = comma
# . = period
# ! = exclamation mark
# $ = dollar sign
# & = ampersand
# - = hyphen
# ? = question mark
# ~ = tilde
# ; = semi-colon
# : = colon
# ' = apostrophe
# % = percent
# ^ = caret
# * = asterisk
set vIpcheckTrigger "!"
# set here the user status required to use the commands in this script
# based on global and channel bot flags
# allowed values are as follows
# 1 = public (no bot access required)
# 2 = partyline (p|)
# 3 = channel or global operator (o|o)
# 4 = global operator (o|)
# 5 = channel or global master (m|m)
# 6 = global master (m|)
# 7 = channel or global owner (n|n)
# 8 = global owner (n|)
# 9 = permanent owner (specified in .conf file)
set vIpcheckStatus(ip) 1
set vIpcheckStatus(ipclear) 3
# set here the text colours used in the bot's responses
# settings are only valid where channel mode permits colour
# allowed values are as follows (the existing settings are recommended)
# 00 = white
# 01 = black
# 02 = blue
# 03 = green
# 04 = light red
# 05 = brown
# 06 = purple
# 07 = orange
# 08 = yellow
# 09 = light green
# 10 = cyan
# 11 = light cyan
# 12 = light blue
# 13 = pink
# 14 = grey
# 15 = light grey
set vIpcheckColor(arrow) 03
set vIpcheckColor(compliance) 10
set vIpcheckColor(dimmed) 14
set vIpcheckColor(emphasis) 05
set vIpcheckColor(errors) 04
# set here if you wish to automate the channel flag setting of +ipcheck for any channel the bot joins
# do not turn on this facility if you intend that the script work in only selected channels
# for 'auto channel setting' the setting can be any of the accepted boolean values 1, yes, true, on
# for 'manual channel setting' (as normal through the .chanset partyline command) the setting can be any ..
# .. of the accepted boolean values 0, no, false, off
# no other values are permitted
set vIpcheckAuto 1
# set here if you wish to additionally have the two digit country code translated to its full text equivalent
# for 'translation' the setting can be any of the accepted boolean values 1, yes, true, on
# for 'no translation' the setting can be any of the accepted boolean values 0, no, false, off
# no other values are permitted
set vIpcheckTranslateCountry 1
# set here if you wish to additionally have the two digit region code translated to its full text equivalent
# note that region translation will only occur if the optional region file for the specific country is present
# for 'translation' the setting can be any of the accepted boolean values 1, yes, true, on
# for 'no translation' the setting can be any of the accepted boolean values 0, no, false, off
# no other values are permitted
set vIpcheckTranslateRegion 1
# ***************************************************************************************************************************** #
# ********** CODE ************************************************************************************************************* #
# *********************************** #
# *** DO NOT EDIT BELOW THIS LINE *** #
# *********************************** #
# ---------- FAILSAFES --------------------------------------------------------------------------------------------------- #
if {![regexp {^[-,.!$&?~;:'%^*]{1}$} $vIpcheckTrigger]} {
die "configuration error in ipcheck.tcl - illegal command trigger character"
}
foreach status [array names vIpcheckStatus] {
if {![string is integer -strict $vIpcheckStatus($status)]} {
die "configuration error in ipcheck.tcl - illegal user status value (not an integer)"
} else {
if {($vIpcheckStatus($status) < 1) || ($vIpcheckStatus($status) > 9)} {
die "configuration error in ipcheck.tcl - illegal user status value (out of permitted range)"
}
}
}
foreach colour [array names vIpcheckColor] {
if {![string is integer -strict $vIpcheckColor($colour)]} {
die "configuration error in ipcheck.tcl - illegal text colour value (not an integer)"
} else {
if {($vIpcheckColor($colour) < 0) || ($vIpcheckColor($colour) > 15)} {
die "configuration error in ipcheck.tcl - illegal text colour value (out of permitted range)"
}
}
}
if {![string is boolean -strict $vIpcheckAuto]} {
die "configuration error in ipcheck.tcl - illegal auto channel setting variable (not boolean)"
}
if {![string is boolean -strict $vIpcheckTranslateCountry]} {
die "configuration error in ipcheck.tcl - illegal country translation variable (not boolean)"
}
if {![string is boolean -strict $vIpcheckTranslateRegion]} {
die "configuration error in ipcheck.tcl - illegal region translation variable (not boolean)"
}
# ---------- INITIALISE -------------------------------------------------------------------------------------------------- #
set vIpcheckVersion 3.0.3
setudef flag ipcheck
proc pIpcheckTrigger {} {
global vIpcheckTrigger
return $vIpcheckTrigger
}
array set vIpcheckFlag {
2 p|
3 o|o
4 o|
5 m|m
6 m|
7 n|n
8 n|
}
array set vIpcheckName {
2 "partyline"
3 "channel operator"
4 "global operator"
5 "channel master"
6 "global master"
7 "channel owner"
8 "global owner"
}
# ---------- BINDS ------------------------------------------------------------------------------------------------------- #
bind JOIN - * pIpcheckJoinAuto
bind PUB - [pIpcheckTrigger]ip pIpcheckPubIp
bind PUB - [pIpcheckTrigger]ipclear pIpcheckPubIpclear
bind RAW - 311 pIpcheckRaw311
bind RAW - 318 pIpcheckRaw318
bind RAW - 402 pIpcheckRaw402
# ---------- BIND PROCS -------------------------------------------------------------------------------------------------- #
proc pIpcheckJoinAuto {nick uhost hand chan} {
global vIpcheckAuto
if {[isbotnick $nick]} {
if {$vIpcheckAuto} {
if {[lsearch -exact [channel info $chan] +ipcheck] == -1} {
channel set $chan +ipcheck
savechannels
}
}
}
return 0
}
proc pIpcheckPubIp {nick uhost hand chan text} {
global vIpcheckChannel
global vIpcheckPending
global vIpcheckSource
global vIpcheckStatus
global vIpcheckTarget
if {[lsearch -exact [channel info $chan] +ipcheck] != -1} {
set command [pIpcheckTrigger]ip
set text [string trim $text]
if {[pIpcheckFlag $nick $chan] >= $vIpcheckStatus(ip)} {
if {[llength [split $text]] == 1} {
if {![info exists vIpcheckPending]} {
set vIpcheckChannel $chan
set vIpcheckPending 1
set vIpcheckSource $nick
set vIpcheckTarget $text
pIpcheckType $nick $chan $text
} else {pIpcheckError 003 $command $nick 0 $chan 0 0 0 0 0 0 0 0 0}
} else {pIpcheckError 002 $command $nick 0 $chan 0 [pIpcheckSyntax ip] 0 0 0 0 0 0 0}
} else {pIpcheckError 001 $command $nick 0 $chan 0 [pIpcheckName $vIpcheckStatus(ip)] 0 0 0 0 0 0 0}
}
return 0
}
proc pIpcheckPubIpclear {nick uhost hand chan text} {
global vIpcheckPending
global vIpcheckStatus
if {[lsearch -exact [channel info $chan] +ipcheck] != -1} {
set command [pIpcheckTrigger]ipclear
set text [string trim $text]
if {[pIpcheckFlag $nick $chan] >= $vIpcheckStatus(ipclear)} {
if {[llength [split $text]] == 0} {
if {[info exists vIpcheckPending]} {
pIpcheckTerminate
} else {pIpcheckError 018 0 $nick 0 $chan 0 0 0 0 0 0 0 0 0}
} else {pIpcheckError 002 $command $nick 0 $chan 0 [pIpcheckSyntax ipclear] 0 0 0 0 0 0 0}
} else {pIpcheckError 001 $command $nick 0 $chan 0 [pIpcheckName $vIpcheckStatus(ipclear)] 0 0 0 0 0 0 0}
}
return 0
}
proc pIpcheckRaw311 {from keyword text} {
global vIpcheckTarget
global vIpcheckPending
global vIpcheckWhois311
set text [stripcodes abcru $text]
set target [join [lindex [split $text] 1]]
if {([info exists vIpcheckPending]) && ([string equal -nocase $vIpcheckTarget $target])} {
set vIpcheckWhois311 [join [lindex [split $text] 3]]
}
return 0
}
proc pIpcheckRaw318 {from keyword text} {
global vIpcheckChannel
global vIpcheckClass
global vIpcheckPending
global vIpcheckSource
global vIpcheckTarget
global vIpcheckType
global vIpcheckWhois311
set text [stripcodes abcru $text]
set target [join [lindex [split $text] 1]]
if {([info exists vIpcheckPending]) && ([string equal -nocase $vIpcheckTarget $target])} {
if {[info exists vIpcheckWhois311]} {
switch -- [pIpcheckNumeric $vIpcheckWhois311] {
0 {
set vIpcheckType "nick hostname $vIpcheckWhois311"
dnslookup $vIpcheckWhois311 pIpcheckDns $vIpcheckSource $vIpcheckChannel
}
2 {
set ip_info [pIpcheckClass $vIpcheckWhois311]
set vIpcheckClass "[join [lrange [split $ip_info] 1 end]] $vIpcheckWhois311"
set vIpcheckType "nick numeric $vIpcheckWhois311"
pIpcheckQuery $vIpcheckSource $vIpcheckChannel $vIpcheckWhois311
}
}
} else {
pIpcheckError 015 0 $vIpcheckSource 0 $vIpcheckChannel 0 $vIpcheckTarget 0 0 0 0 0 0 0
}
}
return 0
}
proc pIpcheckRaw402 {from keyword text} {
global vIpcheckChannel
global vIpcheckSource
global vIpcheckTarget
global vIpcheckPending
set text [stripcodes abcru $text]
set target [join [lindex [split $text] 1]]
if {([info exists vIpcheckPending]) && ([string equal -nocase $vIpcheckTarget $target])} {
pIpcheckError 016 0 $vIpcheckSource 0 $vIpcheckChannel 0 $vIpcheckTarget 0 0 0 0 0 0 0
}
return 0
}
# ---------- DEFINED PROCS ----------------------------------------------------------------------------------------------- #
proc pIpcheckCancel {command nick target chan} {
global vIpcheckPending
global vIpcheckType
if {[info exists vIpcheckPending]} {
pIpcheckReset
pIpcheckError 017 $command $nick 0 $chan 0 $target 0 0 0 0 0 0 0
}
return 0
}
proc pIpcheckColor {chan type number} {
global vIpcheckColor
if {[lsearch [pIpcheckMode $chan] +c] != -1} {
return ""
} else {
switch -- $number {
1 {
switch -- $type {
0 {return "\003$vIpcheckColor(errors)"}
1 {return "\003$vIpcheckColor(compliance)"}
}
}
3 {return "\003$vIpcheckColor(dimmed)"}
5 {return "\003$vIpcheckColor(arrow)"}
7 {return "\003$vIpcheckColor(emphasis)"}
2 - 4 - 6 - 8 {return "\003"}
}
}
}
proc pIpcheckCompliance {number command nick target schan tchan text1 text2 text3 text4 text5 text6 text7 text8} {
for {set loop 1} {$loop <= 8} {incr loop} {
set col($loop) [pIpcheckColor $schan 1 $loop]
}
set output1 "$col(1)Compliance$col(2) ($col(3)$nick$col(4)) $col(5)-->$col(6)"
switch -- $number {
001 {set output2 "target acquired ($col(3)$text1$col(4)) $col(5)-->$col(6) host type ($col(3)$text2$col(4)),\
country ($col(3)$text3$col(4)), region ($col(3)$text4$col(4)), city ($col(3)$text5$col(4)),\
latitude ($col(3)$text6$col(4)), longitude ($col(3)$text7$col(4))"}
}
putserv "PRIVMSG $schan :$output1 $output2"
pIpcheckTerminate
return 0
}
proc pIpcheckClass {ip} {
set octet1 [lindex [split $ip .] 0]
set octet2 [lindex [split $ip .] 1]
set octet3 [lindex [split $ip .] 2]
if {($octet1 == 0) || ([string equal "255.255.255.255" $ip])} {set type 1}
if {$octet1 == 127} {set type 2}
if {($octet1 == 172) && ($octet2 >= 16) && ($octet2 <= 31)} {set type 3}
if {($octet1 == 192) && ($octet2 == 168)} {set type 3}
if {$octet1 == 10} {set type 3}
if {($octet1 == 192) && ($octet2 == 0) && ($octet3 == 2)} {set type 4}
if {($octet1 == 169) && ($octet2 == 254)} {set type 5}
if {($octet1 >= 224) && ($octet1 <= 239)} {set type 6}
if {![info exists type]} {
if {($octet1 >= 240) && ($octet1 <= 255)} {set type 7}
if {($octet1 >= 1) && ($octet1 <= 126)} {set type 8}
if {($octet1 >= 128) && ($octet1 <= 191)} {set type 9}
if {($octet1 >= 192) && ($octet1 <= 223)} {set type 10}
}
switch -- $type {
1 {set text "Broadcast"}
2 {set text "Loopback"}
3 {set text "Private LAN"}
4 {set text "TEST-NET Example Block"}
5 {set text "Link Local"}
6 {set text "Multicasting Class D"}
7 {set text "Experimental Class E"}
8 {set text "Class A"}
9 {set text "Class B"}
10 {set text "Class C"}
}
return "$type $text"
}
proc pIpcheckCountrySet {} {
global vIpcheckCountry
array set vIpcheckCountry {
AC "Ascension Island" AD "Andorra" AE "United Arab Emirates" AF "Afghanistan" AG "Antigua and Barbuda" AI "Anguilla"
AL "Albania" AM "Armenia" AN "Netherlands Antilles" AO "Angola" AQ "Antarctica" AR "Argentina" AS "American Samoa"
AT "Austria" AU "Australia" AW "Aruba" AX "Aland Islands" AZ "Azerbaijan" BA "Bosnia and Hertzegovina" BB "Barbados"
BD "Bangladesh" BE "Belgium" BF "Burkina Faso" BG "Bulgaria" BH "Bahrain" BI "Berundi" BJ "Benin" BM "Bermuda"
BN "Brunei Darussalam" BO "Bolivia" BR "Brazil" BS "Bahamas" BT "Bhutan" BV "Bouvet Island" BW "Botswana"
BY "Belarus" BX "Belize" CA "Canada" CC "Cocos (Keeling) Islands" CD "The Democratic Republic of the Congo"
CF "Central African Republic" CG "Republic of Congo" CH "Switzerland" CI "Cote d'Ivoire" CK "Cook Islands" CL "Chile"
CM "Cameroon" CN "China" CO "Columbia" CR "Costa Rica" CU "Cuba" CV "Cape Verde" CX "Christmas Island" CY "Cyprus"
CZ "Czech Republic" DE "Germany" DJ "Djibouti" DK "Denmark" DM "Dominica" DO "Dominican Republic" DZ "Algeria"
EC "Equador" EE "Estonia" EG "Egypt" EH "Westewrn Sahara" ER "Eritrea" ES "Spain" ET "Ethiopia" EU "European Union"
FI "Finland" FJ "Fiji" FK "Falkland Islands (Malvinas)" FM "Federated States of Micronesia" FO "Faroe Islands"
FR "France" GA "Gabon" GB "United Kingdom" GD "Grenada" GE "Georgia" GF "French Guiana" GG "Guernsey" GH "Ghana"
GI "Gibraltar" GL "Greenland" GM "Gambia" GN "Guinea" GP "Guadeloupe" GQ "Equatorial Guinea" GR "Greece"
GS "South Georgia and the South Sandwich Islands" GT "Guatamala" GU "Guam" GW "Guinea-Bissau" GY "Guyana"
HK "Hong Kong" HM "Heards and McDonald Islands" HN "Honduras" HR "Croatia/Hrvatska" HT "Haiti" HU "Hungary"
ID "Indonesia" IE "Ireland" IL "Israel" IM "Isle of Man" IN "India" IO "British Indian Ocean Territory" IQ "Iraq"
IR "Islamic Republic of Iran" IS "Iceland" IT "Italy" JE "Jersey" JM "Jamaica" JO "Jordan" JP "Japan" KE "Kenya"
KG "Kyrgyzstan" KH "Cambodia" KI "Kiribati" KM "Comoros" KN "Saint Kitts and Nevis"
KP "Democratic People's Republic of Korea" KR "Republic of Korea" KW "Kuwait" KY "Cayman Islands" KZ "Kazakhstan"
LA "Lao People's Democratic Republic" LB "Lebanon" LC "Saint Lucia" LI "Liechtenstein" LK "Sri Lanka" LR "Liberia"
LS "Lesotho" LT "Lithuania" LU "Luxembourg" LV "Latvia" LY "Libyan Arab Jamahiriya" MA "Morocco" MC "Monaco"
MD "Republic of Maldova" ME "Montenegro" MG "Madagascar" MH "Marshall Islands"
MK "The Former Yugoslav Republic of Macedonia" ML "Mali" MM "Myanmar" MN "Mongolia" MO "Macao"
MP "Northern Mariana Islands" MQ "Martinique" MR "Mauritania" MS "Montserrat" MT "Malta" MU "Mauritius" MV "Maldives"
MW "Malawi" MX "Mexico" MY "Malaysia" MZ "Mozambique" NA "Namibia" NC "New Caledonia" NE "Niger" NF "Norfolk Island"
NG "Nigeria" NI "Nicaragua" NL "Netherlands" NO "Norway" NP "Nepal" NR "Nauru" NU "Niue" NZ "New Zealand" OM "Oman"
PA "Panama" PE "Peru" PF "French Polynesia" PG "Papua New Guinea" PH "Philippines" PK "Pakistan" PL "Poland"
PM "Saint Pierre and Miquelon" PN "Pitcairn Island" PR "Puerto Rico" PS "Palestinian Occupied Territory" PT "Portugal"
PW "Palau" PY "Paraguay" QA "Qatar" RE "Reunion Island" RO "Romania" RS "Serbia" RU "Russian Federation" RW "Rwanda"
SA "Saudi Arabia" SB "Solomon Islands" SC "Seychelles" SD "Sudan" SE "Sweden" SG "Singapore" SH "Saint Helena"
SI "Slovenia" SJ "Svalbard and Jan Mayen Islands" SK "Slovak Republic" SL "Sierra Leone" SM "San Marino" SN "Senegal"
SO "Somalia" SR "Suriname" ST "Sao Tome and Principe" SU "Soviet Union" SV "El Salvador" SY "Syrian Arab Republic"
SZ "Swaziland" TC "Turks and Caicos Islands" TD "Chad" TF "French Suothern Territories" TG "Togo" TH "Thailand"
TJ "Tajikistan" TK "Tokelau" TL "Timor-Leste" TM "Turkmenistan" TN "Tunisia" TO "Tonga" TP "East Timor" TR "Turkey"
TT "Trinidad and Tobago" TV "Tuvalu" TW "Taiwan" TZ "Tanzania" UA "Ukraine" UG "Uganda" UK "United Kingdom"
UM "United States Minor Outlying Islands" US "United States" UY "Uruguay" UZ "Uzbekistan" VA "Vatican City State"
VC "Saint Vincent and the Grenadines" VE "Venezuela" VG "British Virgin Islands" VI "United States Virgin Islands"
VN "Vietnam" VU "Vanuatu" WF "Wallis and Futuna Islands" WS "Samoa" YE "Yemen" YT "Mayotte" YU "Yugoslavia"
ZA "South Africa" ZM "Zambia" ZW "Zimbabwe"
}
return 0
}
proc pIpcheckDns {ip host status nick chan} {
global vIpcheckClass
global vIpcheckTarget
global vIpcheckType
if {$status} {
set ip_info [pIpcheckClass $ip]
set vIpcheckClass "[join [lrange [split $ip_info] 1 end]] $ip"
pIpcheckQuery $nick $chan $ip
} else {
switch -- [join [lindex [split $vIpcheckType] 0]] {
hostname {pIpcheckError 008 0 $nick 0 $chan 0 $vIpcheckTarget 0 0 0 0 0 0 0}
nick {pIpcheckError 009 0 $nick 0 $chan 0 $vIpcheckTarget $host 0 0 0 0 0 0}
}
}
return 0
}
proc pIpcheckError {number command nick target schan tchan text1 text2 text3 text4 text5 text6 text7 text8} {
for {set loop 1} {$loop <= 8} {incr loop} {
set col($loop) [pIpcheckColor $schan 0 $loop]
}
set output1 "$col(1)Error$col(2) ($col(3)$nick$col(4)) $col(5)-->$col(6)"
switch -- $number {
001 {set output2 "$col(7)$text1$col(8) bot access is required to use the command $col(7)$command$col(8)"}
002 {
switch -- [string length $text1] {
0 {set output2 "correct syntax is $col(7)$command$col(8) without additional arguments"}
default {set output2 "correct syntax is $col(7)$command $text1$col(8)"}
}
}
003 {set output2 "the command $col(7)$command$col(8) already has an operation pending, please wait and try again $col(5)-->$col(6) if\
the problem persists use $col(7)[pIpcheckTrigger]ipclear$col(8)"}
004 {set output2 "$col(7)$text1$col(8) appears to be a nick but is in an invalid format and/or contains illegal characters"}
005 {set output2 "$col(7)$text1$col(8) appears to be a valid numeric ip but is not externally useable ($col(3)$text2$col(4))"}
006 {set output2 "$col(7)$text1$col(8) appears to be a numeric ip but one or more octet(s) are outside the permitted range"}
007 {set output2 "$col(7)$text1$col(8) appears to be a hostname but is in an invalid format and/or contains illegal characters"}
008 {set output2 "$col(7)$text1$col(8) appears to be a valid hostname but will not reverse dns resolve"}
009 {set output2 "$col(7)$text1$col(8) is a valid online nick but their hostname ($col(3)$text2$col(4)) will not reverse dns resolve"}
010 {set output2 "a socket could not be opened to the geolocation reference website"}
011 {set output2 "the numeric ip $col(7)$text1$col(8) is valid ($col(3)$text2$col(4)) but no information was returned from the online\
geolocation reference site that could be properly interpreted"}
012 {set output2 "the numeric ip for $col(7)$text1$col(8) ($col(3)$text2$col(4)) is valid ($col(3)$text3$col(4)) but no information\
was returned from the online geolocation reference site that could be properly interpreted"}
013 {set output2 "the hostname for $col(7)$text1$col(8) ($col(3)$text2$col(4)) resolves to the numeric ip ($col(3)$text3$col(4)) which\
is valid ($col(3)$text4$col(4)) but no information was returned from the online geolocation reference site that could\
be properly interpreted"}
014 {set output2 "the numeric ip $col(7)$text1$col(8) resolved from the hostname $col(7)$text2$col(8) is valid ($col(3)$text3$col(4)) but\
no information was returned from the online geolocation reference site that could be properly interpreted"}
015 {set output2 "$col(7)$text1$col(8) appears to be a nick but is not in a bot channel and an attempt to find their host via a network\
whois failed"}
016 {set output2 "$col(7)$text1$col(8) appears to be a nick but is not currently online"}
017 {set output2 "the command $col(7)[pIpcheckTrigger]$command $text1(8) has timed out after 10 seconds without response"}
018 {set output2 "the command $col(7).ip$col(8) does not currently have a response pending"}
}
putserv "PRIVMSG $schan :$output1 $output2"
switch -- $number {
001 - 002 - 003 {}
default {pIpcheckTerminate}
}
return 0
}
proc pIpcheckFlag {nick chan} {
global owner
global vIpcheckFlag
if {[lsearch -exact [split [string tolower $owner] ", "] [string tolower [nick2hand $nick]]] != -1} {
return 9
}
for {set loop 8} {$loop >= 2} {incr loop -1} {
if {[matchattr [nick2hand $nick] $vIpcheckFlag($loop) $chan]} {return $loop}
}
return 1
}
proc pIpcheckHostname {host} {
set valid 0
if {([regexp -- {^[-0-9a-zA-Z\.]*$} $host]) && ([string index $host 0] != "-")} {
set valid 1
}
return $valid
}
proc pIpcheckMode {chan} {
set modes [split [getchanmode $chan] "-"]
switch -- [llength $modes] {
0 {
set modelist {}
}
1 {
switch -- [string index [join $modes] 0] {
+ {
set sign "+"
set chars [string replace [join $modes] 0 0]
}
default {
set sign "-"
set chars [join $modes]
}
}
for {set loop 0} {$loop < [string length $chars]} {incr loop} {
lappend modelist $sign[string index $chars $loop]
}
}
2 {
set sign "+"
set chars [string replace [join [lindex $modes 0]] 0 0]
for {set loop 0} {$loop < [string length $chars]} {incr loop} {
lappend modelist $sign[string index $chars $loop]
}
set sign "-"
set chars [join [lindex $modes 1]]
for {set loop 0} {$loop < [string length $chars]} {incr loop} {
lappend modelist $sign[string index $chars $loop]
}
}
}
return $modelist
}
proc pIpcheckName {number} {
global vIpcheckName
switch -- $number {
1 {return "public"}
9 {return "permanent owner"}
default {return $vIpcheckName($number)}
}
}
proc pIpcheckNick {nick} {
set valid 0
if {[regexp -- {^[\x41-\x7D][-\d\x41-\x7D]*$} $nick]} {
set valid 1
}
return $valid
}
proc pIpcheckNumeric {ip} {
set valid 0
if {[regexp -- {^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$} $ip]} {
set valid 2
set octets [split $ip .]
foreach range $octets {
if {[expr {$range > 255}]} {
set valid 1
break
}
}
}
return $valid
}
proc pIpcheckParse {results} {
global vIpcheckData
global vIpcheckCountry
global vIpcheckRegion
global vIpcheckTranslateCountry
global vIpcheckTranslateRegion
set countryidx [lsearch -exact $results "Country"]
if {$countryidx != -1} {
set country_code [join [lindex $results [expr {$countryidx + 1}]]]
if {(![string equal $country_code Latitude]) && ([regexp {[A-Z]{2}} $country_code])} {
pIpcheckCountrySet
foreach {code name} [array get vIpcheckCountry] {
if {[string equal $code $country_code]} {
set country_name $name
break
}
}
unset vIpcheckCountry
if {[info exists country_name]} {
if {$vIpcheckTranslateCountry} {
set vIpcheckData(country) "$country_code, $country_name"
} else {set vIpcheckData(country) $country_code}
} else {set vIpcheckData(country) Unknown}
} else {set vIpcheckData(country) Unknown}
} else {set vIpcheckData(country) Unknown}
if {![string equal vIpcheckData(country) Unknown]} {
if {![string equal vIpcheckData(country) Unlisted]} {
set regionidx [lsearch -exact $results "State/Region"]
if {$regionidx != -1} {
set region_code [join [lindex $results [expr {$regionidx + 1}]]]
if {![string equal $region_code Zipcode]} {
if {[regexp {[A-Z0-9]{2}} $region_code]} {
append procedure "pIpcheckRegionSet" $country_code
if {[lsearch [info procs "pIpcheck*"] $procedure] != -1} {
$procedure
foreach {code region} [array get vIpcheckRegion] {
if {[string match $code $region_code]} {
set region_name $region
break
}
}
unset vIpcheckRegion
if {[info exists region_name]} {
set vIpcheckData(region) "$region_code, $region_name"
} else {set vIpcheckData(region) $region_code}
} else {set vIpcheckData(region) $region_code}
} else {
if {[regexp {[a-zA-Z0-9]} [string index $region_code 0]]} {
set vIpcheckData(region) $region_code
} else {set vIpcheckData(region) Unknown}
}
} else {set vIpcheckData(region) Unknown}
} else {set vIpcheckData(region) Unknown}
set cityidx [lsearch -exact $results "City"]
if {$cityidx != -1} {
set city_code [join [lindex $results [expr {$cityidx + 1}]]]
if {(![string equal $city_code State/Region]) && ([regexp {[a-zA-Z]} [string index $city_code 0]])} {
set vIpcheckData(city) $city_code
} else {set vIpcheckData(city) Unknown}
} else {set vIpcheckData(city) Unknown}
set latitudeidx [lsearch -exact $results "Latitude"]
if {$latitudeidx != -1} {
set latitude_code [join [lindex $results [expr {$latitudeidx + 1}]]]
if {(![string equal $latitude_code Longitude]) && (([string is double $latitude_code]) || ([string is integer $latitude_code]))} {
set vIpcheckData(latitude) $latitude_code
} else {set vIpcheckData(latitude) Unknown}
} else {set vIpcheckData(latitude) Unknown}
set longitudeidx [lsearch -exact $results "Longitude"]
if {$longitudeidx != -1} {
set longitude_code [join [lindex $results end]]
if {(![string equal $longitude_code Longitude]) && (([string is double $longitude_code]) || ([string is integer $longitude_code]))} {
set vIpcheckData(longitude) $longitude_code
} else {set vIpcheckData(longitude) Unknown}
} else {set vIpcheckData(longitude) Unknown}
} else {}
}
return 0
}
proc pIpcheckQuery {nick chan target} {
global vIpcheckClass
global vIpcheckData
global vIpcheckTarget
global vIpcheckType
if {![catch {set sock [socket -async www.mynameserver.com 80]}]} {
fconfigure $sock -buffering full -buffersize 5000
puts $sock "GET /city_from_ip.html?mainsearch=$target HTTP/1.1"
puts $sock "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
puts $sock "Host: www.mynameserver.com"
puts $sock "Connection: Close"
puts $sock ""
flush $sock
set data [read $sock]
close $sock
set start 0
foreach line [split $data \n] {
set newline [string trim [regsub -all -- {<[^>]+>} $line ""]]
set newline [string trim [regsub -all -- {&\S+;} $newline ""]]
if {[string length $newline] == 0} {continue}
if {[string equal $newline Results]} {set start 1}
if {[string match "You can quickly*" $newline]} {break}
if {$start} {
lappend results $newline
}
}
pIpcheckParse $results
set class [lrange [split $vIpcheckClass] 0 end-1]
set host [join [lindex [split $vIpcheckType] 2]]
if {![string equal $vIpcheckData(country) Unknown]} {
pIpcheckCompliance 001 0 $nick 0 $chan 0 $target $class $vIpcheckData(country) $vIpcheckData(region) $vIpcheckData(city) $vIpcheckData(latitude) $vIpcheckData(longitude) 0
} else {
switch -- [join [lindex [split $vIpcheckType] 0]] {
hostname {pIpcheckError 014 0 $nick 0 $chan 0 $target $host $class 0 0 0 0 0}
nick {
switch -- [join [lindex [split $vIpcheckType] 1]] {
hostname {pIpcheckError 013 0 $nick 0 $chan 0 $vIpcheckTarget $host $target $class 0 0 0 0}
numeric {pIpcheckError 012 0 $nick 0 $chan 0 $vIpcheckTarget $target $class 0 0 0 0 0}
}
}
numeric {pIpcheckError 011 0 $nick 0 $chan 0 $target $class 0 0 0 0 0 0}
}
}
} else {pIpcheckError 010 0 $nick 0 $chan 0 0 0 0 0 0 0 0 0}
return 0
}
proc pIpcheckReset {} {
global vIpcheckChannel
global vIpcheckClass
global vIpcheckData
global vIpcheckPending
global vIpcheckSource
global vIpcheckTarget
global vIpcheckType
global vIpcheckRaw311
global vIpcheckRaw318
if {[info exists vIpcheckChannel]} {unset vIpcheckChannel}
if {[info exists vIpcheckClass]} {unset vIpcheckClass}
if {[info exists vIpcheckData]} {unset vIpcheckData}
if {[info exists vIpcheckPending]} {unset vIpcheckPending}
if {[info exists vIpcheckSource]} {unset vIpcheckSource}
if {[info exists vIpcheckTarget]} {unset vIpcheckTarget}
if {[info exists vIpcheckType]} {unset vIpcheckType}
if {[info exists vIpcheckRaw311]} {unset vIpcheckRaw311}
if {[info exists vIpcheckRaw318]} {unset vIpcheckRaw318}
return 0
}
proc pIpcheckSyntax {command} {
switch -- $command {
ip {return "<hostname||nick||numeric>"}
ipclear {return ""}
}
}
proc pIpcheckTerminate {} {
foreach item [utimers] {
if {[string match "*pIpcheckCancel*" [join [lindex $item 1]]]} {
killutimer [join [lindex $item 2]]
}
}
pIpcheckReset
return 0
}
proc pIpcheckType {nick chan target} {
global vIpcheckClass
global vIpcheckTarget
global vIpcheckType
if {[regexp -- {\.} $target]} {
switch -- [pIpcheckNumeric $target] {
0 {
switch -- [pIpcheckHostname $target] {
0 {pIpcheckError 007 0 $nick 0 $chan 0 $target 0 0 0 0 0 0 0}
1 {
set vIpcheckType "hostname hostname $target"
dnslookup $target pIpcheckDns $nick $chan
}
}
}
1 {pIpcheckError 006 0 $nick 0 $chan 0 $target 0 0 0 0 0 0 0}
2 {
set vIpcheckType "numeric numeric $target"
set ip_info [pIpcheckClass $target]
set vIpcheckClass "[join [lrange [split $ip_info] 1 end]] $target"
switch -- [join [lindex [split $ip_info] 0]] {
1 - 2 - 3 - 4 - 5 - 6 - 7 {pIpcheckError 005 0 $nick 0 $chan 0 $target [join [lrange [split $vIpcheckClass] 0 end-1]] 0 0 0 0 0 0}
8 - 9 - 10 {
pIpcheckQuery $nick $chan $target
}
}
}
}
} else {
switch -- [pIpcheckNick $target] {
0 {pIpcheckError 004 0 $nick 0 $chan 0 $target 0 0 0 0 0 0 0}
1 {
if {[onchan $target]} {
set host [join [lindex [split [getchanhost $target] @] 1]]
switch -- [pIpcheckNumeric $host] {
0 {
set vIpcheckType "nick hostname $host"
dnslookup $host pIpcheckDns $nick $chan
}
2 {
set vIpcheckType "nick numeric $host"
set ip_info [pIpcheckClass $host]
set vIpcheckClass "[join [lrange [split $ip_info] 1 end]] $host"
pIpcheckQuery $nick $chan $host
}
}
} else {
putserv "WHOIS $target $target"
utimer 10 [list pIpcheckCancel $nick $vIpcheckTarget $chan]
}
}
}
}
return 0
}
# ---------- ACKNOWLEDGEMENT --------------------------------------------------------------------------------------------- #
putlog "ipcheck.tcl version $vIpcheckVersion by arfer loaded"
# thanks to Robb in DalNet #TCL who originally provided much of the socket code
# thanks to poutine in Dalnet #TCL for help with regexp/regsub syntax
# thanks to proprietors of www.mynameserver.com who offer use of excellent lookup tools, seemingly without legal restriction
# thanks to proprietors of www.statoids.com for providing region codes
# ---------- AUTO-LOAD --------------------------------------------------------------------------------------------------- #
if {[llength [glob -nocomplain -directory scripts/ipcheck -- region*.tcl]] != 0} {
foreach script [glob -directory scripts/ipcheck -- region*.tcl] {
source $script
}
}
# eof
Code: Select all
Tcl error [pIpcheckDns]: can't read "results": no such variable
Code: Select all
Tcl error [pIpcheckPubIp]: can't read "results": no such variable