package net
import (
)
type nssConf struct {
err error
sources map[string][]nssSource
}
type nssSource struct {
source string
criteria []nssCriterion
}
func ( nssSource) () bool {
for , := range .criteria {
if !.standardStatusAction( == len(.criteria)-1) {
return false
}
}
return true
}
type nssCriterion struct {
negate bool
status string
action string
}
func ( nssCriterion) ( bool) bool {
if .negate {
return false
}
var string
switch .status {
case "success":
= "return"
case "notfound", "unavail", "tryagain":
= "continue"
default:
return false
}
if && .action == "return" {
return true
}
return .action ==
}
func ( string) *nssConf {
, := os.Open()
if != nil {
return &nssConf{err: }
}
defer .Close()
return parseNSSConf()
}
func ( io.Reader) *nssConf {
, := readFull()
if != nil {
return &nssConf{err: }
}
:= new(nssConf)
.err = foreachLine(, func( []byte) error {
= trimSpace(removeComment())
if len() == 0 {
return nil
}
:= bytealg.IndexByte(, ':')
if == -1 {
return errors.New("no colon on line")
}
:= string(trimSpace([:]))
:= [+1:]
for {
= trimSpace()
if len() == 0 {
break
}
:= bytealg.IndexByte(, ' ')
var string
if == -1 {
= string()
= nil
} else {
= string([:])
= trimSpace([+1:])
}
var []nssCriterion
if len() > 0 && [0] == '[' {
:= bytealg.IndexByte(, ']')
if == -1 {
return errors.New("unclosed criterion bracket")
}
var error
, = parseCriteria([1:])
if != nil {
return errors.New("invalid criteria: " + string([1:]))
}
= [+1:]
}
if .sources == nil {
.sources = make(map[string][]nssSource)
}
.sources[] = append(.sources[], nssSource{
source: ,
criteria: ,
})
}
return nil
})
return
}
func ( []byte) ( []nssCriterion, error) {
= foreachField(, func( []byte) error {
:= false
if len() > 0 && [0] == '!' {
= true
= [1:]
}
if len() < 3 {
return errors.New("criterion too short")
}
:= bytealg.IndexByte(, '=')
if == -1 {
return errors.New("criterion lacks equal sign")
}
lowerASCIIBytes()
= append(, nssCriterion{
negate: ,
status: string([:]),
action: string([+1:]),
})
return nil
})
return
}