github.com/roboticscm/goman@v0.0.0-20210203095141-87c07b4a0a55/src/net/hosts.go (about)

     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  // Read static host/IP entries from /etc/hosts.
     6  
     7  package net
     8  
     9  import (
    10  	"sync"
    11  	"time"
    12  )
    13  
    14  const cacheMaxAge = 5 * time.Minute
    15  
    16  // hostsPath points to the file with static IP/address entries.
    17  var hostsPath = "/etc/hosts"
    18  
    19  // Simple cache.
    20  var hosts struct {
    21  	sync.Mutex
    22  	byName map[string][]string
    23  	byAddr map[string][]string
    24  	expire time.Time
    25  	path   string
    26  }
    27  
    28  func readHosts() {
    29  	now := time.Now()
    30  	hp := hostsPath
    31  	if len(hosts.byName) == 0 || now.After(hosts.expire) || hosts.path != hp {
    32  		hs := make(map[string][]string)
    33  		is := make(map[string][]string)
    34  		var file *file
    35  		if file, _ = open(hp); file == nil {
    36  			return
    37  		}
    38  		for line, ok := file.readLine(); ok; line, ok = file.readLine() {
    39  			if i := byteIndex(line, '#'); i >= 0 {
    40  				// Discard comments.
    41  				line = line[0:i]
    42  			}
    43  			f := getFields(line)
    44  			if len(f) < 2 || ParseIP(f[0]) == nil {
    45  				continue
    46  			}
    47  			for i := 1; i < len(f); i++ {
    48  				h := f[i]
    49  				hs[h] = append(hs[h], f[0])
    50  				is[f[0]] = append(is[f[0]], h)
    51  			}
    52  		}
    53  		// Update the data cache.
    54  		hosts.expire = now.Add(cacheMaxAge)
    55  		hosts.path = hp
    56  		hosts.byName = hs
    57  		hosts.byAddr = is
    58  		file.close()
    59  	}
    60  }
    61  
    62  // lookupStaticHost looks up the addresses for the given host from /etc/hosts.
    63  func lookupStaticHost(host string) []string {
    64  	hosts.Lock()
    65  	defer hosts.Unlock()
    66  	readHosts()
    67  	if len(hosts.byName) != 0 {
    68  		if ips, ok := hosts.byName[host]; ok {
    69  			return ips
    70  		}
    71  	}
    72  	return nil
    73  }
    74  
    75  // lookupStaticAddr looks up the hosts for the given address from /etc/hosts.
    76  func lookupStaticAddr(addr string) []string {
    77  	hosts.Lock()
    78  	defer hosts.Unlock()
    79  	readHosts()
    80  	if len(hosts.byAddr) != 0 {
    81  		if hosts, ok := hosts.byAddr[addr]; ok {
    82  			return hosts
    83  		}
    84  	}
    85  	return nil
    86  }