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