ref: 866d74c0c4bb50e85e9e8bb95140c10d409e53be
dir: /appl/cmd/whois.b/
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;
}