From: Tanaka Akira Date: 2002-01-21T14:04:22+09:00 Subject: [ruby-dev:15734] Re: win32/registry.rb (Re: [patch] resolv.rb for win32 platform) In article <20020121132319.C46A.USA@osb.att.ne.jp>, "U.Nakamura" writes: > $B$3$l$rF'$^$($F!"(Bresolv.rb $B$X$N%Q%C%A$rKvHx$K!#(B > [ruby-dev:15573] $B$H$N0c$$$O!"(Bhosts $B$r=&$C$F$/$k$H$3$m$H!"$$$-(B > $B$J$j(B win32/registry $B$r(B require $B$7$J$$$G(B RUBY_PLATFORM $B$r8+$k(B > $B$h$&$K$7$?$3$H$G$9!#(B resolv.rb $B$H$7$F$O4pK\E*$K$OLdBj$"$j$^$;$s!#$?$@$7!"(BUnix $BItJ,$H(B Windows $BItJ,$,HsBP>N$J$N$,5$$K$$$j$^$;$s!#BP>N$K$7$?$$$s$G$9$,!"$3$s$J(B $B$N$G$O$I$&$G$7$g$&(B?$B$J$*!"(BWindows $B$G$O(B /etc/resolv.conf $B$O0l@Z8+$J$/$J(B $B$j$^$9!#(B # /etc/resolv.conf $B0J30$N$r;XDj$G$-$k$h$&$K$9$k5!G=$OCfESH>C<$@$C$?$H(B # $B$$$&$3$H$G:o=|!#(B Index: lib/resolv.rb =================================================================== RCS file: /src/ruby/lib/resolv.rb,v retrieving revision 1.7 diff -u -r1.7 resolv.rb --- lib/resolv.rb 2002/01/16 03:36:32 1.7 +++ lib/resolv.rb 2002/01/21 04:57:26 @@ -55,7 +55,7 @@ DNS stub resolver. === class methods ---- Resolv::DNS.new(resolv_conf='/etc/resolv.conf') +--- Resolv::DNS.new === methods --- Resolv::DNS#getaddress(name) @@ -262,7 +262,24 @@ end class Hosts - DefaultFileName = '/etc/hosts' + if /cygwin|mingw|mswin32/ =~ RUBY_PLATFORM + require 'win32/registry' + Win32::Registry.open(Win32::Registry::HKEY_LOCAL_MACHINE, + 'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters') do |reg| + type, data = reg.read('DataBasePath') + case type + when Win32::Registry::REG_EXPAND_SZ + path = data.gsub(/%([^%]+)%/) {ENV[$1]} + when Win32::Registry::REG_SZ + path = data + else + raise TypeError, "unexpected type #{type} (expect string)" + end + DefaultFileName = File.join(path.gsub(/\\/, '/'), 'hosts') + end + else + DefaultFileName = '/etc/hosts' + end def initialize(filename = DefaultFileName) @filename = filename @@ -341,9 +358,9 @@ Port = 53 UDPSize = 512 - def initialize(config="/etc/resolv.conf") + def initialize(config=Config.new) @mutex = Mutex.new - @config = Config.new(config) + @config = config @initialized = nil end @@ -562,7 +579,7 @@ @port = port @sock = UDPSocket.new @sock.connect(host, port) - @sock.fcntl(Fcntl::F_SETFD, 1) + @sock.fcntl(Fcntl::F_SETFD, 1) if Fcntl.const_defined? :F_SETFD @id = -1 @thread = Thread.new { loop { @@ -612,7 +629,7 @@ @port = port @sock = TCPSocket.new @sock.connect(host, port) - @sock.fcntl(Fcntl::F_SETFD, 1) + @sock.fcntl(Fcntl::F_SETFD, 1) if Fcntl.const_defined? :F_SETFD @id = -1 @senders = {} @thread = Thread.new { @@ -663,9 +680,8 @@ end class Config - def initialize(filename="/etc/resolv.conf") + def initialize @mutex = Mutex.new - @filename = filename @initialized = nil end @@ -675,25 +691,13 @@ @nameserver = [] @search = nil @ndots = 1 - begin - open(@filename) {|f| - f.each {|line| - line.sub!(/[#;].*/, '') - keyword, *args = line.split(/\s+/) - next unless keyword - case keyword - when 'nameserver' - @nameserver += args - when 'domain' - @search = [args[0]] - when 'search' - @search = args - end - } - } - rescue Errno::ENOENT - end + if /cygwin|mingw|mswin32/ =~ RUBY_PLATFORM + initialize_win32 + else + initialize_resolv_conf + end + @nameserver = ['0.0.0.0'] if @nameserver.empty? unless @search hostname = Socket.gethostname @@ -703,9 +707,97 @@ @search = [''] end end + @initialized = true end } + end + + DefaultResolvConf = '/etc/resolv.conf' + def initialize_resolv_conf + begin + open(DefaultResolvConf) {|f| + f.each {|line| + line.sub!(/[#;].*/, '') + keyword, *args = line.split(/\s+/) + next unless keyword + case keyword + when 'nameserver' + @nameserver += args + when 'domain' + @search = [args[0]] + when 'search' + @search = args + end + } + } + rescue Errno::ENOENT + end + end + + def initialize_win32 + require 'win32/registry' + + Win32::Registry.open(Win32::Registry::HKEY_LOCAL_MACHINE, + 'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters') do |reg| + begin + slist = reg.read_s('SearchList') + @search = slist.split(/,\s*/) unless slist.empty? + rescue Win32::Registry::Error + end + + if add_search = @search.nil? + @search = [] + begin + nvdom = reg.read_s('NV Domain') + unless nvdom.empty? + @search = [ nvdom ] + if reg.read_i('UseDomainNameDevolution') != 0 + if /^[\w\d]+\./ =~ nvdom + devo = $' + end + end + end + rescue Win32::Registry::Error + end + end + + Win32::Registry.open(reg, 'Interfaces') do |reg| + reg.each_key do |iface,| + Win32::Registry.open(reg, iface) do |regif| + begin + [ 'NameServer', 'DhcpNameServer' ].each do |key| + ns = regif.read_s(key) + unless ns.empty? + ns.split(/,\s*/).each do |ns| + @nameserver << ns unless @nameserver.include? ns + end + break + end + end + rescue Win32::Registry::Error + end + + if add_search + begin + [ 'Domain', 'DhcpDomain' ].each do |key| + dom = regif.read_s(key) + unless dom.empty? + dom.split(/,\s*/).each do |dom| + @search << dom unless @search.include? dom + end + break + end + end + rescue Win32::Registry::Error + end + end + end + end + end + @search << devo if add_search and devo + end + @search = nil if @search.empty? end def single? -- [$BEDCf(B $BE/(B][$B$?$J$+(B $B$"$-$i(B][Tanaka Akira] $B!V$U$($m(B! $B$o$+$a$A$c$s:n@o$G$9$(C"=$B!W(B(Little Worker, $B7KM7@84](B)