diff options
Diffstat (limited to 'appl/cmd/whois.b')
| -rw-r--r-- | appl/cmd/whois.b | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/appl/cmd/whois.b b/appl/cmd/whois.b new file mode 100644 index 00000000..f89fb601 --- /dev/null +++ b/appl/cmd/whois.b @@ -0,0 +1,89 @@ +implement Whois; + +include "sys.m"; sys: Sys; +include "draw.m"; +include "dial.m"; dial: Dial; +include "arg.m"; + +Whois: module { + init: fn(nil: ref Draw->Context, args: list of string); +}; + +init(nil: ref Draw->Context, args: list of string) { + sys = load Sys Sys->PATH; + dial = load Dial Dial->PATH; + arg := load Arg Arg->PATH; + + addr := "tcp!whois.iana.org!43"; + expect_refer := 5; + + arg->init(args); + arg->setusage("whois [-a addr] [-n] host"); + while((opt := arg->opt()) != 0) { + case opt { + 'a' => + addr = dial->netmkaddr(arg->earg(), "tcp", "43"); + 'n' => + expect_refer = 0; + * => + arg->usage(); + } + } + + args = arg->argv(); + if(len args != 1) + arg->usage(); + + host := hd args; + fd := whois(addr, host); + + buf := array[512] of byte; + stdout := sys->fildes(1); + while((i := sys->read(fd, buf, len buf)) > 0) { + if(expect_refer) { + ls := sys->tokenize(string buf[0:i], "\n").t1; + newaddr: string = nil; + while(ls != nil) { + l := hd ls; + (n, rs) := sys->tokenize(l, " \t"); + if(n == 2 && hd rs == "refer:") { + newaddr = dial->netmkaddr(hd tl rs, "tcp", "43"); + break; + } else if(n == 3 && hd rs == "Whois" && hd tl rs == "Server:") { + newaddr = dial->netmkaddr(hd tl tl rs, "tcp", "43"); + break; + } + ls = tl ls; + } + if(newaddr != nil) { + fd = whois(newaddr, host); + expect_refer--; + continue; + } + } + sys->write(stdout, buf, i); + } + if(i < 0) { + sys->fprint(sys->fildes(2), "whois: reading info: %r\n"); + raise "fail:errors"; + } +} + +whois(addr: string, host: string): ref Sys->FD +{ + sys->print("[using server %s]\n", addr); + conn := dial->dial(addr, nil); + if(conn == nil) { + sys->fprint(sys->fildes(2), "whois: dialing %s: %r\n", addr); + raise "fail:errors"; + } + + fd := conn.dfd; + i := sys->fprint(fd, "%s\r\n", host); + if(i != len host + 2) { + sys->fprint(sys->fildes(2), "whois: sending name: %r\n"); + raise "fail:errors"; + } + + return fd; +} |
