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  }