From 760afc07b9ced37d0cd154d63a535318558bf9a864d22449d3ba134eceb27a34 Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Mon, 14 Mar 2022 14:38:27 +0000 Subject: [PATCH] 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 --- fdupes.changes | 5 +++++ fdupes_wrapper.cpp | 31 +++++++++++++++++++++++++++---- macros.fdupes | 2 +- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/fdupes.changes b/fdupes.changes index 6c1f2b9..89cd3df 100644 --- a/fdupes.changes +++ b/fdupes.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Mon Mar 14 13:44:54 UTC 2022 - Stephan Kulow + +- Handle symlinks (-s argument) correctly + ------------------------------------------------------------------- Sat Mar 12 08:17:37 UTC 2022 - Stephan Kulow diff --git a/fdupes_wrapper.cpp b/fdupes_wrapper.cpp index 0e79721..9972152 100644 --- a/fdupes_wrapper.cpp +++ b/fdupes_wrapper.cpp @@ -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 if (dups.size() < 2) @@ -70,6 +70,9 @@ void handle_dups(const dups_map& dups, bool symlink) sort_by_count(dups, sorted); auto inodes = sorted.begin(); std::string target = dups.at(*inodes).front(); + if (symlink) { + target.replace(0, buildroot.length(), ""); + } for (++inodes; inodes != sorted.end(); ++inodes) { const std::vector files = dups.at(*inodes); @@ -83,18 +86,32 @@ int main(int argc, char** argv) { bool symlink = false; std::string root; + std::string buildroot; while (1) { - int result = getopt(argc, argv, "s"); + int result = getopt(argc, argv, "sb:"); if (result == -1) break; /* end of list */ switch (result) { case 's': symlink = true; break; + case 'b': + buildroot = optarg; + break; default: /* unknown */ 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) { root = argv[optind++]; } else { @@ -112,7 +129,13 @@ int main(int argc, char** argv) -r: follow subdirectories -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"); if (!pipe) { throw std::runtime_error("popen() failed!"); @@ -122,7 +145,7 @@ int main(int argc, char** argv) while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) { std::string line = buffer.data(); if (line.length() < 2) { - handle_dups(dups, symlink); + handle_dups(dups, buildroot, symlink); dups.clear(); continue; } diff --git a/macros.fdupes b/macros.fdupes index be95009..fd514d7 100644 --- a/macros.fdupes +++ b/macros.fdupes @@ -1 +1 @@ -%fdupes /usr/lib/rpm/fdupes_wrapper +%fdupes /usr/lib/rpm/fdupes_wrapper -b %{buildroot}