This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
CGI.pm broke again
[perl5.git] / lib / Net / netent.pm
CommitLineData
36477c24 1package Net::netent;
2use strict;
3
4BEGIN {
5 use Exporter ();
8cc95fdb 6 use vars qw(@EXPORT @EXPORT_OK %EXPORT_TAGS);
36477c24 7 @EXPORT = qw(getnetbyname getnetbyaddr getnet);
8 @EXPORT_OK = qw(
9 $n_name @n_aliases
10 $n_addrtype $n_net
11 );
12 %EXPORT_TAGS = ( FIELDS => [ @EXPORT_OK, @EXPORT ] );
13}
14use vars @EXPORT_OK;
15
8cc95fdb 16# Class::Struct forbids use of @ISA
17sub import { goto &Exporter::import }
18
19use Class::Struct qw(struct);
36477c24 20struct 'Net::netent' => [
21 name => '$',
22 aliases => '@',
23 addrtype => '$',
24 net => '$',
25];
26
27sub populate (@) {
28 return unless @_;
29 my $nob = new();
30 $n_name = $nob->[0] = $_[0];
31 @n_aliases = @{ $nob->[1] } = split ' ', $_[1];
32 $n_addrtype = $nob->[2] = $_[2];
33 $n_net = $nob->[3] = $_[3];
34 return $nob;
35}
36
37sub getnetbyname ($) { populate(CORE::getnetbyname(shift)) }
38
39sub getnetbyaddr ($;$) {
40 my ($net, $addrtype);
41 $net = shift;
42 require Socket if @_;
43 $addrtype = @_ ? shift : Socket::AF_INET();
44 populate(CORE::getnetbyaddr($net, $addrtype))
45}
46
47sub getnet($) {
48 if ($_[0] =~ /^\d+(?:\.\d+(?:\.\d+(?:\.\d+)?)?)?$/) {
49 require Socket;
50 &getnetbyaddr(Socket::inet_aton(shift));
51 } else {
52 &getnetbyname;
53 }
54}
55
561;
57__END__
58
59=head1 NAME
60
61Net::netent - by-name interface to Perl's built-in getnet*() functions
62
63=head1 SYNOPSIS
64
65 use Net::netent qw(:FIELDS);
66 getnetbyname("loopback") or die "bad net";
67 printf "%s is %08X\n", $n_name, $n_net;
68
69 use Net::netent;
70
71 $n = getnetbyname("loopback") or die "bad net";
72 { # there's gotta be a better way, eh?
73 @bytes = unpack("C4", pack("N", $n->net));
74 shift @bytes while @bytes && $bytes[0] == 0;
75 }
76 printf "%s is %08X [%d.%d.%d.%d]\n", $n->name, $n->net, @bytes;
77
78=head1 DESCRIPTION
79
80This module's default exports override the core getnetbyname() and
81getnetbyaddr() functions, replacing them with versions that return
82"Net::netent" objects. This object has methods that return the similarly
83named structure field name from the C's netent structure from F<netdb.h>;
84namely name, aliases, addrtype, and net. The aliases
85method returns an array reference, the rest scalars.
86
87You may also import all the structure fields directly into your namespace
88as regular variables using the :FIELDS import tag. (Note that this still
89overrides your core functions.) Access these fields as variables named
90with a preceding C<n_>. Thus, C<$net_obj-E<gt>name()> corresponds to
91$n_name if you import the fields. Array references are available as
92regular array variables, so for example C<@{ $net_obj-E<gt>aliases()
93}> would be simply @n_aliases.
94
95The getnet() funtion is a simple front-end that forwards a numeric
96argument to getnetbyaddr(), and the rest
97to getnetbyname().
98
99To access this functionality without the core overrides,
100pass the C<use> an empty import list, and then access
101function functions with their full qualified names.
102On the other hand, the built-ins are still available
103via the C<CORE::> pseudo-package.
104
105=head1 EXAMPLES
106
107The getnet() functions do this in the Perl core:
108
109 sv_setiv(sv, (I32)nent->n_net);
110
111The gethost() functions do this in the Perl core:
112
113 sv_setpvn(sv, hent->h_addr, len);
114
115That means that the address comes back in binary for the
116host functions, and as a regular perl integer for the net ones.
117This seems a bug, but here's how to deal with it:
a6006777 118
36477c24 119 use strict;
120 use Socket;
121 use Net::netent;
122
123 @ARGV = ('loopback') unless @ARGV;
124
125 my($n, $net);
126
127 for $net ( @ARGV ) {
128
129 unless ($n = getnetbyname($net)) {
130 warn "$0: no such net: $net\n";
131 next;
132 }
133
134 printf "\n%s is %s%s\n",
135 $net,
136 lc($n->name) eq lc($net) ? "" : "*really* ",
137 $n->name;
138
139 print "\taliases are ", join(", ", @{$n->aliases}), "\n"
140 if @{$n->aliases};
141
142 # this is stupid; first, why is this not in binary?
143 # second, why am i going through these convolutions
144 # to make it looks right
145 {
146 my @a = unpack("C4", pack("N", $n->net));
147 shift @a while @a && $a[0] == 0;
148 printf "\taddr is %s [%d.%d.%d.%d]\n", $n->net, @a;
149 }
150
151 if ($n = getnetbyaddr($n->net)) {
152 if (lc($n->name) ne lc($net)) {
153 printf "\tThat addr reverses to net %s!\n", $n->name;
154 $net = $n->name;
155 redo;
156 }
157 }
158 }
a6006777 159
36477c24 160=head1 NOTE
161
8cc95fdb 162While this class is currently implemented using the Class::Struct
36477c24 163module to build a struct-like class, you shouldn't rely upon this.
164
165=head1 AUTHOR
166
167Tom Christiansen