1package Sys::Hostname;
2
3use strict;
4
5use Carp;
6
7require Exporter;
8
9our @ISA     = qw/ Exporter /;
10our @EXPORT  = qw/ hostname /;
11
12our $VERSION;
13
14use warnings ();
15
16our $host;
17
18BEGIN {
19    $VERSION = '1.22';
20    {
21	local $SIG{__DIE__};
22	eval {
23	    require XSLoader;
24	    XSLoader::load();
25	};
26	warn $@ if $@;
27    }
28}
29
30
31sub hostname {
32  @_ and warnings::warnif("deprecated", "hostname() doesn't accept any arguments. This will become fatal in Perl 5.32");
33
34  # method 1 - we already know it
35  return $host if defined $host;
36
37  # method 1' - try to ask the system
38  $host = ghname() if defined &ghname;
39  return $host if defined $host;
40
41  if ($^O eq 'VMS') {
42
43    # method 2 - no sockets ==> return DECnet node name
44    eval { local $SIG{__DIE__}; $host = (gethostbyname('me'))[0] };
45    if ($@) { return $host = $ENV{'SYS$NODE'}; }
46
47    # method 3 - has someone else done the job already?  It's common for the
48    #    TCP/IP stack to advertise the hostname via a logical name.  (Are
49    #    there any other logicals which TCP/IP stacks use for the host name?)
50    $host = $ENV{'ARPANET_HOST_NAME'}  || $ENV{'INTERNET_HOST_NAME'} ||
51            $ENV{'MULTINET_HOST_NAME'} || $ENV{'UCX$INET_HOST'}      ||
52            $ENV{'TCPWARE_DOMAINNAME'} || $ENV{'NEWS_ADDRESS'};
53    return $host if $host;
54
55    # method 4 - does hostname happen to work?
56    my($rslt) = `hostname`;
57    if ($rslt !~ /IVVERB/) { ($host) = $rslt =~ /^(\S+)/; }
58    return $host if $host;
59
60    # rats!
61    $host = '';
62    croak "Cannot get host name of local machine";
63
64  }
65  elsif ($^O eq 'MSWin32') {
66    ($host) = gethostbyname('localhost');
67    chomp($host = `hostname 2> NUL`) unless defined $host;
68    return $host;
69  }
70  else {  # Unix
71    # is anyone going to make it here?
72
73    local $ENV{PATH} = '/usr/bin:/bin:/usr/sbin:/sbin'; # Paranoia.
74
75    # method 2 - syscall is preferred since it avoids tainting problems
76    # XXX: is it such a good idea to return hostname untainted?
77    eval {
78	local $SIG{__DIE__};
79	require "syscall.ph";
80	$host = "\0" x 65; ## preload scalar
81	syscall(&SYS_gethostname, $host, 65) == 0;
82    }
83
84    # method 2a - syscall using systeminfo instead of gethostname
85    #           -- needed on systems like Solaris
86    || eval {
87	local $SIG{__DIE__};
88	require "sys/syscall.ph";
89	require "sys/systeminfo.ph";
90	$host = "\0" x 65; ## preload scalar
91	syscall(&SYS_systeminfo, &SI_HOSTNAME, $host, 65) != -1;
92    }
93
94    # method 3 - trusty old hostname command
95    || eval {
96	local $SIG{__DIE__};
97	local $SIG{CHLD};
98	$host = `(hostname) 2>/dev/null`; # BSDish
99    }
100
101    # method 4 - use POSIX::uname(), which strictly can't be expected to be
102    # correct
103    || eval {
104	local $SIG{__DIE__};
105	require POSIX;
106	$host = (POSIX::uname())[1];
107    }
108
109    # method 5 - sysV uname command (may truncate)
110    || eval {
111	local $SIG{__DIE__};
112	$host = `uname -n 2>/dev/null`; ## sysVish
113    }
114
115    # bummer
116    || croak "Cannot get host name of local machine";
117
118    # remove garbage
119    $host =~ tr/\0\r\n//d;
120    $host;
121  }
122}
123
1241;
125
126__END__
127
128=head1 NAME
129
130Sys::Hostname - Try every conceivable way to get hostname
131
132=head1 SYNOPSIS
133
134    use Sys::Hostname;
135    $host = hostname;
136
137=head1 DESCRIPTION
138
139Attempts several methods of getting the system hostname and
140then caches the result.  It tries the first available of the C
141library's gethostname(), C<`$Config{aphostname}`>, uname(2),
142C<syscall(SYS_gethostname)>, C<`hostname`>, C<`uname -n`>,
143and the file F</com/host>.  If all that fails it C<croak>s.
144
145All NULs, returns, and newlines are removed from the result.
146
147=head1 AUTHOR
148
149David Sundstrom E<lt>F<sunds@asictest.sc.ti.com>E<gt>
150
151Texas Instruments
152
153XS code added by Greg Bacon E<lt>F<gbacon@cs.uah.edu>E<gt>
154
155=cut
156
157