dont delete it

This commit is contained in:
Miek Gieben 2011-07-21 14:32:02 +02:00
parent 5fe15bc754
commit c5e26c4313
1 changed files with 257 additions and 0 deletions

257
zparse.rl Normal file
View File

@ -0,0 +1,257 @@
package dns
// Parse RRs
// With the thankful help of gdnsd and the Go examples for Ragel.
//
import (
"os"
"io"
"net"
"strconv"
)
const _RDATAMAX = 7
const _IOBUF = 65365
// Save up tokens, after we've seen the entire rdata
// we can use this.
type token struct {
T []string // text
N []int // number
ti int // text counter
ni int // number counter
}
func newToken() *token {
to := new(token)
to.T = make([]string, _RDATAMAX)
to.N = make([]int, _RDATAMAX)
to.ni, to.ti = 0, 0
return to
}
// Only push functions are provided. Reading is done, by directly
// accessing the members (T and N). See types.rl.
func (to *token) pushInt(s string) {
i, err := strconv.Atoi(s)
if err != nil {
panic("Failure to parse to int: " + s)
}
to.N[to.ni] = i
to.ni++
if to.ni > _RDATAMAX {
panic("Too much rdata (int)")
}
}
func (to *token) pushString(s string) {
to.T[to.ti] = s
to.ti++
if to.ti > _RDATAMAX {
panic("Too much rdata (string)")
}
}
func (to *token) reset() {
to.ni, to.ti = 0, 0
}
func rdata_aaaa(hdr RR_Header, tok *token) RR {
rr := new(RR_AAAA)
rr.Hdr = hdr
rr.Hdr.Rrtype = TypeAAAA
rr.AAAA = net.ParseIP(tok.T[0])
println("Calling aaaa", tok.T[0])
return rr
}
func rdata_a(hdr RR_Header, tok *token) RR {
rr := new(RR_A)
rr.Hdr = hdr
rr.Hdr.Rrtype = TypeA
rr.A = net.ParseIP(tok.T[0])
return rr
}
func rdata_ns(hdr RR_Header, tok *token) RR {
rr := new(RR_NS)
rr.Hdr = hdr
rr.Hdr.Rrtype = TypeNS
rr.Ns = tok.T[0]
return rr
}
func rdata_cname(hdr RR_Header, tok *token) RR {
rr := new(RR_CNAME)
rr.Hdr = hdr
rr.Hdr.Rrtype = TypeCNAME
rr.Cname = tok.T[0]
return rr
}
func rdata_soa(hdr RR_Header, tok *token) RR {
rr := new(RR_SOA)
rr.Hdr = hdr
rr.Hdr.Rrtype = TypeSOA
rr.Ns = tok.T[0]
rr.Mbox = tok.T[1]
rr.Serial = uint32(tok.N[0])
rr.Refresh = uint32(tok.N[1])
rr.Retry = uint32(tok.N[2])
rr.Expire = uint32(tok.N[3])
rr.Minttl = uint32(tok.N[4])
return rr
}
func rdata_mx(hdr RR_Header, tok *token) RR {
rr := new(RR_MX)
rr.Hdr = hdr;
rr.Hdr.Rrtype = TypeMX
rr.Pref = uint16(tok.N[0])
rr.Mx = tok.T[0]
return rr
}
func rdata_ds(hdr RR_Header, tok *token) RR {
rr := new(RR_DS)
rr.Hdr = hdr;
rr.Hdr.Rrtype = TypeDS
rr.KeyTag = uint16(tok.N[0])
rr.Algorithm = uint8(tok.N[1])
rr.DigestType = uint8(tok.N[2])
rr.Digest = tok.T[0]
return rr
}
func rdata_dnskey(hdr RR_Header, tok *token) RR {
rr := new(RR_DNSKEY)
rr.Hdr = hdr;
rr.Hdr.Rrtype = TypeDNSKEY
rr.Flags = uint16(tok.N[0])
rr.Protocol = uint8(tok.N[1])
rr.Algorithm = uint8(tok.N[2])
rr.PublicKey = tok.T[0]
return rr
}
func rdata_rrsig(hdr RR_Header, tok *token) RR {
rr := new(RR_RRSIG)
rr.Hdr = hdr;
rr.Hdr.Rrtype = TypeRRSIG
rr.TypeCovered = uint16(tok.N[0])
rr.Algorithm = uint8(tok.N[1])
rr.Labels = uint8(tok.N[2])
rr.OrigTtl = uint32(tok.N[3])
rr.Expiration = uint32(tok.N[4])
rr.Inception = uint32(tok.N[5])
rr.KeyTag = uint16(tok.N[6])
rr.SignerName = tok.T[0]
rr.Signature = tok.T[1]
return rr
}
func set(r RR, z *Zone, tok *token) {
z.Push(r)
tok.reset()
println("Resetting")
}
%%{
machine z;
write data;
}%%
// SetString
// All the NewReader stuff is expensive...
// only works for short io.Readers as we put the whole thing
// in a string -- needs to be extended for large files (sliding window).
func Zparse(q io.Reader) (z *Zone, err os.Error) {
buf := make([]byte, _IOBUF)
n, err := q.Read(buf)
if err != nil {
return nil, err
}
buf = buf[:n]
z = new(Zone)
data := string(buf)
cs, p, pe := 0, 0, len(data)
ts, te, act := 0, 0, 0
// top := 0
// stack := make([]int, 100)
eof := len(data)
// keep Go happy - need to fix this ofcourse
ts = ts; te = te; act = act
brace := false
lines := 0
mark := 0
hdr := new(RR_Header)
tok := newToken()
var rr RR
rr = rr
%%{
action mark { mark = p }
action qname { hdr.Name = data[mark:p] }
action qclass { hdr.Class = Str_class[data[mark:p]] }
action defTtl { /* ... */ }
action setTtl { ttl, _ := strconv.Atoi(data[mark:p]); hdr.Ttl = uint32(ttl) }
action number { tok.pushInt(data[mark:p]) }
action text { tok.pushString(data[mark:p]) }
action openBrace { if brace { println("Brace already open")} ; brace = true }
action closeBrace { if !brace { println("Brace already closed")}; brace = false }
action brace { brace }
action linecount { lines++ }
# Newlines
nl = [\n]+ $linecount;
# Comments, entire line. Shorter comments are handled in the
# 'bl' definition below.
comment = ';' [^\n]*;
bl = (
[ \t]+
| '(' $openBrace
| ')' $closeBrace
| (comment? nl)+ when brace
)+ %mark;
# chars = [^; \t"\n\\)(];
ws = [ \t]+;
qclass = ('IN'i|'CS'i|'CH'i|'HS'i|'ANY'i|'NONE'i) %qclass;
qname = [a-zA-Z0-9_\-.]+ %qname;
t = [a-zA-Z0-9_\-.:]+ $1 %0 %text;
tb = [a-zA-Z0-9_\-.: ]+ $1 %0 %text;
n = [0-9]+ $1 %0 %number;
ttl = digit+ >mark;
lhs = qname? bl %defTtl (
(ttl %setTtl bl (qclass bl)?)
| (qclass bl (ttl %setTtl bl)?)
)?;
main := |*
lhs 'A'i bl t nl => { rr = rdata_a(*hdr, tok); set(rr, z, tok); };
lhs 'NS'i bl t nl => { rr = rdata_ns(*hdr, tok); set(rr, z, tok); };
lhs 'CNAME'i bl t nl => { rr = rdata_cname(*hdr, tok); set(rr, z, tok); };
lhs 'AAAA'i bl t nl => { rr = rdata_aaaa(*hdr, tok); set(rr, z, tok); };
lhs 'MX'i bl n bl t nl => { rr = rdata_mx(*hdr, tok); set(rr, z, tok); };
lhs 'SOA'i bl t bl t bl n bl n bl n bl n bl n nl => { rr = rdata_soa(*hdr, tok); set(rr, z, tok); };
*|;
# main := (rr? bl? ((comment? nl) when !brace))*;
write init;
write exec;
}%%
if eof > -1 {
if cs < z_first_final {
// No clue what I'm doing what so ever
if p == pe {
println("unexpected eof")
return z, nil
} else {
println("error at position ", p, "\"",data[mark:p],"\"")
return z, nil
}
}
}
return z, nil
}