forsyth20121205-174063a80cc13 years agoHistory
177 lines · 3.1 KB · Brainfuck
RawDownload
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";}