github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/core/ntpdate/ntpdate.go (about) 1 // Copyright 2016-2017 the u-root 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 // ntpdate uses NTP to adjust the system clock. 6 package main 7 8 import ( 9 "bufio" 10 "flag" 11 "fmt" 12 "log" 13 "os" 14 "strings" 15 "syscall" 16 "time" 17 18 "github.com/beevik/ntp" 19 ) 20 21 var ( 22 config = flag.String("config", "/etc/ntp.conf", "NTP config file.") 23 verbose = flag.Bool("verbose", false, "Verbose output") 24 debug = func(string, ...interface{}) {} 25 ) 26 27 const ( 28 fallback = "time.google.com" 29 ) 30 31 func parseServers(r *bufio.Reader) []string { 32 var uri []string 33 var l string 34 var err error 35 36 debug("Reading config file") 37 for err == nil { 38 // This handles the case where the last line doesn't end in \n 39 l, err = r.ReadString('\n') 40 debug("%v", l) 41 if w := strings.Fields(l); len(w) > 1 && w[0] == "server" { 42 // We look only for the server lines, we ignore options like iburst 43 // TODO(ganshun): figure out what options we want to support. 44 uri = append(uri, w[1]) 45 } 46 } 47 48 return uri 49 } 50 51 func getTime(servers []string) (t time.Time, err error) { 52 for _, s := range servers { 53 debug("Getting time from %v", s) 54 if t, err = ntp.Time(s); err == nil { 55 // Right now we return on the first valid time. 56 // We can implement better heuristics here. 57 debug("Got time %v", t) 58 return 59 } 60 debug("Error getting time: %v", err) 61 } 62 63 err = fmt.Errorf("unable to get any time from servers %v", servers) 64 return 65 } 66 67 func main() { 68 var servers []string 69 flag.Parse() 70 if *verbose { 71 debug = log.Printf 72 } 73 74 debug("Reading NTP servers from config file: %v", *config) 75 f, err := os.Open(*config) 76 if err == nil { 77 defer f.Close() 78 servers = parseServers(bufio.NewReader(f)) 79 debug("Found %v servers", len(servers)) 80 } else { 81 log.Printf("Unable to open config file: %v\nFalling back to : %v", err, fallback) 82 servers = []string{fallback} 83 } 84 85 t, err := getTime(servers) 86 if err != nil { 87 log.Fatalf("Unable to get time: %v", err) 88 } 89 90 tv := syscall.NsecToTimeval(t.UnixNano()) 91 if err = syscall.Settimeofday(&tv); err != nil { 92 log.Fatalf("Unable to set system time: %v", err) 93 } 94 }