]> Sergey Matveev's repositories - sgodup.git/blob - walk.go
Change namespace because of domain expiration
[sgodup.git] / walk.go
1 // sgodup -- File deduplication utility
2 // Copyright (C) 2020-2024 Sergey Matveev <stargrave@stargrave.org>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, version 3 of the License.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 package main
17
18 import (
19         "io"
20         "log"
21         "os"
22         "path"
23         "syscall"
24 )
25
26 type FileInode struct {
27         Path string
28         Size int64
29         Dev  uint64
30         Ino  uint64
31 }
32
33 func walker(c chan FileInode, dirPath string) {
34         dirFd, err := os.Open(dirPath)
35         if err != nil {
36                 log.Fatal(err)
37         }
38         for {
39                 fis, err := dirFd.Readdir(1 << 10)
40                 if err != nil {
41                         if err == io.EOF {
42                                 break
43                         }
44                         log.Fatal(err)
45                 }
46                 for _, fi := range fis {
47                         stat := fi.Sys().(*syscall.Stat_t)
48                         if fi.Mode().IsRegular() {
49                                 c <- FileInode{
50                                         path.Join(dirPath, fi.Name()),
51                                         fi.Size(),
52                                         stat.Dev, stat.Ino,
53                                 }
54                         } else if fi.IsDir() {
55                                 walker(c, path.Join(dirPath, fi.Name()))
56                         }
57                 }
58         }
59         if err = dirFd.Close(); err != nil {
60                 log.Fatal(err)
61         }
62 }
63
64 func walk(dirPath string) chan FileInode {
65         c := make(chan FileInode, 1<<10)
66         go func() {
67                 walker(c, dirPath)
68                 close(c)
69         }()
70         return c
71 }