code.flowtr.dev/mirrors/u-root@v1.0.0/cmds/strings/strings.go (about) 1 // Copyright 2018 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 // Strings finds printable strings. 6 // 7 // Synopsis: 8 // strings OPTIONS [FILES]... 9 // 10 // Description: 11 // Prints all sequences of `n` or more printable characters terminated by a 12 // non-printable character (or EOF). 13 // 14 // If no files are specified, read from stdin. 15 // 16 // Options: 17 // -n number: the minimum string length (default is 4) 18 package main 19 20 import ( 21 "bufio" 22 "io" 23 "log" 24 "os" 25 26 flag "github.com/spf13/pflag" 27 ) 28 29 var ( 30 n = flag.Int("n", 4, "the minimum string length") 31 ) 32 33 func asciiIsPrint(char byte) bool { 34 return char >= 32 && char <= 126 35 } 36 37 func stringsIO(r *bufio.Reader, w io.Writer) error { 38 var o []byte 39 for { 40 b, err := r.ReadByte() 41 if err == io.EOF { 42 if len(o) >= *n { 43 w.Write(o) 44 w.Write([]byte{'\n'}) 45 } 46 return nil 47 } 48 if err != nil { 49 return err 50 } 51 if !asciiIsPrint(b) { 52 if len(o) >= *n { 53 w.Write(o) 54 w.Write([]byte{'\n'}) 55 } 56 o = o[:0] 57 continue 58 } 59 // Prevent the buffer from growing indefinitely. 60 if len(o) >= *n+1024 { 61 w.Write(o[:1024]) 62 o = o[1024:] 63 } 64 o = append(o, b) 65 } 66 } 67 68 func stringsFile(file string, w io.Writer) error { 69 f, err := os.Open(file) 70 if err != nil { 71 return err 72 } 73 defer f.Close() 74 75 // Buffer reduces number of syscalls. 76 rb := bufio.NewReader(f) 77 return stringsIO(rb, w) 78 } 79 80 func strings(files []string, w io.Writer) error { 81 if len(files) == 0 { 82 rb := bufio.NewReader(os.Stdin) 83 if err := stringsIO(rb, w); err != nil { 84 return err 85 } 86 } 87 for _, file := range files { 88 if err := stringsFile(file, w); err != nil { 89 return err 90 } 91 } 92 return nil 93 } 94 95 func main() { 96 flag.Parse() 97 98 if *n < 1 { 99 log.Fatalf("strings: invalid minimum string length %v", *n) 100 } 101 102 // Buffer reduces number of syscalls. 103 wb := bufio.NewWriter(os.Stdout) 104 defer wb.Flush() 105 106 if err := strings(flag.Args(), wb); err != nil { 107 log.Fatalf("strings: %v", err) 108 } 109 }