1package dns 2 3import ( 4 "bufio" 5 "os" 6 "strconv" 7 "strings" 8) 9 10// ClientConfig wraps the contents of the /etc/resolv.conf file. 11type ClientConfig struct { 12 Servers []string // servers to use 13 Search []string // suffixes to append to local name 14 Port string // what port to use 15 Ndots int // number of dots in name to trigger absolute lookup 16 Timeout int // seconds before giving up on packet 17 Attempts int // lost packets before giving up on server, not used in the package dns 18} 19 20// ClientConfigFromFile parses a resolv.conf(5) like file and returns 21// a *ClientConfig. 22func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) { 23 file, err := os.Open(resolvconf) 24 if err != nil { 25 return nil, err 26 } 27 defer file.Close() 28 c := new(ClientConfig) 29 scanner := bufio.NewScanner(file) 30 c.Servers = make([]string, 0) 31 c.Search = make([]string, 0) 32 c.Port = "53" 33 c.Ndots = 1 34 c.Timeout = 5 35 c.Attempts = 2 36 37 for scanner.Scan() { 38 if err := scanner.Err(); err != nil { 39 return nil, err 40 } 41 line := scanner.Text() 42 f := strings.Fields(line) 43 if len(f) < 1 { 44 continue 45 } 46 switch f[0] { 47 case "nameserver": // add one name server 48 if len(f) > 1 { 49 // One more check: make sure server name is 50 // just an IP address. Otherwise we need DNS 51 // to look it up. 52 name := f[1] 53 c.Servers = append(c.Servers, name) 54 } 55 56 case "domain": // set search path to just this domain 57 if len(f) > 1 { 58 c.Search = make([]string, 1) 59 c.Search[0] = f[1] 60 } else { 61 c.Search = make([]string, 0) 62 } 63 64 case "search": // set search path to given servers 65 c.Search = make([]string, len(f)-1) 66 for i := 0; i < len(c.Search); i++ { 67 c.Search[i] = f[i+1] 68 } 69 70 case "options": // magic options 71 for i := 1; i < len(f); i++ { 72 s := f[i] 73 switch { 74 case len(s) >= 6 && s[:6] == "ndots:": 75 n, _ := strconv.Atoi(s[6:]) 76 if n < 1 { 77 n = 1 78 } 79 c.Ndots = n 80 case len(s) >= 8 && s[:8] == "timeout:": 81 n, _ := strconv.Atoi(s[8:]) 82 if n < 1 { 83 n = 1 84 } 85 c.Timeout = n 86 case len(s) >= 8 && s[:9] == "attempts:": 87 n, _ := strconv.Atoi(s[9:]) 88 if n < 1 { 89 n = 1 90 } 91 c.Attempts = n 92 case s == "rotate": 93 /* not imp */ 94 } 95 } 96 } 97 } 98 return c, nil 99} 100