From fbb8f1964a5c642ad2f520a3d3712b47feba9a14 Mon Sep 17 00:00:00 2001 From: akr Date: Wed, 12 May 2004 08:44:11 +0000 Subject: * lib/resolv.rb (Resolv::DNS::Config): make it configurable without external file such as /etc/resolv.conf. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6296 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++ lib/resolv.rb | 127 ++++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 97 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index b014c89464..ef132b3a0b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed May 12 17:41:42 2004 Tanaka Akira + + * lib/resolv.rb (Resolv::DNS::Config): make it configurable without + external file such as /etc/resolv.conf. + Wed May 12 14:37:27 2004 GOTOU Yuuzou * ext/openssl/ossl_x509name.c: attribute value of DC (short name of diff --git a/lib/resolv.rb b/lib/resolv.rb index 3b36d0fc84..d3f441bfc7 100644 --- a/lib/resolv.rb +++ b/lib/resolv.rb @@ -10,9 +10,10 @@ It is possible to lookup various resources of DNS using DNS module directly. Resolv.getaddress("www.ruby-lang.org") Resolv.getname("210.251.121.214") - dns = Resolv::DNS.new - dns.getresources("www.ruby-lang.org", Resolv::DNS::Resource::IN::A).collect {|r| r.address} - dns.getresources("ruby-lang.org", Resolv::DNS::Resource::IN::MX).collect {|r| [r.exchange.to_s, r.preference]} + Resolv::DNS.open {|dns| + dns.getresources("www.ruby-lang.org", Resolv::DNS::Resource::IN::A).collect {|r| r.address} + dns.getresources("ruby-lang.org", Resolv::DNS::Resource::IN::MX).collect {|r| [r.exchange.to_s, r.preference]} + } == Resolv class @@ -57,10 +58,17 @@ hostname resolver using /etc/hosts format. DNS stub resolver. === class methods ---- Resolv::DNS.new(resolv_conf='/etc/resolv.conf') +--- Resolv::DNS.new(config_info=nil) ---- Resolv::DNS.open(resolv_conf='/etc/resolv.conf') ---- Resolv::DNS.open(resolv_conf='/etc/resolv.conf') {|dns| ...} + ((|config_info|)) should be nil, a string or a hash. + If nil is given, /etc/resolv.conf and platform specific information is used. + If a string is given, it should be a filename which format is same as /etc/resolv.conf. + If a hash is given, it may contains information for nameserver, search and ndots as follows. + + Resolv::DNS.new({:nameserver=>["210.251.121.21"], :search=>["ruby-lang.org"], :ndots=>1}) + +--- Resolv::DNS.open(config_info=nil) +--- Resolv::DNS.open(config_info=nil) {|dns| ...} === methods --- Resolv::DNS#close @@ -369,9 +377,9 @@ class Resolv end end - def initialize(config="/etc/resolv.conf") + def initialize(config_info=nil) @mutex = Mutex.new - @config = Config.new(config) + @config = Config.new(config_info) @initialized = nil end @@ -704,47 +712,81 @@ class Resolv end class Config - def initialize(filename="/etc/resolv.conf") + def initialize(config_info=nil) @mutex = Mutex.new - @filename = filename + @config_info = config_info @initialized = nil end + def Config.parse_resolv_conf(filename) + nameserver = [] + search = nil + ndots = 1 + open(filename) {|f| + f.each {|line| + line.sub!(/[#;].*/, '') + keyword, *args = line.split(/\s+/) + args.each { |arg| + arg.untaint + } + next unless keyword + case keyword + when 'nameserver' + nameserver += args + when 'domain' + search = [args[0]] + when 'search' + search = args + end + } + } + return { :nameserver => nameserver, :search => search, :ndots => ndots } + end + + def Config.default_config_hash(filename="/etc/resolv.conf") + if File.exist? filename + config_hash = Config.parse_resolv_conf(filename) + else + if /mswin32|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM + search, nameserver = Win32::Resolv.get_resolv_info + config_hash = {} + config_hash[:nameserver] = nameserver if nameserver + config_hash[:search] = [search] if search + end + end + config_hash + end + def lazy_initialize @mutex.synchronize { unless @initialized @nameserver = [] @search = nil @ndots = 1 - begin - open(@filename) {|f| - f.each {|line| - line.sub!(/[#;].*/, '') - keyword, *args = line.split(/\s+/) - args.each { |arg| - arg.untaint - } - next unless keyword - case keyword - when 'nameserver' - @nameserver += args - when 'domain' - @search = [Label.split(args[0])] - when 'search' - @search = args.map {|arg| Label.split(arg)} - end - } - } - rescue Errno::ENOENT - if /mswin32|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM - search, nameserver = Win32::Resolv.get_resolv_info - @search = [search] if search - @nameserver = nameserver if nameserver + case @config_info + when nil + config_hash = Config.default_config_hash + when String + config_hash = Config.parse_resolv_conf(@config_info) + when Hash + config_hash = @config_info.dup + if String === config_hash[:nameserver] + config_hash[:nameserver] = [config_hash[:nameserver]] + end + if String === config_hash[:search] + config_hash[:search] = [config_hash[:search]] end + else + raise ArgumentError.new("invalid resolv configuration: #{@config_info.inspect}") end + @nameserver = config_hash[:nameserver] if config_hash.include? :nameserver + @search = config_hash[:search] if config_hash.include? :search + @ndots = config_hash[:ndots] if config_hash.include? :ndots @nameserver = ['0.0.0.0'] if @nameserver.empty? - unless @search + if @search + @search = @search.map {|arg| Label.split(arg) } + else hostname = Socket.gethostname if /\./ =~ hostname @search = [Label.split($')] @@ -752,6 +794,21 @@ class Resolv @search = [[]] end end + + if !@nameserver.kind_of?(Array) || + !@nameserver.all? {|ns| String === ns } + raise ArgumentError.new("invalid nameserver config: #{@nameserver.inspect}") + end + + if !@search.kind_of?(Array) || + !@search.all? {|ls| ls.all? {|l| Label::Str === l } } + raise ArgumentError.new("invalid search config: #{@search.inspect}") + end + + if !@ndots.kind_of?(Integer) + raise ArgumentError.new("invalid ndots config: #{@ndots.inspect}") + end + @initialized = true end } -- cgit v1.2.3