OSDN Git Service

libgo: Update to weekly.2011-11-02.
[pf3gnuchains/gcc-fork.git] / libgo / go / net / port.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 port mappings from /etc/services
8
9 package net
10
11 import "sync"
12
13 var services map[string]map[string]int
14 var servicesError error
15 var onceReadServices sync.Once
16
17 func readServices() {
18         services = make(map[string]map[string]int)
19         var file *file
20         if file, servicesError = open("/etc/services"); servicesError != nil {
21                 return
22         }
23         for line, ok := file.readLine(); ok; line, ok = file.readLine() {
24                 // "http 80/tcp www www-http # World Wide Web HTTP"
25                 if i := byteIndex(line, '#'); i >= 0 {
26                         line = line[0:i]
27                 }
28                 f := getFields(line)
29                 if len(f) < 2 {
30                         continue
31                 }
32                 portnet := f[1] // "tcp/80"
33                 port, j, ok := dtoi(portnet, 0)
34                 if !ok || port <= 0 || j >= len(portnet) || portnet[j] != '/' {
35                         continue
36                 }
37                 netw := portnet[j+1:] // "tcp"
38                 m, ok1 := services[netw]
39                 if !ok1 {
40                         m = make(map[string]int)
41                         services[netw] = m
42                 }
43                 for i := 0; i < len(f); i++ {
44                         if i != 1 { // f[1] was port/net
45                                 m[f[i]] = port
46                         }
47                 }
48         }
49         file.close()
50 }
51
52 // goLookupPort is the native Go implementation of LookupPort.
53 func goLookupPort(network, service string) (port int, err error) {
54         onceReadServices.Do(readServices)
55
56         switch network {
57         case "tcp4", "tcp6":
58                 network = "tcp"
59         case "udp4", "udp6":
60                 network = "udp"
61         }
62
63         if m, ok := services[network]; ok {
64                 if port, ok = m[service]; ok {
65                         return
66                 }
67         }
68         return 0, &AddrError{"unknown port", network + "/" + service}
69 }