Pull request: 3435 openwrt detect
Merge in DNS/adguard-home from 3435-openwrt-detect to master Updates #3435. Squashed commit of the following: commit 04b10f407ced1c85ac8089f980d79e9bbfe14e95 Author: Eugene Burkov <e.burkov@adguard.com> Date: Fri Aug 13 19:02:55 2021 +0300 aghos: fix windows build commit d387cec5f9cae9256dccef8c666c02f2fb7449a2 Author: Eugene Burkov <e.burkov@adguard.com> Date: Fri Aug 13 18:22:12 2021 +0300 aghos: imp code, tests commit 2450b98522eb032ec8658f3ef2384fc77b627cc6 Author: Eugene Burkov <e.burkov@adguard.com> Date: Fri Aug 13 13:43:46 2021 +0300 all: imp code, docs commit 7fabba3a8dc70fe61dbaa8fd5445453816fe9ac7 Author: Eugene Burkov <e.burkov@adguard.com> Date: Fri Aug 13 04:04:09 2021 +0300 all: log changes commit 7cc1235308caf09eb4c80c05a4f328b8d6909ec7 Author: Eugene Burkov <e.burkov@adguard.com> Date: Fri Aug 13 03:33:13 2021 +0300 querylog: repl with golibs commit 84592087d3b2aca23613950bb203ff3c862624dc Author: Eugene Burkov <e.burkov@adguard.com> Date: Fri Aug 13 03:16:37 2021 +0300 aghos: use filewalker commit e4f2964b0e031c7a9a053e85c0ff7c792c772929 Author: Eugene Burkov <e.burkov@adguard.com> Date: Fri Aug 13 00:34:20 2021 +0300 aghos: mv recurrentchecker from aghnet
This commit is contained in:
119
internal/aghos/filewalker.go
Normal file
119
internal/aghos/filewalker.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package aghos
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghio"
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
"github.com/AdguardTeam/golibs/stringutil"
|
||||
)
|
||||
|
||||
// FileWalker is the signature of a function called for files in the file tree.
|
||||
// As opposed to filepath.Walk it only walk the files (not directories) matching
|
||||
// the provided pattern and those returned by function itself. All patterns
|
||||
// should be valid for filepath.Glob. If cont is false, the walking terminates.
|
||||
// Each opened file is also limited for reading to MaxWalkedFileSize.
|
||||
//
|
||||
// TODO(e.burkov): Consider moving to the separate package like pathutil.
|
||||
//
|
||||
// TODO(e.burkov): Think about passing filename or any additional data.
|
||||
type FileWalker func(r io.Reader) (patterns []string, cont bool, err error)
|
||||
|
||||
// MaxWalkedFileSize is the maximum length of the file that FileWalker can
|
||||
// check.
|
||||
const MaxWalkedFileSize = 1024 * 1024
|
||||
|
||||
// checkFile tries to open and process a single file located on sourcePath.
|
||||
func checkFile(c FileWalker, sourcePath string) (patterns []string, cont bool, err error) {
|
||||
var f *os.File
|
||||
f, err = os.Open(sourcePath)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
// Ignore non-existing files since this may only happen
|
||||
// when the file was removed after filepath.Glob matched
|
||||
// it.
|
||||
return nil, true, nil
|
||||
}
|
||||
|
||||
return nil, false, err
|
||||
}
|
||||
defer func() { err = errors.WithDeferred(err, f.Close()) }()
|
||||
|
||||
var r io.Reader
|
||||
// Ignore the error since LimitReader function returns error only if
|
||||
// passed limit value is less than zero, but the constant used.
|
||||
//
|
||||
// TODO(e.burkov): Make variable.
|
||||
r, _ = aghio.LimitReader(f, MaxWalkedFileSize)
|
||||
|
||||
return c(r)
|
||||
}
|
||||
|
||||
// handlePatterns parses the patterns and ignores duplicates using srcSet.
|
||||
// srcSet must be non-nil.
|
||||
func handlePatterns(srcSet *stringutil.Set, patterns ...string) (sub []string, err error) {
|
||||
sub = make([]string, 0, len(patterns))
|
||||
for _, p := range patterns {
|
||||
var matches []string
|
||||
matches, err = filepath.Glob(p)
|
||||
if err != nil {
|
||||
// Enrich error with the pattern because filepath.Glob
|
||||
// doesn't do it.
|
||||
return nil, fmt.Errorf("invalid pattern %q: %w", p, err)
|
||||
}
|
||||
|
||||
for _, m := range matches {
|
||||
if srcSet.Has(m) {
|
||||
continue
|
||||
}
|
||||
|
||||
srcSet.Add(m)
|
||||
sub = append(sub, m)
|
||||
}
|
||||
}
|
||||
|
||||
return sub, nil
|
||||
}
|
||||
|
||||
// Walk starts walking the files defined by initPattern. It only returns true
|
||||
// if c signed to stop walking.
|
||||
func (c FileWalker) Walk(initPattern string) (ok bool, err error) {
|
||||
// The slice of sources keeps the order in which the files are walked
|
||||
// since srcSet.Values() returns strings in undefined order.
|
||||
srcSet := stringutil.NewSet()
|
||||
var src []string
|
||||
src, err = handlePatterns(srcSet, initPattern)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
var filename string
|
||||
defer func() { err = errors.Annotate(err, "checking %q: %w", filename) }()
|
||||
|
||||
for i := 0; i < len(src); i++ {
|
||||
var patterns []string
|
||||
var cont bool
|
||||
filename = src[i]
|
||||
patterns, cont, err = checkFile(c, src[i])
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !cont {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
var subsrc []string
|
||||
subsrc, err = handlePatterns(srcSet, patterns...)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
src = append(src, subsrc...)
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
Reference in New Issue
Block a user