...
 
Commits (2)
......@@ -24,3 +24,11 @@ type DataStreamRecord struct {
Records []RR `json:"records"`
IsDeleted bool `json:"$deleted"`
}
func (rr *RR) IsTXT() bool {
return rr.Type == "TXT"
}
func (rr *RR) IsCNAME() bool {
return rr.Type == "CNAME"
}
......@@ -37,6 +37,7 @@ $TTL {{.TTL}}
`
const ZONE_TABSTOP = 8
const MAX_TXT = 128
type ZoneFile struct {
Name string
......@@ -114,6 +115,7 @@ func ZoneFileFromDataStream(data *DataStreamRecord) (*ZoneFile, error) {
l2 = (l2/ZONE_TABSTOP + 1) * ZONE_TABSTOP
// Record mask
mask := fmt.Sprintf("%%-%ds%%-%ds%%s", l1, l2)
txt_cmask := strings.Repeat(" ", l1) + "%s"
suffix := zf.Name + "."
nsuffix := "." + suffix
lnsuffix := len(nsuffix)
......@@ -123,13 +125,21 @@ func ZoneFileFromDataStream(data *DataStreamRecord) (*ZoneFile, error) {
}
r := data.Records[i]
content := r.RData
if r.Type == "CNAME" && strings.HasSuffix(content, nsuffix) {
if r.IsCNAME() && strings.HasSuffix(content, nsuffix) {
content = content[:len(content)-lnsuffix]
}
if r.Priority > 0 {
content = fmt.Sprintf("%d %s", r.Priority, content)
}
zf.Records = append(zf.Records, fmt.Sprintf(mask, r.Name, r.Type, content))
if r.IsTXT() {
txt := SplitTxt(content)
zf.Records = append(zf.Records, fmt.Sprintf(mask, r.Name, r.Type, txt[0]))
for _, s := range txt[1:] {
zf.Records = append(zf.Records, fmt.Sprintf(txt_cmask, s))
}
} else {
zf.Records = append(zf.Records, fmt.Sprintf(mask, r.Name, r.Type, content))
}
}
return zf, nil
}
......@@ -185,6 +195,27 @@ func PrettyTime(t int) string {
return strings.Join(r, " ")
}
func SplitTxt(value string) []string {
if len(value) <= MAX_TXT {
// Single line
if !strings.HasPrefix(value, "\"") {
value = "\"" + value + "\""
}
return []string{value}
}
// Split to multiple lines
if strings.HasPrefix(value, "\"") && strings.HasSuffix(value, "\"") {
value = value[1 : len(value)-1]
}
r := []string{"("}
for len(value) > 0 {
r = append(r, "\""+value[:MAX_TXT]+"\"")
value = value[MAX_TXT:]
}
r = append(r, ")")
return r
}
func init() {
var err error
ZoneTemplate, err = template.New("zone").Parse(ZONE_TEMPLATE)
......