Skip to content

Commit c911f6d

Browse files
Add quarantine command and flag
1 parent 2bb869c commit c911f6d

File tree

5 files changed

+226
-15
lines changed

5 files changed

+226
-15
lines changed

data.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ type Disk struct {
3939
MatchFiles map[*DiskFile]*DiskFile
4040
MissingFiles, ExtraFiles []*DiskFile
4141
IngestMode int
42+
source string
4243
}
4344

4445
type ByMatchFactor []*Disk
@@ -236,6 +237,8 @@ func (d *Disk) ReadFromFile(filename string) error {
236237
dec := gob.NewDecoder(f)
237238
err = dec.Decode(d)
238239

240+
d.source = filename
241+
239242
return err
240243
}
241244

main.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ var filePut = flag.String("file-put", "", "File to put on disk (-with-disk)")
110110
var fileDelete = flag.String("file-delete", "", "File to delete (-with-disk)")
111111
var fileMkdir = flag.String("dir-create", "", "Directory to create (-with-disk)")
112112
var fileCatalog = flag.Bool("catalog", false, "List disk contents (-with-disk)")
113+
var quarantine = flag.Bool("quarantine", false, "Run -as-dupes and -whole-disk in quarantine mode")
113114

114115
func main() {
115116

@@ -286,12 +287,20 @@ func main() {
286287
}
287288

288289
if *wholeDupes {
289-
wholeDupeReport(filterpath)
290+
if *quarantine {
291+
quarantineWholeDisks(filterpath)
292+
} else {
293+
wholeDupeReport(filterpath)
294+
}
290295
os.Exit(0)
291296
}
292297

293298
if *activeDupes {
294-
activeDupeReport(filterpath)
299+
if *quarantine {
300+
quarantineActiveDisks(filterpath)
301+
} else {
302+
activeDupeReport(filterpath)
303+
}
295304
os.Exit(0)
296305
}
297306

make.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ for arch in `echo $ARCHES`; do
2222
go build -o "$EXENAME" .
2323
if [ "$?" == "0" ]; then
2424
echo "Zipping -> $ZIPNAME"
25-
zip "$ZIPNAME" "$EXENAME" "LICENSE" "README.md"
25+
zip "$ZIPNAME" "$EXENAME" "LICENSE" "README.md" "USAGE.md"
2626
else
2727
exit 2
2828
fi

report.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ import (
77
)
88

99
type DuplicateSource struct {
10-
Fullpath string
11-
Filename string
12-
GSHA string
10+
Fullpath string
11+
Filename string
12+
GSHA string
13+
fingerprint string
1314
}
1415

1516
type DuplicateFileCollection struct {
@@ -25,7 +26,7 @@ type DuplicateActiveSectorDiskCollection struct {
2526
data_as map[string][]DuplicateSource
2627
}
2728

28-
func (dfc *DuplicateFileCollection) Add(checksum string, fullpath string, filename string) {
29+
func (dfc *DuplicateFileCollection) Add(checksum string, fullpath string, filename string, fgp string) {
2930

3031
if dfc.data == nil {
3132
dfc.data = make(map[string][]DuplicateSource)
@@ -36,13 +37,13 @@ func (dfc *DuplicateFileCollection) Add(checksum string, fullpath string, filena
3637
list = make([]DuplicateSource, 0)
3738
}
3839

39-
list = append(list, DuplicateSource{Fullpath: fullpath, Filename: filename})
40+
list = append(list, DuplicateSource{Fullpath: fullpath, Filename: filename, fingerprint: fgp})
4041

4142
dfc.data[checksum] = list
4243

4344
}
4445

45-
func (dfc *DuplicateWholeDiskCollection) Add(checksum string, fullpath string) {
46+
func (dfc *DuplicateWholeDiskCollection) Add(checksum string, fullpath string, fgp string) {
4647

4748
if dfc.data == nil {
4849
dfc.data = make(map[string][]DuplicateSource)
@@ -53,13 +54,13 @@ func (dfc *DuplicateWholeDiskCollection) Add(checksum string, fullpath string) {
5354
list = make([]DuplicateSource, 0)
5455
}
5556

56-
list = append(list, DuplicateSource{Fullpath: fullpath})
57+
list = append(list, DuplicateSource{Fullpath: fullpath, fingerprint: fgp})
5758

5859
dfc.data[checksum] = list
5960

6061
}
6162

62-
func (dfc *DuplicateActiveSectorDiskCollection) Add(checksum string, achecksum string, fullpath string) {
63+
func (dfc *DuplicateActiveSectorDiskCollection) Add(checksum string, achecksum string, fullpath string, fgp string) {
6364

6465
if dfc.data == nil {
6566
dfc.data = make(map[string][]DuplicateSource)
@@ -70,7 +71,7 @@ func (dfc *DuplicateActiveSectorDiskCollection) Add(checksum string, achecksum s
7071
list = make([]DuplicateSource, 0)
7172
}
7273

73-
list = append(list, DuplicateSource{Fullpath: fullpath, GSHA: checksum})
74+
list = append(list, DuplicateSource{Fullpath: fullpath, GSHA: checksum, fingerprint: fgp})
7475

7576
dfc.data[achecksum] = list
7677

@@ -110,21 +111,21 @@ func AggregateDuplicateFiles(d *Disk, collection interface{}) {
110111

111112
for _, f := range d.Files {
112113

113-
collection.(*DuplicateFileCollection).Add(f.SHA256, d.FullPath, f.Filename)
114+
collection.(*DuplicateFileCollection).Add(f.SHA256, d.FullPath, f.Filename, d.source)
114115

115116
}
116117

117118
}
118119

119120
func AggregateDuplicateWholeDisks(d *Disk, collection interface{}) {
120121

121-
collection.(*DuplicateWholeDiskCollection).Add(d.SHA256, d.FullPath)
122+
collection.(*DuplicateWholeDiskCollection).Add(d.SHA256, d.FullPath, d.source)
122123

123124
}
124125

125126
func AggregateDuplicateActiveSectorDisks(d *Disk, collection interface{}) {
126127

127-
collection.(*DuplicateActiveSectorDiskCollection).Add(d.SHA256, d.SHA256Active, d.FullPath)
128+
collection.(*DuplicateActiveSectorDiskCollection).Add(d.SHA256, d.SHA256Active, d.FullPath, d.source)
128129

129130
}
130131

shell.go

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"bufio"
45
"fmt"
56
"io/ioutil"
67
"runtime/debug"
@@ -557,6 +558,23 @@ func init() {
557558
"whole-dupes Whole disk dupes report (-whole-dupes at command line)",
558559
},
559560
},
561+
"quarantine": &shellCommand{
562+
Name: "quarantine",
563+
Description: "Like report, but allow moving dupes to a backup folder",
564+
MinArgs: 1,
565+
MaxArgs: 999,
566+
Code: shellQuarantine,
567+
NeedsMount: false,
568+
Context: sccDiskFile,
569+
Text: []string{
570+
"quarantine <name> [<path>]",
571+
"",
572+
"Scans:",
573+
"as-dupes Active sector dupes report (-as-dupes at command line)",
574+
"file-dupes File dupes report (-file-dupes at command line)",
575+
"whole-dupes Whole disk dupes report (-whole-dupes at command line)",
576+
},
577+
},
560578
}
561579
}
562580

@@ -1493,3 +1511,183 @@ func shellReport(args []string) int {
14931511
return -1
14941512

14951513
}
1514+
1515+
func shellQuarantine(args []string) int {
1516+
1517+
switch args[0] {
1518+
case "as-dupes":
1519+
quarantineActiveDisks(args[1:])
1520+
case "whole-dupes":
1521+
quarantineWholeDisks(args[1:])
1522+
}
1523+
1524+
return -1
1525+
1526+
}
1527+
1528+
func moveFile(source, dest string) error {
1529+
1530+
source = strings.Replace(source, "\\", "/", -1)
1531+
dest = strings.Replace(dest, "\\", "/", -1)
1532+
1533+
fmt.Printf("Reading source file: %s\n", source)
1534+
data, err := ioutil.ReadFile(source)
1535+
if err != nil {
1536+
return err
1537+
}
1538+
1539+
// make sure dest dir actually exists
1540+
os.MkdirAll(filepath.Dir(dest), 0755)
1541+
1542+
fmt.Printf("Creating dest file: %s\n", dest)
1543+
f, err := os.Create(dest)
1544+
if err != nil {
1545+
return err
1546+
}
1547+
f.Write(data)
1548+
f.Close()
1549+
1550+
err = os.Remove(source)
1551+
if err != nil {
1552+
return err
1553+
}
1554+
1555+
if _, err := os.Stat(source); err == nil {
1556+
fmt.Println(source + " not deleted!!")
1557+
return errors.New(source + " not deleted!!")
1558+
}
1559+
1560+
return nil
1561+
}
1562+
1563+
func quarantineActiveDisks(filter []string) {
1564+
dfc := &DuplicateActiveSectorDiskCollection{}
1565+
Aggregate(AggregateDuplicateActiveSectorDisks, dfc, filter)
1566+
1567+
reader := bufio.NewReader(os.Stdin)
1568+
1569+
for _, list := range dfc.data {
1570+
1571+
if len(list) == 1 {
1572+
continue
1573+
}
1574+
1575+
prompt:
1576+
1577+
fmt.Println("Which one to keep?")
1578+
fmt.Println("(0) Skip this...")
1579+
for i, v := range list {
1580+
fmt.Printf("(%d) %s\n", i+1, v.Fullpath)
1581+
}
1582+
fmt.Println()
1583+
fmt.Printf("Option (0-%d, q): ", len(list))
1584+
text, _ := reader.ReadString('\n')
1585+
1586+
text = strings.ToLower(strings.Trim(text, "\r\n"))
1587+
1588+
if text == "q" {
1589+
return
1590+
}
1591+
1592+
if text == "0" {
1593+
continue
1594+
}
1595+
1596+
tmp, _ := strconv.ParseInt(text, 10, 32)
1597+
idx := int(tmp) - 1
1598+
1599+
if idx < 0 || idx > len(list) {
1600+
goto prompt
1601+
}
1602+
1603+
for i, v := range list {
1604+
if i == idx {
1605+
continue
1606+
}
1607+
path := v.Fullpath
1608+
path = strings.Replace(path, ":", "", -1)
1609+
path = strings.Replace(path, "\\", "/", -1)
1610+
1611+
bpath := binpath() + "/quarantine/" + path
1612+
err := moveFile(v.Fullpath, bpath)
1613+
if err != nil {
1614+
fmt.Println(err)
1615+
return
1616+
}
1617+
1618+
err = moveFile(v.fingerprint, v.fingerprint+".q")
1619+
if err != nil {
1620+
fmt.Println(err)
1621+
return
1622+
}
1623+
1624+
}
1625+
1626+
}
1627+
}
1628+
1629+
func quarantineWholeDisks(filter []string) {
1630+
dfc := &DuplicateWholeDiskCollection{}
1631+
Aggregate(AggregateDuplicateWholeDisks, dfc, filter)
1632+
1633+
reader := bufio.NewReader(os.Stdin)
1634+
1635+
for _, list := range dfc.data {
1636+
1637+
if len(list) == 1 {
1638+
continue
1639+
}
1640+
1641+
wprompt:
1642+
1643+
fmt.Println("Which one to keep?")
1644+
fmt.Println("(0) Skip this...")
1645+
for i, v := range list {
1646+
fmt.Printf("(%d) %s\n", i+1, v.Fullpath)
1647+
}
1648+
fmt.Println()
1649+
fmt.Printf("Option (0-%d, q): ", len(list))
1650+
text, _ := reader.ReadString('\n')
1651+
1652+
text = strings.ToLower(strings.Trim(text, "\r\n"))
1653+
1654+
if text == "q" {
1655+
return
1656+
}
1657+
1658+
if text == "0" {
1659+
continue
1660+
}
1661+
1662+
tmp, _ := strconv.ParseInt(text, 10, 32)
1663+
idx := int(tmp) - 1
1664+
1665+
if idx < 0 || idx > len(list) {
1666+
goto wprompt
1667+
}
1668+
1669+
for i, v := range list {
1670+
if i == idx {
1671+
continue
1672+
}
1673+
path := v.Fullpath
1674+
path = strings.Replace(path, ":", "", -1)
1675+
path = strings.Replace(path, "\\", "/", -1)
1676+
1677+
bpath := binpath() + "/quarantine/" + path
1678+
err := moveFile(v.Fullpath, bpath)
1679+
if err != nil {
1680+
fmt.Println(err)
1681+
return
1682+
}
1683+
1684+
err = moveFile(v.fingerprint, v.fingerprint+".q")
1685+
if err != nil {
1686+
fmt.Println(err)
1687+
return
1688+
}
1689+
1690+
}
1691+
1692+
}
1693+
}

0 commit comments

Comments
 (0)