diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-11-07 09:01:34 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-11-07 09:01:34 +0000 |
commit | 2f12c07c76c38a377e98555f1af738a8aa12f112 (patch) | |
tree | 0ca8dfde034e3a4837a4d4c7b5536a0bf3540e03 | |
parent | 566c793d9b032ae1bc03340a10c4b5d1dcd116a7 (diff) |
* dir.c (my_getcwd): do not rely on MAXPATHLEN.
* eval.c (rb_yield_0): should not call rb_f_block_given_p().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_6@1814 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | dir.c | 27 | ||||
-rw-r--r-- | eval.c | 9 | ||||
-rw-r--r-- | file.c | 8 | ||||
-rw-r--r-- | lib/resolv.rb | 352 | ||||
-rw-r--r-- | parse.y | 33 | ||||
-rw-r--r-- | string.c | 2 | ||||
-rw-r--r-- | version.h | 4 |
9 files changed, 381 insertions, 69 deletions
@@ -1,9 +1,18 @@ +Tue Nov 6 14:38:48 2001 Yukihiro Matsumoto <[email protected]> + + * dir.c (my_getcwd): do not rely on MAXPATHLEN. + +Mon Nov 5 17:09:55 2001 Yukihiro Matsumoto <[email protected]> + + * eval.c (rb_yield_0): should not call rb_f_block_given_p(). + Sat Nov 3 22:28:51 2001 Keiju Ishitsuka <[email protected]> + + * forwardable.rb: change raise to Kernel::raise + * matrix.rb (Matrix#column_vectors, Matrix#row_vectors): ditto bug. this bug report and fix by [email protected]. - * forwardable.rb: change raise to Kernel::raise - Thu Nov 1 14:08:42 2001 Yukihiro Matsumoto <[email protected]> * bignum.c (rb_big_aref): idx may be a Bignum. diff --git a/configure.in b/configure.in index 1ab6e509d0..07e2ecad3b 100644 --- a/configure.in +++ b/configure.in @@ -528,7 +528,7 @@ if test "$with_dln_a_out" != yes; then LDFLAGS="-Wl,-E" rb_cv_dlopen=yes;; solaris*) if test "$GCC" = yes; then - LDSHARED='$(CC) -Wl,-G' + LDSHARED='$(CC) -Wl,-G -shared' `$CC --print-prog-name=ld` -v 2>&1 | grep "GNU ld" > /dev/null && LDFLAGS="-Wl,-E" else LDSHARED='ld -G' @@ -419,20 +419,29 @@ dir_s_chdir(argc, argv, obj) return INT2FIX(0); } +static char * +my_getcwd() +{ + int size = MAXPATHLEN; + char *buf = xmalloc(size); + + while (!getcwd(buf, size)) { + if (errno != ERANGE) rb_sys_fail(buf); + size *= 2; + buf = xrealloc(buf, size); + } + return buf; +} + static VALUE dir_s_getwd(dir) VALUE dir; { - char path[MAXPATHLEN]; - -#ifdef HAVE_GETCWD - if (getcwd(path, sizeof(path)) == 0) rb_sys_fail(path); -#else - extern char *getwd(); - if (getwd(path) == 0) rb_sys_fail(path); -#endif + char *path = my_getcwd(); + VALUE cwd = rb_tainted_str_new2(path); - return rb_tainted_str_new2(path); + free(path); + return cwd; } static VALUE @@ -3502,7 +3502,8 @@ rb_iterator_p() static VALUE rb_f_block_given_p() { - if (ruby_frame->prev && ruby_frame->prev->iter) return Qtrue; + if (ruby_frame->prev && ruby_frame->prev->iter && ruby_block) + return Qtrue; return Qfalse; } @@ -3521,8 +3522,8 @@ rb_yield_0(val, self, klass, acheck) int state; static unsigned serial = 1; - if (!(rb_block_given_p() || rb_f_block_given_p()) || !ruby_block) { - rb_raise(rb_eLocalJumpError, "yield called out of block"); + if (!rb_block_given_p()) { + rb_raise(rb_eLocalJumpError, "no block given"); } PUSH_VARS(); @@ -4470,7 +4471,7 @@ rb_call0(klass, recv, id, argc, argv, body, nosuper) v = rb_ary_new4(argc,argv); else v = rb_ary_new2(0); - local_vars[node->nd_rest] = v; + ruby_scope->local_vars[node->nd_rest] = v; } } } @@ -2118,10 +2118,10 @@ rb_path_check(path) if (pend) *pend = '\0'; safe = path_check_1(p); - if (!safe) { - if (pend) *pend = sep; - return 0; - } + if (!safe) { + if (pend) *pend = sep; + return 0; + } if (!pend) break; *pend = sep; p = pend + 1; diff --git a/lib/resolv.rb b/lib/resolv.rb index 68b41c65bf..5caaa1af5f 100644 --- a/lib/resolv.rb +++ b/lib/resolv.rb @@ -1,3 +1,176 @@ +=begin += resolv library +resolv.rb is a resolver library written in Ruby. +Since it is written in Ruby, it is thread-aware. +I.e. it can resolv many hostnames concurrently. + +It is possible to lookup various resources of DNS using DNS module directly. + +== example + Resolv.getaddress("www.ruby-lang.org") + Resolv.getname("210.251.121.214").to_s + Resolv::DNS.new.getresources("www.ruby-lang.org", Resolv::DNS::Resource::IN::A).collect {|r| r.address} + Resolv::DNS.new.getresources("ruby-lang.org", Resolv::DNS::Resource::IN::MX).collect {|r| [r.exchange.to_s, r.preference]} + +== Resolv module + +=== module methods +--- Resolv.getaddress(name) +--- Resolv.getaddresses(name) +--- Resolv.each_address(name) {|address| ...} + They lookups IP addresses of ((|name|)) which represents a hostname + as a string. + + getaddress returns first entry of lookupped addresses. + getaddresses returns lookupped addresses. + each_address iterates over lookupped addresses. + +--- Resolv.getname(address) +--- Resolv.getnames(address) +--- Resolv.each_name(address) {|name| ...} + lookups hostnames of ((|address|)) which represents IP address as a string. + + getname returns first entry of lookupped names. + getnames returns lookupped names. + each_names iterates over lookupped names. + +== Resolv::Hosts class +hostname resolver using /etc/hosts format. + +=== class methods +--- Resolv::Hosts.new(hosts='/etc/hosts') + +=== methods +--- Resolv::Hosts#getaddress(name) +--- Resolv::Hosts#getaddresses(name) +--- Resolv::Hosts#each_address(name) {|address| ...} + address lookup methods. + +--- Resolv::Hosts#getname(address) +--- Resolv::Hosts#getnames(address) +--- Resolv::Hosts#each_name(address) {|name| ...} + hostnames lookup methods. + +== Resolv::DNS class +DNS stub resolver. + +=== class methods +--- Resolv::DNS.new(resolv_conf='/etc/resolv.conf') + +=== methods +--- Resolv::DNS#getaddress(name) +--- Resolv::DNS#getaddresses(name) +--- Resolv::DNS#each_address(name) {|address| ...} + address lookup methods. + + ((|name|)) must be a instance of Resolv::Name or String. Lookupped + address is represented as an instance of Resolv::IPv4 or Resolv::IPv6. + +--- Resolv::DNS#getname(address) +--- Resolv::DNS#getnames(address) +--- Resolv::DNS#each_name(address) {|name| ...} + hostnames lookup methods. + + ((|address|)) must be a instance of Resolv::IPv4, Resolv::IPv6 or String. + Lookupped name is represented as an instance of Resolv::Name. + +--- Resolv::DNS#getresource(name, typeclass) +--- Resolv::DNS#getresources(name, typeclass) +--- Resolv::DNS#each_resource(name, typeclass) {|resource| ...} + They lookup DNS resources of ((|name|)). + ((|name|)) must be a instance of Resolv::Name or String. + + ((|typeclass|)) should be one of follows: + * Resolv::DNS::Resource::IN::ANY + * Resolv::DNS::Resource::IN::NS + * Resolv::DNS::Resource::IN::CNAME + * Resolv::DNS::Resource::IN::SOA + * Resolv::DNS::Resource::IN::HINFO + * Resolv::DNS::Resource::IN::MINFO + * Resolv::DNS::Resource::IN::MX + * Resolv::DNS::Resource::IN::TXT + * Resolv::DNS::Resource::IN::ANY + * Resolv::DNS::Resource::IN::A + * Resolv::DNS::Resource::IN::WKS + * Resolv::DNS::Resource::IN::PTR + * Resolv::DNS::Resource::IN::AAAA + + Lookupped resource is represented as an instance of (a subclass of) + Resolv::DNS::Resource. + +== Resolv::DNS::Resource::IN::NS class +--- name +== Resolv::DNS::Resource::IN::CNAME class +--- name +== Resolv::DNS::Resource::IN::SOA class +--- mname +--- rname +--- serial +--- refresh +--- retry +--- expire +--- minimum +== Resolv::DNS::Resource::IN::HINFO class +--- cpu +--- os +== Resolv::DNS::Resource::IN::MINFO class +--- rmailbx +--- emailbx +== Resolv::DNS::Resource::IN::MX class +--- preference +--- exchange +== Resolv::DNS::Resource::IN::TXT class +--- data +== Resolv::DNS::Resource::IN::A class +--- address +== Resolv::DNS::Resource::IN::WKS class +--- address +--- protocol +--- bitmap +== Resolv::DNS::Resource::IN::PTR class +--- name +== Resolv::DNS::Resource::IN::AAAA class +--- address + +== Resolv::DNS::Name class + +=== class methods +--- Resolv::DNS::Name.create(name) + +=== methods +--- Resolv::DNS::Name#to_s + +== Resolv::DNS::Resource class + +== Resolv::IPv4 class +=== class methods +--- Resolv::IPv4.create(address) + +=== methods +--- Resolv::IPv4#to_s +--- Resolv::IPv4#to_name + +=== constants +--- Resolv::IPv4::Regex + regular expression for IPv4 address. + +== Resolv::IPv6 class +=== class methods +--- Resolv::IPv6.create(address) + +=== methods +--- Resolv::IPv6#to_s +--- Resolv::IPv6#to_name + +=== constants +--- Resolv::IPv6::Regex + regular expression for IPv6 address. + +== Bugs +NIS is not supported. + +=end + require 'socket' require 'fcntl' require 'timeout' @@ -8,35 +181,76 @@ class Resolv DefaultResolver.getaddress(name) end + def self.getaddresses(name) + DefaultResolver.getaddresses(name) + end + + def self.each_address(name, &block) + DefaultResolver.each_address(name, &block) + end + def self.getname(address) DefaultResolver.getname(address) end + def self.getnames(address) + DefaultResolver.getnames(address) + end + + def self.each_name(address, &proc) + DefaultResolver.each_name(address, &proc) + end + def initialize(resolvers=[Hosts.new, DNS.new]) @resolvers = resolvers end def getaddress(name) - return name if AddressRegex =~ name - rs = @resolvers.dup - begin - r = rs.shift - return r.getaddress(name) - rescue ResolvError - retry unless rs.empty? - raise + each_address(name) {|address| return address} + raise ResolvError.new("no address for #{name}") + end + + def getaddresses(name) + ret = [] + each_address(name) {|address| ret << address} + return ret + end + + def each_address(name) + if AddressRegex =~ name + yield name + return end + yielded = false + @resolvers.each {|r| + r.each_address(name) {|address| + yield address.to_s + yielded = true + } + return if yielded + } end def getname(address) - rs = @resolvers.dup - begin - r = rs.shift - return r.getname(address) - rescue ResolvError - retry unless rs.empty? - raise - end + each_name(address) {|name| return name} + raise ResolvError.new("no name for #{address}") + end + + def getnames(address) + ret = [] + each_name(address) {|name| ret << name} + return ret + end + + def each_name(address) + yielded = false + @resolvers.each {|r| + r.each_name(address) {|name| + yield name.to_s + yielded = true + } + return if yielded + } end class ResolvError < StandardError @@ -79,20 +293,38 @@ class Resolv end def getaddress(name) + each_address(name) {|address| return address} + raise ResolvError.new("#{@filename} has no name: #{name}") + end + + def getaddresses(name) + ret = [] + each_address(name) {|address| ret << address} + return ret + end + + def each_address(name, &proc) lazy_initialize if @name2addr.include?(name) - return @name2addr[name][0] - else - raise ResolvError.new("#{@filename} has no name: #{name}") + @name2addr[name].each(&proc) end end def getname(address) + each_name(address) {|name| return name} + raise ResolvError.new("#{@filename} has no address: #{address}") + end + + def getnames(address) + ret = [] + each_name(address) {|name| ret << name} + return ret + end + + def each_name(address, &proc) lazy_initialize if @addr2name.include?(address) - return @addr2name[address][0] - else - raise ResolvError.new("#{@filename} has no address: #{address}") + @addr2name[address].each(&proc) end end end @@ -127,10 +359,32 @@ class Resolv end def getaddress(name) - return getresource(name, Resource::IN::A).address + each_address(name) {|address| return address} + raise ResolvError.new("DNS result has no information for #{name}") + end + + def getaddresses(name) + ret = [] + each_address(name) {|address| ret << address} + return ret + end + + def each_address(name) + each_resource(name, Resource::IN::A) {|resource| yield resource.address} end def getname(address) + each_name(address) {|name| return name} + raise ResolvError.new("DNS result has no information for #{address}") + end + + def getnames(address) + ret = [] + each_name(address) {|name| ret << name} + return ret + end + + def each_name(address) case address when Name ptr = address @@ -141,10 +395,21 @@ class Resolv else raise ResolvError.new("cannot interpret as address: #{address}") end - return getresource(ptr, Resource::IN::PTR).name + each_resource(ptr, Resource::IN::PTR) {|resource| yield resource.name} end def getresource(name, typeclass) + each_resource(name, typeclass) {|resource| return resource} + raise ResolvError.new("DNS result has no information for #{name}") + end + + def getresources(name, typeclass) + ret = [] + each_resource(name, typeclass) {|resource| ret << resource} + return ret + end + + def each_resource(name, typeclass, &proc) lazy_initialize q = Queue.new senders = {} @@ -162,7 +427,8 @@ class Resolv timeout(tout) { reply, reply_name = q.pop } case reply.rcode when RCode::NoError - return extract_resource(reply, reply_name, typeclass) + extract_resources(reply, reply_name, typeclass, &proc) + return when RCode::NXDomain raise Config::NXDomain.new(reply_name) else @@ -174,27 +440,35 @@ class Resolv end end - def extract_resource(msg, name, typeclass) + def extract_resources(msg, name, typeclass) + if typeclass < Resource::ANY + n0 = Name.create(name) + msg.each_answer {|n, ttl, data| + yield data if n0 == n + } + end + yielded = false n0 = Name.create(name) msg.each_answer {|n, ttl, data| if n0 == n case data when typeclass - return data + yield data + yielded = true when Resource::CNAME n0 = data.name end end } + return if yielded msg.each_answer {|n, ttl, data| if n0 == n case data when typeclass - return data + yield data end end } - raise ResolvError.new("DNS result has no information for #{name}") end class Requester @@ -551,6 +825,10 @@ class Resolv return @string end + def inspect + return "#<#{self.class} #{self.to_s}>" + end + def ==(other) return @downcase == other.downcase end @@ -1101,7 +1379,7 @@ class Resolv end def self.decode_rdata(msg) - preference = msg.get_unpack('n') + preference, = msg.get_unpack('n') exchange = msg.get_name return self.new(preference, exchange) end @@ -1180,7 +1458,7 @@ class Resolv def self.decode_rdata(msg) address = IPv4.new(msg.get_bytes(4)) - protocol = msg.get_unpack("n") + protocol, = msg.get_unpack("n") bitmap = msg.get_bytes return self.new(address, protocol, bitmap) end @@ -1239,6 +1517,10 @@ class Resolv return sprintf("%d.%d.%d.%d", *@address.unpack("CCCC")) end + def inspect + return "#<#{self.class} #{self.to_s}>" + end + def to_name return DNS::Name.new( @address.unpack("CCCC").reverse + ['in-addr', 'arpa']) @@ -1312,7 +1594,7 @@ class Resolv def initialize(address) unless address.kind_of?(String) && address.length == 16 - raise ArgumentError.new('IPv4 address muse be 16 bytes') + raise ArgumentError.new('IPv6 address muse be 16 bytes') end @address = address end @@ -1326,6 +1608,10 @@ class Resolv return address end + def inspect + return "#<#{self.class} #{self.to_s}>" + end + def to_name return DNS::Name.new( @address.unpack("H32")[0].split(//).reverse + ['ip6', 'int']) @@ -1345,5 +1631,5 @@ class Resolv end DefaultResolver = self.new - AddressRegex = /(?:#{IPv4::Regex.source})|(?:#{IPv6::Regex})/ + AddressRegex = /(?:#{IPv4::Regex.source})|(?:#{IPv6::Regex.source})/ end @@ -669,24 +669,29 @@ arg : lhs '=' arg } | variable tOP_ASGN {$$ = assignable($1, 0);} arg { - if ($2 == tOROP) { - $<node>3->nd_value = $4; - $$ = NEW_OP_ASGN_OR(gettable($1), $<node>3); - if (is_instance_id($1)) { - $$->nd_aid = $1; + if ($<node>3) { + if ($2 == tOROP) { + $<node>3->nd_value = $4; + $$ = NEW_OP_ASGN_OR(gettable($1), $<node>3); + if (is_instance_id($1)) { + $$->nd_aid = $1; + } } - } - else if ($2 == tANDOP) { - $<node>3->nd_value = $4; - $$ = NEW_OP_ASGN_AND(gettable($1), $<node>3); + else if ($2 == tANDOP) { + $<node>3->nd_value = $4; + $$ = NEW_OP_ASGN_AND(gettable($1), $<node>3); + } + else { + $$ = $<node>3; + if ($$) { + $$->nd_value = call_op(gettable($1),$2,1,$4); + } + } + fixpos($$, $4); } else { - $$ = $<node>3; - if ($$) { - $$->nd_value = call_op(gettable($1),$2,1,$4); - } + $$ = 0; } - fixpos($$, $4); } | primary '[' aref_args ']' tOP_ASGN arg { @@ -211,6 +211,8 @@ rb_str_dup(str) } else if (RSTRING(str)->orig) { str2 = rb_str_new3(RSTRING(str)->orig); + FL_UNSET(str2, FL_TAINT); + OBJ_INFECT(str2, str); } else { str2 = rb_str_new3(rb_str_new4(str)); @@ -1,4 +1,4 @@ #define RUBY_VERSION "1.6.5" -#define RUBY_RELEASE_DATE "2001-11-01" +#define RUBY_RELEASE_DATE "2001-11-07" #define RUBY_VERSION_CODE 165 -#define RUBY_RELEASE_CODE 20011101 +#define RUBY_RELEASE_CODE 20011107 |