diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /appl/cmd/ndb/dnsquery.b | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'appl/cmd/ndb/dnsquery.b')
| -rw-r--r-- | appl/cmd/ndb/dnsquery.b | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/appl/cmd/ndb/dnsquery.b b/appl/cmd/ndb/dnsquery.b new file mode 100644 index 00000000..194c08a2 --- /dev/null +++ b/appl/cmd/ndb/dnsquery.b @@ -0,0 +1,177 @@ +implement Dnsquery; + +# +# Copyright © 2003 Vita Nuova Holdings LImited. All rights reserved. +# + +include "sys.m"; + sys: Sys; + +include "draw.m"; + +include "bufio.m"; + bufio: Bufio; + Iobuf: import bufio; + +include "arg.m"; + +Dnsquery: module +{ + init: fn(nil: ref Draw->Context, nil: list of string); +}; + +usage() +{ + sys->fprint(sys->fildes(2), "usage: dnsquery [-x /net] [-s server] [address ...]\n"); + raise "fail:usage"; +} + +init(nil: ref Draw->Context, args: list of string) +{ + sys = load Sys Sys->PATH; + bufio = load Bufio Bufio->PATH; + if(bufio == nil) + cantload(Bufio->PATH); + + net := "/net"; + server: string; + arg := load Arg Arg->PATH; + if(arg == nil) + cantload(Arg->PATH); + arg->init(args); + while((c := arg->opt()) != 0) + case c { + 'x' => + net = arg->arg(); + if(net == nil) + usage(); + 's' => + server = arg->arg(); + if(server == nil) + usage(); + * => + usage(); + } + args = arg->argv(); + arg = nil; + + if(server == nil) + server = net+"/dns"; + if(args != nil){ + for(; args != nil; args = tl args) + dnsquery(server, hd args); + }else{ + f := bufio->fopen(sys->fildes(0), Sys->OREAD); + if(f == nil) + exit; + for(;;){ + sys->print("> "); + s := f.gets('\n'); + if(s == nil) + break; + dnsquery(server, s[0:len s-1]); + } + } +} + +cantload(s: string) +{ + sys->fprint(sys->fildes(2), "dnsquery: can't load %s: %r\n", s); + raise "fail:load"; +} + +dnsquery(server: string, query: string) +{ + dns := sys->open(server, Sys->ORDWR); + if(dns == nil){ + sys->fprint(sys->fildes(2), "dnsquery: can't open %s: %r\n", server); + raise "fail:open"; + } + stdout := sys->fildes(1); + for(i := len query; --i >= 0 && query[i] != ' ';) + {} + if(i < 0){ + i = len query; + case dbattr(query) { + "ip" => + query += " ptr"; + * => + query += " ip"; + } + } + if(query[i+1:] == "ptr"){ + while(i > 0 && query[i-1] == ' ') + i--; + if(!hastail(query[0:i], ".in-addr.arpa") && !hastail(query[0:i], ".IN-ADDR.ARPA")) + query = addr2arpa(query[0:i])+" ptr"; + } + b := array of byte query; + if(sys->write(dns, b, len b) > 0){ + sys->seek(dns, big 0, Sys->SEEKSTART); + buf := array[256] of byte; + while((n := sys->read(dns, buf, len buf)) > 0) + sys->print("%s\n", string buf[0:n]); + if(n == 0) + return; + } + sys->print("!%r\n"); +} + +hastail(s: string, t: string): int +{ + if(len s >= len t && s[len s - len t:] == t) + return 1; + return 0; +} + +addr2arpa(a: string): string +{ + (nf, flds) := sys->tokenize(a, "."); + rl: list of string; + for(; flds != nil; flds = tl flds) + rl = hd flds :: rl; + addr: string; + for(; rl != nil; rl = tl rl){ + if(addr != nil) + addr[len addr] = '.'; + addr += hd rl; + } + return addr+".in-addr.arpa"; +} + +dbattr(s: string): string +{ + digit := 0; + dot := 0; + alpha := 0; + hex := 0; + colon := 0; + for(i := 0; i < len s; i++){ + case c := s[i] { + '0' to '9' => + digit = 1; + 'a' to 'f' or 'A' to 'F' => + hex = 1; + '.' => + dot = 1; + ':' => + colon = 1; + * => + if(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '-' || c == '&') + alpha = 1; + } + } + if(alpha){ + if(dot) + return "dom"; + return "sys"; + } + if(colon) + return "ip"; + if(dot){ + if(!hex) + return "ip"; + return "dom"; + } + return "sys"; +} |
