File Coverage

blib/lib/Dyns/Client.pm
Criterion Covered Total %
statement 47 81 58.0
branch 4 18 22.2
condition 1 12 8.3
subroutine 13 14 92.8
pod 3 3 100.0
total 68 128 53.1


line stmt bran cond sub pod time code
1             package Dyns::Client;
2              
3 1     1   160990 use 5.006;
  1         3  
  1         31  
4 1     1   4 use strict;
  1         2  
  1         21  
5 1     1   7 use warnings;
  1         6  
  1         46  
6 1     1   5 use vars qw( $VERSION );
  1         1  
  1         42  
7 1     1   4 use Carp;
  1         1  
  1         52  
8 1     1   12619 use LWP::UserAgent;
  1         817574  
  1         37  
9 1     1   47 use HTTP::Request;
  1         2  
  1         28  
10 1     1   1078 use Sys::Hostname;
  1         1511  
  1         58  
11 1     1   1423 use Socket;
  1         6834  
  1         656  
12 1     1   1135 use Net::hostent;
  1         165350  
  1         7  
13 1     1   1001 use CGI::Util qw( escape );
  1         5988  
  1         739  
14              
15             $VERSION = '0.6';
16              
17             =head1 NAME
18              
19             Dyns::Client - A client for the dyns.cx dynamic DNS service
20              
21             =head1 DESCRIPTION
22              
23             A simple client for the dyns.cx dynamic DNS service. Allows you to post an
24             update to the dyns dynamic dns service, as documented on:
25            
26             http://www.dyns.cx/documentation/technical/protocol/v1.1.php
27              
28             The dyns dynamic IP service is run by Stefaan Ponnet, who started this service more than 4 years ago.
29              
30             =head1 METHODS
31              
32             =over 4
33              
34             =item B - Constructor
35              
36             =cut
37              
38             sub new {
39 1     1 1 422 my ($proto, %args) = @_;
40              
41 1   33     11 my $class = ref($proto) || $proto;
42              
43 1         2 my $self = { };
44              
45 1         4 bless $self, $class;
46              
47 1         5 return $self;
48             }
49              
50             =item B - Send an update to dyns.cx
51              
52             die unless $dyns->update(
53             -username => 'mandatory username',
54             -password => 'mandatory password',
55             -hostname => 'mandatory hostname',
56             -domain => 'optional domain',
57             -ip => 'optional ip'
58             );
59              
60             =cut
61              
62             sub update {
63 0     0 1 0 my ($self, %args) = @_;
64              
65             my $username = $args{-username}
66 0   0     0 || do { carp "username mandatory"; return undef; };
67             my $password = $args{-password}
68 0   0     0 || do { carp "password mandatory"; return undef; };
69             my $hostname = $args{-hostname}
70 0   0     0 || do { carp "hostname required"; return undef; };
71 0         0 my $domain = $args{-domain};
72 0         0 my $ip = $args{-ip};
73              
74 0         0 my $url = 'http://www.dyns.net/postscript011.php?';
75              
76 0         0 $url .= 'username=' . escape( $username );
77 0         0 $url .= '&';
78              
79 0         0 $url .= 'password=' . escape( $password );
80 0         0 $url .= '&';
81              
82 0         0 $url .= 'host=' . escape( $hostname );
83              
84 0 0       0 if ( $domain ) {
85 0         0 $url .= '&';
86 0         0 $url .= 'domain=' . escape( $domain );
87             }
88              
89 0 0       0 if ( $ip ) {
90 0         0 $url .= '&';
91 0         0 $url .= 'ip=' . escape( $ip );
92             }
93            
94 0         0 my $ua = LWP::UserAgent->new( env_proxy => 1 );
95 0         0 my $req = HTTP::Request->new( "GET", $url );
96 0         0 my $res = $ua->request($req);
97              
98 0 0       0 if ( $res->is_success ) {
99 0         0 my ($code, $message) = ( $res->content =~ /(\d+)\s+(.+)$/i );
100 0 0       0 return 1 if $code eq '200';
101 0         0 carp "Update failed: $code - $message";
102 0         0 return undef;
103             }
104 0         0 carp "Update failed: " . $res->status_line;
105            
106 0         0 return undef;
107             }
108              
109             =item B - Return local IP of the machine
110              
111             =cut
112              
113             sub get_ip {
114 1     1 1 565 my ($self, $interface) = @_;
115              
116 1 50       4 return undef unless $interface;
117              
118 1         4 my $win32 = 0;
119 1 50       16 $win32 = 1 if $^O =~ /win32|cygwin/i;
120              
121 1         2 my $ip;
122 1 50       4 if ($win32) {
123 0         0 my $ipconfig = `ipconfig`;
124 0         0 $ipconfig =~ /IP.+?: ([0-9]{1,3}(\.[0-9]{1,3}){3})$/s;
125 0         0 $ip = $1;
126 0 0       0 warn "Cannot get IP address from ipconfig output:\n$ipconfig"
127             unless $ip;
128             } else {
129 1         13304 $ip = `/sbin/ifconfig $interface`;
130 1 50       477 if ($ip !~ s/^.*inet (?:addr:)?([0-9]{1,3}(\.[0-9]{1,3}){3}).*$/$1/s) {
131 0         0 warn "Cannot get IP address from ifconfig output:\n$ip";
132 0         0 return undef;
133             }
134             }
135 1         123 return $ip;
136             }
137              
138             =back
139              
140             =cut
141              
142             1;
143             __END__