Unbewohnte
3 years ago
6 changed files with 322 additions and 184 deletions
@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright (C) 2021 Kasyanov Nikolay Alexeevich (Unbewohnte (me@unbewohnte.xyz)) |
||||
|
||||
This file is part of broom. |
||||
|
||||
broom is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
broom is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with broom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
# ifndef BROOM_HPP |
||||
# define BROOM_HPP |
||||
|
||||
#include <cstdint> |
||||
#include <iostream> |
||||
|
||||
// A class to find and manage duplicate files
|
||||
class Broom { |
||||
protected: |
||||
// how many files has been "sweeped"
|
||||
uintmax_t m_sweeped_files; |
||||
// how many bytes was freed
|
||||
uintmax_t m_sweeped_size; |
||||
|
||||
public: |
||||
Broom() {}; |
||||
~Broom() {}; |
||||
|
||||
// Print current statistics
|
||||
void print_statistics(); |
||||
|
||||
// Determines whether entry1 is a duplicate of entry2
|
||||
bool is_duplicate(Entry entry1, Entry entry2); |
||||
|
||||
// find all duplicates in the directory
|
||||
int find_duplicates(std::filesystem::path directory, Entry entries[], bool recursive = false); |
||||
|
||||
// remove ALL duplicate files
|
||||
int sweep_all(Entry entries[]); |
||||
|
||||
// remove ALL duplicates but the one with specified index
|
||||
int sweep_all_but(Entry entries[], uint32_t index = 0); |
||||
}; |
||||
|
||||
# endif |
@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright (C) 2021 Kasyanov Nikolay Alexeevich (Unbewohnte (me@unbewohnte.xyz)) |
||||
|
||||
This file is part of broom. |
||||
|
||||
broom is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
broom is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with broom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#include "entry.hpp" |
||||
|
||||
// A wrapper for every file with all necessary information
|
||||
class Entry { |
||||
public: |
||||
Entry(std::filesystem::path path) { |
||||
// check for existense and being a directory
|
||||
if (!std::filesystem::exists(path) || std::filesystem::is_directory(path)) { |
||||
throw "Does not exist or a directory"; |
||||
}; |
||||
|
||||
// filename
|
||||
filename = path.filename(); |
||||
|
||||
// filesize
|
||||
filesize = std::filesystem::file_size(path); |
||||
|
||||
// checksum
|
||||
std::fstream entry_file; |
||||
entry_file.open(path); |
||||
|
||||
if (!entry_file.is_open()) { |
||||
throw "Could not open file"; |
||||
} |
||||
|
||||
char start_buf[CHUNK_SIZE]; |
||||
entry_file.read(start_buf, CHUNK_SIZE); |
||||
|
||||
char end_buf[CHUNK_SIZE]; |
||||
entry_file.read(end_buf, CHUNK_SIZE); |
||||
|
||||
char middle_buf[CHUNK_SIZE]; |
||||
entry_file.read(middle_buf, CHUNK_SIZE); |
||||
|
||||
for (uint8_t i = 0; i < CHECKSUM_SIZE; i++) { |
||||
if (i < CHUNK_SIZE) { |
||||
checksum[i] = start_buf[i]; |
||||
} |
||||
else if (i > CHUNK_SIZE*2) { |
||||
checksum[i] = middle_buf[i-(CHUNK_SIZE*2)]; |
||||
} |
||||
else if (i > CHUNK_SIZE) { |
||||
checksum[i] = end_buf[i - CHUNK_SIZE]; |
||||
} |
||||
}; |
||||
}; |
||||
|
||||
~Entry() {}; |
||||
|
||||
std::string filename; |
||||
std::filesystem::path path; |
||||
uintmax_t filesize; |
||||
char checksum[CHECKSUM_SIZE]; |
||||
|
||||
// Compare this entry`s checksum with the other one.
|
||||
// If the checksums are the same -> returns true, else -> false
|
||||
bool compare_checksums(char other_checksum[CHECKSUM_SIZE]) { |
||||
for (uint8_t i = 0; i < CHECKSUM_SIZE; i++) { |
||||
if (checksum[i] != other_checksum[i]) { |
||||
return false; |
||||
}; |
||||
}; |
||||
return true; |
||||
}; |
||||
|
||||
// Remove entity from the disk
|
||||
void remove() { |
||||
std::filesystem::remove(path); |
||||
}; |
||||
}; |
@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright (C) 2021 Kasyanov Nikolay Alexeevich (Unbewohnte (me@unbewohnte.xyz)) |
||||
|
||||
This file is part of broom. |
||||
|
||||
broom is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
broom is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with broom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
# ifndef ENTRY_HPP |
||||
# define ENTRY_HPP |
||||
|
||||
#include <filesystem> |
||||
#include <fstream> |
||||
|
||||
// 3 chunks (beginning, end, middle of the file)
|
||||
const uint8_t CHUNK_SIZE = 24; |
||||
const uint8_t CHECKSUM_SIZE = CHUNK_SIZE * 3; |
||||
|
||||
// A wrapper for every file with all necessary information
|
||||
class Entry { |
||||
public: |
||||
Entry(std::filesystem::path path); |
||||
~Entry(); |
||||
|
||||
std::string filename; |
||||
std::filesystem::path path; |
||||
uintmax_t filesize; |
||||
char checksum[CHECKSUM_SIZE]; |
||||
|
||||
// Compare this entry`s checksum with the other one.
|
||||
// If the checksums are the same -> returns true, else -> false
|
||||
bool compare_checksums(char other_checksum[CHECKSUM_SIZE]); |
||||
|
||||
// Remove entity from the disk
|
||||
void remove(); |
||||
}; |
||||
|
||||
|
||||
# endif |
@ -0,0 +1,108 @@
|
||||
/*
|
||||
Copyright (C) 2021 Kasyanov Nikolay Alexeevich (Unbewohnte (me@unbewohnte.xyz)) |
||||
|
||||
This file is part of broom. |
||||
|
||||
broom is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
broom is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with broom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#include <iostream> |
||||
#include <fstream> |
||||
#include <string.h> |
||||
#include <cstdint> |
||||
#include <vector> |
||||
#include <filesystem> |
||||
|
||||
#include "entry.hpp" |
||||
#include "broom.hpp" |
||||
|
||||
// Broom version number
|
||||
#define VERSION "v0.1.0" |
||||
|
||||
// Broom`s settings
|
||||
struct Options { |
||||
bool sweeping; |
||||
std::vector<std::filesystem::path> paths; |
||||
}; |
||||
|
||||
void print_help() { |
||||
std::cout |
||||
<< "broom [FLAGS..] [COMMAND] [FILES|DIRECTORIES...]" << std::endl << std::endl |
||||
<< "FLAGS" << std::endl |
||||
<< "-v | --version -> print version information and exit" << std::endl |
||||
<< "-h | --help -> print this message and exit" << std::endl << std::endl |
||||
<< "COMMANDS" << std::endl |
||||
<< "sweep -> scan for duplicate files and delete (sweep) all of them but the last one" << std::endl |
||||
<< "scan -> scan for duplicate files and output information in a file" << std::endl |
||||
<< std::endl; |
||||
}; |
||||
|
||||
void print_version() { |
||||
std::cout |
||||
<< "broom " << VERSION << std::endl |
||||
<< "a command line utility to locate and manage duplicate files" << std::endl << std::endl |
||||
<< "Copyright (C) 2021 Kasyanov Nikolay Alexeevich (Unbewohnte (me@unbewohnte.xyz))" << std::endl |
||||
<< "This program comes with ABSOLUTELY NO WARRANTY." << std::endl |
||||
<< "This is free software, and you are welcome to redistribute it" << std::endl |
||||
<< "under certain conditions" << std::endl |
||||
<< std::endl; |
||||
}; |
||||
|
||||
int main(int argc, char* argv[]) { |
||||
Options options; |
||||
|
||||
if (argc < 2) { |
||||
print_help(); |
||||
return 0; |
||||
}; |
||||
|
||||
// process command line arguments
|
||||
for (unsigned int i = 0; i < argc; i++) { |
||||
// flags -> command -> directories&&files
|
||||
|
||||
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { |
||||
print_help(); |
||||
return 0; |
||||
} |
||||
else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) { |
||||
print_version(); |
||||
return 0; |
||||
} |
||||
else if (strcmp(argv[i], "sweep") == 0) { |
||||
options.sweeping = true; |
||||
} |
||||
else if (strcmp(argv[i], "scan") == 0) { |
||||
options.sweeping = false; |
||||
} |
||||
else { |
||||
// add path
|
||||
if (i == 0) { |
||||
continue; |
||||
} else { |
||||
options.paths.push_back(argv[i]); |
||||
} |
||||
}; |
||||
}; |
||||
|
||||
// printing all directories just for testing
|
||||
for (uint32_t i = 0; i < options.paths.size(); i++) { |
||||
for (auto& p : std::filesystem::recursive_directory_iterator(options.paths.at(i))) { |
||||
if (p.is_directory()) { |
||||
std::cout << p.path() << std::endl; |
||||
} |
||||
}; |
||||
}; |
||||
|
||||
return 0; |
||||
}; |
Loading…
Reference in new issue