File Coverage

blib/lib/POE/Component/IRC/Plugin/QueryDNS.pm
Criterion Covered Total %
statement 30 81 37.0
branch 3 26 11.5
condition 1 19 5.2
subroutine 9 13 69.2
pod 1 5 20.0
total 44 144 30.5


line stmt bran cond sub pod time code
1             package POE::Component::IRC::Plugin::QueryDNS;
2             {
3             $POE::Component::IRC::Plugin::QueryDNS::VERSION = '1.04';
4             }
5              
6             #ABSTRACT: A POE::Component::IRC plugin for IRC based DNS queries
7              
8 1     1   775730 use strict;
  1         2  
  1         139  
9 1     1   7 use warnings;
  1         2  
  1         106  
10 1     1   7 use POE;
  1         1  
  1         78  
11 1     1   374 use POE::Component::Client::DNS;
  1         2  
  1         31  
12 1     1   6 use POE::Component::IRC::Plugin qw(:ALL);
  1         2  
  1         3413  
13 1     1   1482 use Net::IP::Minimal qw[ip_is_ipv4];
  1         1057  
  1         7513  
14              
15             sub new {
16 1     1 1 7456 my $package = shift;
17 1         4 my %args = @_;
18 1         5 $args{lc $_} = delete $args{$_} for keys %args;
19 1 50 33     9 delete $args{resolver}
20             unless ref $args{resolver} and $args{resolver}->isa('POE::Component::Client::DNS');
21 1         6 bless \%args, $package;
22             }
23              
24             sub PCI_register {
25 1     1 0 568 my ($self,$irc) = @_;
26 1         6 $irc->plugin_register( $self, 'SERVER', qw(public msg) );
27 1         47 $self->{resolver} = $irc->resolver();
28 1 50       26 unless ( $self->{resolver} ) {
29 0         0 $self->{resolver} = POE::Component::Client::DNS->spawn();
30 0         0 $self->{_mydns} = 1;
31             }
32 1         4 return 1;
33             }
34              
35             sub PCI_unregister {
36 1     1 0 1995 my $self = shift;
37 1 50       7 return 1 unless $self->{_mydns};
38 0           $self->{resolver}->shutdown();
39 0           delete $self->{resolver};
40 0           return 1;
41             }
42              
43             sub S_public {
44 0     0 0   my ($self,$irc) = splice @_, 0 , 2;
45 0           my ($nick,$userhost) = ( split /!/, ${ $_[0] } )[0..1];
  0            
46 0           my $channel = ${ $_[1] }->[0];
  0            
47 0           my $what = ${ $_[2] };
  0            
48 0           my $mynick = $irc->nick_name();
49 0   0       my $cmdstr = $self->{command} || 'dns';
50 0           my ($command) = $what =~ m/^\s*\Q$mynick\E[\:\,\;\.]?\s*(.*)$/i;
51 0 0 0       return PCI_EAT_NONE unless ( $command and $command =~ /^\Q$cmdstr\E/i );
52 0           $self->_dns_query( $irc, $channel, 'privmsg', split(/\s+/, $command) );
53 0           return PCI_EAT_NONE;
54             }
55              
56             sub S_msg {
57 0     0 0   my ($self,$irc) = splice @_, 0 , 2;
58 0           my ($nick,$userhost) = ( split /!/, ${ $_[0] } )[0..1];
  0            
59 0           my $string = ${ $_[2] };
  0            
60 0   0       my $cmdstr = $self->{command} || 'dns';
61 0 0 0       return PCI_EAT_NONE unless ( $string and $string =~ /^\Q$cmdstr\E\s+/i );
62 0 0         $self->_dns_query( $irc, $nick, ( $self->{privmsg} ? 'privmsg' : 'notice' ), split(/\s+/, $string) );
63 0           return PCI_EAT_NONE;
64             }
65              
66             sub _dns_query {
67 0     0     my ($self,$irc,$target,$method,$cmdstr,$query,$type) = @_;
68 0 0 0       return unless $cmdstr and $query;
69 0           $poe_kernel->state( '_querydns_response', $self, '_response' );
70 0 0 0       $type = 'A' unless $type and $type =~ /^(A|CNAME|NS|MX|PTR|TXT|AAAA|SRV|SOA)$/i;
71 0 0         $type = 'PTR' if ip_is_ipv4( $query );
72 0           my $response = $self->{resolver}->resolve(
73             event => '_querydns_response',
74             host => $query,
75             type => $type,
76             context => { targ => $target, meth => $method, irc => $irc },
77             );
78 0 0         $poe_kernel->yield( '_querydns_response', $response ) if $response;
79 0           return 1;
80             }
81              
82             sub _response {
83 0     0     my $response = $_[ARG0];
84 0           my $target = $response->{context}->{targ};
85 0           my $method = $response->{context}->{meth};
86 0           my $irc = $response->{context}->{irc};
87 0 0         if ( !$response->{response} ) {
88 0           $irc->yield( $method, $target, 'Thanks, that generated an error!' );
89             }
90             else {
91 0           my @answers;
92 0           foreach my $ans ( $response->{response}->answer() ) {
93 0 0         if ( $ans->type() eq 'SOA' ) {
94 0           push @answers, 'SOA=' . join(':', $ans->mname, $ans->rname, $ans->serial, $ans->refresh, $ans->retry, $ans->expire, $ans->minimum );
95             }
96             else {
97 0           push @answers, join('=', $ans->type(), $ans->rdatastr() );
98             }
99             }
100 0 0         if ( @answers ) {
101 0           $irc->yield( $method, $target, $response->{host} . ' [ ' . join(' ', @answers) . ' ]' );
102             }
103             else {
104 0           $irc->yield( $method, $target, 'No answers for ' . $response->{host} );
105             }
106             }
107 0           $poe_kernel->state( '_querydns_response' );
108 0           return;
109             }
110              
111             1;
112              
113              
114             __END__