more complete File::Spec support for Mac and VMS, tests (from
[p5sagit/p5-mst-13.2.git] / lib / Sys / Hostname.pm
CommitLineData
a0d0e21e 1package Sys::Hostname;
8990e307 2
a0d0e21e 3use Carp;
8990e307 4require Exporter;
a0d0e21e 5@ISA = qw(Exporter);
6@EXPORT = qw(hostname);
8990e307 7
cb1a09d0 8=head1 NAME
9
10Sys::Hostname - Try every conceivable way to get hostname
11
12=head1 SYNOPSIS
13
14 use Sys::Hostname;
15 $host = hostname;
16
17=head1 DESCRIPTION
18
19Attempts several methods of getting the system hostname and
20then caches the result. It tries C<syscall(SYS_gethostname)>,
21C<`hostname`>, C<`uname -n`>, and the file F</com/host>.
22If all that fails it C<croak>s.
23
24All nulls, returns, and newlines are removed from the result.
25
26=head1 AUTHOR
27
1fef88e7 28David Sundstrom E<lt>F<sunds@asictest.sc.ti.com>E<gt>
cb1a09d0 29
30Texas Instruments
31
32=cut
8990e307 33
34sub hostname {
a0d0e21e 35
567d72c2 36 # method 1 - we already know it
37 return $host if defined $host;
38
c5f45532 39 if ($^O eq 'VMS') {
567d72c2 40
41 # method 2 - no sockets ==> return DECnet node name
84902520 42 eval { local $SIG{__DIE__}; $host = (gethostbyname('me'))[0] };
c5f45532 43 if ($@) { return $host = $ENV{'SYS$NODE'}; }
567d72c2 44
45 # method 3 - has someone else done the job already? It's common for the
46 # TCP/IP stack to advertise the hostname via a logical name. (Are
47 # there any other logicals which TCP/IP stacks use for the host name?)
48 $host = $ENV{'ARPANET_HOST_NAME'} || $ENV{'INTERNET_HOST_NAME'} ||
49 $ENV{'MULTINET_HOST_NAME'} || $ENV{'UCX$INET_HOST'} ||
50 $ENV{'TCPWARE_DOMAINNAME'} || $ENV{'NEWS_ADDRESS'};
51 return $host if $host;
52
53 # method 4 - does hostname happen to work?
54 my($rslt) = `hostname`;
55 if ($rslt !~ /IVVERB/) { ($host) = $rslt =~ /^(\S+)/; }
56 return $host if $host;
57
58 # rats!
c5f45532 59 $host = '';
567d72c2 60 Carp::croak "Cannot get host name of local machine";
61
62 }
7bac28a0 63 elsif ($^O eq 'MSWin32') {
64 ($host) = gethostbyname('localhost');
65 chomp($host = `hostname 2> NUL`) unless defined $host;
66 return $host;
67 }
3a2f06e9 68 elsif ($^O eq 'epoc') {
69 $host = 'localhost';
70 return $host;
71 }
567d72c2 72 else { # Unix
8990e307 73
154a3d54 74 # method 2 - syscall is preferred since it avoids tainting problems
8990e307 75 eval {
84902520 76 local $SIG{__DIE__};
6bb694c1 77 require "syscall.ph";
8990e307 78 $host = "\0" x 65; ## preload scalar
6bb694c1 79 syscall(&SYS_gethostname, $host, 65) == 0;
8990e307 80 }
81
154a3d54 82 # method 2a - syscall using systeminfo instead of gethostname
67693aa5 83 # -- needed on systems like Solaris
84 || eval {
85 local $SIG{__DIE__};
6bb694c1 86 require "sys/syscall.ph";
87 require "sys/systeminfo.ph";
67693aa5 88 $host = "\0" x 65; ## preload scalar
6bb694c1 89 syscall(&SYS_systeminfo, &SI_HOSTNAME, $host, 65) != -1;
67693aa5 90 }
91
154a3d54 92 # method 3 - trusty old hostname command
8990e307 93 || eval {
84902520 94 local $SIG{__DIE__};
b522bf06 95 local $SIG{CHLD};
a0d0e21e 96 $host = `(hostname) 2>/dev/null`; # bsdish
8990e307 97 }
98
154a3d54 99 # method 4 - use POSIX::uname(), which strictly can't be expected to be
100 # correct
101 || eval {
102 local $SIG{__DIE__};
103 require POSIX;
104 $host = (POSIX::uname())[1];
105 }
106
6bb694c1 107 # method 5 - sysV uname command (may truncate)
8990e307 108 || eval {
84902520 109 local $SIG{__DIE__};
85e6fe83 110 $host = `uname -n 2>/dev/null`; ## sysVish
8990e307 111 }
112
6bb694c1 113 # method 6 - Apollo pre-SR10
8990e307 114 || eval {
84902520 115 local $SIG{__DIE__};
8990e307 116 ($host,$a,$b,$c,$d)=split(/[:\. ]/,`/com/host`,6);
117 }
118
119 # bummer
a0d0e21e 120 || Carp::croak "Cannot get host name of local machine";
8990e307 121
122 # remove garbage
123 $host =~ tr/\0\r\n//d;
124 $host;
567d72c2 125 }
8990e307 126}
127
1281;