Skip to content

Commit

Permalink
do all the things (#7)
Browse files Browse the repository at this point in the history
* do all the things

* define directory before if statements in main.go
  • Loading branch information
selfup authored Feb 3, 2023
1 parent 5a060a1 commit 5eb65e5
Show file tree
Hide file tree
Showing 5 changed files with 341 additions and 36 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ end_of_line = lf
insert_final_newline = true
charset = utf-8
indent_style = space
indent_size = 2
indent_size = 4

# ignore go files - let gofmt do work
[*.{go}]
Expand Down
95 changes: 81 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Scnnr](#scnnr)
- [Examples](#examples)
- [Examples (scn mode)](#examples)
- [Help](#help)
- [No Keywords](#no-keywords)
- [Single Keyword](#single-keyword)
- [Multiple Keywords and Multiple File Extensions](#multiple-keywords-and-multiple-file-extensions)
- [FileNameFinder](#file-name-finder-namefinder-fnf)
- [FileSizeFinder](#file-size-finder-sizefinder-fsf)
- [BackToScnnr](#back-to-scnnr)
- [Using the package github.com/selfup/scnnr/pkg](#using-the-package-githubcomselfupscnnrpkg)
- [Regex](#regex)
- [Using Regex Patterns](#using-regex-patterns)
Expand All @@ -29,34 +32,59 @@ Scans files (by extension) in a given directory for a keyword. Can be any file,

Prints out a `\n` delimited string of each file (filepath in artifact) containing one of the keywords.

Max file descriptors is set to 1024 (linux default).
Max file descriptors is set to 1024 (linux default) in scnnr scn mode.

## Examples

`scn` mode is the default

### Help

Call scnnr with the `-h` flag:

```
$ scnnr -h
-d string
OPTIONAL
OPTIONAL Scnnr MODE
directory where scnnr will scan
default is current directory and all child directories (default ".")
-e string
OPTIONAL
a comma delimted list of file extensions to scan
OPTIONAL Scnnr MODE
a comma delimited list of file extensions to scan
if none are given all files will be searched
-f string
REQUIRED NameFinder MODE
fuzzy find the filename(s) contain(s) - can be comma delimited: Example 'wow' or 'wow,omg,lol'
-k string
OPTIONAL
a comma delimted list of characters to look for in a file
OPTIONAL Scnnr MODE
a comma delimited list of characters to look for in a file
if no keywords are given - all file paths of given file extensions will be returned
if keywords are given only filepaths of matches will be returned
-r OPTIONAL
wether to use the regex engine or not
if keywords are given - only filepaths of matches will be returned
-m string
OPTIONAL
mode that scnnr will run in
options are:
(scn) for scnnr
(fnf) for File/NameFinder
(fsf) for File/SizeFinder
ex: scnnr -d / -k password,token,authorization
ex: scnnr -m fsf -s 100MB -d E:/LotsOfStuff
ex: scnnr -m fnf -f DEFCON -p /tmp,/usr,/etc,$HOME/Documents
(default "scn")
-p string
REQUIRED NameFinder MODE
any absolute path - can be comma delimited: Example: $HOME or '/tmp,/usr'
-r OPTIONAL Scnnr MODE
if you want to use the regex engine or not
defaults to false and will not use the regex engine for scans unless set to a truthy value
truthy values are: 1, t, T, true, True, TRUE
flasey values are: 0, f, F, false, False, FALSE
falsy values are: 0, f, F, false, False, FALSE
-s string
REQUIRED SizeFinder MODE
size: 1MB,10MB,100MB,1GB,10GB,100GB,1TB
```

### No Keywords
Expand Down Expand Up @@ -104,6 +132,44 @@ README.md
cmd/scanner.go
```

# File Name Finder (NameFinder) (fnf)

```
-p string
REQUIRED NameFinder MODE
any absolute path - can be comma delimited: Example: $HOME or '/tmp,/usr'
-f string
REQUIRED NameFinder MODE
fuzzy find the filename(s) contain(s) - can be comma delimited: Example 'wow' or 'wow,omg,lol'
```

Example use to search `/tmp`, `/etc`, `/usr`, and `$HOME/Documents` for filenames that contain:

1. DEFCON
1. Tax
1. Return
1. Finance

```bash
scnnr -m fnf -f DEFCON,Finance,Tax,Return -p /tmp,/usr,/etc,$HOME/Documents
```

# File Size Finder (SizeFinder) (fsf)

```
-s string
REQUIRED SizeFinder MODE
size: 1MB,10MB,100MB,1GB,10GB,100GB,1TB
```

Example use to find any file over 100MB in E:/LotsOfStuff

```bash
scnnr -m fsf -s 100MB -d E:/LotsOfStuff
```

# Back to Scnnr

### Using the package github.com/selfup/scnnr/pkg

```go
Expand Down Expand Up @@ -177,8 +243,7 @@ if err != nil {
### If you have Go

```bash
go get -u github.com/selfup/scnnr
go install github.com/selfup/scnnr
go install github.com/selfup/scnnr@latest
```

### If you do not have Go
Expand Down Expand Up @@ -246,7 +311,9 @@ scnnr_bins/windows:
scnnr.exe
```

## Performance
## Performance (scn)

_I will add perf numbers for fnf and fsf modes soon!_

Use of goroutines, buffers, streams, mutexes, and simple checks.

Expand Down
95 changes: 74 additions & 21 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ package main

import (
"flag"
"fmt"
"log"
"strings"

Expand All @@ -37,45 +38,97 @@ func main() {
var extensions []string
var keywords []string

var mode string
flag.StringVar(&mode, "m", "scn", `OPTIONAL
mode that scnnr will run in
options are:
(scn) for scnnr
(fnf) for File/NameFinder
(fsf) for File/SizeFinder
ex: scnnr -d / -k password,token,authorization
ex: scnnr -m fsf -s 100MB -d E:/LotsOfStuff
ex: scnnr -m fnf -f DEFCON -p /tmp,/usr,/etc,$HOME/Documents
`)

var dir string
flag.StringVar(&dir, "d", ".", `OPTIONAL
flag.StringVar(&dir, "d", ".", `OPTIONAL Scnnr MODE
directory where scnnr will scan
default is current directory and all child directories`)

var ext string
flag.StringVar(&ext, "e", "", `OPTIONAL
a comma delimted list of file extensions to scan
flag.StringVar(&ext, "e", "", `OPTIONAL Scnnr MODE
a comma delimited list of file extensions to scan
if none are given all files will be searched`)

var kwd string
flag.StringVar(&kwd, "k", "", `OPTIONAL
a comma delimted list of characters to look for in a file
flag.StringVar(&kwd, "k", "", `OPTIONAL Scnnr MODE
a comma delimited list of characters to look for in a file
if no keywords are given - all file paths of given file extensions will be returned
if keywords are given only filepaths of matches will be returned`)
if keywords are given - only filepaths of matches will be returned`)

var rgx bool
flag.BoolVar(&rgx, "r", false, `OPTIONAL
wether to use the regex engine or not
flag.BoolVar(&rgx, "r", false, `OPTIONAL Scnnr MODE
if you want to use the regex engine or not
defaults to false and will not use the regex engine for scans unless set to a truthy value
truthy values are: 1, t, T, true, True, TRUE
flasey values are: 0, f, F, false, False, FALSE`)
falsy values are: 0, f, F, false, False, FALSE`)

// FileNameFinder mode
var paths string
flag.StringVar(&paths, "p", "", `REQUIRED NameFinder MODE
any absolute path - can be comma delimited: Example: $HOME or '/tmp,/usr'`)

var fuzzy string
flag.StringVar(&fuzzy, "f", "", `REQUIRED NameFinder MODE
fuzzy find the filename(s) contain(s) - can be comma delimited: Example 'wow' or 'wow,omg,lol'`)

var size string
flag.StringVar(&size, "s", "", `REQUIRED SizeFinder MODE
size: 1MB,10MB,100MB,1GB,10GB,100GB,1TB`)

flag.Parse()

directory = dir
extensions = strings.Split(ext, ",")
keywords = strings.Split(kwd, ",")

scanner := scnnr.Scanner{
Regex: rgx,
Keywords: keywords,
Directory: directory,
FileExtensions: extensions,
}

err := scanner.Scan()
if mode == "fnf" {
scanFuzzy := strings.Split(fuzzy, ",")
scanPaths := strings.Split(paths, ",")

nfnf := scnnr.NewFileNameFinder(scanFuzzy)

for _, path := range scanPaths {
nfnf.Scan(path)
}

for _, file := range nfnf.Files {
fmt.Println(file)
}
} else if mode == "scn" {
extensions = strings.Split(ext, ",")
keywords = strings.Split(kwd, ",")

scanner := scnnr.Scanner{
Regex: rgx,
Keywords: keywords,
Directory: directory,
FileExtensions: extensions,
}

err := scanner.Scan()

if err != nil {
log.Fatal(err)
}
} else if mode == "fsf" {
nfsf := scnnr.NewFileSizeFinder(size)

nfsf.Scan(directory)

if err != nil {
log.Fatal(err)
for _, file := range nfsf.Files {
fmt.Println(file)
}
}
}
82 changes: 82 additions & 0 deletions pkg/fnf.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package scnnr

import (
"io/ioutil"
"os"
"runtime"
"strings"
"sync"
)

// FileNameFinder struct contains needed data to perform concurrent operations
type FileNameFinder struct {
mutex sync.Mutex
Direction string
Files []string
Keywords []string
}

// NewFileNameFinder creates a pointer to FileNameFinder with default values
func NewFileNameFinder(keywords []string) *FileNameFinder {
fnf := new(FileNameFinder)

if runtime.GOOS == "windows" {
fnf.Direction = "\\"
} else {
fnf.Direction = "/"
}

fnf.Keywords = keywords

return fnf
}

// Scan is a concurrent/parallel directory walker
func (f *FileNameFinder) Scan(directory string) {
_, err := ioutil.ReadDir(directory)
if err != nil {
panic(err)
}

f.findFiles(directory, "")
}

func (f *FileNameFinder) findFiles(directory string, prefix string) {
paths, _ := ioutil.ReadDir(directory)

var dirs []os.FileInfo
var files []os.FileInfo

for _, path := range paths {
if path.IsDir() {
dirs = append(dirs, path)
} else {
files = append(files, path)
}
}

for _, file := range files {
for _, keyword := range f.Keywords {
if strings.Contains(file.Name(), keyword) {
f.mutex.Lock()
f.Files = append(f.Files, directory+f.Direction+file.Name())
f.mutex.Unlock()
}
}
}

dirLen := len(dirs)
if dirLen > 0 {
var dirGroup sync.WaitGroup
dirGroup.Add(dirLen)

for _, dir := range dirs {
go func(diR os.FileInfo, direcTory string, direcTion string) {
f.findFiles(direcTory+direcTion+diR.Name(), direcTory)
dirGroup.Done()
}(dir, directory, f.Direction)
}

dirGroup.Wait()
}
}
Loading

0 comments on commit 5eb65e5

Please sign in to comment.