home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Updates / Perl / Perl_Libs / site_perl / Net / Domain.pm < prev    next >
Encoding:
Perl POD Document  |  1997-11-30  |  5.9 KB  |  298 lines

  1. # Net::Domain.pm
  2. #
  3. # Copyright (c) 1995-1997 Graham Barr <gbarr@pobox.com>. All rights reserved.
  4. # This program is free software; you can redistribute it and/or
  5. # modify it under the same terms as Perl itself.
  6.  
  7. package Net::Domain;
  8.  
  9. require Exporter;
  10.  
  11. use Carp;
  12. use strict;
  13. use vars qw($VERSION @ISA @EXPORT_OK);
  14. use Net::Config;
  15.  
  16. @ISA = qw(Exporter);
  17. @EXPORT_OK = qw(hostname hostdomain hostfqdn domainname);
  18.  
  19. $VERSION = "2.06"; # $Id: //depot/libnet/Net/Domain.pm#4$
  20.  
  21. my($host,$domain,$fqdn) = (undef,undef,undef);
  22.  
  23. # Try every conceivable way to get hostname.
  24.  
  25. sub _hostname {
  26.  
  27.     # we already know it
  28.     return $host
  29.         if(defined $host);
  30.  
  31.     local $SIG{__DIE__} = undef;
  32.  
  33.     # syscall is preferred since it avoids tainting problems
  34.     eval {
  35.         my $tmp = "\0" x 256; ## preload scalar
  36.         eval {
  37.             package main;
  38.              require "syscall.ph";
  39.         }
  40.         || eval {
  41.             package main;
  42.              require "sys/syscall.ph";
  43.         }
  44.         and $host = (syscall(&main::SYS_gethostname, $tmp, 256) == 0)
  45.         ? $tmp
  46.         : undef;
  47.     }
  48.  
  49.     # POSIX
  50.     || eval {
  51.     require POSIX;
  52.     $host = (POSIX::uname())[1];
  53.     }
  54.  
  55.     # trusty old hostname command
  56.     || eval {
  57.         chop($host = `(hostname) 2>/dev/null`); # BSD'ish
  58.     }
  59.  
  60.     # sysV/POSIX uname command (may truncate)
  61.     || eval {
  62.         chop($host = `uname -n 2>/dev/null`); ## SYSV'ish && POSIX'ish
  63.     }
  64.  
  65.     # Apollo pre-SR10
  66.     || eval {
  67.         $host = (split(/[:\. ]/,`/com/host`,6))[0];
  68.     }
  69.  
  70.     || eval {
  71.         $host = "";
  72.     };
  73.  
  74.     # remove garbage 
  75.     $host =~ s/[\0\r\n]+//go;
  76.     $host =~ s/(\A\.+|\.+\Z)//go;
  77.     $host =~ s/\.\.+/\./go;
  78.  
  79.     $host;
  80. }
  81.  
  82. sub _hostdomain {
  83.  
  84.     # we already know it
  85.     return $domain
  86.         if(defined $domain);
  87.  
  88.     local $SIG{__DIE__} = undef;
  89.  
  90.     return $domain = $NetConfig{'inet_domain'}
  91.     if defined $NetConfig{'inet_domain'};
  92.  
  93.     # try looking in /etc/resolv.conf
  94.     # putting this here and assuming that it is correct, eliminates
  95.     # calls to gethostbyname, and therefore DNS lookups. This helps
  96.     # those on dialup systems.
  97.  
  98.     local *RES;
  99.  
  100.     if(open(RES,"/etc/resolv.conf")) {
  101.         while(<RES>) {
  102.             $domain = $1
  103.                 if(/\A\s*(?:domain|search)\s+(\S+)/);
  104.         }
  105.         close(RES);
  106.  
  107.         return $domain
  108.             if(defined $domain);
  109.     }
  110.  
  111.     # just try hostname and system calls
  112.  
  113.     my $host = _hostname();
  114.     my(@hosts);
  115.     local($_);
  116.  
  117.     @hosts = ($host,"localhost");
  118.  
  119.     unless($host =~ /\./) {
  120.     my $dom = undef;
  121.         eval {
  122.             my $tmp = "\0" x 256; ## preload scalar
  123.             eval {
  124.                 package main;
  125.                  require "syscall.ph";
  126.             }
  127.             || eval {
  128.                 package main;
  129.                  require "sys/syscall.ph";
  130.             }
  131.             and $dom = (syscall(&main::SYS_getdomainname, $tmp, 256) == 0)
  132.             ? $tmp
  133.             : undef;
  134.         };
  135.  
  136.     chop($dom = `domainname 2>/dev/null`)
  137.         unless(defined $dom);
  138.  
  139.     if(defined $dom) {
  140.         my @h = ();
  141.         while(length($dom)) {
  142.         push(@h, "$host.$dom");
  143.         $dom =~ s/^[^.]+.//;
  144.         }
  145.         unshift(@hosts,@h);
  146.         }
  147.     }
  148.  
  149.     # Attempt to locate FQDN
  150.  
  151.     foreach (@hosts) {
  152.         my @info = gethostbyname($_);
  153.  
  154.         next unless @info;
  155.  
  156.         # look at real name & aliases
  157.         my $site;
  158.         foreach $site ($info[0], split(/ /,$info[1])) { 
  159.             if(rindex($site,".") > 0) {
  160.  
  161.                 # Extract domain from FQDN
  162.  
  163.                  ($domain = $site) =~ s/\A[^\.]+\.//; 
  164.                  return $domain;
  165.             }
  166.         }
  167.     }
  168.  
  169.     # Look for environment variable
  170.  
  171.     $domain ||= $ENV{LOCALDOMAIN} ||= $ENV{DOMAIN} || undef;
  172.  
  173.     if(defined $domain) {
  174.         $domain =~ s/[\r\n\0]+//g;
  175.         $domain =~ s/(\A\.+|\.+\Z)//g;
  176.         $domain =~ s/\.\.+/\./g;
  177.     }
  178.  
  179.     $domain;
  180. }
  181.  
  182. sub domainname {
  183.  
  184.     return $fqdn
  185.         if(defined $fqdn);
  186.  
  187.     _hostname();
  188.     _hostdomain();
  189.  
  190.     # Assumption: If the host name does not contain a period
  191.     # and the domain name does, then assume that they are correct
  192.     # this helps to eliminate calls to gethostbyname, and therefore
  193.     # eleminate DNS lookups
  194.  
  195.     return $fqdn = $host . "." . $domain
  196.     if($host !~ /\./ && $domain =~ /\./);
  197.  
  198.     my @host   = split(/\./, $host);
  199.     my @domain = split(/\./, $domain);
  200.     my @fqdn   = ();
  201.  
  202.     # Determine from @host & @domain the FQDN
  203.  
  204.     my @d = @domain;
  205.  
  206. LOOP:
  207.     while(1) {
  208.         my @h = @host;
  209.         while(@h) {
  210.             my $tmp = join(".",@h,@d);
  211.             if((gethostbyname($tmp))[0]) {
  212.                  @fqdn = (@h,@d);
  213.                  $fqdn = $tmp;
  214.                last LOOP;
  215.             }
  216.             pop @h;
  217.         }
  218.         last unless shift @d;
  219.     }
  220.  
  221.     if(@fqdn) {
  222.         $host = shift @fqdn;
  223.         until((gethostbyname($host))[0]) {
  224.             $host .= "." . shift @fqdn;
  225.         }
  226.         $domain = join(".", @fqdn);
  227.     }
  228.     else {
  229.         undef $host;
  230.         undef $domain;
  231.         undef $fqdn;
  232.     }
  233.  
  234.     $fqdn;
  235. }
  236.  
  237. sub hostfqdn { domainname() }
  238.  
  239. sub hostname {
  240.     domainname()
  241.         unless(defined $host);
  242.     return $host;
  243. }
  244.  
  245. sub hostdomain {
  246.     domainname()
  247.         unless(defined $domain);
  248.     return $domain;
  249. }
  250.  
  251. 1; # Keep require happy
  252.  
  253. __END__
  254.  
  255. =head1 NAME
  256.  
  257. Net::Domain - Attempt to evaluate the current host's internet name and domain
  258.  
  259. =head1 SYNOPSIS
  260.  
  261.     use Net::Domain qw(hostname hostfqdn hostdomain);
  262.  
  263. =head1 DESCRIPTION
  264.  
  265. Using various methods B<attempt> to find the Fully Qualified Domain Name (FQDN)
  266. of the current host. From this determine the host-name and the host-domain.
  267.  
  268. Each of the functions will return I<undef> if the FQDN cannot be determined.
  269.  
  270. =over 4
  271.  
  272. =item hostfqdn ()
  273.  
  274. Identify and return the FQDN of the current host.
  275.  
  276. =item hostname ()
  277.  
  278. Returns the smallest part of the FQDN which can be used to identify the host.
  279.  
  280. =item hostdomain ()
  281.  
  282. Returns the remainder of the FQDN after the I<hostname> has been removed.
  283.  
  284. =back
  285.  
  286. =head1 AUTHOR
  287.  
  288. Graham Barr <gbarr@pobox.com>.
  289. Adapted from Sys::Hostname by David Sundstrom <sunds@asictest.sc.ti.com>
  290.  
  291. =head1 COPYRIGHT
  292.  
  293. Copyright (c) 1995-1997 Graham Barr. All rights reserved.
  294. This program is free software; you can redistribute it and/or modify
  295. it under the same terms as Perl itself.
  296.  
  297. =cut
  298.