package net
import (
"errors"
"internal/bytealg"
"io"
"os"
)
type nssConf struct {
err error
sources map [string ][]nssSource
}
type nssSource struct {
source string
criteria []nssCriterion
}
func (s nssSource ) standardCriteria () bool {
for i , crit := range s .criteria {
if !crit .standardStatusAction (i == len (s .criteria )-1 ) {
return false
}
}
return true
}
type nssCriterion struct {
negate bool
status string
action string
}
func (c nssCriterion ) standardStatusAction (last bool ) bool {
if c .negate {
return false
}
var def string
switch c .status {
case "success" :
def = "return"
case "notfound" , "unavail" , "tryagain" :
def = "continue"
default :
return false
}
if last && c .action == "return" {
return true
}
return c .action == def
}
func parseNSSConfFile (file string ) *nssConf {
f , err := os .Open (file )
if err != nil {
return &nssConf {err : err }
}
defer f .Close ()
return parseNSSConf (f )
}
func parseNSSConf (r io .Reader ) *nssConf {
slurp , err := readFull (r )
if err != nil {
return &nssConf {err : err }
}
conf := new (nssConf )
conf .err = foreachLine (slurp , func (line []byte ) error {
line = trimSpace (removeComment (line ))
if len (line ) == 0 {
return nil
}
colon := bytealg .IndexByte (line , ':' )
if colon == -1 {
return errors .New ("no colon on line" )
}
db := string (trimSpace (line [:colon ]))
srcs := line [colon +1 :]
for {
srcs = trimSpace (srcs )
if len (srcs ) == 0 {
break
}
sp := bytealg .IndexByte (srcs , ' ' )
var src string
if sp == -1 {
src = string (srcs )
srcs = nil
} else {
src = string (srcs [:sp ])
srcs = trimSpace (srcs [sp +1 :])
}
var criteria []nssCriterion
if len (srcs ) > 0 && srcs [0 ] == '[' {
bclose := bytealg .IndexByte (srcs , ']' )
if bclose == -1 {
return errors .New ("unclosed criterion bracket" )
}
var err error
criteria , err = parseCriteria (srcs [1 :bclose ])
if err != nil {
return errors .New ("invalid criteria: " + string (srcs [1 :bclose ]))
}
srcs = srcs [bclose +1 :]
}
if conf .sources == nil {
conf .sources = make (map [string ][]nssSource )
}
conf .sources [db ] = append (conf .sources [db ], nssSource {
source : src ,
criteria : criteria ,
})
}
return nil
})
return conf
}
func parseCriteria (x []byte ) (c []nssCriterion , err error ) {
err = foreachField (x , func (f []byte ) error {
not := false
if len (f ) > 0 && f [0 ] == '!' {
not = true
f = f [1 :]
}
if len (f ) < 3 {
return errors .New ("criterion too short" )
}
eq := bytealg .IndexByte (f , '=' )
if eq == -1 {
return errors .New ("criterion lacks equal sign" )
}
lowerASCIIBytes (f )
c = append (c , nssCriterion {
negate : not ,
status : string (f [:eq ]),
action : string (f [eq +1 :]),
})
return nil
})
return
}
The pages are generated with Golds v0.3.6 . (GOOS=darwin GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .