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