|
1 | 1 | package main |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bufio" |
4 | 5 | "fmt" |
5 | 6 | "io/ioutil" |
6 | 7 | "runtime/debug" |
@@ -557,6 +558,23 @@ func init() { |
557 | 558 | "whole-dupes Whole disk dupes report (-whole-dupes at command line)", |
558 | 559 | }, |
559 | 560 | }, |
| 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 | + }, |
560 | 578 | } |
561 | 579 | } |
562 | 580 |
|
@@ -1493,3 +1511,183 @@ func shellReport(args []string) int { |
1493 | 1511 | return -1 |
1494 | 1512 |
|
1495 | 1513 | } |
| 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