3 # Versions up to 2.21 Copyright (c) 1995-1998 Graham Barr <gbarr@pobox.com>.
5 # Changes in Version 2.22 onwards Copyright (C) 2013-2014 Steve Hay. All rights
7 # This module is free software; you can redistribute it and/or modify it under
8 # the same terms as Perl itself, i.e. under the terms of either the GNU General
9 # Public License or the Artistic License, as specified in the F<LICENCE> file.
22 our @ISA = qw(Exporter);
23 our @EXPORT_OK = qw(hostname hostdomain hostfqdn domainname);
24 our $VERSION = "3.06";
26 my ($host, $domain, $fqdn) = (undef, undef, undef);
28 # Try every conceivable way to get hostname.
37 if ($^O eq 'MSWin32') {
39 my ($name, $alias, $type, $len, @addr) = gethostbyname($ENV{'COMPUTERNAME'} || 'localhost');
42 $host = gethostbyaddr($a, Socket::AF_INET());
43 last if defined $host;
45 if (defined($host) && index($host, '.') > 0) {
47 ($host, $domain) = $fqdn =~ /^([^.]+)\.(.*)$/;
51 elsif ($^O eq 'MacOS') {
52 chomp($host = `hostname`);
54 elsif ($^O eq 'VMS') { ## multiple varieties of net s/w makes this hard
55 $host = $ENV{'UCX$INET_HOST'} if defined($ENV{'UCX$INET_HOST'});
56 $host = $ENV{'MULTINET_HOST_NAME'} if defined($ENV{'MULTINET_HOST_NAME'});
57 if (index($host, '.') > 0) {
59 ($host, $domain) = $fqdn =~ /^([^.]+)\.(.*)$/;
64 local $SIG{'__DIE__'};
66 # syscall is preferred since it avoids tainting problems
68 my $tmp = "\0" x 256; ## preload scalar
71 require "syscall.ph"; ## no critic (Modules::RequireBarewordIncludes)
72 defined(&main::SYS_gethostname);
76 require "sys/syscall.ph"; ## no critic (Modules::RequireBarewordIncludes)
77 defined(&main::SYS_gethostname);
80 (syscall(&main::SYS_gethostname, $tmp, 256) == 0)
88 $host = (POSIX::uname())[1];
91 # trusty old hostname command
93 chop($host = `(hostname) 2>/dev/null`); # BSD'ish
96 # sysV/POSIX uname command (may truncate)
98 chop($host = `uname -n 2>/dev/null`); ## SYSV'ish && POSIX'ish
102 || eval { $host = (split(/[:. ]/, `/com/host`, 6))[0]; }
104 || eval { $host = ""; };
108 $host =~ s/[\0\r\n]+//go;
109 $host =~ s/(\A\.+|\.+\Z)//go;
110 $host =~ s/\.\.+/\./go;
120 if (defined $domain);
122 local $SIG{'__DIE__'};
124 return $domain = $NetConfig{'inet_domain'}
125 if defined $NetConfig{'inet_domain'};
127 # try looking in /etc/resolv.conf
128 # putting this here and assuming that it is correct, eliminates
129 # calls to gethostbyname, and therefore DNS lookups. This helps
130 # those on dialup systems.
134 if (open(my $res, '<', "/etc/resolv.conf")) {
137 if (/\A\s*(?:domain|search)\s+(\S+)/);
142 if (defined $domain);
145 # just try hostname and system calls
147 my $host = _hostname();
150 @hosts = ($host, "localhost");
152 unless (defined($host) && $host =~ /\./) {
155 my $tmp = "\0" x 256; ## preload scalar
158 require "syscall.ph"; ## no critic (Modules::RequireBarewordIncludes)
162 require "sys/syscall.ph"; ## no critic (Modules::RequireBarewordIncludes)
165 (syscall(&main::SYS_getdomainname, $tmp, 256) == 0)
171 $dom ||= $ENV{'TCPIP$INET_DOMAIN'}
172 || $ENV{'UCX$INET_DOMAIN'};
175 chop($dom = `domainname 2>/dev/null`)
176 unless (defined $dom || $^O =~ /^(?:cygwin|MSWin32|android)/);
181 while (length($dom)) {
182 push(@h, "$host.$dom");
183 $dom =~ s/^[^.]+.+// or last;
189 # Attempt to locate FQDN
191 foreach (grep { defined $_ } @hosts) {
192 my @info = gethostbyname($_);
196 # look at real name & aliases
197 foreach my $site ($info[0], split(/ /, $info[1])) {
198 if (rindex($site, ".") > 0) {
200 # Extract domain from FQDN
202 ($domain = $site) =~ s/\A[^.]+\.//;
208 # Look for environment variable
210 $domain ||= $ENV{LOCALDOMAIN} || $ENV{DOMAIN};
212 if (defined $domain) {
213 $domain =~ s/[\r\n\0]+//g;
214 $domain =~ s/(\A\.+|\.+\Z)//g;
215 $domain =~ s/\.\.+/\./g;
229 # *.local names are special on darwin. If we call gethostbyname below, it
230 # may hang while waiting for another, non-existent computer to respond.
231 if($^O eq 'darwin' && $host =~ /\.local$/) {
237 # Assumption: If the host name does not contain a period
238 # and the domain name does, then assume that they are correct
239 # this helps to eliminate calls to gethostbyname, and therefore
240 # eliminate DNS lookups
242 return $fqdn = $host . "." . $domain
246 and $domain =~ /\./);
248 # For hosts that have no name, just an IP address
249 return $fqdn = $host if defined $host and $host =~ /^\d+(\.\d+){3}$/;
251 my @host = defined $host ? split(/\./, $host) : ('localhost');
252 my @domain = defined $domain ? split(/\./, $domain) : ();
255 # Determine from @host & @domain the FQDN
263 my $tmp = join(".", @h, @d);
264 if ((gethostbyname($tmp))[0]) {
271 last unless shift @d;
276 until ((gethostbyname($host))[0]) {
277 $host .= "." . shift @fqdn;
279 $domain = join(".", @fqdn);
291 sub hostfqdn { domainname() }
296 unless (defined $host);
303 unless (defined $domain);
307 1; # Keep require happy
313 Net::Domain - Attempt to evaluate the current host's internet name and domain
317 use Net::Domain qw(hostname hostfqdn hostdomain domainname);
321 Using various methods B<attempt> to find the Fully Qualified Domain Name (FQDN)
322 of the current host. From this determine the host-name and the host-domain.
324 Each of the functions will return I<undef> if the FQDN cannot be determined.
330 Identify and return the FQDN of the current host.
334 An alias for hostfqdn ().
338 Returns the smallest part of the FQDN which can be used to identify the host.
342 Returns the remainder of the FQDN after the I<hostname> has been removed.
348 Graham Barr E<lt>F<gbarr@pobox.com>E<gt>.
349 Adapted from Sys::Hostname by David Sundstrom E<lt>F<sunds@asictest.sc.ti.com>E<gt>
351 Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
356 Versions up to 2.21 Copyright (c) 1995-1998 Graham Barr. All rights reserved.
357 Changes in Version 2.22 onwards Copyright (C) 2013-2014 Steve Hay. All rights
360 This module is free software; you can redistribute it and/or modify it under the
361 same terms as Perl itself, i.e. under the terms of either the GNU General Public
362 License or the Artistic License, as specified in the F<LICENCE> file.