1b8851fccSafresh1# Net::Time.pm 2b8851fccSafresh1# 35759b3d2Safresh1# Copyright (C) 1995-2004 Graham Barr. All rights reserved. 4eac174f2Safresh1# Copyright (C) 2014, 2020 Steve Hay. All rights reserved. 5b8851fccSafresh1# This module is free software; you can redistribute it and/or modify it under 6b8851fccSafresh1# the same terms as Perl itself, i.e. under the terms of either the GNU General 7b8851fccSafresh1# Public License or the Artistic License, as specified in the F<LICENCE> file. 8b8851fccSafresh1 9b8851fccSafresh1package Net::Time; 10b8851fccSafresh1 11b8851fccSafresh1use 5.008001; 12b8851fccSafresh1 13b8851fccSafresh1use strict; 14b8851fccSafresh1use warnings; 15b8851fccSafresh1 16b8851fccSafresh1use Carp; 17b8851fccSafresh1use Exporter; 18b8851fccSafresh1use IO::Select; 19b8851fccSafresh1use IO::Socket; 20b8851fccSafresh1use Net::Config; 21b8851fccSafresh1 22b8851fccSafresh1our @ISA = qw(Exporter); 23b8851fccSafresh1our @EXPORT_OK = qw(inet_time inet_daytime); 24b8851fccSafresh1 25*e0680481Safresh1our $VERSION = "3.15"; 26b8851fccSafresh1 27b8851fccSafresh1our $TIMEOUT = 120; 28b8851fccSafresh1 29b8851fccSafresh1sub _socket { 30b8851fccSafresh1 my ($pname, $pnum, $host, $proto, $timeout) = @_; 31b8851fccSafresh1 32b8851fccSafresh1 $proto ||= 'udp'; 33b8851fccSafresh1 34b8851fccSafresh1 my $port = (getservbyname($pname, $proto))[2] || $pnum; 35b8851fccSafresh1 36b8851fccSafresh1 my $hosts = defined $host ? [$host] : $NetConfig{$pname . '_hosts'}; 37b8851fccSafresh1 38b8851fccSafresh1 my $me; 39b8851fccSafresh1 40b8851fccSafresh1 foreach my $addr (@$hosts) { 41b8851fccSafresh1 $me = IO::Socket::INET->new( 42b8851fccSafresh1 PeerAddr => $addr, 43b8851fccSafresh1 PeerPort => $port, 44b8851fccSafresh1 Proto => $proto 45b8851fccSafresh1 ) 46b8851fccSafresh1 and last; 47b8851fccSafresh1 } 48b8851fccSafresh1 49b8851fccSafresh1 return unless $me; 50b8851fccSafresh1 51b8851fccSafresh1 $me->send("\n") 52b8851fccSafresh1 if $proto eq 'udp'; 53b8851fccSafresh1 54b8851fccSafresh1 $timeout = $TIMEOUT 55b8851fccSafresh1 unless defined $timeout; 56b8851fccSafresh1 57b8851fccSafresh1 IO::Select->new($me)->can_read($timeout) 58b8851fccSafresh1 ? $me 59b8851fccSafresh1 : undef; 60b8851fccSafresh1} 61b8851fccSafresh1 62b8851fccSafresh1 63b8851fccSafresh1sub inet_time { 64b8851fccSafresh1 my $s = _socket('time', 37, @_) || return; 65b8851fccSafresh1 my $buf = ''; 66b8851fccSafresh1 my $offset = 0 | 0; 67b8851fccSafresh1 68b8851fccSafresh1 return 69b8851fccSafresh1 unless defined $s->recv($buf, length(pack("N", 0))); 70b8851fccSafresh1 71b8851fccSafresh1 # unpack, we | 0 to ensure we have an unsigned 72b8851fccSafresh1 my $time = (unpack("N", $buf))[0] | 0; 73b8851fccSafresh1 74b8851fccSafresh1 # the time protocol return time in seconds since 1900, convert 75b8851fccSafresh1 # it to a the required format 76b8851fccSafresh1 77b8851fccSafresh1 if ($^O eq "MacOS") { 78b8851fccSafresh1 79b8851fccSafresh1 # MacOS return seconds since 1904, 1900 was not a leap year. 80b8851fccSafresh1 $offset = (4 * 31536000) | 0; 81b8851fccSafresh1 } 82b8851fccSafresh1 else { 83b8851fccSafresh1 84b8851fccSafresh1 # otherwise return seconds since 1972, there were 17 leap years between 85b8851fccSafresh1 # 1900 and 1972 86b8851fccSafresh1 $offset = (70 * 31536000 + 17 * 86400) | 0; 87b8851fccSafresh1 } 88b8851fccSafresh1 89b8851fccSafresh1 $time - $offset; 90b8851fccSafresh1} 91b8851fccSafresh1 92b8851fccSafresh1 93b8851fccSafresh1sub inet_daytime { 94b8851fccSafresh1 my $s = _socket('daytime', 13, @_) || return; 95b8851fccSafresh1 my $buf = ''; 96b8851fccSafresh1 97b8851fccSafresh1 defined($s->recv($buf, 1024)) 98b8851fccSafresh1 ? $buf 99b8851fccSafresh1 : undef; 100b8851fccSafresh1} 101b8851fccSafresh1 102b8851fccSafresh11; 103b8851fccSafresh1 104b8851fccSafresh1__END__ 105b8851fccSafresh1 106b8851fccSafresh1=head1 NAME 107b8851fccSafresh1 108b8851fccSafresh1Net::Time - time and daytime network client interface 109b8851fccSafresh1 110b8851fccSafresh1=head1 SYNOPSIS 111b8851fccSafresh1 112b8851fccSafresh1 use Net::Time qw(inet_time inet_daytime); 113b8851fccSafresh1 114b8851fccSafresh1 print inet_time(); # use default host from Net::Config 115b8851fccSafresh1 print inet_time('localhost'); 116b8851fccSafresh1 print inet_time('localhost', 'tcp'); 117b8851fccSafresh1 118b8851fccSafresh1 print inet_daytime(); # use default host from Net::Config 119b8851fccSafresh1 print inet_daytime('localhost'); 120b8851fccSafresh1 print inet_daytime('localhost', 'tcp'); 121b8851fccSafresh1 122b8851fccSafresh1=head1 DESCRIPTION 123b8851fccSafresh1 124b8851fccSafresh1C<Net::Time> provides subroutines that obtain the time on a remote machine. 125b8851fccSafresh1 126eac174f2Safresh1=head2 Functions 127eac174f2Safresh1 128b8851fccSafresh1=over 4 129b8851fccSafresh1 130eac174f2Safresh1=item C<inet_time([$host[, $protocol[, $timeout]]])> 131b8851fccSafresh1 132eac174f2Safresh1Obtain the time on C<$host>, or some default host if C<$host> is not given 133b8851fccSafresh1or not defined, using the protocol as defined in RFC868. The optional 134eac174f2Safresh1argument C<$protocol> should define the protocol to use, either C<tcp> or 135b8851fccSafresh1C<udp>. The result will be a time value in the same units as returned 136b8851fccSafresh1by time() or I<undef> upon failure. 137b8851fccSafresh1 138eac174f2Safresh1=item C<inet_daytime([$host[, $protocol[, $timeout]]])> 139b8851fccSafresh1 140eac174f2Safresh1Obtain the time on C<$host>, or some default host if C<$host> is not given 141b8851fccSafresh1or not defined, using the protocol as defined in RFC867. The optional 142eac174f2Safresh1argument C<$protocol> should define the protocol to use, either C<tcp> or 143b8851fccSafresh1C<udp>. The result will be an ASCII string or I<undef> upon failure. 144b8851fccSafresh1 145b8851fccSafresh1=back 146b8851fccSafresh1 147eac174f2Safresh1=head1 EXPORTS 148eac174f2Safresh1 149eac174f2Safresh1The following symbols are, or can be, exported by this module: 150eac174f2Safresh1 151eac174f2Safresh1=over 4 152eac174f2Safresh1 153eac174f2Safresh1=item Default Exports 154eac174f2Safresh1 155eac174f2Safresh1I<None>. 156eac174f2Safresh1 157eac174f2Safresh1=item Optional Exports 158eac174f2Safresh1 159eac174f2Safresh1C<inet_time>, 160eac174f2Safresh1C<inet_daytime>. 161eac174f2Safresh1 162eac174f2Safresh1=item Export Tags 163eac174f2Safresh1 164eac174f2Safresh1I<None>. 165eac174f2Safresh1 166eac174f2Safresh1=back 167eac174f2Safresh1 168eac174f2Safresh1=head1 KNOWN BUGS 169eac174f2Safresh1 170eac174f2Safresh1I<None>. 171eac174f2Safresh1 172b8851fccSafresh1=head1 AUTHOR 173b8851fccSafresh1 174eac174f2Safresh1Graham Barr E<lt>L<gbarr@pobox.com|mailto:gbarr@pobox.com>E<gt>. 175b8851fccSafresh1 176eac174f2Safresh1Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining 177eac174f2Safresh1libnet as of version 1.22_02. 178b8851fccSafresh1 179b8851fccSafresh1=head1 COPYRIGHT 180b8851fccSafresh1 1815759b3d2Safresh1Copyright (C) 1995-2004 Graham Barr. All rights reserved. 1825759b3d2Safresh1 183eac174f2Safresh1Copyright (C) 2014, 2020 Steve Hay. All rights reserved. 1845759b3d2Safresh1 1855759b3d2Safresh1=head1 LICENCE 186b8851fccSafresh1 187b8851fccSafresh1This module is free software; you can redistribute it and/or modify it under the 188b8851fccSafresh1same terms as Perl itself, i.e. under the terms of either the GNU General Public 189b8851fccSafresh1License or the Artistic License, as specified in the F<LICENCE> file. 190b8851fccSafresh1 191eac174f2Safresh1=head1 VERSION 192eac174f2Safresh1 193*e0680481Safresh1Version 3.15 194eac174f2Safresh1 195eac174f2Safresh1=head1 DATE 196eac174f2Safresh1 197*e0680481Safresh120 March 2023 198eac174f2Safresh1 199eac174f2Safresh1=head1 HISTORY 200eac174f2Safresh1 201eac174f2Safresh1See the F<Changes> file. 202eac174f2Safresh1 203b8851fccSafresh1=cut 204