gopkg.in/hugelgupf/u-root.v9@v9.0.0-20180831063832-3f6f1057f09b/cmds/find/find.go (about)

     1  // Copyright 2013-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  // Find finds files. It is similar to the Unix command. It uses REs, not globs,
     6  // for matching.
     7  //
     8  // OPTIONS:
     9  //     -d: enable debugging in the find package
    10  //     -mode integer-arg: match against mode, e.g. -mode 0755
    11  //     -type: match against a file type, e.g. -type f will match files
    12  //     -name: glob to match against file
    13  //     -l: long listing. It's not very good, yet, but it's useful enough.
    14  package main
    15  
    16  import (
    17  	"flag"
    18  	"fmt"
    19  	"log"
    20  	"os"
    21  	"strings"
    22  
    23  	"github.com/u-root/u-root/pkg/find"
    24  )
    25  
    26  const cmd = "find [opts] starting-at-path"
    27  
    28  var (
    29  	perm      = flag.Int("mode", -1, "Permissions")
    30  	fileType  = flag.String("type", "", "File type")
    31  	name      = flag.String("name", "", "glob for name")
    32  	long      = flag.Bool("l", false, "long listing")
    33  	debug     = flag.Bool("d", false, "Enable debugging in the find package")
    34  	fileTypes = map[string]os.FileMode{
    35  		"f":         0,
    36  		"file":      0,
    37  		"d":         os.ModeDir,
    38  		"directory": os.ModeDir,
    39  	}
    40  )
    41  
    42  func init() {
    43  	defUsage := flag.Usage
    44  	flag.Usage = func() {
    45  		os.Args[0] = cmd
    46  		defUsage()
    47  		os.Exit(1)
    48  	}
    49  }
    50  
    51  func main() {
    52  	flag.Parse()
    53  	a := flag.Args()
    54  	if len(a) != 1 {
    55  		flag.Usage()
    56  	}
    57  	root := a[0]
    58  	var mask, mode os.FileMode
    59  	if *perm != -1 {
    60  		mask = os.ModePerm
    61  		mode = os.FileMode(*perm)
    62  	}
    63  	if *fileType != "" {
    64  		intType, ok := fileTypes[*fileType]
    65  		if !ok {
    66  			var keys []string
    67  			for key := range fileTypes {
    68  				keys = append(keys, key)
    69  			}
    70  			log.Fatalf("%v is not a valid file type\n valid types are %v", *fileType, strings.Join(keys, ","))
    71  		}
    72  		mode |= intType
    73  		mask |= os.ModeType
    74  	}
    75  
    76  	f, err := find.New(func(f *find.Finder) error {
    77  		f.Root = root
    78  		f.Pattern = *name
    79  		f.ModeMask = mask
    80  		f.Mode = mode
    81  		if *debug {
    82  			f.Debug = log.Printf
    83  		}
    84  		return nil
    85  	})
    86  	if err != nil {
    87  		log.Fatal(err)
    88  	}
    89  	go f.Find()
    90  	for l := range f.Names {
    91  		if l.Err != nil {
    92  			fmt.Fprintf(os.Stderr, "%v: %v\n", l.Name, l.Err)
    93  			continue
    94  		}
    95  		// TODO: get long listing formats out of ls and into a package.
    96  		if *long {
    97  			fmt.Printf("%v\n", l.FileInfo)
    98  			continue
    99  		}
   100  		fmt.Printf("%s\n", l.Name)
   101  	}
   102  }