An implementation of whois. master db/master gh/master
authorPete <pete@debu.gs>
Thu, 9 Nov 2023 12:44:48 +0000 (04:44 -0800)
committerPete <pete@debu.gs>
Thu, 9 Nov 2023 12:45:31 +0000 (04:45 -0800)
appl/cmd/mkfile
appl/cmd/whois.b [new file with mode: 0644]

index f785c795fcbabd38794df8de93e48d01cfa3f015..2d7767849042d15795305ca584d8075faba7d901 100644 (file)
@@ -171,6 +171,7 @@ TARG=\
        wav2iaf.dis\
        wc.dis\
        webgrab.dis\
+       whois.dis\
        wish.dis\
        wmexport.dis\
        wmimport.dis\
diff --git a/appl/cmd/whois.b b/appl/cmd/whois.b
new file mode 100644 (file)
index 0000000..f89fb60
--- /dev/null
@@ -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;
+}