SHA256
1
0
forked from pool/fdupes

Accepting request 961692 from home:coolo:branches:utilities

- Handle symlinks (-s argument) correctly

OBS-URL: https://build.opensuse.org/request/show/961692
OBS-URL: https://build.opensuse.org/package/show/utilities/fdupes?expand=0&rev=24
This commit is contained in:
Peter Simons 2022-03-14 14:38:27 +00:00 committed by Git OBS Bridge
parent da1a4eb97b
commit 760afc07b9
3 changed files with 33 additions and 5 deletions

View File

@ -1,3 +1,8 @@
-------------------------------------------------------------------
Mon Mar 14 13:44:54 UTC 2022 - Stephan Kulow <coolo@suse.com>
- Handle symlinks (-s argument) correctly
------------------------------------------------------------------- -------------------------------------------------------------------
Sat Mar 12 08:17:37 UTC 2022 - Stephan Kulow <coolo@suse.com> Sat Mar 12 08:17:37 UTC 2022 - Stephan Kulow <coolo@suse.com>

View File

@ -61,7 +61,7 @@ void link_file(const std::string& file, const std::string& target, bool symlink)
} }
} }
void handle_dups(const dups_map& dups, bool symlink) void handle_dups(const dups_map& dups, const std::string& buildroot, bool symlink)
{ {
// all are hardlinks to the same data // all are hardlinks to the same data
if (dups.size() < 2) if (dups.size() < 2)
@ -70,6 +70,9 @@ void handle_dups(const dups_map& dups, bool symlink)
sort_by_count(dups, sorted); sort_by_count(dups, sorted);
auto inodes = sorted.begin(); auto inodes = sorted.begin();
std::string target = dups.at(*inodes).front(); std::string target = dups.at(*inodes).front();
if (symlink) {
target.replace(0, buildroot.length(), "");
}
for (++inodes; inodes != sorted.end(); ++inodes) { for (++inodes; inodes != sorted.end(); ++inodes) {
const std::vector<std::string> files = dups.at(*inodes); const std::vector<std::string> files = dups.at(*inodes);
@ -83,18 +86,32 @@ int main(int argc, char** argv)
{ {
bool symlink = false; bool symlink = false;
std::string root; std::string root;
std::string buildroot;
while (1) { while (1) {
int result = getopt(argc, argv, "s"); int result = getopt(argc, argv, "sb:");
if (result == -1) if (result == -1)
break; /* end of list */ break; /* end of list */
switch (result) { switch (result) {
case 's': case 's':
symlink = true; symlink = true;
break; break;
case 'b':
buildroot = optarg;
break;
default: /* unknown */ default: /* unknown */
break; break;
} }
} }
if (buildroot.empty()) {
if (symlink) {
std::cerr << "Missing -b argument to remove bootroot from symlink targets";
return 1;
}
// eliminate final slash from directory argument
if (buildroot.back() == '/') {
buildroot.pop_back();
}
}
if (optind < argc) { if (optind < argc) {
root = argv[optind++]; root = argv[optind++];
} else { } else {
@ -112,7 +129,13 @@ int main(int argc, char** argv)
-r: follow subdirectories -r: follow subdirectories
-H: also report hard links as duplicates -H: also report hard links as duplicates
*/ */
std::string command = "fdupes -q -p -n -o name -r -H '" + root + "'"; std::string command = "fdupes -q -p -n -o name";
if (!symlink) {
/* if we create symlinks, avoid looking at hard links being duplicated. This way
fdupes is faster and won't break them up anyway */
command += " -H";
}
command += " -r '" + root + "'";
FILE* pipe = popen(command.c_str(), "r"); FILE* pipe = popen(command.c_str(), "r");
if (!pipe) { if (!pipe) {
throw std::runtime_error("popen() failed!"); throw std::runtime_error("popen() failed!");
@ -122,7 +145,7 @@ int main(int argc, char** argv)
while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) { while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) {
std::string line = buffer.data(); std::string line = buffer.data();
if (line.length() < 2) { if (line.length() < 2) {
handle_dups(dups, symlink); handle_dups(dups, buildroot, symlink);
dups.clear(); dups.clear();
continue; continue;
} }

View File

@ -1 +1 @@
%fdupes /usr/lib/rpm/fdupes_wrapper %fdupes /usr/lib/rpm/fdupes_wrapper -b %{buildroot}