home *** CD-ROM | disk | FTP | other *** search
/ CLIX - Fazer Clix Custa Nix / CLIX-CD.cdr / mac / lib / Net / Domain.pm < prev    next >
Text File  |  1997-11-18  |  6KB  |  297 lines

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