goduf.go
author Mikael Berthe <mikael@lilotux.net>
Wed, 23 Feb 2022 22:56:53 +0100
changeset 45 ea6a9ba7a3c8
parent 44 af90d9396ef1
permissions -rw-r--r--
Display existing hard links in result sets This is a breaking change in the plain text output, but somehow the list displayed in case of existing hard links was arbitrary, since the all the hardlinked filenames were not displayed. Here's a sample JSON result with this patch: { "file_size": 9216, "paths": [ "test_tree/f09-1_5.raw", "test_tree/f09-4_5.raw" ], "links": { "test_tree/f09-1_5.raw": [ "test_tree/f09-2_5.raw", "test_tree/f09-3_5.raw" ], "test_tree/f09-4_5.raw": [ "test_tree/f09-5_5.raw" ] } } Here the 5 files have the same contents, but there are two hardlink groups: "test_tree/f09-1_5.raw" "test_tree/f09-2_5.raw" "test_tree/f09-3_5.raw" are hard-linked, and "test_tree/f09-4_5.raw" "test_tree/f09-5_5.raw" are hard-linked. Here's the same set displayed With the regular text output: Group #5 (2 files * 9216 bytes): test_tree/f09-1_5.raw test_tree/f09-2_5.raw test_tree/f09-3_5.raw test_tree/f09-4_5.raw test_tree/f09-5_5.raw (The link file names are indented using 1 space character.)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     1
/*
45
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
     2
 * Copyright (C) 2014-2022 Mikael Berthe <mikael@lilotux.net>
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     3
 *
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     4
 * This program is free software; you can redistribute it and/or modify
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     5
 * it under the terms of the GNU General Public License as published by
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     6
 * the Free Software Foundation; either version 2 of the License, or (at
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     7
 * your option) any later version.
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     8
 *
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     9
 * This program is distributed in the hope that it will be useful, but
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    10
 * WITHOUT ANY WARRANTY; without even the implied warranty of
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    12
 * General Public License for more details.
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    13
 *
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    14
 * You should have received a copy of the GNU General Public License
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    15
 * along with this program; if not, write to the Free Software
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    17
 * USA
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    18
 */
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    19
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    20
// This program (Goduf) is a fast duplicate file finder.
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    21
// Use goduf --help to get the list of available options.
25
129fd2cee200 Move comment
Mikael Berthe <mikael@lilotux.net>
parents: 24
diff changeset
    22
//
24
40074e33c579 Add installation command line example
Mikael Berthe <mikael@lilotux.net>
parents: 23
diff changeset
    23
// Installation:
40074e33c579 Add installation command line example
Mikael Berthe <mikael@lilotux.net>
parents: 23
diff changeset
    24
//
40074e33c579 Add installation command line example
Mikael Berthe <mikael@lilotux.net>
parents: 23
diff changeset
    25
// % go get hg.lilotux.net/golang/mikael/goduf
35
730377b4449f Mention github mirror in the comments
Mikael Berthe <mikael@lilotux.net>
parents: 34
diff changeset
    26
// or
730377b4449f Mention github mirror in the comments
Mikael Berthe <mikael@lilotux.net>
parents: 34
diff changeset
    27
// % go get github.com/McKael/goduf
24
40074e33c579 Add installation command line example
Mikael Berthe <mikael@lilotux.net>
parents: 23
diff changeset
    28
25
129fd2cee200 Move comment
Mikael Berthe <mikael@lilotux.net>
parents: 24
diff changeset
    29
package main
129fd2cee200 Move comment
Mikael Berthe <mikael@lilotux.net>
parents: 24
diff changeset
    30
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    31
import (
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    32
	"crypto/sha1"
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    33
	"encoding/hex"
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    34
	"errors"
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    35
	"flag"
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    36
	"fmt"
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    37
	"io"
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    38
	"os"
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    39
	"path/filepath"
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    40
	"sort"
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    41
)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    42
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    43
const medsumBytes = 128
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    44
const minSizePartialChecksum = 49152 // Should be > 3*medsumBytes
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    45
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    46
type sumType int
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    47
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    48
const (
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
    49
	noChecksum sumType = iota
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
    50
	fullChecksum
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    51
	partialChecksum
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    52
)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    53
38
25db238bf03f Cosmetic changes
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
    54
// Options contains the command-line flags
37
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
    55
type Options struct {
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
    56
	Summary     bool
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
    57
	OutToJSON   bool
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
    58
	SkipPartial bool
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
    59
	IgnoreEmpty bool
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
    60
}
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
    61
36
e918b7e63748 Add JSON output
Mikael Berthe <mikael@lilotux.net>
parents: 35
diff changeset
    62
// Results contains the results of the duplicates search
e918b7e63748 Add JSON output
Mikael Berthe <mikael@lilotux.net>
parents: 35
diff changeset
    63
type Results struct {
42
3fa13770e970 Rename JSON size fields
Mikael Berthe <mikael@lilotux.net>
parents: 41
diff changeset
    64
	Groups                 []ResultSet `json:"groups"`                    // List of duplicate sets
3fa13770e970 Rename JSON size fields
Mikael Berthe <mikael@lilotux.net>
parents: 41
diff changeset
    65
	Duplicates             uint        `json:"duplicates"`                // Number of duplicates
3fa13770e970 Rename JSON size fields
Mikael Berthe <mikael@lilotux.net>
parents: 41
diff changeset
    66
	NumberOfSets           uint        `json:"number_of_sets"`            // Number of duplicate sets
3fa13770e970 Rename JSON size fields
Mikael Berthe <mikael@lilotux.net>
parents: 41
diff changeset
    67
	RedundantDataSizeBytes uint64      `json:"redundant_data_size_bytes"` // Redundant data size
3fa13770e970 Rename JSON size fields
Mikael Berthe <mikael@lilotux.net>
parents: 41
diff changeset
    68
	RedundantDataSizeHuman string      `json:"redundant_data_size_human"` // Same, human-readable
3fa13770e970 Rename JSON size fields
Mikael Berthe <mikael@lilotux.net>
parents: 41
diff changeset
    69
	TotalFileCount         uint        `json:"total_file_count"`          // Total number of checked files
3fa13770e970 Rename JSON size fields
Mikael Berthe <mikael@lilotux.net>
parents: 41
diff changeset
    70
	TotalSizeBytes         uint64      `json:"total_size_bytes"`          // Total size for checked files
3fa13770e970 Rename JSON size fields
Mikael Berthe <mikael@lilotux.net>
parents: 41
diff changeset
    71
	TotalSizeHuman         string      `json:"total_size_human"`          // Same, human-readable
36
e918b7e63748 Add JSON output
Mikael Berthe <mikael@lilotux.net>
parents: 35
diff changeset
    72
}
e918b7e63748 Add JSON output
Mikael Berthe <mikael@lilotux.net>
parents: 35
diff changeset
    73
e918b7e63748 Add JSON output
Mikael Berthe <mikael@lilotux.net>
parents: 35
diff changeset
    74
// ResultSet contains a group of identical duplicate files
e918b7e63748 Add JSON output
Mikael Berthe <mikael@lilotux.net>
parents: 35
diff changeset
    75
type ResultSet struct {
45
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
    76
	FileSize uint64              `json:"file_size"`       // Size of each item
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
    77
	Paths    []string            `json:"paths"`           // List of file paths
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
    78
	Links    map[string][]string `json:"links,omitempty"` // Existing hard links
36
e918b7e63748 Add JSON output
Mikael Berthe <mikael@lilotux.net>
parents: 35
diff changeset
    79
}
e918b7e63748 Add JSON output
Mikael Berthe <mikael@lilotux.net>
parents: 35
diff changeset
    80
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    81
type fileObj struct {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    82
	//Unique   bool
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    83
	FilePath string
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    84
	os.FileInfo
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    85
	PartialHash []byte
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    86
	Hash        []byte
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
    87
	needHash    sumType
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    88
}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    89
5
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
    90
// FileObjList is only exported so that we can have a sort interface on inodes.
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    91
type FileObjList []*fileObj
16
cc0ee80cf216 Sort results
Mikael Berthe <mikael@lilotux.net>
parents: 15
diff changeset
    92
type foListList []FileObjList
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    93
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    94
type dataT struct {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    95
	totalSize   uint64
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    96
	cmpt        uint
14
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
    97
	sizeGroups  map[int64]*FileObjList
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    98
	emptyFiles  FileObjList
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    99
	ignoreCount int
45
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
   100
	hardLinks   map[string][]string
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   101
}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   102
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   103
var data dataT
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   104
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   105
// Implement my own logger
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   106
var myLog myLogT
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   107
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   108
// visit is called for every file and directory.
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   109
// We check the file object is correct (regular, readable...) and add
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   110
// it to the data.sizeGroups hash.
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   111
func visit(path string, f os.FileInfo, err error) error {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   112
	if err != nil {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   113
		if f == nil {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   114
			return err
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   115
		}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   116
		if f.IsDir() {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   117
			myLog.Println(-1, "Warning: cannot process directory:",
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   118
				path)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   119
			return filepath.SkipDir
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   120
		}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   121
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   122
		myLog.Println(-1, "Ignoring ", path, " - ", err)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   123
		data.ignoreCount++
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   124
		return nil
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   125
	}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   126
	if f.IsDir() {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   127
		return nil
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   128
	}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   129
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   130
	if mode := f.Mode(); mode&os.ModeType != 0 {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   131
		if mode&os.ModeSymlink != 0 {
5
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   132
			myLog.Println(6, "Ignoring symbolic link", path)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   133
		} else {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   134
			myLog.Println(0, "Ignoring special file", path)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   135
		}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   136
		data.ignoreCount++
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   137
		return nil
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   138
	}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   139
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   140
	data.cmpt++
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   141
	data.totalSize += uint64(f.Size())
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   142
	fo := &fileObj{FilePath: path, FileInfo: f}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   143
	if _, ok := data.sizeGroups[f.Size()]; !ok {
14
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   144
		data.sizeGroups[f.Size()] = new(FileObjList)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   145
	}
14
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   146
	*data.sizeGroups[f.Size()] = append(*data.sizeGroups[f.Size()], fo)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   147
	return nil
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   148
}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   149
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   150
// Checksum computes the file's complete SHA1 hash.
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   151
func (fo *fileObj) Checksum() error {
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   152
	file, err := os.Open(fo.FilePath)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   153
	if err != nil {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   154
		return err
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   155
	}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   156
	defer file.Close()
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   157
	hash := sha1.New()
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   158
	if size, err := io.Copy(hash, file); size != fo.Size() || err != nil {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   159
		if err == nil {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   160
			return errors.New("failed to read the whole file: " +
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   161
				fo.FilePath)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   162
		}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   163
		return err
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   164
	}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   165
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   166
	fo.Hash = hash.Sum(nil)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   167
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   168
	return nil
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   169
}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   170
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   171
// partialChecksum computes the file's partial SHA1 hash (first and last bytes).
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   172
func (fo *fileObj) partialChecksum() error {
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   173
	file, err := os.Open(fo.FilePath)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   174
	if err != nil {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   175
		return err
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   176
	}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   177
	defer file.Close()
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   178
	hash := sha1.New()
19
3389a17fc0d2 Remove duplicated code
Mikael Berthe <mikael@lilotux.net>
parents: 16
diff changeset
   179
3389a17fc0d2 Remove duplicated code
Mikael Berthe <mikael@lilotux.net>
parents: 16
diff changeset
   180
	// Read first bytes and last bytes from file
3389a17fc0d2 Remove duplicated code
Mikael Berthe <mikael@lilotux.net>
parents: 16
diff changeset
   181
	for i := 0; i < 2; i++ {
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   182
		if _, err := io.CopyN(hash, file, medsumBytes); err != nil {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   183
			if err == nil {
19
3389a17fc0d2 Remove duplicated code
Mikael Berthe <mikael@lilotux.net>
parents: 16
diff changeset
   184
				const errmsg = "failed to read bytes from file: "
3389a17fc0d2 Remove duplicated code
Mikael Berthe <mikael@lilotux.net>
parents: 16
diff changeset
   185
				return errors.New(errmsg + fo.FilePath)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   186
			}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   187
			return err
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   188
		}
19
3389a17fc0d2 Remove duplicated code
Mikael Berthe <mikael@lilotux.net>
parents: 16
diff changeset
   189
		if i == 0 { // Seek to end of file
3389a17fc0d2 Remove duplicated code
Mikael Berthe <mikael@lilotux.net>
parents: 16
diff changeset
   190
			file.Seek(0-medsumBytes, 2)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   191
		}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   192
	}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   193
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   194
	fo.PartialHash = hash.Sum(nil)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   195
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   196
	return nil
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   197
}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   198
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   199
// Sum computes the file's SHA1 hash, partial or full according to sType.
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   200
func (fo *fileObj) Sum(sType sumType) error {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   201
	if sType == partialChecksum {
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   202
		return fo.partialChecksum()
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   203
	} else if sType == fullChecksum {
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   204
		return fo.Checksum()
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   205
	} else if sType == noChecksum {
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   206
		return nil
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   207
	}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   208
	panic("Internal error: Invalid sType")
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   209
}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   210
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   211
// dispCount display statistics to the user.
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   212
func (data *dataT) dispCount() { // It this still useful?
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   213
	if myLog.verbosity < 4 {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   214
		return
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   215
	}
5
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   216
	var c1, c1b, c2 int
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   217
	var s1 string
14
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   218
	for _, scListP := range data.sizeGroups {
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   219
		c1 += len(*scListP)
5
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   220
		c2++
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   221
	}
5
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   222
	c1b = len(data.emptyFiles)
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   223
	if c1b > 0 {
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   224
		s1 = fmt.Sprintf("+%d", c1b)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   225
	}
5
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   226
	myLog.Printf(4, "  Current countdown: %d  [%d%s/%d]\n",
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   227
		c1+c1b, c1, s1, c2)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   228
}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   229
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   230
// checksum returns the requested checksum as a string.
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   231
// If the checksum has not been pre-computed, it is calculated now.
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   232
func (fo fileObj) checksum(sType sumType) (string, error) {
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   233
	var hbytes []byte
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   234
	if sType == partialChecksum {
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   235
		hbytes = fo.PartialHash
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   236
	} else if sType == fullChecksum {
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   237
		hbytes = fo.Hash
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   238
	} else {
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   239
		panic("Internal error: Invalid sType")
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   240
	}
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   241
	if hbytes == nil {
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   242
		if err := fo.Sum(sType); err != nil {
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   243
			return "", err
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   244
		}
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   245
		if sType == partialChecksum {
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   246
			hbytes = fo.PartialHash
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   247
		} else if sType == fullChecksum {
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   248
			hbytes = fo.Hash
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   249
		}
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   250
	}
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   251
	return hex.EncodeToString(hbytes), nil
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   252
}
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   253
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   254
// computeSheduledChecksums calculates the checksums for all the files
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   255
// from the fileLists slice items (the kind of hash is taken from the
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   256
// needHash field).
16
cc0ee80cf216 Sort results
Mikael Berthe <mikael@lilotux.net>
parents: 15
diff changeset
   257
func computeSheduledChecksums(fileLists ...foListList) {
10
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   258
	var bigFileList FileObjList
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   259
	// Merge the lists of FileObjList lists and create a unique list
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   260
	// of file objects.
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   261
	for _, foll := range fileLists {
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   262
		for _, fol := range foll {
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   263
			bigFileList = append(bigFileList, fol...)
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   264
		}
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   265
	}
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   266
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   267
	// Sort the list for better efficiency
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   268
	sort.Sort(ByInode(bigFileList))
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   269
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   270
	// Compute checksums
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   271
	for _, fo := range bigFileList {
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   272
		if err := fo.Sum(fo.needHash); err != nil {
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   273
			myLog.Println(0, "Error:", err)
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   274
		}
22
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   275
		fo.needHash = noChecksum
10
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   276
	}
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   277
}
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   278
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   279
func (fileList FileObjList) scheduleChecksum(sType sumType) {
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   280
	for _, fo := range fileList {
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   281
		fo.needHash = sType
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   282
	}
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   283
}
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   284
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   285
// findDupesChecksums splits the fileObj list into several lists with the
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   286
// same sType hash.
22
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   287
func (fileList FileObjList) findDupesChecksums(sType sumType, dryRun bool) foListList {
16
cc0ee80cf216 Sort results
Mikael Berthe <mikael@lilotux.net>
parents: 15
diff changeset
   288
	var dupeList foListList
cc0ee80cf216 Sort results
Mikael Berthe <mikael@lilotux.net>
parents: 15
diff changeset
   289
	var scheduleFull foListList
5
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   290
	hashes := make(map[string]FileObjList)
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   291
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   292
	// Sort the list for better efficiency
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   293
	sort.Sort(ByInode(fileList))
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   294
22
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   295
	if sType == fullChecksum && dryRun {
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   296
		fileList.scheduleChecksum(fullChecksum)
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   297
		return append(dupeList, fileList)
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   298
	}
7
68375cc98f98 Refactor checksum functions to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents: 6
diff changeset
   299
	// Compute checksums
5
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   300
	for _, fo := range fileList {
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   301
		hash, err := fo.checksum(sType)
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   302
		if err != nil {
5
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   303
			myLog.Println(0, "Error:", err)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   304
			continue
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   305
		}
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   306
		hashes[hash] = append(hashes[hash], fo)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   307
	}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   308
5
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   309
	// Let's de-dupe now...
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   310
	for _, l := range hashes {
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   311
		if len(l) < 2 {
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   312
			continue
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   313
		}
7
68375cc98f98 Refactor checksum functions to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents: 6
diff changeset
   314
		if sType == partialChecksum {
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   315
			scheduleFull = append(scheduleFull, l)
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   316
		} else { // full checksums -> we're done
7
68375cc98f98 Refactor checksum functions to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents: 6
diff changeset
   317
			dupeList = append(dupeList, l)
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   318
			myLog.Printf(5, "  . found %d new duplicates\n", len(l))
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   319
		}
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   320
	}
9
5b58342459eb Small optimization
Mikael Berthe <mikael@lilotux.net>
parents: 8
diff changeset
   321
	if sType == partialChecksum && len(scheduleFull) > 0 {
22
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   322
		//computeSheduledChecksums(scheduleFull)
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   323
		for _, l := range scheduleFull {
22
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   324
			r := l.findDupesChecksums(fullChecksum, dryRun)
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   325
			dupeList = append(dupeList, r...)
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   326
		}
22
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   327
		if dryRun {
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   328
			return scheduleFull
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   329
		}
5
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   330
	}
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   331
5
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   332
	return dupeList
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   333
}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   334
6
6740350569d3 Cosmetics - move function
Mikael Berthe <mikael@lilotux.net>
parents: 5
diff changeset
   335
// findDupes() uses checksums to find file duplicates
16
cc0ee80cf216 Sort results
Mikael Berthe <mikael@lilotux.net>
parents: 15
diff changeset
   336
func (data *dataT) findDupes(skipPartial bool) foListList {
cc0ee80cf216 Sort results
Mikael Berthe <mikael@lilotux.net>
parents: 15
diff changeset
   337
	var dupeList foListList
cc0ee80cf216 Sort results
Mikael Berthe <mikael@lilotux.net>
parents: 15
diff changeset
   338
	var schedulePartial foListList
22
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   339
	var schedulePartial2 foListList
16
cc0ee80cf216 Sort results
Mikael Berthe <mikael@lilotux.net>
parents: 15
diff changeset
   340
	var scheduleFull foListList
6
6740350569d3 Cosmetics - move function
Mikael Berthe <mikael@lilotux.net>
parents: 5
diff changeset
   341
14
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   342
	for size, sgListP := range data.sizeGroups {
6
6740350569d3 Cosmetics - move function
Mikael Berthe <mikael@lilotux.net>
parents: 5
diff changeset
   343
		// We skip partial checksums for small files or if requested
6740350569d3 Cosmetics - move function
Mikael Berthe <mikael@lilotux.net>
parents: 5
diff changeset
   344
		if size > minSizePartialChecksum && !skipPartial {
14
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   345
			sgListP.scheduleChecksum(partialChecksum)
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   346
			schedulePartial = append(schedulePartial, *sgListP)
6
6740350569d3 Cosmetics - move function
Mikael Berthe <mikael@lilotux.net>
parents: 5
diff changeset
   347
		} else {
14
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   348
			sgListP.scheduleChecksum(fullChecksum)
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   349
			scheduleFull = append(scheduleFull, *sgListP)
6
6740350569d3 Cosmetics - move function
Mikael Berthe <mikael@lilotux.net>
parents: 5
diff changeset
   350
		}
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   351
	}
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   352
10
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   353
	computeSheduledChecksums(schedulePartial, scheduleFull)
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   354
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   355
	for _, l := range schedulePartial {
22
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   356
		r := l.findDupesChecksums(partialChecksum, true) // dry-run
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   357
		schedulePartial2 = append(schedulePartial2, r...)
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   358
	}
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   359
	computeSheduledChecksums(schedulePartial2)
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   360
	for _, l := range schedulePartial {
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   361
		r := l.findDupesChecksums(partialChecksum, false)
6
6740350569d3 Cosmetics - move function
Mikael Berthe <mikael@lilotux.net>
parents: 5
diff changeset
   362
		dupeList = append(dupeList, r...)
6740350569d3 Cosmetics - move function
Mikael Berthe <mikael@lilotux.net>
parents: 5
diff changeset
   363
	}
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   364
	for _, l := range scheduleFull {
22
46681d21157a Experimental optimization
Mikael Berthe <mikael@lilotux.net>
parents: 21
diff changeset
   365
		r := l.findDupesChecksums(fullChecksum, false)
8
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   366
		dupeList = append(dupeList, r...)
25ad96511395 Schedule checksum computations so that we reduce hard drive seeks
Mikael Berthe <mikael@lilotux.net>
parents: 7
diff changeset
   367
	}
6
6740350569d3 Cosmetics - move function
Mikael Berthe <mikael@lilotux.net>
parents: 5
diff changeset
   368
	return dupeList
6740350569d3 Cosmetics - move function
Mikael Berthe <mikael@lilotux.net>
parents: 5
diff changeset
   369
}
6740350569d3 Cosmetics - move function
Mikael Berthe <mikael@lilotux.net>
parents: 5
diff changeset
   370
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   371
// dropEmptyFiles removes the empty files from the main map, since we don't
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   372
// have to do any processing about them.
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   373
// If ignoreEmpty is false, the empty file list is saved in data.emptyFiles.
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   374
func (data *dataT) dropEmptyFiles(ignoreEmpty bool) (emptyCount int) {
14
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   375
	sgListP, ok := data.sizeGroups[0]
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   376
	if ok == false {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   377
		return // no empty files
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   378
	}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   379
	if !ignoreEmpty {
14
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   380
		if len(*sgListP) > 1 {
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   381
			data.emptyFiles = *sgListP
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   382
		}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   383
		delete(data.sizeGroups, 0)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   384
		return
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   385
	}
14
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   386
	emptyCount = len(*sgListP)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   387
	delete(data.sizeGroups, 0)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   388
	return
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   389
}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   390
2
55098d552ae2 s/createSizeHash/initialCleanup/
Mikael Berthe <mikael@lilotux.net>
parents: 1
diff changeset
   391
// initialCleanup() removes files with unique size as well as hard links
55098d552ae2 s/createSizeHash/initialCleanup/
Mikael Berthe <mikael@lilotux.net>
parents: 1
diff changeset
   392
func (data *dataT) initialCleanup() (hardLinkCount, uniqueSizeCount int) {
14
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   393
	for s, sgListP := range data.sizeGroups {
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   394
		if len(*sgListP) < 2 {
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   395
			delete(data.sizeGroups, s)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   396
			uniqueSizeCount++
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   397
			continue
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   398
		}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   399
10
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   400
		// We can't look for hard links if the O.S. does not support
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   401
		// them...
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   402
		if !OSHasInodes() {
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   403
			continue
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   404
		}
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   405
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   406
		var hardlinksFound bool
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   407
10
1ee01b135e0e Reduce code duplication related to computeSheduledChecksums()
Mikael Berthe <mikael@lilotux.net>
parents: 9
diff changeset
   408
		// Check for hard links
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   409
		// Remove unique dev/inodes
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   410
		// Instead of this loop, another way would be to use the field
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   411
		// "Unique" of the fileObj to mark them to be discarded
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   412
		// and remove them all at the end.
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   413
		// TODO: Should we also check for duplicate paths?
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   414
		for {
15
4e3a67dc70a0 Cosmetics (go fmt and comments...)
Mikael Berthe <mikael@lilotux.net>
parents: 14
diff changeset
   415
			type devinode struct{ dev, ino uint64 }
45
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
   416
			devinodes := make(map[devinode]string)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   417
			var hardLinkIndex int
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   418
14
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   419
			for i, fo := range *sgListP {
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   420
				dev, ino := GetDevIno(fo)
15
4e3a67dc70a0 Cosmetics (go fmt and comments...)
Mikael Berthe <mikael@lilotux.net>
parents: 14
diff changeset
   421
				di := devinode{dev, ino}
45
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
   422
				if primaryPath, ok := devinodes[di]; ok {
12
15e3580cfb8d Fix hard link detection
Mikael Berthe <mikael@lilotux.net>
parents: 10
diff changeset
   423
					hardLinkIndex = i
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   424
					hardLinkCount++
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   425
					hardlinksFound = true
45
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
   426
					data.hardLinks[primaryPath] = append(data.hardLinks[primaryPath], fo.FilePath)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   427
					break
12
15e3580cfb8d Fix hard link detection
Mikael Berthe <mikael@lilotux.net>
parents: 10
diff changeset
   428
				} else {
45
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
   429
					devinodes[di] = fo.FilePath
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   430
				}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   431
			}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   432
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   433
			if hardLinkIndex == 0 {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   434
				break
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   435
			}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   436
			i := hardLinkIndex
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   437
			// Remove hardink
14
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   438
			copy((*sgListP)[i:], (*sgListP)[i+1:])
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   439
			(*sgListP)[len(*sgListP)-1] = nil
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   440
			*sgListP = (*sgListP)[:len(*sgListP)-1]
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   441
		}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   442
		// We have found hard links in this size group,
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   443
		// maybe we can remove it
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   444
		if hardlinksFound {
14
ea4286b6c4b1 Get rid of the now useless sizeClass structure
Mikael Berthe <mikael@lilotux.net>
parents: 13
diff changeset
   445
			if len(*sgListP) < 2 {
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   446
				delete(data.sizeGroups, s)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   447
				uniqueSizeCount++
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   448
				continue
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   449
			}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   450
		}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   451
	}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   452
	return
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   453
}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   454
37
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   455
func duf(dirs []string, options Options) (Results, error) {
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   456
	var verbose bool
37
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   457
	if myLog.verbosity > 0 {
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   458
		verbose = true
23
9ce0f2e2a33f Add an assertion on constant variables
Mikael Berthe <mikael@lilotux.net>
parents: 22
diff changeset
   459
	}
9ce0f2e2a33f Add an assertion on constant variables
Mikael Berthe <mikael@lilotux.net>
parents: 22
diff changeset
   460
37
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   461
	var results Results
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   462
	data.sizeGroups = make(map[int64]*FileObjList)
45
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
   463
	data.hardLinks = make(map[string][]string)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   464
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   465
	myLog.Println(1, "* Reading file metadata")
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   466
37
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   467
	for _, root := range dirs {
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   468
		if err := filepath.Walk(root, visit); err != nil {
37
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   469
			return results, fmt.Errorf("could not read file tree: %v", err)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   470
		}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   471
	}
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   472
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   473
	// Count empty files and drop them if they should be ignored
37
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   474
	emptyCount := data.dropEmptyFiles(options.IgnoreEmpty)
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   475
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   476
	// Display a small report
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   477
	if verbose {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   478
		if data.ignoreCount > 0 {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   479
			myLog.Printf(1, "  %d special files were ignored\n",
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   480
				data.ignoreCount)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   481
		}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   482
		myLog.Println(2, "  Initial counter:", data.cmpt, "files")
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   483
		myLog.Println(2, "  Total size:", formatSize(data.totalSize,
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   484
			false))
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   485
		if emptyCount > 0 {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   486
			myLog.Printf(1, "  %d empty files were ignored\n",
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   487
				emptyCount)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   488
		}
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   489
		data.dispCount()
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   490
		myLog.Println(3, "* Number of size groups:", len(data.sizeGroups))
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   491
	}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   492
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   493
	// Remove unique sizes and hard links
5
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   494
	myLog.Println(1, "* Removing files with unique size and hard links...")
2
55098d552ae2 s/createSizeHash/initialCleanup/
Mikael Berthe <mikael@lilotux.net>
parents: 1
diff changeset
   495
	hardLinkCount, uniqueSizeCount := data.initialCleanup()
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   496
	if verbose {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   497
		myLog.Printf(2, "  Dropped %d files with unique size\n",
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   498
			uniqueSizeCount)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   499
		myLog.Printf(2, "  Dropped %d hard links\n", hardLinkCount)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   500
		myLog.Println(3, "* Number of size groups:", len(data.sizeGroups))
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   501
		data.dispCount()
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   502
	}
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   503
20
f7ce9d750e83 Better documentation
Mikael Berthe <mikael@lilotux.net>
parents: 19
diff changeset
   504
	// Get the final list of dupes, using checksums
5
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   505
	myLog.Println(1, "* Computing checksums...")
16
cc0ee80cf216 Sort results
Mikael Berthe <mikael@lilotux.net>
parents: 15
diff changeset
   506
	var result foListList
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   507
	if len(data.emptyFiles) > 0 {
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   508
		result = append(result, data.emptyFiles)
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   509
	}
37
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   510
	result = append(result, data.findDupes(options.SkipPartial)...)
5
887c21c26cc8 Refactor the checksum part
Mikael Berthe <mikael@lilotux.net>
parents: 2
diff changeset
   511
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   512
	myLog.Println(3, "* Number of match groups:", len(result))
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   513
36
e918b7e63748 Add JSON output
Mikael Berthe <mikael@lilotux.net>
parents: 35
diff changeset
   514
	// Done!  Prepare results data
44
af90d9396ef1 Improve previous commit (JSON output)
Mikael Berthe <mikael@lilotux.net>
parents: 43
diff changeset
   515
	if len(result) > 0 && !options.Summary {
af90d9396ef1 Improve previous commit (JSON output)
Mikael Berthe <mikael@lilotux.net>
parents: 43
diff changeset
   516
		if options.OutToJSON {
af90d9396ef1 Improve previous commit (JSON output)
Mikael Berthe <mikael@lilotux.net>
parents: 43
diff changeset
   517
			myLog.Println(1, "* Dumping dupes as JSON...")
af90d9396ef1 Improve previous commit (JSON output)
Mikael Berthe <mikael@lilotux.net>
parents: 43
diff changeset
   518
		} else {
af90d9396ef1 Improve previous commit (JSON output)
Mikael Berthe <mikael@lilotux.net>
parents: 43
diff changeset
   519
			myLog.Println(1, "* Dupes:")
af90d9396ef1 Improve previous commit (JSON output)
Mikael Berthe <mikael@lilotux.net>
parents: 43
diff changeset
   520
		}
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   521
	}
21
dee0e0c1ad10 Improve file sorting
Mikael Berthe <mikael@lilotux.net>
parents: 20
diff changeset
   522
dee0e0c1ad10 Improve file sorting
Mikael Berthe <mikael@lilotux.net>
parents: 20
diff changeset
   523
	// Sort files by path inside each group
dee0e0c1ad10 Improve file sorting
Mikael Berthe <mikael@lilotux.net>
parents: 20
diff changeset
   524
	for _, l := range result {
dee0e0c1ad10 Improve file sorting
Mikael Berthe <mikael@lilotux.net>
parents: 20
diff changeset
   525
		sort.Sort(byFilePathName(l))
dee0e0c1ad10 Improve file sorting
Mikael Berthe <mikael@lilotux.net>
parents: 20
diff changeset
   526
	}
dee0e0c1ad10 Improve file sorting
Mikael Berthe <mikael@lilotux.net>
parents: 20
diff changeset
   527
	// Sort groups by increasing size (of the duplicated files)
16
cc0ee80cf216 Sort results
Mikael Berthe <mikael@lilotux.net>
parents: 15
diff changeset
   528
	sort.Sort(byGroupFileSize(result))
cc0ee80cf216 Sort results
Mikael Berthe <mikael@lilotux.net>
parents: 15
diff changeset
   529
45
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
   530
	// Build the result duplicate sets
36
e918b7e63748 Add JSON output
Mikael Berthe <mikael@lilotux.net>
parents: 35
diff changeset
   531
	for _, l := range result {
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   532
		size := uint64(l[0].Size())
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   533
		// We do not count the size of the 1st item
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   534
		// so we get only duplicate size.
42
3fa13770e970 Rename JSON size fields
Mikael Berthe <mikael@lilotux.net>
parents: 41
diff changeset
   535
		results.RedundantDataSizeBytes += size * uint64(len(l)-1)
3fa13770e970 Rename JSON size fields
Mikael Berthe <mikael@lilotux.net>
parents: 41
diff changeset
   536
		newSet := ResultSet{FileSize: size}
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   537
		for _, f := range l {
36
e918b7e63748 Add JSON output
Mikael Berthe <mikael@lilotux.net>
parents: 35
diff changeset
   538
			newSet.Paths = append(newSet.Paths, f.FilePath)
e918b7e63748 Add JSON output
Mikael Berthe <mikael@lilotux.net>
parents: 35
diff changeset
   539
			results.Duplicates++
45
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
   540
			if len(data.hardLinks[f.FilePath]) > 0 {
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
   541
				if newSet.Links == nil {
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
   542
					newSet.Links = make(map[string][]string)
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
   543
				}
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
   544
				newSet.Links[f.FilePath] = data.hardLinks[f.FilePath]
ea6a9ba7a3c8 Display existing hard links in result sets
Mikael Berthe <mikael@lilotux.net>
parents: 44
diff changeset
   545
			}
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   546
		}
36
e918b7e63748 Add JSON output
Mikael Berthe <mikael@lilotux.net>
parents: 35
diff changeset
   547
		results.Groups = append(results.Groups, newSet)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   548
	}
40
7f9cdb9d166d JSON output: NumberOfSets was not set
Mikael Berthe <mikael@lilotux.net>
parents: 39
diff changeset
   549
	results.NumberOfSets = uint(len(results.Groups))
42
3fa13770e970 Rename JSON size fields
Mikael Berthe <mikael@lilotux.net>
parents: 41
diff changeset
   550
	results.RedundantDataSizeHuman = formatSize(results.RedundantDataSizeBytes, true)
36
e918b7e63748 Add JSON output
Mikael Berthe <mikael@lilotux.net>
parents: 35
diff changeset
   551
	results.TotalFileCount = data.cmpt
42
3fa13770e970 Rename JSON size fields
Mikael Berthe <mikael@lilotux.net>
parents: 41
diff changeset
   552
	results.TotalSizeBytes = data.totalSize
3fa13770e970 Rename JSON size fields
Mikael Berthe <mikael@lilotux.net>
parents: 41
diff changeset
   553
	results.TotalSizeHuman = formatSize(data.totalSize, true)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   554
37
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   555
	return results, nil
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   556
}
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   557
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   558
// It all starts here.
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   559
func main() {
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   560
	var verbose bool
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   561
	var options Options
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   562
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   563
	// Assertion on constant values
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   564
	if minSizePartialChecksum <= 2*medsumBytes {
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   565
		myLog.Fatal("Internal error: assert minSizePartialChecksum > 2*medsumBytes")
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   566
	}
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   567
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   568
	// Command line parameters parsingg
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   569
	flag.BoolVar(&verbose, "verbose", false, "Be verbose (verbosity=1)")
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   570
	flag.BoolVar(&verbose, "v", false, "See --verbose")
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   571
	flag.BoolVar(&options.OutToJSON, "json", false, "Use JSON format for output")
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   572
	flag.BoolVar(&options.Summary, "summary", false, "Do not display the duplicate list")
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   573
	flag.BoolVar(&options.Summary, "s", false, "See --summary")
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   574
	flag.BoolVar(&options.SkipPartial, "skip-partial", false, "Skip partial checksums")
38
25db238bf03f Cosmetic changes
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
   575
	flag.BoolVar(&options.IgnoreEmpty, "no-empty", false, "Ignore empty files")
25db238bf03f Cosmetic changes
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
   576
	flag.IntVar(&myLog.verbosity, "verbosity", 0, "Set verbosity level (1-6)")
37
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   577
	flag.IntVar(&myLog.verbosity, "vl", 0, "See verbosity")
38
25db238bf03f Cosmetic changes
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
   578
	timings := flag.Bool("timings", false, "Show detailed log timings")
37
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   579
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   580
	flag.Parse()
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   581
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   582
	// Set verbosity: --verbose=true == --verbosity=1
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   583
	if myLog.verbosity > 0 {
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   584
		verbose = true
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   585
	} else if verbose == true {
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   586
		myLog.verbosity = 1
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   587
	}
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   588
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   589
	if len(flag.Args()) == 0 {
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   590
		// TODO: more helpful usage statement
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   591
		myLog.Println(-1, "Usage:", os.Args[0],
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   592
			"[options] base_directory|file...")
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   593
		os.Exit(0)
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   594
	}
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   595
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   596
	// Change log format for benchmarking
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   597
	if *timings {
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   598
		myLog.SetBenchFlags()
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   599
	}
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   600
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   601
	results, err := duf(flag.Args(), options)
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   602
	if err != nil {
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   603
		myLog.Fatal("ERROR: " + err.Error())
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   604
	}
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   605
36
e918b7e63748 Add JSON output
Mikael Berthe <mikael@lilotux.net>
parents: 35
diff changeset
   606
	// Output the results
37
a7662fbfbe02 Some code refactoring
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   607
	displayResults(results, options.OutToJSON, options.Summary)
0
a5642cd03cef Goduf - initial version-controlled revision
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   608
}