xref: /openbsd-src/gnu/usr.bin/perl/cpan/libnet/lib/Net/Time.pm (revision e068048151d29f2562a32185e21a8ba885482260)
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