github.com/rck/u-root@v0.0.0-20180106144920-7eb602e381bb/cmds/which/which.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 // Which locates a command. 6 // 7 // Synopsis: 8 // which [-a] [COMMAND]... 9 // 10 // Options: 11 // -a: print all matching pathnames of each argument 12 package main 13 14 import ( 15 "flag" 16 "io" 17 "log" 18 "os" 19 "path/filepath" 20 "strings" 21 ) 22 23 var ( 24 flags struct { 25 allPaths bool 26 } 27 ) 28 29 func init() { 30 flag.BoolVar(&flags.allPaths, "a", false, "print all matching pathnames of each argument") 31 } 32 33 func which(p string, writer io.Writer, cmds []string) { 34 pathArray := strings.Split(p, ":") 35 36 // If no matches are found will exit 1, else 0 37 exitValue := 1 38 for _, name := range cmds { 39 for _, p := range pathArray { 40 f := filepath.Join(p, name) 41 if info, err := os.Stat(f); err == nil { 42 // TODO: this test (0111) is not quite right. 43 // Consider a file executable only by root (0100) 44 // when I'm not root. I can't run it. 45 if m := info.Mode(); m&0111 != 0 && !(m&os.ModeType == os.ModeSymlink) { 46 exitValue = 0 47 writer.Write([]byte(f + "\n")) 48 if !flags.allPaths { 49 break 50 } 51 } 52 } 53 } 54 } 55 os.Exit(exitValue) 56 } 57 58 func main() { 59 flag.Parse() 60 61 p := os.Getenv("PATH") 62 if len(p) == 0 { 63 // The default bin path of uroot is ubin, fallbacking to it. 64 log.Print("No path variable found! Fallbacking to /ubin") 65 p = "/ubin" 66 } 67 68 which(p, os.Stdout, flag.Args()) 69 }