Blame lib/Net/Time.pm

Packit bd23c0
# Net::Time.pm
Packit bd23c0
#
Packit bd23c0
# Copyright (C) 1995-2004 Graham Barr.  All rights reserved.
Packit bd23c0
# Copyright (C) 2014 Steve Hay.  All rights reserved.
Packit bd23c0
# This module is free software; you can redistribute it and/or modify it under
Packit bd23c0
# the same terms as Perl itself, i.e. under the terms of either the GNU General
Packit bd23c0
# Public License or the Artistic License, as specified in the F<LICENCE> file.
Packit bd23c0
Packit bd23c0
package Net::Time;
Packit bd23c0
Packit bd23c0
use 5.008001;
Packit bd23c0
Packit bd23c0
use strict;
Packit bd23c0
use warnings;
Packit bd23c0
Packit bd23c0
use Carp;
Packit bd23c0
use Exporter;
Packit bd23c0
use IO::Select;
Packit bd23c0
use IO::Socket;
Packit bd23c0
use Net::Config;
Packit bd23c0
Packit bd23c0
our @ISA       = qw(Exporter);
Packit bd23c0
our @EXPORT_OK = qw(inet_time inet_daytime);
Packit bd23c0
Packit bd23c0
our $VERSION = "3.11";
Packit bd23c0
Packit bd23c0
our $TIMEOUT = 120;
Packit bd23c0
Packit bd23c0
sub _socket {
Packit bd23c0
  my ($pname, $pnum, $host, $proto, $timeout) = @_;
Packit bd23c0
Packit bd23c0
  $proto ||= 'udp';
Packit bd23c0
Packit bd23c0
  my $port = (getservbyname($pname, $proto))[2] || $pnum;
Packit bd23c0
Packit bd23c0
  my $hosts = defined $host ? [$host] : $NetConfig{$pname . '_hosts'};
Packit bd23c0
Packit bd23c0
  my $me;
Packit bd23c0
Packit bd23c0
  foreach my $addr (@$hosts) {
Packit bd23c0
    $me = IO::Socket::INET->new(
Packit bd23c0
      PeerAddr => $addr,
Packit bd23c0
      PeerPort => $port,
Packit bd23c0
      Proto    => $proto
Packit bd23c0
      )
Packit bd23c0
      and last;
Packit bd23c0
  }
Packit bd23c0
Packit bd23c0
  return unless $me;
Packit bd23c0
Packit bd23c0
  $me->send("\n")
Packit bd23c0
    if $proto eq 'udp';
Packit bd23c0
Packit bd23c0
  $timeout = $TIMEOUT
Packit bd23c0
    unless defined $timeout;
Packit bd23c0
Packit bd23c0
  IO::Select->new($me)->can_read($timeout)
Packit bd23c0
    ? $me
Packit bd23c0
    : undef;
Packit bd23c0
}
Packit bd23c0
Packit bd23c0
Packit bd23c0
sub inet_time {
Packit bd23c0
  my $s      = _socket('time', 37, @_) || return;
Packit bd23c0
  my $buf    = '';
Packit bd23c0
  my $offset = 0 | 0;
Packit bd23c0
Packit bd23c0
  return
Packit bd23c0
    unless defined $s->recv($buf, length(pack("N", 0)));
Packit bd23c0
Packit bd23c0
  # unpack, we | 0 to ensure we have an unsigned
Packit bd23c0
  my $time = (unpack("N", $buf))[0] | 0;
Packit bd23c0
Packit bd23c0
  # the time protocol return time in seconds since 1900, convert
Packit bd23c0
  # it to a the required format
Packit bd23c0
Packit bd23c0
  if ($^O eq "MacOS") {
Packit bd23c0
Packit bd23c0
    # MacOS return seconds since 1904, 1900 was not a leap year.
Packit bd23c0
    $offset = (4 * 31536000) | 0;
Packit bd23c0
  }
Packit bd23c0
  else {
Packit bd23c0
Packit bd23c0
    # otherwise return seconds since 1972, there were 17 leap years between
Packit bd23c0
    # 1900 and 1972
Packit bd23c0
    $offset = (70 * 31536000 + 17 * 86400) | 0;
Packit bd23c0
  }
Packit bd23c0
Packit bd23c0
  $time - $offset;
Packit bd23c0
}
Packit bd23c0
Packit bd23c0
Packit bd23c0
sub inet_daytime {
Packit bd23c0
  my $s   = _socket('daytime', 13, @_) || return;
Packit bd23c0
  my $buf = '';
Packit bd23c0
Packit bd23c0
  defined($s->recv($buf, 1024))
Packit bd23c0
    ? $buf
Packit bd23c0
    : undef;
Packit bd23c0
}
Packit bd23c0
Packit bd23c0
1;
Packit bd23c0
Packit bd23c0
__END__
Packit bd23c0
Packit bd23c0
=head1 NAME
Packit bd23c0
Packit bd23c0
Net::Time - time and daytime network client interface
Packit bd23c0
Packit bd23c0
=head1 SYNOPSIS
Packit bd23c0
Packit bd23c0
    use Net::Time qw(inet_time inet_daytime);
Packit bd23c0
Packit bd23c0
    print inet_time();          # use default host from Net::Config
Packit bd23c0
    print inet_time('localhost');
Packit bd23c0
    print inet_time('localhost', 'tcp');
Packit bd23c0
Packit bd23c0
    print inet_daytime();       # use default host from Net::Config
Packit bd23c0
    print inet_daytime('localhost');
Packit bd23c0
    print inet_daytime('localhost', 'tcp');
Packit bd23c0
Packit bd23c0
=head1 DESCRIPTION
Packit bd23c0
Packit bd23c0
C<Net::Time> provides subroutines that obtain the time on a remote machine.
Packit bd23c0
Packit bd23c0
=over 4
Packit bd23c0
Packit bd23c0
=item inet_time ( [HOST [, PROTOCOL [, TIMEOUT]]])
Packit bd23c0
Packit bd23c0
Obtain the time on C<HOST>, or some default host if C<HOST> is not given
Packit bd23c0
or not defined, using the protocol as defined in RFC868. The optional
Packit bd23c0
argument C<PROTOCOL> should define the protocol to use, either C<tcp> or
Packit bd23c0
C<udp>. The result will be a time value in the same units as returned
Packit bd23c0
by time() or I<undef> upon failure.
Packit bd23c0
Packit bd23c0
=item inet_daytime ( [HOST [, PROTOCOL [, TIMEOUT]]])
Packit bd23c0
Packit bd23c0
Obtain the time on C<HOST>, or some default host if C<HOST> is not given
Packit bd23c0
or not defined, using the protocol as defined in RFC867. The optional
Packit bd23c0
argument C<PROTOCOL> should define the protocol to use, either C<tcp> or
Packit bd23c0
C<udp>. The result will be an ASCII string or I<undef> upon failure.
Packit bd23c0
Packit bd23c0
=back
Packit bd23c0
Packit bd23c0
=head1 AUTHOR
Packit bd23c0
Packit bd23c0
Graham Barr E<lt>F<gbarr@pobox.com>E<gt>.
Packit bd23c0
Packit bd23c0
Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
Packit bd23c0
1.22_02.
Packit bd23c0
Packit bd23c0
=head1 COPYRIGHT
Packit bd23c0
Packit bd23c0
Copyright (C) 1995-2004 Graham Barr.  All rights reserved.
Packit bd23c0
Packit bd23c0
Copyright (C) 2014 Steve Hay.  All rights reserved.
Packit bd23c0
Packit bd23c0
=head1 LICENCE
Packit bd23c0
Packit bd23c0
This module is free software; you can redistribute it and/or modify it under the
Packit bd23c0
same terms as Perl itself, i.e. under the terms of either the GNU General Public
Packit bd23c0
License or the Artistic License, as specified in the F<LICENCE> file.
Packit bd23c0
Packit bd23c0
=cut