]> Sergey Matveev's repositories - glocate.git/blob - main.go
a5fcb41451e9410c3be3d629ba89dea6d354c675abe9fd2fa7e0879514b10095
[glocate.git] / main.go
1 package main
2
3 import (
4         "bufio"
5         "flag"
6         "log"
7         "os"
8         "strings"
9         "syscall"
10 )
11
12 type Ent struct {
13         name  []string
14         mtime int64
15         size  int64
16 }
17
18 func (ent *Ent) IsDir() bool {
19         return IsDir(ent.name[len(ent.name)-1])
20 }
21
22 func dbCommit(dbPath string, tmp *os.File) {
23         umask := syscall.Umask(0)
24         syscall.Umask(umask)
25         if err := os.Chmod(tmp.Name(), os.FileMode(0666&^umask)); err != nil {
26                 log.Fatalln(err)
27         }
28         if err := os.Rename(tmp.Name(), dbPath); err != nil {
29                 log.Fatalln(err)
30         }
31 }
32
33 func main() {
34         dbPath := flag.String("db", "glocate.db", "Path to database")
35         doIndex := flag.Bool("index", false, "Perform indexing")
36         doUpdate := flag.Bool("update", false, "Feed zfs-diff and update the database")
37         strip := flag.String("strip", "", "Strip prefix from zfs-diff's paths")
38         showMachine := flag.Bool("machine", false, "Show machine friendly")
39         showTree := flag.Bool("tree", false, "Show human-friendly tree")
40         dryRun := flag.Bool("n", false, "Dry run, do not overwrite database")
41         flag.Parse()
42         log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Lshortfile)
43
44         if *doIndex {
45                 tmp := index()
46                 tmp.Close()
47                 if !*dryRun {
48                         dbCommit(*dbPath, tmp)
49                 }
50                 return
51         }
52
53         if *doUpdate {
54                 tmp := updateWithDiff(*dbPath, *strip)
55                 tmp.Close()
56                 if !*dryRun {
57                         dbCommit(*dbPath, tmp)
58                 }
59                 return
60         }
61
62         db, err := os.Open(*dbPath)
63         if err != nil {
64                 log.Fatalln(err)
65         }
66         entsReader := make(chan Ent, 1<<10)
67         go reader(bufio.NewReaderSize(db, 1<<17), entsReader)
68
69         entsPrinter := make(chan Ent, 1<<10)
70         printerJob := make(chan struct{})
71         go func() {
72                 if *showMachine {
73                         printerMachine(entsPrinter)
74                 } else if *showTree {
75                         printerTree(entsPrinter)
76                 } else {
77                         printerSimple(entsPrinter)
78                 }
79                 close(printerJob)
80         }()
81
82         var root []string
83         if len(flag.Args()) > 0 {
84                 root = strings.Split("./"+flag.Arg(0), "/")
85         }
86
87         rootMet := false
88         for ent := range entsReader {
89                 if hasPrefix(ent.name, root) {
90                         entsPrinter <- ent
91                         rootMet = true
92                 } else if rootMet {
93                         break
94                 }
95         }
96         close(entsPrinter)
97         <-printerJob
98 }