package network::test; # $Id$ use strict; use MDK::Common; use run_program; use Socket; sub new { my ($class, $o_hostname) = @_; bless { hostname => $o_hostname || "mandrakesoft.com" }, $class; } #- launch synchronous test, will hang until the test finishes sub test_synchronous { my ($o) = @_; ($o->{address}, $o->{ping}) = resolve_and_ping($o->{hostname}); $o->{done} = 1; } #- launch asynchronous test, won't hang sub start { my ($o) = @_; $o->{done} = 0; $o->{kid} = bg_command->new(sub { my ($address, $ping) = resolve_and_ping($o->{hostname}); print "$address|$ping\n"; }); } #- abort asynchronous test sub abort { my ($o) = @_; if ($o->{kid}) { kill -9, $o->{kid}{pid}; undef $o->{kid}; } } #- returns a true value if the test is finished, usefull for asynchronous tests sub is_done { my ($o) = @_; $o->update_status; to_bool($o->{done}); } #- return a true value if the connection works (hostname resolution and ping) sub is_connected { my ($o) = @_; to_bool(defined($o->{hostname}) && defined($o->{ping})); } #- get hostname used in test for resolution and ping sub get_hostname { my ($o) = @_; $o->{hostname}; } #- get resolved address (if any) of given hostname sub get_address { my ($o) = @_; $o->{address}; } #- get ping (if any) to given hostname sub get_ping { my ($o) = @_; $o->{ping}; } sub resolve_and_ping { my ($hostname) = @_; require Net::Ping; require Time::HiRes; my $p; if ($>) { $p = Net::Ping->new('tcp'); # Try connecting to the www port instead of the echo port $p->{port_num} = getservbyname('http', 'tcp'); } else { $p = Net::Ping->new('icmp'); } $p->hires; #- get ping as float #- default timeout is 5 seconds my ($ret, $ping, $address) = $p->ping($hostname, 5); if ($ret) { return $address, $ping; } elsif (defined($ret)) { return $address; } } sub update_status { my ($o) = @_; if ($o->{kid}) { my $fd = $o->{kid}{fd}; fcntl($fd, c::F_SETFL(), c::O_NONBLOCK()) or die "can't fcntl F_SETFL: $!"; local $| = 1; if (defined(my $output = <$fd>)) { ($o->{address}, $o->{ping}) = $output =~ /^([\d\.]+)\|([\d\.,]+)*$/; $o->{done} = 1; undef $o->{kid}; } } } 1; =head1 network::test =head2 Test synchronously #- resolve and get ping to hostname from command line if given, else to Mandrakesoft use lib qw(/usr/lib/libDrakX); use network::test; my $net_test = network::test->new($ARGV[0]); $net_test->test_synchronous; my $is_connected = $net_test->is_connected; my $hostname = $net_test->get_hostname; my $address = $net_test->get_address; my $ping = $net_test->get_ping; print "connected: $is_connected host: $hostname resolved host: $address ping to host: $ping "; =head2 Test asynchronously #- resolve and get ping to hostname from command line if given, else to Mandrakesoft #- prints a "." every 10 miliseconds during connection test use lib qw(/usr/lib/libDrakX); use network::test; my $net_test = network::test->new($ARGV[0]); $net_test->start; do { print ".\n"; select(undef, undef, undef, 0.01); } while !$net_test->is_done; my $is_connected = $net_test->is_connected; my $hostname = $net_test->get_hostname; my $address = $net_test->get_address; my $ping = $net_test->get_ping; print "connected: $is_connected host: $hostname resolved host: $address ping to host: $ping "; =cut