diff options
author | Janik Kleinhoff <ilbelkyr@shalture.org> | 2016-10-28 13:48:16 +0000 |
---|---|---|
committer | Janik Kleinhoff <ilbelkyr@shalture.org> | 2016-10-28 14:12:19 +0000 |
commit | 3dda2775b73b29ca72f3996eb5788124950f9e70 (patch) | |
tree | 0a02aeffbfee3392c1d38e79338291cfea7cd771 | |
parent | 546df459147cf5842724d88428794eaf296cb879 (diff) | |
download | antispammeta-3dda2775b73b29ca72f3996eb5788124950f9e70.tar.bz2 antispammeta-3dda2775b73b29ca72f3996eb5788124950f9e70.tar.xz antispammeta-3dda2775b73b29ca72f3996eb5788124950f9e70.tar.zst |
Use DBIx::Class
For now this is a relatively quick-and-dirty transition, but this
enables us to reuse ASM::DB from the website. Yay
-rw-r--r-- | cpanfile | 2 | ||||
-rw-r--r-- | cpanfile.snapshot | 1373 | ||||
-rw-r--r-- | lib/ASM/Commander.pm | 169 | ||||
-rw-r--r-- | lib/ASM/DB.pm | 202 | ||||
-rw-r--r-- | lib/ASM/DB/Result/Actionlog.pm | 37 | ||||
-rw-r--r-- | lib/ASM/DB/Result/Alertlog.pm | 30 | ||||
-rw-r--r-- | lib/ASM/Event.pm | 12 | ||||
-rw-r--r-- | lib/ASM/Inspect.pm | 5 | ||||
-rw-r--r-- | lib/ASM/Log.pm | 122 | ||||
-rwxr-xr-x | meta.pl | 40 |
10 files changed, 1714 insertions, 278 deletions
@@ -21,5 +21,7 @@ requires 'URI::Escape', '3.31'; requires 'DBI', '1.63'; requires 'DBD::mysql', '4.025'; +requires 'DBIx::Class', '0.082840'; +requires 'DateTime::Format::MySQL', '0.06'; # vim: ft=perl diff --git a/cpanfile.snapshot b/cpanfile.snapshot index 6883846..8d2985b 100644 --- a/cpanfile.snapshot +++ b/cpanfile.snapshot @@ -1,5 +1,14 @@ # carton snapshot format: version 1.0 DISTRIBUTIONS + Algorithm-C3-0.10 + pathname: H/HA/HAARG/Algorithm-C3-0.10.tar.gz + provides: + Algorithm::C3 0.10 + requirements: + Carp 0.01 + ExtUtils::MakeMaker 0 + Test::More 0.47 + perl 5.006 Apache-Htgroup-1.23 pathname: R/RB/RBOW/Apache-Htgroup-1.23.tar.gz provides: @@ -21,6 +30,21 @@ DISTRIBUTIONS Array::Utils 0.5 requirements: ExtUtils::MakeMaker 0 + B-Hooks-EndOfScope-0.21 + pathname: E/ET/ETHER/B-Hooks-EndOfScope-0.21.tar.gz + provides: + B::Hooks::EndOfScope 0.21 + B::Hooks::EndOfScope::PP 0.21 + B::Hooks::EndOfScope::XS 0.21 + requirements: + ExtUtils::MakeMaker 0 + Module::Implementation 0.05 + Sub::Exporter::Progressive 0.001006 + Text::ParseWords 0 + Variable::Magic 0.48 + perl 5.008001 + strict 0 + warnings 0 CGI-4.32 pathname: L/LE/LEEJO/CGI-4.32.tar.gz provides: @@ -51,6 +75,144 @@ DISTRIBUTIONS strict 0 utf8 0 warnings 0 + Class-Accessor-0.34 + pathname: K/KA/KASEI/Class-Accessor-0.34.tar.gz + provides: + Class::Accessor 0.34 + Class::Accessor::Fast 0.34 + Class::Accessor::Faster 0.34 + requirements: + ExtUtils::MakeMaker 0 + base 1.01 + Class-Accessor-Chained-0.01 + pathname: R/RC/RCLAMP/Class-Accessor-Chained-0.01.tar.gz + provides: + Class::Accessor::Chained 0.01 + Class::Accessor::Chained::Fast undef + requirements: + Class::Accessor 0 + Test::More 0 + Class-Accessor-Grouped-0.10012 + pathname: R/RI/RIBASUSHI/Class-Accessor-Grouped-0.10012.tar.gz + provides: + Class::Accessor::Grouped 0.10012 + requirements: + Carp 0 + Class::XSAccessor 1.19 + ExtUtils::CBuilder 0.27 + ExtUtils::MakeMaker 6.59 + Module::Runtime 0.012 + Scalar::Util 0 + Sub::Name 0.05 + Test::Exception 0.31 + Test::More 0.88 + perl 5.006 + Class-C3-0.32 + pathname: H/HA/HAARG/Class-C3-0.32.tar.gz + provides: + Class::C3 0.32 + requirements: + Algorithm::C3 0.07 + ExtUtils::MakeMaker 0 + Scalar::Util 0 + perl 5.006 + Class-C3-Componentised-1.001000 + pathname: F/FR/FREW/Class-C3-Componentised-1.001000.tar.gz + provides: + Class::C3::Componentised 1.001000 + Class::C3::Componentised::ApplyHooks undef + requirements: + Carp 0 + Class::C3 0.20 + Class::Inspector 0 + ExtUtils::MakeMaker 6.42 + MRO::Compat 0 + Test::Exception 0 + perl 5.006002 + Class-Data-Inheritable-0.08 + pathname: T/TM/TMTM/Class-Data-Inheritable-0.08.tar.gz + provides: + Class::Data::Inheritable 0.08 + requirements: + ExtUtils::MakeMaker 0 + Class-Factory-Util-1.7 + pathname: D/DR/DROLSKY/Class-Factory-Util-1.7.tar.gz + provides: + Class::Factory::Util 1.7 + requirements: + Class-Inspector-1.28 + pathname: A/AD/ADAMK/Class-Inspector-1.28.tar.gz + provides: + Class::Inspector 1.28 + Class::Inspector::Functions 1.28 + requirements: + ExtUtils::MakeMaker 6.59 + File::Spec 0.80 + Test::More 0.47 + perl 5.006 + Class-Method-Modifiers-2.12 + pathname: E/ET/ETHER/Class-Method-Modifiers-2.12.tar.gz + provides: + Class::Method::Modifiers 2.12 + requirements: + B 0 + Carp 0 + Exporter 0 + ExtUtils::MakeMaker 0 + base 0 + perl 5.006 + strict 0 + warnings 0 + Class-Singleton-1.5 + pathname: S/SH/SHAY/Class-Singleton-1.5.tar.gz + provides: + Class::Singleton 1.5 + requirements: + ExtUtils::MakeMaker 0 + Class-XSAccessor-1.19 + pathname: S/SM/SMUELLER/Class-XSAccessor-1.19.tar.gz + provides: + Class::XSAccessor 1.19 + Class::XSAccessor::Array 1.19 + requirements: + ExtUtils::MakeMaker 0 + Test::More 0 + Time::HiRes 0 + XSLoader 0 + perl 5.008 + Clone-0.38 + pathname: G/GA/GARU/Clone-0.38.tar.gz + provides: + Clone 0.38 + requirements: + ExtUtils::MakeMaker 0 + Test::More 0 + Config-Any-0.27 + pathname: B/BR/BRICAS/Config-Any-0.27.tar.gz + provides: + Config::Any 0.27 + Config::Any::Base undef + Config::Any::General undef + Config::Any::INI undef + Config::Any::JSON undef + Config::Any::Perl undef + Config::Any::XML undef + Config::Any::YAML undef + requirements: + ExtUtils::MakeMaker 6.59 + Module::Pluggable::Object 3.6 + Test::More 0 + perl 5.006 + Context-Preserve-0.01 + pathname: J/JR/JROCKWAY/Context-Preserve-0.01.tar.gz + provides: + Context::Preserve 0.01 + requirements: + Exporter 0 + ExtUtils::MakeMaker 0 + Test::Exception 0 + Test::More 0 + ok 0 Crypt-PasswdMD5-1.40 pathname: R/RS/RSAVAGE/Crypt-PasswdMD5-1.40.tgz provides: @@ -61,6 +223,25 @@ DISTRIBUTIONS Test::More 0.94 strict 0 warnings 0 + DBD-SQLite-1.50 + pathname: I/IS/ISHIGAKI/DBD-SQLite-1.50.tar.gz + provides: + DBD::SQLite 1.50 + DBD::SQLite::Constants undef + DBD::SQLite::VirtualTable 1.50 + DBD::SQLite::VirtualTable::Cursor 1.50 + DBD::SQLite::VirtualTable::FileContent undef + DBD::SQLite::VirtualTable::FileContent::Cursor undef + DBD::SQLite::VirtualTable::PerlData undef + DBD::SQLite::VirtualTable::PerlData::Cursor undef + requirements: + DBI 1.57 + ExtUtils::MakeMaker 0 + File::Spec 0.82 + Test::Builder 0.86 + Test::More 0.47 + Tie::Hash 0 + perl 5.006 DBD-mysql-4.036 pathname: M/MI/MICHIELB/DBD-mysql-4.036.tar.gz provides: @@ -170,6 +351,144 @@ DISTRIBUTIONS ExtUtils::MakeMaker 6.48 Test::Simple 0.90 perl 5.008 + DBIx-Class-0.082840 + pathname: R/RI/RIBASUSHI/DBIx-Class-0.082840.tar.gz + provides: + DBIx::Class 0.082840 + DBIx::Class::AccessorGroup undef + DBIx::Class::Admin undef + DBIx::Class::CDBICompat undef + DBIx::Class::Core undef + DBIx::Class::Cursor undef + DBIx::Class::DB undef + DBIx::Class::Exception undef + DBIx::Class::FilterColumn undef + DBIx::Class::InflateColumn undef + DBIx::Class::InflateColumn::DateTime undef + DBIx::Class::InflateColumn::File undef + DBIx::Class::Optional::Dependencies undef + DBIx::Class::Ordered undef + DBIx::Class::PK undef + DBIx::Class::PK::Auto undef + DBIx::Class::Relationship undef + DBIx::Class::Relationship::Base undef + DBIx::Class::ResultClass::HashRefInflator undef + DBIx::Class::ResultSet undef + DBIx::Class::ResultSetColumn undef + DBIx::Class::ResultSetManager undef + DBIx::Class::ResultSource undef + DBIx::Class::ResultSource::Table undef + DBIx::Class::ResultSource::View undef + DBIx::Class::ResultSourceHandle undef + DBIx::Class::ResultSourceProxy::Table undef + DBIx::Class::Row undef + DBIx::Class::SQLMaker undef + DBIx::Class::SQLMaker::LimitDialects undef + DBIx::Class::SQLMaker::OracleJoins undef + DBIx::Class::Schema undef + DBIx::Class::Schema::Versioned undef + DBIx::Class::Serialize::Storable undef + DBIx::Class::StartupCheck undef + DBIx::Class::Storage undef + DBIx::Class::Storage::DBI undef + DBIx::Class::Storage::DBI::ACCESS undef + DBIx::Class::Storage::DBI::ADO undef + DBIx::Class::Storage::DBI::ADO::MS_Jet undef + DBIx::Class::Storage::DBI::ADO::MS_Jet::Cursor undef + DBIx::Class::Storage::DBI::ADO::Microsoft_SQL_Server undef + DBIx::Class::Storage::DBI::ADO::Microsoft_SQL_Server::Cursor undef + DBIx::Class::Storage::DBI::AutoCast undef + DBIx::Class::Storage::DBI::Cursor undef + DBIx::Class::Storage::DBI::DB2 undef + DBIx::Class::Storage::DBI::Firebird undef + DBIx::Class::Storage::DBI::Firebird::Common undef + DBIx::Class::Storage::DBI::IdentityInsert undef + DBIx::Class::Storage::DBI::Informix undef + DBIx::Class::Storage::DBI::InterBase undef + DBIx::Class::Storage::DBI::MSSQL undef + DBIx::Class::Storage::DBI::NoBindVars undef + DBIx::Class::Storage::DBI::ODBC undef + DBIx::Class::Storage::DBI::ODBC::ACCESS undef + DBIx::Class::Storage::DBI::ODBC::DB2_400_SQL undef + DBIx::Class::Storage::DBI::ODBC::Firebird undef + DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server undef + DBIx::Class::Storage::DBI::ODBC::SQL_Anywhere undef + DBIx::Class::Storage::DBI::Oracle undef + DBIx::Class::Storage::DBI::Oracle::Generic undef + DBIx::Class::Storage::DBI::Oracle::WhereJoins undef + DBIx::Class::Storage::DBI::Pg undef + DBIx::Class::Storage::DBI::Replicated undef + DBIx::Class::Storage::DBI::Replicated::Balancer undef + DBIx::Class::Storage::DBI::Replicated::Balancer::First undef + DBIx::Class::Storage::DBI::Replicated::Balancer::Random undef + DBIx::Class::Storage::DBI::Replicated::Pool undef + DBIx::Class::Storage::DBI::Replicated::Replicant undef + DBIx::Class::Storage::DBI::Replicated::WithDSN undef + DBIx::Class::Storage::DBI::SQLAnywhere undef + DBIx::Class::Storage::DBI::SQLAnywhere::Cursor undef + DBIx::Class::Storage::DBI::SQLite undef + DBIx::Class::Storage::DBI::Sybase undef + DBIx::Class::Storage::DBI::Sybase::ASE undef + DBIx::Class::Storage::DBI::Sybase::ASE::NoBindVars undef + DBIx::Class::Storage::DBI::Sybase::FreeTDS undef + DBIx::Class::Storage::DBI::Sybase::MSSQL undef + DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server undef + DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server::NoBindVars undef + DBIx::Class::Storage::DBI::UniqueIdentifier undef + DBIx::Class::Storage::DBI::mysql undef + DBIx::Class::Storage::Statistics undef + DBIx::Class::Storage::TxnScopeGuard undef + DBIx::Class::UTF8Columns undef + SQL::Translator::Parser::DBIx::Class 1.10 + SQL::Translator::Producer::DBIx::Class::File 0.1 + requirements: + Class::Accessor::Grouped 0.10012 + Class::C3::Componentised 1.0009 + Class::Inspector 1.24 + Config::Any 0.20 + Context::Preserve 0.01 + DBD::SQLite 1.29 + DBI 1.57 + Data::Dumper::Concise 2.020 + Data::Page 2.00 + Devel::GlobalDestruction 0.09 + ExtUtils::MakeMaker 6.59 + File::Temp 0.22 + Hash::Merge 0.12 + List::Util 1.16 + MRO::Compat 0.12 + Module::Find 0.07 + Moo 2.000 + Package::Stash 0.28 + Path::Class 0.18 + SQL::Abstract 1.81 + Scope::Guard 0.03 + Sub::Name 0.04 + Test::Deep 0.101 + Test::Exception 0.31 + Test::More 0.94 + Test::Warn 0.21 + Text::Balanced 2.00 + Try::Tiny 0.07 + namespace::clean 0.24 + perl 5.008001 + Data-Dumper-Concise-2.022 + pathname: F/FR/FREW/Data-Dumper-Concise-2.022.tar.gz + provides: + Data::Dumper::Concise 2.022 + Data::Dumper::Concise::Sugar undef + Devel::Dwarn undef + requirements: + ExtUtils::MakeMaker 6.59 + perl 5.006 + Data-Page-2.02 + pathname: L/LB/LBROCARD/Data-Page-2.02.tar.gz + provides: + Data::Page 2.02 + requirements: + Class::Accessor::Chained::Fast 0 + Test::Exception 0 + Test::More 0 Data-UUID-1.221 pathname: R/RJ/RJBS/Data-UUID-1.221.tar.gz provides: @@ -177,6 +496,527 @@ DISTRIBUTIONS requirements: Digest::MD5 0 ExtUtils::MakeMaker 0 + DateTime-1.39 + pathname: D/DR/DROLSKY/DateTime-1.39.tar.gz + provides: + DateTime 1.39 + DateTime::Duration 1.39 + DateTime::Helpers 1.39 + DateTime::Infinite 1.39 + DateTime::Infinite::Future 1.39 + DateTime::Infinite::Past 1.39 + DateTime::LeapSecond 1.39 + DateTime::PP 1.39 + DateTime::PPExtra 1.39 + DateTime::Types 1.39 + requirements: + Carp 0 + DateTime::Locale 1.06 + DateTime::TimeZone 2.02 + Dist::CheckConflicts 0.02 + ExtUtils::MakeMaker 0 + POSIX 0 + Params::ValidationCompiler 0.13 + Scalar::Util 0 + Specio 0.18 + Specio::Declare 0 + Specio::Exporter 0 + Specio::Library::Builtins 0 + Specio::Library::Numeric 0 + Specio::Library::String 0 + Try::Tiny 0 + XSLoader 0 + base 0 + integer 0 + namespace::autoclean 0.19 + overload 0 + parent 0 + perl 5.008004 + strict 0 + warnings 0 + warnings::register 0 + DateTime-Format-Builder-0.81 + pathname: D/DR/DROLSKY/DateTime-Format-Builder-0.81.tar.gz + provides: + DateTime::Format::Builder 0.81 + DateTime::Format::Builder::Parser 0.81 + DateTime::Format::Builder::Parser::Dispatch 0.81 + DateTime::Format::Builder::Parser::Quick 0.81 + DateTime::Format::Builder::Parser::Regex 0.81 + DateTime::Format::Builder::Parser::Strptime 0.81 + DateTime::Format::Builder::Parser::generic 0.81 + DateTime::Format::Fall undef + DateTime::Format::Simple undef + requirements: + Carp 0 + Class::Factory::Util 1.6 + DateTime 1.00 + DateTime::Format::Strptime 1.04 + ExtUtils::MakeMaker 6.30 + Params::Validate 0.72 + Scalar::Util 0 + base 0 + strict 0 + vars 0 + warnings 0 + DateTime-Format-MySQL-0.06 + pathname: X/XM/XMIKEW/DateTime-Format-MySQL-0.06.tar.gz + provides: + DateTime::Format::MySQL 0.06 + requirements: + DateTime 0 + DateTime::Format::Builder 0.6 + Module::Build 0 + DateTime-Format-Strptime-1.68 + pathname: D/DR/DROLSKY/DateTime-Format-Strptime-1.68.tar.gz + provides: + DateTime::Format::Strptime 1.68 + requirements: + Carp 0 + DateTime 1.00 + DateTime::Locale 0.45 + DateTime::TimeZone 0.79 + Exporter 0 + ExtUtils::MakeMaker 0 + Package::DeprecationManager 0.15 + Params::Validate 1.20 + Try::Tiny 0 + constant 0 + strict 0 + warnings 0 + DateTime-Locale-1.10 + pathname: D/DR/DROLSKY/DateTime-Locale-1.10.tar.gz + provides: + DateTime::Locale 1.10 + DateTime::Locale::Base 1.10 + DateTime::Locale::Catalog 1.10 + DateTime::Locale::Data 1.10 + DateTime::Locale::FromData 1.10 + DateTime::Locale::Util 1.10 + requirements: + Carp 0 + Dist::CheckConflicts 0.02 + Exporter 0 + ExtUtils::MakeMaker 0 + List::Util 1.45 + Params::ValidationCompiler 0.13 + Specio::Declare 0 + Specio::Library::String 0 + namespace::autoclean 0.19 + perl 5.008004 + strict 0 + warnings 0 + DateTime-TimeZone-2.06 + pathname: D/DR/DROLSKY/DateTime-TimeZone-2.06.tar.gz + provides: + DateTime::TimeZone 2.06 + DateTime::TimeZone::Africa::Abidjan 2.06 + DateTime::TimeZone::Africa::Accra 2.06 + DateTime::TimeZone::Africa::Algiers 2.06 + DateTime::TimeZone::Africa::Bissau 2.06 + DateTime::TimeZone::Africa::Cairo 2.06 + DateTime::TimeZone::Africa::Casablanca 2.06 + DateTime::TimeZone::Africa::Ceuta 2.06 + DateTime::TimeZone::Africa::El_Aaiun 2.06 + DateTime::TimeZone::Africa::Johannesburg 2.06 + DateTime::TimeZone::Africa::Khartoum 2.06 + DateTime::TimeZone::Africa::Lagos 2.06 + DateTime::TimeZone::Africa::Maputo 2.06 + DateTime::TimeZone::Africa::Monrovia 2.06 + DateTime::TimeZone::Africa::Nairobi 2.06 + DateTime::TimeZone::Africa::Ndjamena 2.06 + DateTime::TimeZone::Africa::Tripoli 2.06 + DateTime::TimeZone::Africa::Tunis 2.06 + DateTime::TimeZone::Africa::Windhoek 2.06 + DateTime::TimeZone::America::Adak 2.06 + DateTime::TimeZone::America::Anchorage 2.06 + DateTime::TimeZone::America::Araguaina 2.06 + DateTime::TimeZone::America::Argentina::Buenos_Aires 2.06 + DateTime::TimeZone::America::Argentina::Catamarca 2.06 + DateTime::TimeZone::America::Argentina::Cordoba 2.06 + DateTime::TimeZone::America::Argentina::Jujuy 2.06 + DateTime::TimeZone::America::Argentina::La_Rioja 2.06 + DateTime::TimeZone::America::Argentina::Mendoza 2.06 + DateTime::TimeZone::America::Argentina::Rio_Gallegos 2.06 + DateTime::TimeZone::America::Argentina::Salta 2.06 + DateTime::TimeZone::America::Argentina::San_Juan 2.06 + DateTime::TimeZone::America::Argentina::San_Luis 2.06 + DateTime::TimeZone::America::Argentina::Tucuman 2.06 + DateTime::TimeZone::America::Argentina::Ushuaia 2.06 + DateTime::TimeZone::America::Asuncion 2.06 + DateTime::TimeZone::America::Atikokan 2.06 + DateTime::TimeZone::America::Bahia 2.06 + DateTime::TimeZone::America::Bahia_Banderas 2.06 + DateTime::TimeZone::America::Barbados 2.06 + DateTime::TimeZone::America::Belem 2.06 + DateTime::TimeZone::America::Belize 2.06 + DateTime::TimeZone::America::Blanc_Sablon 2.06 + DateTime::TimeZone::America::Boa_Vista 2.06 + DateTime::TimeZone::America::Bogota 2.06 + DateTime::TimeZone::America::Boise 2.06 + DateTime::TimeZone::America::Cambridge_Bay 2.06 + DateTime::TimeZone::America::Campo_Grande 2.06 + DateTime::TimeZone::America::Cancun 2.06 + DateTime::TimeZone::America::Caracas 2.06 + DateTime::TimeZone::America::Cayenne 2.06 + DateTime::TimeZone::America::Chicago 2.06 + DateTime::TimeZone::America::Chihuahua 2.06 + DateTime::TimeZone::America::Costa_Rica 2.06 + DateTime::TimeZone::America::Creston 2.06 + DateTime::TimeZone::America::Cuiaba 2.06 + DateTime::TimeZone::America::Curacao 2.06 + DateTime::TimeZone::America::Danmarkshavn 2.06 + DateTime::TimeZone::America::Dawson 2.06 + DateTime::TimeZone::America::Dawson_Creek 2.06 + DateTime::TimeZone::America::Denver 2.06 + DateTime::TimeZone::America::Detroit 2.06 + DateTime::TimeZone::America::Edmonton 2.06 + DateTime::TimeZone::America::Eirunepe 2.06 + DateTime::TimeZone::America::El_Salvador 2.06 + DateTime::TimeZone::America::Fort_Nelson 2.06 + DateTime::TimeZone::America::Fortaleza 2.06 + DateTime::TimeZone::America::Glace_Bay 2.06 + DateTime::TimeZone::America::Godthab 2.06 + DateTime::TimeZone::America::Goose_Bay 2.06 + DateTime::TimeZone::America::Grand_Turk 2.06 + DateTime::TimeZone::America::Guatemala 2.06 + DateTime::TimeZone::America::Guayaquil 2.06 + DateTime::TimeZone::America::Guyana 2.06 + DateTime::TimeZone::America::Halifax 2.06 + DateTime::TimeZone::America::Havana 2.06 + DateTime::TimeZone::America::Hermosillo 2.06 + DateTime::TimeZone::America::Indiana::Indianapolis 2.06 + DateTime::TimeZone::America::Indiana::Knox 2.06 + DateTime::TimeZone::America::Indiana::Marengo 2.06 + DateTime::TimeZone::America::Indiana::Petersburg 2.06 + DateTime::TimeZone::America::Indiana::Tell_City 2.06 + DateTime::TimeZone::America::Indiana::Vevay 2.06 + DateTime::TimeZone::America::Indiana::Vincennes 2.06 + DateTime::TimeZone::America::Indiana::Winamac 2.06 + DateTime::TimeZone::America::Inuvik 2.06 + DateTime::TimeZone::America::Iqaluit 2.06 + DateTime::TimeZone::America::Jamaica 2.06 + DateTime::TimeZone::America::Juneau 2.06 + DateTime::TimeZone::America::Kentucky::Louisville 2.06 + DateTime::TimeZone::America::Kentucky::Monticello 2.06 + DateTime::TimeZone::America::La_Paz 2.06 + DateTime::TimeZone::America::Lima 2.06 + DateTime::TimeZone::America::Los_Angeles 2.06 + DateTime::TimeZone::America::Maceio 2.06 + DateTime::TimeZone::America::Managua 2.06 + DateTime::TimeZone::America::Manaus 2.06 + DateTime::TimeZone::America::Martinique 2.06 + DateTime::TimeZone::America::Matamoros 2.06 + DateTime::TimeZone::America::Mazatlan 2.06 + DateTime::TimeZone::America::Menominee 2.06 + DateTime::TimeZone::America::Merida 2.06 + DateTime::TimeZone::America::Metlakatla 2.06 + DateTime::TimeZone::America::Mexico_City 2.06 + DateTime::TimeZone::America::Miquelon 2.06 + DateTime::TimeZone::America::Moncton 2.06 + DateTime::TimeZone::America::Monterrey 2.06 + DateTime::TimeZone::America::Montevideo 2.06 + DateTime::TimeZone::America::Nassau 2.06 + DateTime::TimeZone::America::New_York 2.06 + DateTime::TimeZone::America::Nipigon 2.06 + DateTime::TimeZone::America::Nome 2.06 + DateTime::TimeZone::America::Noronha 2.06 + DateTime::TimeZone::America::North_Dakota::Beulah 2.06 + DateTime::TimeZone::America::North_Dakota::Center 2.06 + DateTime::TimeZone::America::North_Dakota::New_Salem 2.06 + DateTime::TimeZone::America::Ojinaga 2.06 + DateTime::TimeZone::America::Panama 2.06 + DateTime::TimeZone::America::Pangnirtung 2.06 + DateTime::TimeZone::America::Paramaribo 2.06 + DateTime::TimeZone::America::Phoenix 2.06 + DateTime::TimeZone::America::Port_au_Prince 2.06 + DateTime::TimeZone::America::Port_of_Spain 2.06 + DateTime::TimeZone::America::Porto_Velho 2.06 + DateTime::TimeZone::America::Puerto_Rico 2.06 + DateTime::TimeZone::America::Rainy_River 2.06 + DateTime::TimeZone::America::Rankin_Inlet 2.06 + DateTime::TimeZone::America::Recife 2.06 + DateTime::TimeZone::America::Regina 2.06 + DateTime::TimeZone::America::Resolute 2.06 + DateTime::TimeZone::America::Rio_Branco 2.06 + DateTime::TimeZone::America::Santarem 2.06 + DateTime::TimeZone::America::Santiago 2.06 + DateTime::TimeZone::America::Santo_Domingo 2.06 + DateTime::TimeZone::America::Sao_Paulo 2.06 + DateTime::TimeZone::America::Scoresbysund 2.06 + DateTime::TimeZone::America::Sitka 2.06 + DateTime::TimeZone::America::St_Johns 2.06 + DateTime::TimeZone::America::Swift_Current 2.06 + DateTime::TimeZone::America::Tegucigalpa 2.06 + DateTime::TimeZone::America::Thule 2.06 + DateTime::TimeZone::America::Thunder_Bay 2.06 + DateTime::TimeZone::America::Tijuana 2.06 + DateTime::TimeZone::America::Toronto 2.06 + DateTime::TimeZone::America::Vancouver 2.06 + DateTime::TimeZone::America::Whitehorse 2.06 + DateTime::TimeZone::America::Winnipeg 2.06 + DateTime::TimeZone::America::Yakutat 2.06 + DateTime::TimeZone::America::Yellowknife 2.06 + DateTime::TimeZone::Antarctica::Casey 2.06 + DateTime::TimeZone::Antarctica::Davis 2.06 + DateTime::TimeZone::Antarctica::DumontDUrville 2.06 + DateTime::TimeZone::Antarctica::Macquarie 2.06 + DateTime::TimeZone::Antarctica::Mawson 2.06 + DateTime::TimeZone::Antarctica::Palmer 2.06 + DateTime::TimeZone::Antarctica::Rothera 2.06 + DateTime::TimeZone::Antarctica::Syowa 2.06 + DateTime::TimeZone::Antarctica::Troll 2.06 + DateTime::TimeZone::Antarctica::Vostok 2.06 + DateTime::TimeZone::Asia::Almaty 2.06 + DateTime::TimeZone::Asia::Amman 2.06 + DateTime::TimeZone::Asia::Anadyr 2.06 + DateTime::TimeZone::Asia::Aqtau 2.06 + DateTime::TimeZone::Asia::Aqtobe 2.06 + DateTime::TimeZone::Asia::Ashgabat 2.06 + DateTime::TimeZone::Asia::Baghdad 2.06 + DateTime::TimeZone::Asia::Baku 2.06 + DateTime::TimeZone::Asia::Bangkok 2.06 + DateTime::TimeZone::Asia::Barnaul 2.06 + DateTime::TimeZone::Asia::Beirut 2.06 + DateTime::TimeZone::Asia::Bishkek 2.06 + DateTime::TimeZone::Asia::Brunei 2.06 + DateTime::TimeZone::Asia::Chita 2.06 + DateTime::TimeZone::Asia::Choibalsan 2.06 + DateTime::TimeZone::Asia::Colombo 2.06 + DateTime::TimeZone::Asia::Damascus 2.06 + DateTime::TimeZone::Asia::Dhaka 2.06 + DateTime::TimeZone::Asia::Dili 2.06 + DateTime::TimeZone::Asia::Dubai 2.06 + DateTime::TimeZone::Asia::Dushanbe 2.06 + DateTime::TimeZone::Asia::Gaza 2.06 + DateTime::TimeZone::Asia::Hebron 2.06 + DateTime::TimeZone::Asia::Ho_Chi_Minh 2.06 + DateTime::TimeZone::Asia::Hong_Kong 2.06 + DateTime::TimeZone::Asia::Hovd 2.06 + DateTime::TimeZone::Asia::Irkutsk 2.06 + DateTime::TimeZone::Asia::Jakarta 2.06 + DateTime::TimeZone::Asia::Jayapura 2.06 + DateTime::TimeZone::Asia::Jerusalem 2.06 + DateTime::TimeZone::Asia::Kabul 2.06 + DateTime::TimeZone::Asia::Kamchatka 2.06 + DateTime::TimeZone::Asia::Karachi 2.06 + DateTime::TimeZone::Asia::Kathmandu 2.06 + DateTime::TimeZone::Asia::Khandyga 2.06 + DateTime::TimeZone::Asia::Kolkata 2.06 + DateTime::TimeZone::Asia::Krasnoyarsk 2.06 + DateTime::TimeZone::Asia::Kuala_Lumpur 2.06 + DateTime::TimeZone::Asia::Kuching 2.06 + DateTime::TimeZone::Asia::Macau 2.06 + DateTime::TimeZone::Asia::Magadan 2.06 + DateTime::TimeZone::Asia::Makassar 2.06 + DateTime::TimeZone::Asia::Manila 2.06 + DateTime::TimeZone::Asia::Nicosia 2.06 + DateTime::TimeZone::Asia::Novokuznetsk 2.06 + DateTime::TimeZone::Asia::Novosibirsk 2.06 + DateTime::TimeZone::Asia::Omsk 2.06 + DateTime::TimeZone::Asia::Oral 2.06 + DateTime::TimeZone::Asia::Pontianak 2.06 + DateTime::TimeZone::Asia::Pyongyang 2.06 + DateTime::TimeZone::Asia::Qatar 2.06 + DateTime::TimeZone::Asia::Qyzylorda 2.06 + DateTime::TimeZone::Asia::Riyadh 2.06 + DateTime::TimeZone::Asia::Sakhalin 2.06 + DateTime::TimeZone::Asia::Samarkand 2.06 + DateTime::TimeZone::Asia::Seoul 2.06 + DateTime::TimeZone::Asia::Shanghai 2.06 + DateTime::TimeZone::Asia::Singapore 2.06 + DateTime::TimeZone::Asia::Srednekolymsk 2.06 + DateTime::TimeZone::Asia::Taipei 2.06 + DateTime::TimeZone::Asia::Tashkent 2.06 + DateTime::TimeZone::Asia::Tbilisi 2.06 + DateTime::TimeZone::Asia::Tehran 2.06 + DateTime::TimeZone::Asia::Thimphu 2.06 + DateTime::TimeZone::Asia::Tokyo 2.06 + DateTime::TimeZone::Asia::Tomsk 2.06 + DateTime::TimeZone::Asia::Ulaanbaatar 2.06 + DateTime::TimeZone::Asia::Urumqi 2.06 + DateTime::TimeZone::Asia::Ust_Nera 2.06 + DateTime::TimeZone::Asia::Vladivostok 2.06 + DateTime::TimeZone::Asia::Yakutsk 2.06 + DateTime::TimeZone::Asia::Yangon 2.06 + DateTime::TimeZone::Asia::Yekaterinburg 2.06 + DateTime::TimeZone::Asia::Yerevan 2.06 + DateTime::TimeZone::Atlantic::Azores 2.06 + DateTime::TimeZone::Atlantic::Bermuda 2.06 + DateTime::TimeZone::Atlantic::Canary 2.06 + DateTime::TimeZone::Atlantic::Cape_Verde 2.06 + DateTime::TimeZone::Atlantic::Faroe 2.06 + DateTime::TimeZone::Atlantic::Madeira 2.06 + DateTime::TimeZone::Atlantic::Reykjavik 2.06 + DateTime::TimeZone::Atlantic::South_Georgia 2.06 + DateTime::TimeZone::Atlantic::Stanley 2.06 + DateTime::TimeZone::Australia::Adelaide 2.06 + DateTime::TimeZone::Australia::Brisbane 2.06 + DateTime::TimeZone::Australia::Broken_Hill 2.06 + DateTime::TimeZone::Australia::Currie 2.06 + DateTime::TimeZone::Australia::Darwin 2.06 + DateTime::TimeZone::Australia::Eucla 2.06 + DateTime::TimeZone::Australia::Hobart 2.06 + DateTime::TimeZone::Australia::Lindeman 2.06 + DateTime::TimeZone::Australia::Lord_Howe 2.06 + DateTime::TimeZone::Australia::Melbourne 2.06 + DateTime::TimeZone::Australia::Perth 2.06 + DateTime::TimeZone::Australia::Sydney 2.06 + DateTime::TimeZone::CET 2.06 + DateTime::TimeZone::CST6CDT 2.06 + DateTime::TimeZone::Catalog 2.06 + DateTime::TimeZone::EET 2.06 + DateTime::TimeZone::EST 2.06 + DateTime::TimeZone::EST5EDT 2.06 + DateTime::TimeZone::Europe::Amsterdam 2.06 + DateTime::TimeZone::Europe::Andorra 2.06 + DateTime::TimeZone::Europe::Astrakhan 2.06 + DateTime::TimeZone::Europe::Athens 2.06 + DateTime::TimeZone::Europe::Belgrade 2.06 + DateTime::TimeZone::Europe::Berlin 2.06 + DateTime::TimeZone::Europe::Brussels 2.06 + DateTime::TimeZone::Europe::Bucharest 2.06 + DateTime::TimeZone::Europe::Budapest 2.06 + DateTime::TimeZone::Europe::Chisinau 2.06 + DateTime::TimeZone::Europe::Copenhagen 2.06 + DateTime::TimeZone::Europe::Dublin 2.06 + DateTime::TimeZone::Europe::Gibraltar 2.06 + DateTime::TimeZone::Europe::Helsinki 2.06 + DateTime::TimeZone::Europe::Istanbul 2.06 + DateTime::TimeZone::Europe::Kaliningrad 2.06 + DateTime::TimeZone::Europe::Kiev 2.06 + DateTime::TimeZone::Europe::Kirov 2.06 + DateTime::TimeZone::Europe::Lisbon 2.06 + DateTime::TimeZone::Europe::London 2.06 + DateTime::TimeZone::Europe::Luxembourg 2.06 + DateTime::TimeZone::Europe::Madrid 2.06 + DateTime::TimeZone::Europe::Malta 2.06 + DateTime::TimeZone::Europe::Minsk 2.06 + DateTime::TimeZone::Europe::Monaco 2.06 + DateTime::TimeZone::Europe::Moscow 2.06 + DateTime::TimeZone::Europe::Oslo 2.06 + DateTime::TimeZone::Europe::Paris 2.06 + DateTime::TimeZone::Europe::Prague 2.06 + DateTime::TimeZone::Europe::Riga 2.06 + DateTime::TimeZone::Europe::Rome 2.06 + DateTime::TimeZone::Europe::Samara 2.06 + DateTime::TimeZone::Europe::Simferopol 2.06 + DateTime::TimeZone::Europe::Sofia 2.06 + DateTime::TimeZone::Europe::Stockholm 2.06 + DateTime::TimeZone::Europe::Tallinn 2.06 + DateTime::TimeZone::Europe::Tirane 2.06 + DateTime::TimeZone::Europe::Ulyanovsk 2.06 + DateTime::TimeZone::Europe::Uzhgorod 2.06 + DateTime::TimeZone::Europe::Vienna 2.06 + DateTime::TimeZone::Europe::Vilnius 2.06 + DateTime::TimeZone::Europe::Volgograd 2.06 + DateTime::TimeZone::Europe::Warsaw 2.06 + DateTime::TimeZone::Europe::Zaporozhye 2.06 + DateTime::TimeZone::Europe::Zurich 2.06 + DateTime::TimeZone::Floating 2.06 + DateTime::TimeZone::HST 2.06 + DateTime::TimeZone::Indian::Chagos 2.06 + DateTime::TimeZone::Indian::Christmas 2.06 + DateTime::TimeZone::Indian::Cocos 2.06 + DateTime::TimeZone::Indian::Kerguelen 2.06 + DateTime::TimeZone::Indian::Mahe 2.06 + DateTime::TimeZone::Indian::Maldives 2.06 + DateTime::TimeZone::Indian::Mauritius 2.06 + DateTime::TimeZone::Indian::Reunion 2.06 + DateTime::TimeZone::Local 2.06 + DateTime::TimeZone::Local::Android 2.06 + DateTime::TimeZone::Local::Unix 2.06 + DateTime::TimeZone::Local::VMS 2.06 + DateTime::TimeZone::MET 2.06 + DateTime::TimeZone::MST 2.06 + DateTime::TimeZone::MST7MDT 2.06 + DateTime::TimeZone::OffsetOnly 2.06 + DateTime::TimeZone::OlsonDB 2.06 + DateTime::TimeZone::OlsonDB::Change 2.06 + DateTime::TimeZone::OlsonDB::Observance 2.06 + DateTime::TimeZone::OlsonDB::Rule 2.06 + DateTime::TimeZone::OlsonDB::Zone 2.06 + DateTime::TimeZone::PST8PDT 2.06 + DateTime::TimeZone::Pacific::Apia 2.06 + DateTime::TimeZone::Pacific::Auckland 2.06 + DateTime::TimeZone::Pacific::Bougainville 2.06 + DateTime::TimeZone::Pacific::Chatham 2.06 + DateTime::TimeZone::Pacific::Chuuk 2.06 + DateTime::TimeZone::Pacific::Easter 2.06 + DateTime::TimeZone::Pacific::Efate 2.06 + DateTime::TimeZone::Pacific::Enderbury 2.06 + DateTime::TimeZone::Pacific::Fakaofo 2.06 + DateTime::TimeZone::Pacific::Fiji 2.06 + DateTime::TimeZone::Pacific::Funafuti 2.06 + DateTime::TimeZone::Pacific::Galapagos 2.06 + DateTime::TimeZone::Pacific::Gambier 2.06 + DateTime::TimeZone::Pacific::Guadalcanal 2.06 + DateTime::TimeZone::Pacific::Guam 2.06 + DateTime::TimeZone::Pacific::Honolulu 2.06 + DateTime::TimeZone::Pacific::Kiritimati 2.06 + DateTime::TimeZone::Pacific::Kosrae 2.06 + DateTime::TimeZone::Pacific::Kwajalein 2.06 + DateTime::TimeZone::Pacific::Majuro 2.06 + DateTime::TimeZone::Pacific::Marquesas 2.06 + DateTime::TimeZone::Pacific::Nauru 2.06 + DateTime::TimeZone::Pacific::Niue 2.06 + DateTime::TimeZone::Pacific::Norfolk 2.06 + DateTime::TimeZone::Pacific::Noumea 2.06 + DateTime::TimeZone::Pacific::Pago_Pago 2.06 + DateTime::TimeZone::Pacific::Palau 2.06 + DateTime::TimeZone::Pacific::Pitcairn 2.06 + DateTime::TimeZone::Pacific::Pohnpei 2.06 + DateTime::TimeZone::Pacific::Port_Moresby 2.06 + DateTime::TimeZone::Pacific::Rarotonga 2.06 + DateTime::TimeZone::Pacific::Tahiti 2.06 + DateTime::TimeZone::Pacific::Tarawa 2.06 + DateTime::TimeZone::Pacific::Tongatapu 2.06 + DateTime::TimeZone::Pacific::Wake 2.06 + DateTime::TimeZone::Pacific::Wallis 2.06 + DateTime::TimeZone::UTC 2.06 + DateTime::TimeZone::WET 2.06 + requirements: + Class::Singleton 1.03 + Cwd 3 + ExtUtils::MakeMaker 0 + File::Basename 0 + File::Compare 0 + File::Find 0 + File::Spec 0 + List::Util 1.33 + Module::Runtime 0 + Params::ValidationCompiler 0.13 + Specio::Library::Builtins 0 + Specio::Library::String 0 + Try::Tiny 0 + constant 0 + namespace::autoclean 0 + parent 0 + perl 5.008004 + strict 0 + warnings 0 + Devel-GlobalDestruction-0.13 + pathname: H/HA/HAARG/Devel-GlobalDestruction-0.13.tar.gz + provides: + Devel::GlobalDestruction 0.13 + requirements: + ExtUtils::CBuilder 0.27 + ExtUtils::MakeMaker 0 + Sub::Exporter::Progressive 0.001011 + perl 5.006 + Devel-StackTrace-2.01 + pathname: D/DR/DROLSKY/Devel-StackTrace-2.01.tar.gz + provides: + Devel::StackTrace 2.01 + Devel::StackTrace::Frame 2.01 + requirements: + ExtUtils::MakeMaker 0 + File::Spec 0 + Scalar::Util 0 + overload 0 + perl 5.006 + strict 0 + warnings 0 Digest-HMAC-1.03 pathname: G/GA/GAAS/Digest-HMAC-1.03.tar.gz provides: @@ -188,6 +1028,18 @@ DISTRIBUTIONS Digest::SHA 1 ExtUtils::MakeMaker 0 perl 5.004 + Dist-CheckConflicts-0.11 + pathname: D/DO/DOY/Dist-CheckConflicts-0.11.tar.gz + provides: + Dist::CheckConflicts 0.11 + requirements: + Carp 0 + Exporter 0 + ExtUtils::MakeMaker 6.30 + Module::Runtime 0.009 + base 0 + strict 0 + warnings 0 Encode-Locale-1.05 pathname: G/GA/GAAS/Encode-Locale-1.05.tar.gz provides: @@ -197,6 +1049,34 @@ DISTRIBUTIONS Encode::Alias 0 ExtUtils::MakeMaker 0 perl 5.008 + Eval-Closure-0.14 + pathname: D/DO/DOY/Eval-Closure-0.14.tar.gz + provides: + Eval::Closure 0.14 + requirements: + Carp 0 + Exporter 0 + ExtUtils::MakeMaker 0 + Scalar::Util 0 + constant 0 + overload 0 + strict 0 + warnings 0 + Exception-Class-1.40 + pathname: D/DR/DROLSKY/Exception-Class-1.40.tar.gz + provides: + Exception::Class 1.40 + Exception::Class::Base 1.40 + requirements: + Class::Data::Inheritable 0.02 + Devel::StackTrace 2.00 + ExtUtils::MakeMaker 0 + Scalar::Util 0 + base 0 + overload 0 + perl 5.008001 + strict 0 + warnings 0 File-Listing-6.04 pathname: G/GA/GAAS/File-Listing-6.04.tar.gz provides: @@ -354,6 +1234,14 @@ DISTRIBUTIONS ExtUtils::MakeMaker 6.36 Socket 1.94 Test::More 0 + Hash-Merge-0.200 + pathname: R/RE/REHSACK/Hash-Merge-0.200.tar.gz + provides: + Hash::Merge 0.200 + requirements: + Clone 0 + ExtUtils::MakeMaker 0 + perl 5.008001 IO-All-0.86 pathname: I/IN/INGY/IO-All-0.86.tar.gz provides: @@ -417,6 +1305,14 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 perl 5.006002 + MRO-Compat-0.12 + pathname: B/BO/BOBTFISH/MRO-Compat-0.12.tar.gz + provides: + MRO::Compat 0.12 + requirements: + ExtUtils::MakeMaker 6.59 + Test::More 0.47 + perl 5.006 Module-Build-0.4220 pathname: L/LE/LEONT/Module-Build-0.4220.tar.gz provides: @@ -467,6 +1363,86 @@ DISTRIBUTIONS Text::ParseWords 0 perl 5.006001 version 0.87 + Module-Find-0.13 + pathname: C/CR/CRENZ/Module-Find-0.13.tar.gz + provides: + Module::Find 0.13 + ModuleFindTest undef + ModuleFindTest::SubMod undef + ModuleFindTest::SubMod::SubSubMod undef + requirements: + ExtUtils::MakeMaker 0 + File::Find 0 + File::Spec 0 + Test::More 0 + perl 5.006001 + Module-Implementation-0.09 + pathname: D/DR/DROLSKY/Module-Implementation-0.09.tar.gz + provides: + Module::Implementation 0.09 + requirements: + Carp 0 + ExtUtils::MakeMaker 0 + Module::Runtime 0.012 + Try::Tiny 0 + strict 0 + warnings 0 + Module-Pluggable-5.2 + pathname: S/SI/SIMONW/Module-Pluggable-5.2.tar.gz + provides: + Devel::InnerPackage 0.4 + Module::Pluggable 5.2 + Module::Pluggable::Object 5.2 + requirements: + Exporter 5.57 + ExtUtils::MakeMaker 0 + File::Basename 0 + File::Find 0 + File::Spec 3.00 + File::Spec::Functions 0 + if 0 + perl 5.00503 + strict 0 + Module-Runtime-0.014 + pathname: Z/ZE/ZEFRAM/Module-Runtime-0.014.tar.gz + provides: + Module::Runtime 0.014 + requirements: + Module::Build 0 + Test::More 0 + perl 5.006 + strict 0 + warnings 0 + Moo-2.002004 + pathname: H/HA/HAARG/Moo-2.002004.tar.gz + provides: + Method::Generate::Accessor undef + Method::Generate::BuildAll undef + Method::Generate::Constructor undef + Method::Generate::DemolishAll undef + Moo 2.002004 + Moo::HandleMoose undef + Moo::HandleMoose::FakeConstructor undef + Moo::HandleMoose::FakeMetaClass undef + Moo::HandleMoose::_TypeMap undef + Moo::Object undef + Moo::Role 2.002004 + Moo::_Utils undef + Moo::_mro undef + Moo::_strictures undef + Moo::sification undef + Sub::Defer 2.002004 + Sub::Quote 2.002004 + oo undef + requirements: + Class::Method::Modifiers 1.1 + Devel::GlobalDestruction 0.11 + Exporter 5.57 + ExtUtils::MakeMaker 0 + Module::Runtime 0.014 + Role::Tiny 2.000002 + Scalar::Util 0 + perl 5.006 Mozilla-CA-20160104 pathname: A/AB/ABH/Mozilla-CA-20160104.tar.gz provides: @@ -624,6 +1600,50 @@ DISTRIBUTIONS MIME::Base64 0 Test::More 0.60_01 perl 5.005 + Package-DeprecationManager-0.17 + pathname: D/DR/DROLSKY/Package-DeprecationManager-0.17.tar.gz + provides: + Package::DeprecationManager 0.17 + requirements: + Carp 0 + ExtUtils::MakeMaker 0 + List::Util 1.33 + Package::Stash 0 + Params::Util 0 + Sub::Install 0 + Sub::Name 0 + strict 0 + warnings 0 + Package-Stash-0.37 + pathname: D/DO/DOY/Package-Stash-0.37.tar.gz + provides: + Package::Stash 0.37 + Package::Stash::PP 0.37 + requirements: + B 0 + Carp 0 + Config 0 + Dist::CheckConflicts 0.02 + ExtUtils::MakeMaker 0 + File::Spec 0 + Getopt::Long 0 + Module::Implementation 0.06 + Package::Stash::XS 0.26 + Scalar::Util 0 + Symbol 0 + Text::ParseWords 0 + constant 0 + strict 0 + warnings 0 + Package-Stash-XS-0.28 + pathname: D/DO/DOY/Package-Stash-XS-0.28.tar.gz + provides: + Package::Stash::XS 0.28 + requirements: + ExtUtils::MakeMaker 6.30 + XSLoader 0 + strict 0 + warnings 0 PadWalker-2.2 pathname: R/RO/ROBIN/PadWalker-2.2.tar.gz provides: @@ -631,6 +1651,76 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 perl 5.008001 + Params-Util-1.07 + pathname: A/AD/ADAMK/Params-Util-1.07.tar.gz + provides: + Params::Util 1.07 + requirements: + ExtUtils::CBuilder 0.27 + ExtUtils::MakeMaker 6.52 + File::Spec 0.80 + Scalar::Util 1.18 + Test::More 0.42 + perl 5.00503 + Params-Validate-1.26 + pathname: D/DR/DROLSKY/Params-Validate-1.26.tar.gz + provides: + Params::Validate 1.26 + Params::Validate::Constants 1.26 + Params::Validate::PP 1.26 + Params::Validate::XS 1.26 + requirements: + Carp 0 + Exporter 0 + ExtUtils::CBuilder 0 + Module::Build 0.28 + Module::Implementation 0 + Scalar::Util 1.10 + XSLoader 0 + perl 5.008001 + strict 0 + vars 0 + warnings 0 + Params-ValidationCompiler-0.13 + pathname: D/DR/DROLSKY/Params-ValidationCompiler-0.13.tar.gz + provides: + Params::ValidationCompiler 0.13 + Params::ValidationCompiler::Compiler 0.13 + Params::ValidationCompiler::Exceptions 0.13 + requirements: + Eval::Closure 0 + Exception::Class 0 + Exporter 0 + ExtUtils::MakeMaker 0 + Scalar::Util 0 + overload 0 + strict 0 + warnings 0 + Path-Class-0.37 + pathname: K/KW/KWILLIAMS/Path-Class-0.37.tar.gz + provides: + Path::Class 0.37 + Path::Class::Dir 0.37 + Path::Class::Entity 0.37 + Path::Class::File 0.37 + requirements: + Carp 0 + Cwd 0 + Exporter 0 + ExtUtils::MakeMaker 6.30 + File::Copy 0 + File::Path 0 + File::Spec 3.26 + File::Temp 0 + File::stat 0 + IO::Dir 0 + IO::File 0 + Module::Build 0.3601 + Perl::OSType 0 + Scalar::Util 0 + overload 0 + parent 0 + strict 0 Regexp-Wildcards-1.05 pathname: V/VP/VPIT/Regexp-Wildcards-1.05.tar.gz provides: @@ -641,6 +1731,35 @@ DISTRIBUTIONS Scalar::Util 0 Text::Balanced 0 perl 5.006 + Role-Tiny-2.000003 + pathname: H/HA/HAARG/Role-Tiny-2.000003.tar.gz + provides: + Role::Tiny 2.000003 + Role::Tiny::With 2.000003 + requirements: + Exporter 5.57 + perl 5.006 + SQL-Abstract-1.81 + pathname: R/RI/RIBASUSHI/SQL-Abstract-1.81.tar.gz + provides: + SQL::Abstract 1.81 + SQL::Abstract::Test undef + SQL::Abstract::Tree undef + requirements: + Exporter 5.57 + ExtUtils::MakeMaker 6.59 + Hash::Merge 0.12 + List::Util 0 + MRO::Compat 0.12 + Moo 1.004002 + Scalar::Util 0 + Storable 0 + Test::Deep 0.101 + Test::Exception 0.31 + Test::More 0.88 + Test::Warn 0 + Text::Balanced 2.00 + perl 5.006 Safe-Hole-0.13 pathname: T/TO/TODDR/Safe-Hole-0.13.tar.gz provides: @@ -649,6 +1768,84 @@ DISTRIBUTIONS ExtUtils::CBuilder 0 Module::Build 0.35 Test::More 0.40 + Scalar-List-Utils-1.46 + pathname: P/PE/PEVANS/Scalar-List-Utils-1.46.tar.gz + provides: + List::Util 1.46 + List::Util::XS 1.46 + Scalar::Util 1.46 + Sub::Util 1.46 + requirements: + ExtUtils::MakeMaker 0 + Test::More 0 + perl 5.006 + Scope-Guard-0.21 + pathname: C/CH/CHOCOLATE/Scope-Guard-0.21.tar.gz + provides: + Scope::Guard 0.21 + requirements: + ExtUtils::MakeMaker 0 + Test::More 0 + perl 5.006001 + Specio-0.30 + pathname: D/DR/DROLSKY/Specio-0.30.tar.gz + provides: + Specio 0.30 + Specio::Coercion 0.30 + Specio::Constraint::AnyCan 0.30 + Specio::Constraint::AnyDoes 0.30 + Specio::Constraint::AnyIsa 0.30 + Specio::Constraint::Enum 0.30 + Specio::Constraint::Intersection 0.30 + Specio::Constraint::ObjectCan 0.30 + Specio::Constraint::ObjectDoes 0.30 + Specio::Constraint::ObjectIsa 0.30 + Specio::Constraint::Parameterizable 0.30 + Specio::Constraint::Parameterized 0.30 + Specio::Constraint::Role::CanType 0.30 + Specio::Constraint::Role::DoesType 0.30 + Specio::Constraint::Role::Interface 0.30 + Specio::Constraint::Role::IsaType 0.30 + Specio::Constraint::Simple 0.30 + Specio::Constraint::Union 0.30 + Specio::Declare 0.30 + Specio::DeclaredAt 0.30 + Specio::Exception 0.30 + Specio::Exporter 0.30 + Specio::Helpers 0.30 + Specio::Library::Builtins 0.30 + Specio::Library::Numeric 0.30 + Specio::Library::Perl 0.30 + Specio::Library::String 0.30 + Specio::OO 0.30 + Specio::PartialDump 0.30 + Specio::Registry 0.30 + Specio::Role::Inlinable 0.30 + Specio::TypeChecks 0.30 + Test::Specio 0.30 + requirements: + B 0 + Carp 0 + Devel::StackTrace 0 + Eval::Closure 0 + Exporter 0 + ExtUtils::MakeMaker 0 + IO::File 0 + List::Util 1.33 + MRO::Compat 0 + Role::Tiny 1.003003 + Role::Tiny::With 0 + Scalar::Util 0 + Storable 0 + Test::Fatal 0 + Test::More 0.96 + overload 0 + parent 0 + perl 5.008 + re 0 + strict 0 + version 0.83 + warnings 0 String-CRC32-1.5 pathname: S/SO/SOENKE/String-CRC32-1.5.tar.gz provides: @@ -674,6 +1871,127 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 + Sub-Exporter-Progressive-0.001013 + pathname: F/FR/FREW/Sub-Exporter-Progressive-0.001013.tar.gz + provides: + Sub::Exporter::Progressive 0.001013 + requirements: + ExtUtils::MakeMaker 0 + Sub-Identify-0.12 + pathname: R/RG/RGARCIA/Sub-Identify-0.12.tar.gz + provides: + Sub::Identify 0.12 + requirements: + ExtUtils::MakeMaker 0 + Test::More 0 + Sub-Install-0.928 + pathname: R/RJ/RJBS/Sub-Install-0.928.tar.gz + provides: + Sub::Install 0.928 + requirements: + B 0 + Carp 0 + ExtUtils::MakeMaker 6.30 + Scalar::Util 0 + strict 0 + warnings 0 + Sub-Name-0.21 + pathname: E/ET/ETHER/Sub-Name-0.21.tar.gz + provides: + Sub::Name 0.21 + requirements: + Exporter 5.57 + ExtUtils::MakeMaker 0 + XSLoader 0 + perl 5.006 + strict 0 + warnings 0 + Sub-Uplevel-0.2600 + pathname: D/DA/DAGOLDEN/Sub-Uplevel-0.2600.tar.gz + provides: + Sub::Uplevel 0.2600 + requirements: + Carp 0 + ExtUtils::MakeMaker 6.17 + constant 0 + perl 5.006 + strict 0 + warnings 0 + Test-Deep-1.123 + pathname: R/RJ/RJBS/Test-Deep-1.123.tar.gz + provides: + Test::Deep 1.123 + Test::Deep::All undef + Test::Deep::Any undef + Test::Deep::Array undef + Test::Deep::ArrayEach undef + Test::Deep::ArrayElementsOnly undef + Test::Deep::ArrayLength undef + Test::Deep::ArrayLengthOnly undef + Test::Deep::Blessed undef + Test::Deep::Boolean undef + Test::Deep::Cache undef + Test::Deep::Cache::Simple undef + Test::Deep::Class undef + Test::Deep::Cmp undef + Test::Deep::Code undef + Test::Deep::Hash undef + Test::Deep::HashEach undef + Test::Deep::HashElements undef + Test::Deep::HashKeys undef + Test::Deep::HashKeysOnly undef + Test::Deep::Ignore undef + Test::Deep::Isa undef + Test::Deep::ListMethods undef + Test::Deep::MM undef + Test::Deep::Methods undef + Test::Deep::NoTest undef + Test::Deep::None undef + Test::Deep::Number undef + Test::Deep::Obj undef + Test::Deep::Ref undef + Test::Deep::RefType undef + Test::Deep::Regexp undef + Test::Deep::RegexpMatches undef + Test::Deep::RegexpOnly undef + Test::Deep::RegexpRef undef + Test::Deep::RegexpRefOnly undef + Test::Deep::RegexpVersion undef + Test::Deep::ScalarRef undef + Test::Deep::ScalarRefOnly undef + Test::Deep::Set undef + Test::Deep::Shallow undef + Test::Deep::Stack undef + Test::Deep::String undef + Test::Deep::SubHash undef + Test::Deep::SubHashElements undef + Test::Deep::SubHashKeys undef + Test::Deep::SubHashKeysOnly undef + Test::Deep::SuperHash undef + Test::Deep::SuperHashElements undef + Test::Deep::SuperHashKeys undef + Test::Deep::SuperHashKeysOnly undef + requirements: + ExtUtils::MakeMaker 0 + List::Util 1.09 + Scalar::Util 1.09 + Test::Builder 0 + Test-Exception-0.43 + pathname: E/EX/EXODIST/Test-Exception-0.43.tar.gz + provides: + Test::Exception 0.43 + requirements: + Carp 0 + Exporter 0 + ExtUtils::MakeMaker 0 + Sub::Uplevel 0.18 + Test::Builder 0.7 + Test::Builder::Tester 1.07 + Test::Harness 2.03 + base 0 + perl 5.006001 + strict 0 + warnings 0 Test-Fatal-0.014 pathname: R/RJ/RJBS/Test-Fatal-0.014.tar.gz provides: @@ -725,6 +2043,20 @@ DISTRIBUTIONS Test::SharedFork 0.29 Time::HiRes 0 perl 5.008001 + Test-Warn-0.30 + pathname: C/CH/CHORNY/Test-Warn-0.30.tar.gz + provides: + Test::Warn 0.30 + Test::Warn::Categorization 0.30 + requirements: + Carp 1.22 + ExtUtils::MakeMaker 0 + File::Spec 0 + Sub::Uplevel 0.12 + Test::Builder 0.13 + Test::Builder::Tester 1.02 + Test::More 0 + perl 5.006 Text-LevenshteinXS-0.03 pathname: J/JG/JGOLDBERG/Text-LevenshteinXS-0.03.tar.gz provides: @@ -816,6 +2148,25 @@ DISTRIBUTIONS parent 0 perl 5.008001 utf8 0 + Variable-Magic-0.60 + pathname: V/VP/VPIT/Variable-Magic-0.60.tar.gz + provides: + Variable::Magic 0.60 + requirements: + Carp 0 + Config 0 + Exporter 0 + ExtUtils::MakeMaker 0 + IO::Handle 0 + IO::Select 0 + IPC::Open3 0 + POSIX 0 + Socket 0 + Test::More 0 + XSLoader 0 + base 0 + lib 0 + perl 5.008 WWW-RobotRules-6.02 pathname: G/GA/GAAS/WWW-RobotRules-6.02.tar.gz provides: @@ -967,3 +2318,25 @@ DISTRIBUTIONS URI::Escape 0 WWW::RobotRules 6 perl 5.008001 + namespace-autoclean-0.28 + pathname: E/ET/ETHER/namespace-autoclean-0.28.tar.gz + provides: + namespace::autoclean 0.28 + requirements: + B::Hooks::EndOfScope 0.12 + ExtUtils::MakeMaker 0 + List::Util 0 + Sub::Identify 0 + namespace::clean 0.20 + perl 5.006 + strict 0 + warnings 0 + namespace-clean-0.27 + pathname: R/RI/RIBASUSHI/namespace-clean-0.27.tar.gz + provides: + namespace::clean 0.27 + requirements: + B::Hooks::EndOfScope 0.12 + ExtUtils::MakeMaker 0 + Package::Stash 0.23 + perl 5.008001 diff --git a/lib/ASM/Commander.pm b/lib/ASM/Commander.pm index c2012d3..39a566f 100644 --- a/lib/ASM/Commander.pm +++ b/lib/ASM/Commander.pm @@ -30,9 +30,6 @@ my $cmdtbl = { 'cmd' => \&cmd_mship }, '^;source$' => { 'cmd' => \&cmd_source }, - '^;sql (?<db>main|log) (?<string>.*)' => { - 'flag' => 'd', - 'cmd' => \&cmd_sql }, '^;monitor (?<chan>\S+) *$' => { 'flag' => 's', 'cmd' => \&cmd_monitor }, @@ -345,18 +342,6 @@ sub cmd_source { $conn->privmsg($event->replyto, 'source is at http://asm.rocks/source'); } -sub cmd_sql { - my ($conn, $event) = @_; - - if (!defined $::db) { - $conn->privmsg($event->replyto, "I am set to run without a database, fool."); - return; - } - - my $dbh = $::db->{DBH}; - $::db->raw($conn, $event->{to}->[0], $dbh, $+{string}); -} - sub cmd_monitor { my ($conn, $event) = @_; @@ -456,13 +441,29 @@ sub cmd_db { $conn->privmsg($event->replyto, "db is at http://antispammeta.net/query.html"); } +sub sql_wildcard { + my ($str) = @_; + # Ugh ... + $str =~ s/\*/%/g; + $str =~ s/_/\\_/g; + $str =~ s/\?/_/g; + + return $str; +} + sub cmd_query { my ($conn, $event) = @_; return unless defined $::db; my $channel = defined($2) ? $1 : '%'; - my @nuh = split(/(\!|\@)/, defined($2) ? $2 : $1); - my $result = $::db->query($channel, $nuh[0], $nuh[2], $nuh[4]); + my ($nick, $user, $host) = split(/(\!|\@)/, defined($2) ? $2 : $1); + + my $result = $::db->resultset('Alertlog')->count( { + channel => { like => sql_wildcard($channel) }, + nick => { like => sql_wildcard($nick) }, + user => { like => sql_wildcard($user) }, + host => { like => sql_wildcard($host) }, + }); $conn->privmsg($event->replyto, "$result results found."); } @@ -479,33 +480,62 @@ sub cmd_investigate { my $person = $::sn{$nick}; my $user = lc $person->{user}; my $gecos = lc $person->{gecos}; - my $dbh = $::db->{DBH}; + my $acc = $person->{account}; - my $mnicks = $dbh->do("SELECT * from $::db->{ACTIONTABLE} WHERE nick like " . $dbh->quote($nick) . ';'); - my $musers = ($user ~~ $::mysql->{ignoredidents}) ? "didn't check" : $dbh->do("SELECT * from $::db->{ACTIONTABLE} WHERE user like " . $dbh->quote($person->{user}) . ';'); - my $mhosts = $dbh->do("SELECT * from $::db->{ACTIONTABLE} WHERE host like " . $dbh->quote($person->{host}) . ';'); - my $maccts = $dbh->do("SELECT * from $::db->{ACTIONTABLE} WHERE account like " . $dbh->quote($person->{account}) . ';'); - my $mgecos = ($gecos ~~ $::mysql->{ignoredgecos}) ? "didn't check" : $dbh->do("SELECT * from $::db->{ACTIONTABLE} WHERE gecos like " . $dbh->quote($person->{gecos}) . ';'); + my $actions = $::db->resultset('Actionlog'); + my $mnicks = $actions->count({ nick => $nick }); + my $mhosts = $actions->count({ host => $person->{host} }); + my $maccts; + my $musers; + my $mgecos; + + if (defined $acc and $acc ne '0' and $acc ne '*') { + $maccts = $actions->count({ account => $acc }); + } + + if ($user !~ $::mysql->{ignoredidents}) { + $musers = $actions->count({ user => $person->{user} }); + } + + if ($gecos !~ $::mysql->{ignoredgecos}) { + $mgecos = $actions->count({ gecos => $person->{gecos} }); + } + my $matchedip; my $ip = ASM::Util->getNickIP($nick); - my $matchedip = 0; - $matchedip = $dbh->do("SELECT * from $::db->{ACTIONTABLE} WHERE ip = " . $dbh->quote($ip) . ';') if defined($ip); - $mnicks =~ s/0E0/0/; - $musers =~ s/0E0/0/; - $mhosts =~ s/0E0/0/; - $maccts =~ s/0E0/0/; - $mgecos =~ s/0E0/0/; - $matchedip =~ s/0E0/0/; - my $dq = ''; + if (defined $ip) { + $matchedip = $actions->count({ ip => $ip }); + } + + my $dq; if (defined($ip)) { $dq = join '.', unpack 'C4', pack 'N', $ip; } - $conn->privmsg($event->replyto, "I found $mnicks matches by nick ($nick), $musers by user ($person->{user}), $mhosts by hostname ($person->{host}), " . - "$maccts by NickServ account ($person->{account}), $mgecos by gecos field ($person->{gecos}), and $matchedip by real IP ($dq). " . - ASM::Shortener->shorturl('https://antispammeta.net/cgi-bin/secret/investigate.pl?nick=' . uri_escape($nick) . - (($user ~~ $::mysql->{ignoredidents}) ? '' : '&user=' . uri_escape($person->{user})) . - '&host=' . uri_escape($person->{host}) . '&account=' . uri_escape($person->{account}) . - (($gecos ~~ $::mysql->{ignoredgecos}) ? '' : '&gecos=' . uri_escape($person->{gecos})) . '&realip=' . $dq)); + + my $found_by_fmt = '%s%s by %s (%s)'; + my @found; + + push @found, sprintf $found_by_fmt, $mnicks, ' matches', 'nick', $nick; + push @found, sprintf $found_by_fmt, ($musers // "didn't check"), '', 'user', $person->{user}; + push @found, sprintf $found_by_fmt, $mhosts, '', 'hostname', $person->{host}; + push @found, sprintf $found_by_fmt, $maccts, '', 'NickServ account', $person->{account} if defined $maccts; + push @found, sprintf $found_by_fmt, ($mgecos // "didn't check"), '', 'gecos field', $person->{gecos}; + push @found, sprintf $found_by_fmt, $matchedip, '', 'real IP', $dq if defined $ip; + + my $all_found = ASM::Util->commaAndify(@found); + + my @queries; + push @queries, 'nick=' . uri_escape($nick); + push @queries, 'user=' . uri_escape($person->{user}) if defined $musers; + push @queries, 'host=' . uri_escape($person->{host}); + push @queries, 'account=' . uri_escape($person->{account}) if defined $maccts; + push @queries, 'gecos=' . uri_escape($person->{gecos}) if defined $mgecos; + push @queries, 'realip=' . uri_escape($dq) if defined $ip; + + my $query_string = join '&', @queries; + + $conn->privmsg( $event->replyto, "I found $all_found. " . + ASM::Shortener->shorturl("https://antispammeta.net/cgi-bin/secret/investigate.pl?$query_string") ); } sub cmd_investigate2 { @@ -515,46 +545,53 @@ sub cmd_investigate2 { my $nick = lc $+{nick}; my $skip = 0; $skip = $+{skip} if (defined($+{skip}) and ($+{skip} ne "")); + $skip = 1 if $skip < 1; + $skip = int(2**31-1) if $skip > int(2**31-1); cmd_investigate($conn, $event); unless (defined($::sn{$nick})) { return; } my $person = $::sn{$nick}; - my $dbh = $::db->{DBH}; - my $query = "SELECT * from $::db->{ACTIONTABLE} WHERE nick like " . $dbh->quote($nick) . - ((lc $person->{user} ~~ $::mysql->{ignoredidents}) ? '' : ' or user like ' . $dbh->quote($person->{user})) . - ' or host like ' . $dbh->quote($person->{host}) . - ' or account like ' . $dbh->quote($person->{account}) . - ((lc $person->{gecos} ~~ $::mysql->{ignoredgecos}) ? '' : ' or gecos like ' . $dbh->quote($person->{gecos})); + my $acc = $person->{account}; + undef $acc if $acc eq '0' or $acc eq '*'; + my $ip = ASM::Util->getNickIP($nick); - if (defined($ip)) { - $query = $query . ' or ip = ' . $dbh->quote($ip); - } - $query = $query . " order by time desc limit $skip,10;"; - ASM::Util->dprint($query, 'mysql'); - my $query_handle = $dbh->prepare($query); - $query_handle->execute(); - my @data = @{$query_handle->fetchall_arrayref()}; - if (@data) { + + my $query = [ + nick => $nick, + host => $person->{host}, + (defined $acc ? (account => $acc) : ()), + (defined $ip ? (ip => $ip) : ()), + ($person->{user} ~~ $::mysql->{ignoredidents} ? () : (user => $person->{user})), + ($person->{gecos} ~~ $::mysql->{ignoredgecos} ? () : (gecos => $person->{gecos})), + ]; + + my @incidents = $::db->resultset('Actionlog')->search($query, { + order_by => { -desc => 'time' }, + rows => 10, + page => $skip, + })->all; + + if (@incidents) { $conn->privmsg($event->replyto, 'Sending you the results...'); } else { $conn->privmsg($event->replyto, 'No results to send!'); + return; } -# reverse @data; -#$data will be an array of arrays, - my ($xindex, $xtime, $xaction, $xreason, $xchannel, $xnick, $xuser, $xhost, $xip, $xgecos, $xaccount, $xbynick, $xbyuser, $xbyhost, $xbygecos, $xbyaccount ) = ( 0 .. 15 ); - foreach my $line (@data) { - my $reason = ''; my $channel = ''; - $reason = ' (' . $line->[$xreason] . ')' if defined($line->[$xreason]); - $channel = ' on ' . $line->[$xchannel] if defined($line->[$xchannel]); - $conn->privmsg($event->nick, '#' . $line->[$xindex] . ': ' . $line->[$xtime] . ' ' . - $line->[$xnick] . '!' . $line->[$xuser] . '@' . $line->[$xhost] . ' (' . $line->[$xgecos] . ') ' . - $line->[$xaction] . $reason . $channel . ' by ' . $line->[$xbynick]); # . "\n"; - } - if (@data) { - $conn->privmsg($event->nick, "Only 10 results are shown at a time. For more, do ;investigate2 $nick " . ($skip+10) . '.'); + + my $format = '#%d: %s %s!%s@%s (%s) %s%s%s%s'; + for my $line (@incidents) { + my $out = sprintf $format, ($line->index, $line->time, $line->nick, $line->user, $line->host, $line->gecos, $line->action, + (defined $line->reason ? ' (' . $line->reason . ')' : ''), + (defined $line->channel ? ' on ' . $line->channel : ''), + (defined $line->bynick ? ' by ' . $line->bynick : ''), + ); + + $conn->privmsg($event->nick, $out); } + + $conn->privmsg($event->nick, "Only 10 results are shown at a time. For more, do ;investigate2 $nick " . ($skip+1) . '.'); } sub cmd_user_add { diff --git a/lib/ASM/DB.pm b/lib/ASM/DB.pm index b8c7b63..6bd9519 100644 --- a/lib/ASM/DB.pm +++ b/lib/ASM/DB.pm @@ -1,205 +1,11 @@ +use utf8; package ASM::DB; -no autovivification; -use warnings; use strict; -use DBI; -use Data::Dumper; -no if $] >= 5.017011, warnings => 'experimental::smartmatch'; - -sub new { - my $module = shift; - my ($db, $host, $port, $user, $pass, $table, $actiontable, $dblog) = @_; - my $self = {}; - $self->{DBH} = DBI->connect("DBI:mysql:database=$db;host=$host;port=$port", $user, $pass); - $self->{DBH}->{mysql_auto_reconnect} = 1; - $self->{TABLE} = $table; - $self->{ACTIONTABLE} = $actiontable; - bless($self); - return $self; -} - -sub raw -{ - my $self = shift; - my ($conn, $tgt, $dbh, $qry) = @_; - my $sth = $dbh->prepare($qry); - $sth->execute; - my $names = $sth->{'NAME'}; - my $numFields = $sth->{'NUM_OF_FIELDS'}; - my $string = ""; - for (my $i = 0; $i < $numFields; $i++) { - $string = $string . sprintf("%s%s", $i ? "," : "", $$names[$i]); - } - $conn->privmsg($tgt, $string); - while (my $ref = $sth->fetchrow_arrayref) { - $string = ""; - for (my $i = 0; $i < $numFields; $i++) { - $string = $string . sprintf("%s%s", $i ? "," : "", $$ref[$i]); - } - $conn->privmsg($tgt, $string); - } -} - -sub record -{ - my $self = shift; - my ($channel, $nick, $user, $host, $gecos, $level, $id, $reason) = @_; - $gecos //= "NOT_DEFINED"; - - my $dbh = $self->{DBH}; - $dbh->do("INSERT INTO $self->{TABLE} (channel, nick, user, host, gecos, level, id, reason) VALUES (" . - $dbh->quote($channel) . ", " . $dbh->quote($nick) . ", " . $dbh->quote($user) . - ", " . $dbh->quote($host) . ", " . $dbh->quote($gecos) . ", " . $dbh->quote($level) . ", " . - $dbh->quote($id) . ", " . $dbh->quote($reason) . ");"); -} - -sub actionlog -{ - my ($self, $event, $modedata1, $modedata2) = @_; - my $dbh = $self->{DBH}; - my ($action, $reason, $channel, - $nick, $user, $host, $gecos, $account, $ip, - $bynick, $byuser, $byhost, $bygecos, $byaccount); - my ($lcnick, $lcbynick); - - if ($event->{type} eq 'mode') { - $action = $modedata1; - $nick = $modedata2; - $channel = lc $event->{to}->[0]; - $bynick = $event->{nick}; - $byuser = $event->{user}; - $byhost = $event->{host}; - } elsif ($event->{type} eq 'quit') { - my $quitmsg = $event->{args}->[0]; - if ($quitmsg =~ /^Killed \((\S+) \((.*)\)\)$/) { - $bynick = $1; - $reason = $2 unless ($2 eq '<No reason given>'); - return if (($reason // '') =~ /Nickname regained by services/); - $action = 'kill'; - } elsif ($quitmsg =~ /^K-Lined$/) { - $action = 'k-line'; - } else { - return; #quit not forced/tracked - } - $nick = $event->{nick}; - $user = $event->{user}; - $host = $event->{host}; - } elsif (($event->{type} eq 'part') && ($event->{args}->[0] =~ /^requested by (\S+) \((.*)\)/)) { - $bynick = $1; - $reason = $2 unless (lc $2 eq lc $event->{nick}); - $action = 'remove'; - $nick = $event->{nick}; - $user = $event->{user}; - $host = $event->{host}; - $channel = $event->{to}->[0]; - } elsif ($event->{type} eq 'kick') { - $action = 'kick'; - $bynick = $event->{nick}; - $byuser = $event->{user}; - $byhost = $event->{host}; - $reason = $event->{args}->[1] unless ($event->{args}->[1] eq $event->{to}->[0]); - $nick = $event->{to}->[0]; - $channel = $event->{args}->[0]; - } - return unless defined($action); - $lcbynick = lc $bynick if defined $bynick; #we will lowercase the NUHGA info later. - if ( (defined($bynick)) && (defined($::sn{$lcbynick})) ) { #we have the nick taking the action available, fill in missing NUHGA info - $byuser //= $::sn{$lcbynick}{user}; - $byhost //= $::sn{$lcbynick}{host}; - $bygecos //= $::sn{$lcbynick}{gecos}; - $byaccount //= $::sn{$lcbynick}{account}; - if (($byaccount eq '0') or ($byaccount eq '*')) { - $byaccount = undef; - } - } - $lcnick = lc $nick if defined $nick; - if ( (defined($nick)) && (defined($::sn{$lcnick})) ) { #this should always be true, else something has gone FUBAR - $user //= $::sn{$lcnick}{user}; - $host //= $::sn{$lcnick}{host}; - $gecos //= $::sn{$lcnick}{gecos}; - $account //= $::sn{$lcnick}{account}; - if (($account eq '0') or ($account eq '*')) { - $account = undef; - } - $ip = ASM::Util->getNickIP($lcnick); - } -# my ($action, $reason, $channel, -# $nick, $user, $host, $gecos, $account, $ip -# $bynick, $byuser, $byhost, $bygecos, $byaccount); -#Now, time to escape/NULLify everything - $action = $dbh->quote($action); - if (defined($reason)) { $reason = $dbh->quote($reason); } else { $reason = 'NULL'; } -## removed lc's from everything except IP - if (defined($channel)) { $channel = $dbh->quote($channel); } else { $channel = 'NULL'; } - - if (defined($nick)) { $nick = $dbh->quote($nick); } else { $nick = 'NULL'; } - if (defined($user)) { $user = $dbh->quote($user); } else { $user = 'NULL'; } - if (defined($host)) { $host = $dbh->quote($host); } else { $host = 'NULL'; } - if (defined($gecos)) { $gecos = $dbh->quote($gecos); } else { $gecos = 'NULL'; } - if (defined($account)) { $account = $dbh->quote($account); } else { $account = 'NULL'; } - if (defined($ip)) { $ip = $dbh->quote($ip); } else { $ip = 'NULL'; } - - if (defined($bynick)) { $bynick = $dbh->quote($bynick); } else { $bynick = 'NULL'; } - if (defined($byuser)) { $byuser = $dbh->quote($byuser); } else { $byuser = 'NULL'; } - if (defined($byhost)) { $byhost = $dbh->quote($byhost); } else { $byhost = 'NULL'; } - if (defined($bygecos)) { $bygecos = $dbh->quote($bygecos); } else { $bygecos = 'NULL'; } - if (defined($byaccount)) { $byaccount = $dbh->quote($byaccount); } else { $byaccount = 'NULL'; } - my $sqlstr = "INSERT INTO $self->{ACTIONTABLE} " . - "(action, reason, channel, " . - "nick, user, host, gecos, account, ip, " . - "bynick, byuser, byhost, bygecos, byaccount)" . - " VALUES " . - "($action, $reason, $channel, " . - "$nick, $user, $host, $gecos, $account, $ip, " . - "$bynick, $byuser, $byhost, $bygecos, $byaccount);"; - ASM::Util->dprint( $sqlstr, 'mysql' ); - $dbh->do( $sqlstr ); - return $dbh->last_insert_id(undef, undef, $self->{ACTIONTABLE}, undef); -# $::sn{ow} looks like: -#$VAR1 = { -# "account" => "afterdeath", -# "gecos" => "William Athanasius Heimbigner", -# "user" => "icxcnika", -# "mship" => [ -# "#baadf00d", -# "#antispammeta-debug", -# "#antispammeta" -# ], -# "host" => "freenode/weird-exception/network-troll/afterdeath" -# }; - -} - -sub query -{ - my $self = shift; - my ($channel, $nick, $user, $host) = @_; - my $dbh = $self->{DBH}; - $channel = $dbh->quote($channel); - $nick = $dbh->quote($nick); - $user = $dbh->quote($user); - $host = $dbh->quote($host); +use warnings; - $nick =~ s/\*/%/g; - $nick =~ s/_/\\_/g; - $nick =~ s/\?/_/g; +use parent 'DBIx::Class::Schema'; - $user =~ s/\*/%/g; - $user =~ s/_/\\_/g; - $user =~ s/\?/_/g; +__PACKAGE__->load_namespaces; - $host =~ s/\*/%/g; - $host =~ s/_/\\_/g; - $host =~ s/\?/_/g; - my $sth = $dbh->prepare("SELECT * from $self->{TABLE} WHERE channel like $channel and nick like $nick and user like $user and host like $host;"); - $sth->execute; - my $i = 0; - while (my $ref = $sth->fetchrow_arrayref) { - $i++; - } - return $i; -} - 1; -# vim: ts=2:sts=2:sw=2:expandtab diff --git a/lib/ASM/DB/Result/Actionlog.pm b/lib/ASM/DB/Result/Actionlog.pm new file mode 100644 index 0000000..5385650 --- /dev/null +++ b/lib/ASM/DB/Result/Actionlog.pm @@ -0,0 +1,37 @@ +use utf8; +package ASM::DB::Result::Actionlog; + +use strict; +use warnings; + +use parent 'DBIx::Class::Core'; + +__PACKAGE__->load_components('InflateColumn::DateTime'); +__PACKAGE__->table('actionlog'); +__PACKAGE__->add_columns( + index => { data_type => 'bigint', is_auto_increment => 1, is_nullable => 0 }, + time => { + data_type => 'timestamp', + datetime_undef_if_invalid => 1, + default_value => \'current_timestamp', + is_nullable => 0, + }, + action => { data_type => 'varchar', is_nullable => 0, size => 20 }, + reason => { data_type => 'varchar', is_nullable => 1, size => 512 }, + channel => { data_type => 'varchar', is_nullable => 1, size => 51 }, + nick => { data_type => 'varchar', is_nullable => 0, size => 17 }, + user => { data_type => 'varchar', is_nullable => 1, size => 11 }, + host => { data_type => 'varchar', is_nullable => 1, size => 64 }, + ip => { data_type => 'integer', is_nullable => 1, extra => { unsigned => 1 } }, + gecos => { data_type => 'varchar', is_nullable => 1, size => 512 }, + account => { data_type => 'varchar', is_nullable => 1, size => 17 }, + bynick => { data_type => 'varchar', is_nullable => 1, size => 17 }, + byuser => { data_type => 'varchar', is_nullable => 1, size => 11 }, + byhost => { data_type => 'varchar', is_nullable => 1, size => 64 }, + bygecos => { data_type => 'varchar', is_nullable => 1, size => 512 }, + byaccount => { data_type => 'varchar', is_nullable => 1, size => 17 }, +); + +__PACKAGE__->set_primary_key('index'); + +1; diff --git a/lib/ASM/DB/Result/Alertlog.pm b/lib/ASM/DB/Result/Alertlog.pm new file mode 100644 index 0000000..8ce22ff --- /dev/null +++ b/lib/ASM/DB/Result/Alertlog.pm @@ -0,0 +1,30 @@ +use utf8; +package ASM::DB::Result::Alertlog; + +use strict; +use warnings; + +use parent 'DBIx::Class::Core'; + +__PACKAGE__->load_components('InflateColumn::DateTime'); +__PACKAGE__->table('alertlog'); +__PACKAGE__->add_columns( + time => { + data_type => 'timestamp', + datetime_undef_if_invalid => 1, + default_value => \'current_timestamp', + is_nullable => 0, + }, + channel => { data_type => 'text', is_nullable => 0 }, + nick => { data_type => 'text', is_nullable => 0 }, + user => { data_type => 'text', is_nullable => 0 }, + host => { data_type => 'text', is_nullable => 0 }, + gecos => { data_type => 'text', is_nullable => 0 }, + level => { data_type => 'tinytext', is_nullable => 0 }, + id => { data_type => 'tinytext', is_nullable => 0 }, + reason => { data_type => 'text', is_nullable => 0 }, +); + +__PACKAGE__->set_primary_key('id'); + +1; diff --git a/lib/ASM/Event.pm b/lib/ASM/Event.pm index fac5c06..5e0435c 100644 --- a/lib/ASM/Event.pm +++ b/lib/ASM/Event.pm @@ -222,8 +222,8 @@ sub on_part my $nick = lc $event->{nick}; my $chan = lc $event->{to}->[0]; # Ignore channels that are +s and not monitored - if (defined $::db and $event->{args}->[0] =~ /^requested by/ and (not ((grep { /^s$/ } @{$::sc{$chan}{modes}} ) && ($::channels->{channel}->{$chan}->{monitor} eq "no"))) ) { - my $idx = $::db->actionlog( $event); + if ($event->{args}->[0] =~ /^requested by/ and (not ((grep { /^s$/ } @{$::sc{$chan}{modes}} ) && ($::channels->{channel}->{$chan}->{monitor} eq "no"))) ) { + my $idx = $::log->actionlog( $event); $::log->sqlIncident($chan, $idx) if $idx; } if (defined($::sn{$nick}) && defined($::sn{$nick}->{mship})) { @@ -299,7 +299,7 @@ sub on_quit } $event->{to} = \@channels; if (defined $::db) { - my $idx = $::db->actionlog($event); + my $idx = $::log->actionlog($event); # Ignore channels that are +s and not monitored my @actionlog_channels = grep { not ((grep { /^s$/ } @{$::sc{$_}{modes}}) && ($::channels->{channel}->{$_}->{monitor} eq "no")) } @channels; $::log->sqlIncident( join(',', @actionlog_channels), $idx ) if $idx; @@ -425,7 +425,7 @@ sub on_kick { if (defined $::db) { # Ignore channels that are +s and not monitored if ( not ((grep { /^s$/ } @{$::sc{$chan}{modes}}) && ($::channels->{channel}->{$chan}->{monitor} eq "no")) ) { - my $idx = $::db->actionlog($event); + my $idx = $::log->actionlog($event); $::log->sqlIncident($chan, $idx) if $idx; } } @@ -567,7 +567,7 @@ sub on_mode foreach my $victim (@affected) { # Ignore channels that are +s and not monitored if ( not ((grep { /^s$/ } @{$::sc{$chan}{modes}}) && ($::channels->{channel}->{$chan}->{monitor} eq "no")) ) { - my $idx = $::db->actionlog($event, 'ban', $victim); + my $idx = $::log->actionlog($event, 'ban', $victim); $::log->sqlIncident( $chan, $idx ) if $idx; } } @@ -594,7 +594,7 @@ sub on_mode foreach my $victim (@affected) { # Ignore channels that are +s and not monitored if ( not ((grep { /^s$/ } @{$::sc{$chan}{modes}}) && ($::channels->{channel}->{$chan}->{monitor} eq "no")) ) { - my $idx = $::db->actionlog($event, 'quiet', $victim); + my $idx = $::log->actionlog($event, 'quiet', $victim); $::log->sqlIncident( $chan, $idx ) if $idx; } } diff --git a/lib/ASM/Inspect.pm b/lib/ASM/Inspect.pm index d85d10d..d6121fb 100644 --- a/lib/ASM/Inspect.pm +++ b/lib/ASM/Inspect.pm @@ -125,14 +125,11 @@ sub inspect { return unless (ASM::Util->notRestricted($nick, "notrigger") && ASM::Util->notRestricted($nick, "no$id")); $xresult = $dct{$id}{xresult}; my $nicereason = interpolate($dct{$id}{reason}); - if (defined $::db) { - $::db->record($chan, $displaynick, $event->{user}, $event->{host}, $::sn{lc $nick}->{gecos}, $dct{$id}{risk}, $id, $nicereason); - } $txtz = "\x03" . $::RCOLOR{$::RISKS{$dct{$id}{risk}}} . "\u$dct{$id}{risk}\x03 risk threat [\x02$chan\x02] - ". "\x02$displaynick\x02 - ${nicereason}; ping "; $txtz = $txtz . ASM::Util->commaAndify(ASM::Util->getAlert($chan, $dct{$id}{risk}, 'hilights')) if (ASM::Util->getAlert($chan, $dct{$id}{risk}, 'hilights')); $txtz = $txtz . ' !att-' . $chan . '-' . $dct{$id}{risk}; - my $uuid = $::log->incident($chan, "$chan: $dct{$id}{risk} risk: $displaynick - $nicereason\n"); + my $uuid = $::log->incident($chan, $displaynick, $event->{user}, $event->{host}, $::sn{lc $nick}->{gecos}, $dct{$id}{risk}, $id, $nicereason); $txtz = $txtz . ' ' . ASM::Shortener->shorturl($::settings->{web}->{detectdir} . $uuid . '.txt'); if ($id eq 'last_measure_regex') { #TODO: Note that this is another example of things that shouldn't be hardcoded, but are. diff --git a/lib/ASM/Log.pm b/lib/ASM/Log.pm index 46bda4c..e9a6d6f 100644 --- a/lib/ASM/Log.pm +++ b/lib/ASM/Log.pm @@ -34,12 +34,118 @@ sub new return $self; } +sub actionlog +{ + my ($self, $event, $modedata1, $modedata2) = @_; + my ($action, $reason, $channel, + $nick, $user, $host, $gecos, $account, $ip, + $bynick, $byuser, $byhost, $bygecos, $byaccount); + my ($lcnick, $lcbynick); + + if ($event->{type} eq 'mode') { + $action = $modedata1; + $nick = $modedata2; + $channel = lc $event->{to}->[0]; + $bynick = $event->{nick}; + $byuser = $event->{user}; + $byhost = $event->{host}; + } elsif ($event->{type} eq 'quit') { + my $quitmsg = $event->{args}->[0]; + if ($quitmsg =~ /^Killed \((\S+) \((.*)\)\)$/) { + $bynick = $1; + $reason = $2 unless ($2 eq '<No reason given>'); + return if (($reason // '') =~ /Nickname regained by services/); + $action = 'kill'; + } elsif ($quitmsg =~ /^K-Lined$/) { + $action = 'k-line'; + } else { + return; #quit not forced/tracked + } + $nick = $event->{nick}; + $user = $event->{user}; + $host = $event->{host}; + } elsif (($event->{type} eq 'part') && ($event->{args}->[0] =~ /^requested by (\S+) \((.*)\)/)) { + $bynick = $1; + $reason = $2 unless (lc $2 eq lc $event->{nick}); + $action = 'remove'; + $nick = $event->{nick}; + $user = $event->{user}; + $host = $event->{host}; + $channel = $event->{to}->[0]; + } elsif ($event->{type} eq 'kick') { + $action = 'kick'; + $bynick = $event->{nick}; + $byuser = $event->{user}; + $byhost = $event->{host}; + $reason = $event->{args}->[1] unless ($event->{args}->[1] eq $event->{to}->[0]); + $nick = $event->{to}->[0]; + $channel = $event->{args}->[0]; + } + return unless defined($action); + $lcbynick = lc $bynick if defined $bynick; #we will lowercase the NUHGA info later. + if ( (defined($bynick)) && (defined($::sn{$lcbynick})) ) { #we have the nick taking the action available, fill in missing NUHGA info + $byuser //= $::sn{$lcbynick}{user}; + $byhost //= $::sn{$lcbynick}{host}; + $bygecos //= $::sn{$lcbynick}{gecos}; + $byaccount //= $::sn{$lcbynick}{account}; + if (($byaccount eq '0') or ($byaccount eq '*')) { + $byaccount = undef; + } + } + $lcnick = lc $nick if defined $nick; + if ( (defined($nick)) && (defined($::sn{$lcnick})) ) { #this should always be true, else something has gone FUBAR + $user //= $::sn{$lcnick}{user}; + $host //= $::sn{$lcnick}{host}; + $gecos //= $::sn{$lcnick}{gecos}; + $account //= $::sn{$lcnick}{account}; + if (($account eq '0') or ($account eq '*')) { + $account = undef; + } + $ip = ASM::Util->getNickIP($lcnick); + } + + return $::db->resultset('Actionlog')->create({ + action => $action, + reason => $reason, + channel => $channel, + + nick => $nick, + user => $user, + host => $host, + gecos => $gecos, + account => $account, + ip => $ip, + + bynick => $bynick, + byuser => $byuser, + byhost => $byhost, + bygecos => $bygecos, + byaccount => $byaccount, + })->id; +# $::sn{ow} looks like: +#$VAR1 = { +# "account" => "afterdeath", +# "gecos" => "William Athanasius Heimbigner", +# "user" => "icxcnika", +# "mship" => [ +# "#baadf00d", +# "#antispammeta-debug", +# "#antispammeta" +# ], +# "host" => "freenode/weird-exception/network-troll/afterdeath" +# }; + +} + sub incident { my $self = shift; - my ($chan, $header) = @_; + my ($chan, $nick, $user, $host, $gecos, $risk, $id, $reason) = @_; $chan = lc $chan; my $uuid = $self->{UUID}->create_str(); + + my $header = "$chan: $risk risk: $nick - $reason\n"; + open(FH, '>', $self->{CONFIG}->{detectdir} . $uuid . '.txt'); print FH $header; if (defined($self->{backlog}->{$chan})) { @@ -47,6 +153,20 @@ sub incident } print FH "\n\n"; close(FH); + + $gecos //= "NOT_DEFINED"; + + $::db->resultset('Alertlog')->create({ + channel => $chan, + nick => $nick, + user => $user, + host => $host, + gecos => $gecos, + level => $risk, + id => $id, + reason => $reason, + }); + return $uuid; } @@ -123,10 +123,44 @@ sub init { if (-e "debugsock") { $irc->debugsock(1); } + + my $mysql_config_bad = 0; + + if (exists $::mysql->{table}) { + if ($::mysql->{table} ne 'alertlog') { + warn "The 'table' option in mysql.json is no longer supported. Please ensure your table is named 'alertlog'.\n"; + $mysql_config_bad++; + } + else { + warn "The 'table' option in mysql.json is no longer supported. Please remove it from the configuration.\n"; + } + } + if (exists $::mysql->{actiontable}) { + if ($::mysql->{actiontable} ne 'actionlog') { + warn "The 'actiontable' option in mysql.json is no longer supported. Please ensure your table is named 'actionlog'.\n"; + $mysql_config_bad++; + } + else { + warn "The 'actiontable' option in mysql.json is no longer supported. Please remove it from the configuration.\n"; + } + } + + if ($mysql_config_bad) { + die "The bot cannot operate with the current database configuration.\n"; + } + if (!$::mysql->{disable}) { - $::db = ASM::DB->new($::mysql->{db}, $::mysql->{host}, $::mysql->{port}, - $::mysql->{user}, $::mysql->{pass}, $::mysql->{table}, - $::mysql->{actiontable}, $::mysql->{dblog}); + my $dsn; + if (exists $::mysql->{dsn}) { + $dsn = $::mysql->{dsn}; + } + else { + # This isn't what we *should* do - notably, we'd have to wrap IPv6 addresses given + # as host in brackets. It's what the old code did, though, and all we need is + # compatibility with that. + $dsn = sprintf 'DBI:mysql:database=%s;host=%s;port=%s', @{ $::mysql }{'db', 'host', 'port'}; + } + $::db = ASM::DB->connect($dsn, $::mysql->{user}, $::mysql->{pass}); } $conn = $irc->newconn( Server => $host, Port => $::settings->{port} || '6667', |