File Coverage

blib/lib/Net/RNDC.pm
Criterion Covered Total %
statement 27 74 36.4
branch 1 14 7.1
condition 1 2 50.0
subroutine 8 16 50.0
pod 4 4 100.0
total 41 110 37.2


line stmt bran cond sub pod time code
1             package Net::RNDC;
2             {
3             $Net::RNDC::VERSION = '0.003';
4             }
5             # ABSTRACT: Speak the BIND RNDC protocol
6              
7 1     1   26293 use strict;
  1         3  
  1         47  
8 1     1   6 use warnings;
  1         2  
  1         40  
9              
10 1     1   6 use Carp qw(croak);
  1         6  
  1         86  
11              
12 1     1   744 use Net::RNDC::Session;
  1         4  
  1         12  
13              
14             my $sock;
15              
16             BEGIN {
17 1     1   133 eval 'use IO::Socket::INET6;';
  1     1   936  
  1         44920  
  1         11  
18              
19 1 50       738 if ($@) {
20 0         0 eval 'use IO::Socket::INET;';
21              
22 0 0       0 die $@ if $@;
23              
24 0         0 $sock = 'IO::Socket::INET';
25             } else {
26 1         655 $sock = 'IO::Socket::INET6';
27             }
28             }
29              
30             # Required for new()
31             my @required_args = qw(
32             );
33              
34             # Optional for new()/do()
35             my @optional_args = qw(
36             key
37             host
38             port
39             );
40              
41             sub new {
42 1     1 1 14 my ($class, %args) = @_;
43              
44 1         9 my %obj = $class->_parse_args(%args);
45              
46 1         7 return bless \%obj, $class;
47             }
48              
49             sub _parse_args {
50 1     1   3 my ($class, %args) = @_;
51              
52 1         4 for my $r (@required_args) {
53 0 0       0 unless ($args{$r}) {
54 0         0 croak("Required argument '$r' is missing");
55             }
56             }
57              
58 1   50     9 $args{port} ||= 953;
59              
60 1         7 return map {
61 3         8 $_ => $args{$_}
62 1         4 } grep { $args{$_} } (@required_args, @optional_args);
63             }
64              
65             sub _check_do_args {
66 0     0     my ($self, %args) = @_;
67              
68 0           for my $r (qw(key host)) {
69 0 0         unless ($args{$r}) {
70 0           croak("Required argument '$r' is missing");
71             }
72             }
73             }
74              
75             sub do {
76 0     0 1   my ($self, $command, %override) = @_;
77              
78 0           $self->{response} = $self->{error} = '';
79              
80 0           my $host = $self->{host};
81 0           my $port = $self->{port};
82 0           my $key = $self->{key};
83              
84 0 0         if (%override) {
85 0           my %args = $self->_parse_args(
86             host => $host,
87             port => $port,
88             key => $key,
89             %override,
90             );
91              
92 0           $host = $args{host};
93 0           $port = $args{port};
94 0           $key = $args{key};
95             }
96              
97             $self->_check_do_args(
98 0           host => $host,
99             port => $port,
100             key => $key,
101             );
102              
103 0           my $c = $sock->new(
104             PeerAddr => "$host:$port",
105             );
106              
107 0 0         unless ($c) {
108 0           $self->{error} = "Failed to create a socket: $@ ($!)";
109              
110 0           return 0;
111             }
112              
113             # Net::RNDC::Session does all of the work
114             my $sess = Net::RNDC::Session->new(
115             key => $key,
116             command => $command,
117             is_client => 1,
118              
119             want_write => sub {
120 0     0     my $s = shift;
121              
122 0           $c->send(shift);
123              
124 0           $s->next;
125             },
126              
127             want_read => sub {
128 0     0     my $s = shift;
129              
130 0           my $buff;
131              
132 0           $c->recv($buff, 4096);
133              
134 0           $s->next($buff);
135             },
136              
137             want_finish => sub {
138 0     0     my $s = shift;
139 0           my $res = shift;
140              
141 0           $self->{response} = $res;
142             },
143              
144             want_error => sub {
145 0     0     my $s = shift;
146 0           my $err = shift;
147              
148 0           $self->{error} = $err;
149             }
150 0           );
151              
152             # Work!
153 0           $sess->start;
154              
155 0           $c->close;
156              
157 0 0         if ($self->response) {
158 0           return 1;
159             } else {
160 0           return 0;
161             }
162             }
163              
164             sub response {
165 0     0 1   my ($self) = @_;
166              
167 0           return $self->{response};
168             }
169              
170             sub error {
171 0     0 1   my ($self) = @_;
172              
173 0           return $self->{error};
174             }
175              
176             1;
177             __END__;