debconf: implement dat file parser

This commit is contained in:
mappu 2024-06-30 13:47:29 +12:00
parent 0b91c379b8
commit 053e07c319
2 changed files with 122 additions and 0 deletions

92
debconf/debconf.go Normal file
View File

@ -0,0 +1,92 @@
package debconf
import (
"bufio"
"fmt"
"io"
"strings"
)
const (
DefaultConfigDat = `/var/cache/debconf/config.dat`
DefaultPasswordsDat = `/var/cache/debconf/passwords.dat`
DefaultTemplatesDat = `/var/cache/debconf/templates.dat`
)
type Entry struct {
Name string
Properties [][2]string
}
type Database struct {
Entries []Entry
AllColumnNames []string
}
func Parse(r io.Reader) (*Database, error) {
sc := bufio.NewScanner(r)
var entries []Entry
var wip Entry
var linenum int = 0
knownColumnNames := map[string]struct{}{
"Name": struct{}{},
}
var discoveredColumns []string
for sc.Scan() {
linenum++
line := sc.Text()
if line == "" {
if wip.Name != "" {
entries = append(entries, wip)
wip = Entry{}
}
continue
}
if line[0] == ' ' {
// continuation of last text entry
if len(wip.Properties) == 0 {
return nil, fmt.Errorf("Continuation of nonexistent entry on line %d", linenum)
}
wip.Properties[len(wip.Properties)-1][1] += line[1:]
} else {
// New pair on current element
key, rest, ok := strings.Cut(line, `:`)
if !ok {
return nil, fmt.Errorf("Missing : on line %d", linenum)
}
if _, ok := knownColumnNames[key]; !ok {
knownColumnNames[key] = struct{}{}
discoveredColumns = append(discoveredColumns, key)
}
if key == `Name` {
wip.Name = rest
} else {
wip.Properties = append(wip.Properties, [2]string{key, rest})
}
}
}
if sc.Err() != nil {
return nil, sc.Err()
}
if wip.Name != "" {
entries = append(entries, wip)
}
return &Database{
Entries: entries,
AllColumnNames: discoveredColumns,
}, nil
}

30
debconf/debconf_test.go Normal file
View File

@ -0,0 +1,30 @@
package debconf
import (
"os"
"testing"
)
func TestDebconfParse(t *testing.T) {
src, err := os.Open(DefaultConfigDat)
if err != nil {
if os.IsNotExist(err) {
t.Skip(err)
}
t.Fatal(err)
}
defer src.Close()
db, err := Parse(src)
if err != nil {
t.Fatalf("Parse: %v", err)
}
if len(db.Entries) == 0 {
t.Errorf("expected >0 entries, got %v", len(db.Entries))
}
if len(db.AllColumnNames) == 0 {
t.Errorf("expected >0 column names, got %v", len(db.AllColumnNames))
}
}