]> Sergey Matveev's repositories - glocate.git/blobdiff - main.go
Newer ZFS has different octalize rule
[glocate.git] / main.go
diff --git a/main.go b/main.go
index c8615fdd85d4f2b76db67f755348feb0a9baf32c17bfdab0b72473fdb634dd58..0965a93e8eef7dcd68df08b9b1f3760c8e93286bbbdefdf74b3bf8e3c813bfa9 100644 (file)
--- a/main.go
+++ b/main.go
@@ -1,13 +1,34 @@
+/*
+glocate -- ZFS-diff-friendly locate-like utility
+Copyright (C) 2022-2023 Sergey Matveev <stargrave@stargrave.org>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 3 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 package main
 
 import (
        "flag"
        "log"
        "os"
+       "path"
+       "path/filepath"
        "strings"
        "syscall"
 )
 
+var TmpDir string
+
 type Ent struct {
        name  []string
        mtime int64
@@ -32,14 +53,21 @@ func dbCommit(dbPath string, tmp *os.File) {
 func main() {
        dbPath := flag.String("db", "glocate.db", "Path to database")
        doIndex := flag.Bool("index", false, "Perform indexing")
-       doUpdate := flag.Bool("update", false, "Feed zfs-diff and update the database")
-       strip := flag.String("strip", "", "Strip prefix from zfs-diff's paths")
+       doUpdate := flag.String("update", "", "Update database")
        showMachine := flag.Bool("machine", false, "Show machine friendly")
        showTree := flag.Bool("tree", false, "Show human-friendly tree")
        dryRun := flag.Bool("n", false, "Dry run, do not overwrite database")
+       rootPath := flag.String("root", "", "Search only that part of tree")
        flag.Parse()
        log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Lshortfile)
 
+       var err error
+       TmpDir, err = filepath.Abs(*dbPath)
+       if err != nil {
+               panic(err)
+       }
+       TmpDir = path.Dir(TmpDir)
+
        if *doIndex {
                tmp := index()
                tmp.Close()
@@ -49,8 +77,8 @@ func main() {
                return
        }
 
-       if *doUpdate {
-               tmp := updateWithDiff(*dbPath, *strip)
+       if *doUpdate != "" {
+               tmp := updateWithDiff(*dbPath, *doUpdate)
                tmp.Close()
                if !*dryRun {
                        dbCommit(*dbPath, tmp)
@@ -79,15 +107,42 @@ func main() {
        }()
 
        var root []string
+       if *rootPath != "" {
+               root = strings.Split("./"+*rootPath, "/")
+       }
+
+       var pat string
        if len(flag.Args()) > 0 {
-               root = strings.Split("./"+flag.Arg(0), "/")
+               pat = "*" + flag.Arg(0) + "*"
        }
 
        rootMet := false
+       var matched bool
+       var namePrev []string
+       var i int
        for ent := range entsReader {
                if hasPrefix(ent.name, root) {
-                       entsPrinter <- ent
                        rootMet = true
+                       if pat == "" {
+                               entsPrinter <- ent
+                               continue
+                       }
+                       for i = 0; i < len(ent.name); i++ {
+                               if i == len(namePrev) || ent.name[i] != namePrev[i] {
+                                       break
+                               }
+                       }
+                       for ; i < len(ent.name); i++ {
+                               matched, err = path.Match(pat,
+                                       strings.ToLower(strings.TrimSuffix(ent.name[i], "/")))
+                               if err != nil {
+                                       log.Fatalln(err)
+                               }
+                       }
+                       if matched {
+                               entsPrinter <- ent
+                       }
+                       namePrev = ent.name
                } else if rootMet {
                        break
                }