Imported Upstream version 4.7.2
[platform/upstream/gcc48.git] / libgo / go / net / lookup_unix.go
1 // Copyright 2011 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 netbsd openbsd
6
7 package net
8
9 import (
10         "errors"
11         "sync"
12 )
13
14 var (
15         protocols         map[string]int
16         onceReadProtocols sync.Once
17 )
18
19 // readProtocols loads contents of /etc/protocols into protocols map
20 // for quick access.
21 func readProtocols() {
22         protocols = make(map[string]int)
23         if file, err := open("/etc/protocols"); err == nil {
24                 for line, ok := file.readLine(); ok; line, ok = file.readLine() {
25                         // tcp    6   TCP    # transmission control protocol
26                         if i := byteIndex(line, '#'); i >= 0 {
27                                 line = line[0:i]
28                         }
29                         f := getFields(line)
30                         if len(f) < 2 {
31                                 continue
32                         }
33                         if proto, _, ok := dtoi(f[1], 0); ok {
34                                 protocols[f[0]] = proto
35                                 for _, alias := range f[2:] {
36                                         protocols[alias] = proto
37                                 }
38                         }
39                 }
40                 file.close()
41         }
42 }
43
44 // lookupProtocol looks up IP protocol name in /etc/protocols and
45 // returns correspondent protocol number.
46 func lookupProtocol(name string) (proto int, err error) {
47         onceReadProtocols.Do(readProtocols)
48         proto, found := protocols[name]
49         if !found {
50                 return 0, errors.New("unknown IP protocol specified: " + name)
51         }
52         return
53 }
54
55 func lookupHost(host string) (addrs []string, err error) {
56         addrs, err, ok := cgoLookupHost(host)
57         if !ok {
58                 addrs, err = goLookupHost(host)
59         }
60         return
61 }
62
63 func lookupIP(host string) (addrs []IP, err error) {
64         addrs, err, ok := cgoLookupIP(host)
65         if !ok {
66                 addrs, err = goLookupIP(host)
67         }
68         return
69 }
70
71 func lookupPort(network, service string) (port int, err error) {
72         port, err, ok := cgoLookupPort(network, service)
73         if !ok {
74                 port, err = goLookupPort(network, service)
75         }
76         return
77 }
78
79 func lookupCNAME(name string) (cname string, err error) {
80         cname, err, ok := cgoLookupCNAME(name)
81         if !ok {
82                 cname, err = goLookupCNAME(name)
83         }
84         return
85 }
86
87 func lookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
88         var target string
89         if service == "" && proto == "" {
90                 target = name
91         } else {
92                 target = "_" + service + "._" + proto + "." + name
93         }
94         var records []dnsRR
95         cname, records, err = lookup(target, dnsTypeSRV)
96         if err != nil {
97                 return
98         }
99         addrs = make([]*SRV, len(records))
100         for i, rr := range records {
101                 r := rr.(*dnsRR_SRV)
102                 addrs[i] = &SRV{r.Target, r.Port, r.Priority, r.Weight}
103         }
104         byPriorityWeight(addrs).sort()
105         return
106 }
107
108 func lookupMX(name string) (mx []*MX, err error) {
109         _, records, err := lookup(name, dnsTypeMX)
110         if err != nil {
111                 return
112         }
113         mx = make([]*MX, len(records))
114         for i, rr := range records {
115                 r := rr.(*dnsRR_MX)
116                 mx[i] = &MX{r.Mx, r.Pref}
117         }
118         byPref(mx).sort()
119         return
120 }
121
122 func lookupTXT(name string) (txt []string, err error) {
123         _, records, err := lookup(name, dnsTypeTXT)
124         if err != nil {
125                 return
126         }
127         txt = make([]string, len(records))
128         for i, r := range records {
129                 txt[i] = r.(*dnsRR_TXT).Txt
130         }
131         return
132 }
133
134 func lookupAddr(addr string) (name []string, err error) {
135         name = lookupStaticAddr(addr)
136         if len(name) > 0 {
137                 return
138         }
139         var arpa string
140         arpa, err = reverseaddr(addr)
141         if err != nil {
142                 return
143         }
144         var records []dnsRR
145         _, records, err = lookup(arpa, dnsTypePTR)
146         if err != nil {
147                 return
148         }
149         name = make([]string, len(records))
150         for i := range records {
151                 r := records[i].(*dnsRR_PTR)
152                 name[i] = r.Ptr
153         }
154         return
155 }