Blame lib/Net/DNS/Resolver/cygwin.pm

Packit e6c8bb
package Net::DNS::Resolver::cygwin;
Packit e6c8bb
Packit e6c8bb
#
Packit e6c8bb
# $Id: cygwin.pm 1568 2017-05-27 06:40:20Z willem $
Packit e6c8bb
#
Packit e6c8bb
our $VERSION = (qw$LastChangedRevision: 1568 $)[1];
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
=head1 NAME
Packit e6c8bb
Packit e6c8bb
Net::DNS::Resolver::cygwin - Cygwin resolver class
Packit e6c8bb
Packit e6c8bb
=cut
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
use strict;
Packit e6c8bb
use warnings;
Packit e6c8bb
use base qw(Net::DNS::Resolver::Base);
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
sub _getregkey {
Packit e6c8bb
	my $key = join '/', @_;
Packit e6c8bb
Packit e6c8bb
	local *LM;
Packit e6c8bb
	open( LM, "<$key" ) or return '';
Packit e6c8bb
	my $value = <LM>;
Packit e6c8bb
	$value =~ s/\0+$// if $value;
Packit e6c8bb
	close(LM);
Packit e6c8bb
Packit e6c8bb
	return $value || '';
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
sub _init {
Packit e6c8bb
	my $defaults = shift->_defaults;
Packit e6c8bb
Packit e6c8bb
	local *LM;
Packit e6c8bb
Packit e6c8bb
	my $root = '/proc/registry/HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters';
Packit e6c8bb
Packit e6c8bb
	unless ( -d $root ) {
Packit e6c8bb
Packit e6c8bb
		# Doesn't exist, maybe we are on 95/98/Me?
Packit e6c8bb
		$root = '/proc/registry/HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/VxD/MSTCP';
Packit e6c8bb
		-d $root || Carp::croak "can't read registry: $!";
Packit e6c8bb
	}
Packit e6c8bb
Packit e6c8bb
	# Best effort to find a useful domain name for the current host
Packit e6c8bb
	# if domain ends up blank, we're probably (?) not connected anywhere
Packit e6c8bb
	# a DNS server is interesting either...
Packit e6c8bb
	my $domain = _getregkey( $root, 'Domain' ) || _getregkey( $root, 'DhcpDomain' );
Packit e6c8bb
Packit e6c8bb
	# If nothing else, the searchlist should probably contain our own domain
Packit e6c8bb
	# also see below for domain name devolution if so configured
Packit e6c8bb
	# (also remove any duplicates later)
Packit e6c8bb
	my $devolution = _getregkey( $root, 'UseDomainNameDevolution' );
Packit e6c8bb
	my $searchlist = _getregkey( $root, 'SearchList' );
Packit e6c8bb
	my @searchlist = ( $domain, split m/[\s,]+/, $searchlist );
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
	# This is (probably) adequate on NT4
Packit e6c8bb
	my @nt4nameservers;
Packit e6c8bb
	foreach ( grep length, _getregkey( $root, 'NameServer' ), _getregkey( $root, 'DhcpNameServer' ) ) {
Packit e6c8bb
		push @nt4nameservers, split m/[\s,]+/;
Packit e6c8bb
		last;
Packit e6c8bb
	}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
	# but on W2K/XP the registry layout is more advanced due to dynamically
Packit e6c8bb
	# appearing connections. So we attempt to handle them, too...
Packit e6c8bb
	# opt to silently fail if something isn't ok (maybe we're on NT4)
Packit e6c8bb
	# If this doesn't fail override any NT4 style result we found, as it
Packit e6c8bb
	# may be there but is not valid.
Packit e6c8bb
	# drop any duplicates later
Packit e6c8bb
	my @nameservers;
Packit e6c8bb
Packit e6c8bb
	my $dnsadapters = join '/', $root, 'DNSRegisteredAdapters';
Packit e6c8bb
	if ( opendir( LM, $dnsadapters ) ) {
Packit e6c8bb
		my @adapters = grep !/^\.\.?$/, readdir(LM);
Packit e6c8bb
		closedir(LM);
Packit e6c8bb
		foreach my $adapter (@adapters) {
Packit e6c8bb
			my $ns = _getregkey( $dnsadapters, $adapter, 'DNSServerAddresses' );
Packit e6c8bb
			until ( length($ns) < 4 ) {
Packit e6c8bb
				push @nameservers, join '.', unpack( 'C4', $ns );
Packit e6c8bb
				substr( $ns, 0, 4 ) = '';
Packit e6c8bb
			}
Packit e6c8bb
		}
Packit e6c8bb
	}
Packit e6c8bb
Packit e6c8bb
	my $interfaces = join '/', $root, 'Interfaces';
Packit e6c8bb
	if ( opendir( LM, $interfaces ) ) {
Packit e6c8bb
		my @ifacelist = grep !/^\.\.?$/, readdir(LM);
Packit e6c8bb
		closedir(LM);
Packit e6c8bb
		foreach my $iface (@ifacelist) {
Packit e6c8bb
			my $ip = _getregkey( $interfaces, $iface, 'DhcpIPAddress' )
Packit e6c8bb
					|| _getregkey( $interfaces, $iface, 'IPAddress' );
Packit e6c8bb
			next unless $ip;
Packit e6c8bb
			next if $ip eq '0.0.0.0';
Packit e6c8bb
Packit e6c8bb
			foreach (
Packit e6c8bb
				grep length,
Packit e6c8bb
				_getregkey( $interfaces, $iface, 'NameServer' ),
Packit e6c8bb
				_getregkey( $interfaces, $iface, 'DhcpNameServer' )
Packit e6c8bb
				) {
Packit e6c8bb
				push @nameservers, split m/[\s,]+/;
Packit e6c8bb
				last;
Packit e6c8bb
			}
Packit e6c8bb
		}
Packit e6c8bb
	}
Packit e6c8bb
Packit e6c8bb
	@nameservers = @nt4nameservers unless @nameservers;
Packit e6c8bb
	$defaults->nameservers(@nameservers);
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
	# fix devolution if configured, and simultaneously
Packit e6c8bb
	# eliminate duplicate entries (but keep the order)
Packit e6c8bb
	my @list;
Packit e6c8bb
	my %seen;
Packit e6c8bb
	foreach (@searchlist) {
Packit e6c8bb
		s/\.+$//;
Packit e6c8bb
		push( @list, $_ ) unless $seen{lc $_}++;
Packit e6c8bb
Packit e6c8bb
		next unless $devolution;
Packit e6c8bb
Packit e6c8bb
		# while there are more than two labels, cut
Packit e6c8bb
		while (s#^[^.]+\.(.+\..+)$#$1#) {
Packit e6c8bb
			push( @list, $_ ) unless $seen{lc $_}++;
Packit e6c8bb
		}
Packit e6c8bb
	}
Packit e6c8bb
	$defaults->searchlist(@list);
Packit e6c8bb
Packit e6c8bb
	%$defaults = Net::DNS::Resolver::Base::_untaint(%$defaults);
Packit e6c8bb
Packit e6c8bb
	$defaults->_read_env;
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
1;
Packit e6c8bb
__END__
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
=head1 SYNOPSIS
Packit e6c8bb
Packit e6c8bb
    use Net::DNS::Resolver;
Packit e6c8bb
Packit e6c8bb
=head1 DESCRIPTION
Packit e6c8bb
Packit e6c8bb
This class implements the OS specific portions of C<Net::DNS::Resolver>.
Packit e6c8bb
Packit e6c8bb
No user serviceable parts inside, see L<Net::DNS::Resolver>
Packit e6c8bb
for all your resolving needs.
Packit e6c8bb
Packit e6c8bb
=head1 COPYRIGHT
Packit e6c8bb
Packit e6c8bb
Copyright (c)2003 Sidney Markowitz.
Packit e6c8bb
Packit e6c8bb
All rights reserved.
Packit e6c8bb
Packit e6c8bb
=head1 LICENSE
Packit e6c8bb
Packit e6c8bb
Permission to use, copy, modify, and distribute this software and its
Packit e6c8bb
documentation for any purpose and without fee is hereby granted, provided
Packit e6c8bb
that the above copyright notice appear in all copies and that both that
Packit e6c8bb
copyright notice and this permission notice appear in supporting
Packit e6c8bb
documentation, and that the name of the author not be used in advertising
Packit e6c8bb
or publicity pertaining to distribution of the software without specific
Packit e6c8bb
prior written permission.
Packit e6c8bb
Packit e6c8bb
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Packit e6c8bb
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit e6c8bb
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Packit e6c8bb
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Packit e6c8bb
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Packit e6c8bb
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Packit e6c8bb
DEALINGS IN THE SOFTWARE.
Packit e6c8bb
Packit e6c8bb
=head1 SEE ALSO
Packit e6c8bb
Packit e6c8bb
L<perl>, L<Net::DNS>, L<Net::DNS::Resolver>
Packit e6c8bb
Packit e6c8bb
=cut
Packit e6c8bb