OSDN Git Service

libgo: Update to weekly 2011-11-09.
[pf3gnuchains/gcc-fork.git] / libgo / go / net / dnsconfig.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // +build darwin freebsd linux openbsd
6
7 // Read system DNS config from /etc/resolv.conf
8
9 package net
10
11 type dnsConfig struct {
12         servers  []string // servers to use
13         search   []string // suffixes to append to local name
14         ndots    int      // number of dots in name to trigger absolute lookup
15         timeout  int      // seconds before giving up on packet
16         attempts int      // lost packets before giving up on server
17         rotate   bool     // round robin among servers
18 }
19
20 var dnsconfigError error
21
22 type DNSConfigError struct {
23         Err error
24 }
25
26 func (e *DNSConfigError) Error() string {
27         return "error reading DNS config: " + e.Err.Error()
28 }
29
30 func (e *DNSConfigError) Timeout() bool   { return false }
31 func (e *DNSConfigError) Temporary() bool { return false }
32
33 // See resolv.conf(5) on a Linux machine.
34 // TODO(rsc): Supposed to call uname() and chop the beginning
35 // of the host name to get the default search domain.
36 // We assume it's in resolv.conf anyway.
37 func dnsReadConfig() (*dnsConfig, error) {
38         file, err := open("/etc/resolv.conf")
39         if err != nil {
40                 return nil, &DNSConfigError{err}
41         }
42         conf := new(dnsConfig)
43         conf.servers = make([]string, 3)[0:0] // small, but the standard limit
44         conf.search = make([]string, 0)
45         conf.ndots = 1
46         conf.timeout = 5
47         conf.attempts = 2
48         conf.rotate = false
49         for line, ok := file.readLine(); ok; line, ok = file.readLine() {
50                 f := getFields(line)
51                 if len(f) < 1 {
52                         continue
53                 }
54                 switch f[0] {
55                 case "nameserver": // add one name server
56                         a := conf.servers
57                         n := len(a)
58                         if len(f) > 1 && n < cap(a) {
59                                 // One more check: make sure server name is
60                                 // just an IP address.  Otherwise we need DNS
61                                 // to look it up.
62                                 name := f[1]
63                                 switch len(ParseIP(name)) {
64                                 case 16:
65                                         name = "[" + name + "]"
66                                         fallthrough
67                                 case 4:
68                                         a = a[0 : n+1]
69                                         a[n] = name
70                                         conf.servers = a
71                                 }
72                         }
73
74                 case "domain": // set search path to just this domain
75                         if len(f) > 1 {
76                                 conf.search = make([]string, 1)
77                                 conf.search[0] = f[1]
78                         } else {
79                                 conf.search = make([]string, 0)
80                         }
81
82                 case "search": // set search path to given servers
83                         conf.search = make([]string, len(f)-1)
84                         for i := 0; i < len(conf.search); i++ {
85                                 conf.search[i] = f[i+1]
86                         }
87
88                 case "options": // magic options
89                         for i := 1; i < len(f); i++ {
90                                 s := f[i]
91                                 switch {
92                                 case len(s) >= 6 && s[0:6] == "ndots:":
93                                         n, _, _ := dtoi(s, 6)
94                                         if n < 1 {
95                                                 n = 1
96                                         }
97                                         conf.ndots = n
98                                 case len(s) >= 8 && s[0:8] == "timeout:":
99                                         n, _, _ := dtoi(s, 8)
100                                         if n < 1 {
101                                                 n = 1
102                                         }
103                                         conf.timeout = n
104                                 case len(s) >= 8 && s[0:9] == "attempts:":
105                                         n, _, _ := dtoi(s, 9)
106                                         if n < 1 {
107                                                 n = 1
108                                         }
109                                         conf.attempts = n
110                                 case s == "rotate":
111                                         conf.rotate = true
112                                 }
113                         }
114                 }
115         }
116         file.close()
117
118         return conf, nil
119 }