Source: cruft-ng
Version: 0.9.62
Severity: wishlist
Tags: patch

Hi Alexandre,

I would like to use cruft-ng on systems without having a locate
installed as it is fast enough without it on my SSD. Please find two
patches attached to implement this.

Thanks for maintaining cruft-ng!

Cheers Jochen


-- System Information:
Debian Release: trixie/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)

Kernel: Linux 6.8.11-amd64 (SMP w/8 CPU threads; PREEMPT)
Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
From d79bac0c57cab984fc2708dd7596b387bfd4d5ec Mon Sep 17 00:00:00 2001
From: Jochen Sprickerhof <jspri...@debian.org>
Date: Sun, 2 Jun 2024 11:59:28 +0200
Subject: [PATCH 1/2] Move read_ignores to own file

Allows using it in other functions.
---
 Makefile        |  5 +++--
 plocate.cc      | 18 +-----------------
 read_ignores.cc | 23 +++++++++++++++++++++++
 read_ignores.h  |  6 ++++++
 4 files changed, 33 insertions(+), 19 deletions(-)
 create mode 100644 read_ignores.cc
 create mode 100644 read_ignores.h

diff --git a/Makefile b/Makefile
index d9fe79e..5eb73be 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ CXXFLAGS ?= -O2 -fstack-protector-strong -Wformat 
-Werror=format-security -Wl,-z
 CXXFLAGS += -Wall -Wextra
 override CXXFLAGS += $(LIBDPKG_CFLAGS)
 #CXXFLAGS += -std=c++17 #  clang++
-SHARED_OBJS = explain.o filters.o shellexp.o usr_merge.o python.o owner.o
+SHARED_OBJS = explain.o filters.o shellexp.o usr_merge.o python.o owner.o 
read_ignores.o
 CRUFT_OBJS = cruft.o dpkg_exclude.o bugs.o
 
 sid: cruft ruleset cpigs
@@ -19,8 +19,9 @@ cpigs.o: cpigs.cc owner.h
 owner.o: owner.cc owner.h
 explain.o: explain.cc owner.h
 filters.o: filters.cc owner.h
-plocate.o: plocate.cc locate.h
+plocate.o: plocate.cc locate.h read_ignores.h
 mlocate.o: mlocate.cc locate.h
+read_ignores.o: read_ignores.cc read_ignores.h
 
 cruft.o: cruft.cc explain.h filters.h dpkg.h python.h
 dpkg_lib.o: dpkg_lib.cc dpkg.h /usr/include/dpkg/dpkg.h
diff --git a/plocate.cc b/plocate.cc
index 20cf762..9af52ce 100644
--- a/plocate.cc
+++ b/plocate.cc
@@ -9,23 +9,7 @@
 
 #include "locate.h"
 #include "python.h"
-
-static void read_ignores(vector<string>& ignores, const string& ignore_path)
-{
-       ifstream ignore_file(ignore_path);
-       if (!ignore_file.is_open())
-               ignore_file.open("/usr/share/cruft/ignore");
-
-       for (string ignore_line; getline(ignore_file,ignore_line);)
-       {
-               if (ignore_line.empty()) continue;
-               if (ignore_line.front() == '/') {
-                       if (ignore_line.back() != '/')
-                               ignore_line += "/";
-                       ignores.emplace_back(std::move(ignore_line));
-               }
-       }
-}
+#include "read_ignores.h"
 
 int read_locate(vector<string>& fs, const string& ignore_path)
 {
diff --git a/read_ignores.cc b/read_ignores.cc
new file mode 100644
index 0000000..d3cd1e5
--- /dev/null
+++ b/read_ignores.cc
@@ -0,0 +1,23 @@
+// Copyright © 2015 Alexandre Detiste <alexan...@detiste.be>
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <fstream>
+
+#include "read_ignores.h"
+
+void read_ignores(vector<string>& ignores, const string& ignore_path)
+{
+       ifstream ignore_file(ignore_path);
+       if (!ignore_file.is_open())
+               ignore_file.open("/usr/share/cruft/ignore");
+
+       for (string ignore_line; getline(ignore_file,ignore_line);)
+       {
+               if (ignore_line.empty()) continue;
+               if (ignore_line.front() == '/') {
+                       if (ignore_line.back() != '/')
+                               ignore_line += "/";
+                       ignores.emplace_back(std::move(ignore_line));
+               }
+       }
+}
diff --git a/read_ignores.h b/read_ignores.h
new file mode 100644
index 0000000..cb6c68b
--- /dev/null
+++ b/read_ignores.h
@@ -0,0 +1,6 @@
+#include <string>
+#include <vector>
+
+using namespace std;
+
+void read_ignores(vector<string>& ignores, const string& ignore_path);
-- 
2.45.1

>From 79e76c76202a8183d027d64b931da34c4445750f Mon Sep 17 00:00:00 2001
From: Jochen Sprickerhof <jspri...@debian.org>
Date: Sun, 2 Jun 2024 12:00:53 +0200
Subject: [PATCH 2/2] Support running without a locate

Also move p/mlocate to Recommends.
---
 Makefile       |  2 +-
 cruft.cc       | 92 +++++++++++++++++++++++++++++++++++++++++++++-----
 debian/control |  1 +
 3 files changed, 86 insertions(+), 9 deletions(-)

diff --git a/Makefile b/Makefile
index 5eb73be..5b81236 100644
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,7 @@ plocate.o: plocate.cc locate.h read_ignores.h
 mlocate.o: mlocate.cc locate.h
 read_ignores.o: read_ignores.cc read_ignores.h
 
-cruft.o: cruft.cc explain.h filters.h dpkg.h python.h
+cruft.o: cruft.cc explain.h filters.h dpkg.h python.h read_ignores.h
 dpkg_lib.o: dpkg_lib.cc dpkg.h /usr/include/dpkg/dpkg.h
 dpkg_popen.o: dpkg_popen.cc dpkg.h
 
diff --git a/cruft.cc b/cruft.cc
index d191582..9eb5f74 100644
--- a/cruft.cc
+++ b/cruft.cc
@@ -6,12 +6,15 @@
 #include <algorithm>
 #include <ctime>
 #include <thread>
+#include <filesystem>
 
 #include <sys/stat.h>
 #include <getopt.h>
 #include <cstring>
 #include <unistd.h>
 #include <dirent.h>
+#include <sys/vfs.h>
+#include <linux/magic.h>
 
 #include "explain.h"
 #include "filters.h"
@@ -20,6 +23,8 @@
 #include "dpkg_exclude.h"
 #include "shellexp.h"
 #include "bugs.h"
+#include "python.h"
+#include "read_ignores.h"
 
 using namespace std;
 
@@ -188,6 +193,7 @@ static void print_help_message()
 
        cout << "OPTIONS\n";
        cout << "    -p --package     list volatile files only for this one 
package\n";
+       cout << "    -n --nolocate    do not use locate\n";
        cout << "    -E --explain     directory for explain scripts (default: " 
<< default_explain_dir << ")\n";
        cout << "    -F --filter      directory for filters (default: " << 
default_filter_dir << ")\n";
        cout << "    -I --ignore      path for ignore file (default: " << 
default_ignore_file << ")\n";
@@ -199,11 +205,73 @@ static void print_help_message()
        cout << "    -h --help        this help message\n";
 }
 
+int read_nolocate(vector<string>& fs, const string& ignore_path)
+{
+       bool debug=getenv("DEBUG") != nullptr;
+
+       if (debug) cerr << "FILESYSTEM DATA\n";
+
+       init_python();
+
+       vector<string> ignores;
+       read_ignores(ignores, ignore_path);
+
+       struct statfs buf;
+
+        for (auto entry =
+                 filesystem::recursive_directory_iterator{
+                     "/",
+                     filesystem::directory_options::skip_permission_denied};
+             entry != filesystem::recursive_directory_iterator(); entry++)
+       {
+               std::string filename{entry->path()};
+
+               statfs(filename.c_str(), &buf);
+
+               if (buf.f_type == TMPFS_MAGIC
+                   or buf.f_type == SYSFS_MAGIC
+                   or buf.f_type == PROC_SUPER_MAGIC
+                   or filename == "/dev"
+                   or (filename == "/home" /* and dirname != "/home" */)
+                   or filename == "/mnt"
+                   or filename == "/root"
+                   or filename == "/tmp")
+                       entry.disable_recursion_pending();
+
+               bool ignored = false;
+               for (const auto& it : ignores) {
+                       if (filename.size() > it.size() && filename.compare(0, 
it.size(), it) == 0) {
+                               ignored = true;
+                               break;
+                       }
+
+                       // ignore directory '/foo' for ignore entry '/foo/'
+                       error_code ec;
+                       if (filename.size() + 1 == it.size()
+                       && it.compare(0, filename.size(), filename) == 0
+                       && filesystem::is_directory(filename, ec)) {
+                               ignored = true;
+                               break;
+                       }
+               }
+               if (ignored) continue;
+
+               if (!pyc_has_py(string{filename}, debug))
+                       fs.emplace_back(filename);
+       }
+
+       sort(fs.begin(), fs.end());
+       fs.erase( unique( fs.begin(), fs.end() ), fs.end() );
+       if (debug) cerr << fs.size() << " relevant files in filesystem"  << 
endl << endl;
+       return 0;
+}
+
 static void cruft(const string& ignore_file,
                   const string& filter_dir,
                   const string& ruleset_file,
                   const string& explain_dir,
-                  const string& bugs_file)
+                  const string& bugs_file,
+                  bool locate)
 {
        bool debug = getenv("DEBUG") != nullptr;
 
@@ -217,14 +285,16 @@ static void cruft(const string& ignore_file,
        strftime(buf, sizeof(buf), "%c", timeinfo);
        cout << "cruft report: " << buf << '\n';
 
-       bool updated = updatedb();
-       if (!updated) {
-               cerr << "warning: plocate database is outdated" << endl << 
flush;
+       if (locate) {
+               bool updated = updatedb();
+               if (!updated) {
+                       cerr << "warning: plocate database is outdated" << endl 
<< flush;
+               }
+               elapsed("updatedb");
        }
-       elapsed("updatedb");
 
        vector<string> fs;
-       thread thr_plocate(read_locate, ref(fs), ignore_file);
+       thread thr_plocate(locate ? read_locate : read_nolocate, ref(fs), 
ignore_file);
 
        vector<string> packages;
        vector<string> dpkg;
@@ -347,6 +417,7 @@ static void cruft(const string& ignore_file,
 int main(int argc, char *argv[])
 {
        bool do_one_package = false;
+       bool locate = true;
        string package = "";
        string explain_dir = default_explain_dir;
        string filter_dir = default_filter_dir;
@@ -357,6 +428,7 @@ int main(int argc, char *argv[])
        const struct option long_options[] =
        {
                {"help", no_argument, nullptr, 'h'},
+               {"no-locate", no_argument, nullptr, 'n'},
                {"package", required_argument, nullptr, 'p'},
                {"explain", required_argument, nullptr, 'E'},
                {"filter", required_argument, nullptr, 'F'},
@@ -367,7 +439,7 @@ int main(int argc, char *argv[])
        };
 
        int opt, opti = 0;
-       while ((opt = getopt_long(argc, argv, "p:E:F:hI:R:B:", long_options, 
&opti)) != 0) {
+       while ((opt = getopt_long(argc, argv, "p:E:F:hI:nR:B:", long_options, 
&opti)) != 0) {
                if (opt == EOF)
                        break;
 
@@ -396,6 +468,10 @@ int main(int argc, char *argv[])
                        ignore_file = optarg;
                        break;
 
+               case 'n':
+                       locate = false;
+                       break;
+
                case 'R':
                        ruleset_file = optarg;
                        break;
@@ -430,5 +506,5 @@ int main(int argc, char *argv[])
        }
 
        // else: standard cruft report
-       cruft(ignore_file, filter_dir, ruleset_file, explain_dir, bugs_file);
+       cruft(ignore_file, filter_dir, ruleset_file, explain_dir, bugs_file, 
locate);
 }
diff --git a/debian/control b/debian/control
index 7a33e4d..a4c115d 100644
--- a/debian/control
+++ b/debian/control
@@ -18,6 +18,7 @@ Architecture: any
 Depends:
   ${shlibs:Depends},
   ${misc:Depends},
+Recommends:
   ${dist:Depends},
 Suggests:
   ncdu,
-- 
2.45.1

Reply via email to