aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThorsten Töpper <atsutane@freethoughts.de>2026-02-28 22:01:40 +0100
committerThorsten Töpper <atsutane@freethoughts.de>2026-02-28 22:01:40 +0100
commit55d4d6adc4c7e9e849229b24bcf75910d548ff44 (patch)
tree92afe71ad6a0fe19c0b176e6f2a4f2a1a0043b2e /src
parent819779a68bc6da0c3d298efe52e3b1ca0d2e66cf (diff)
downloadduplicate_finder-55d4d6adc4c7e9e849229b24bcf75910d548ff44.tar.gz
duplicate_finder-55d4d6adc4c7e9e849229b24bcf75910d548ff44.tar.bz2
dump: fullpath and fileinfos
Diffstat (limited to 'src')
-rw-r--r--src/database_interaction.c41
-rw-r--r--src/duplicate_finder.c44
-rw-r--r--src/options.c10
3 files changed, 94 insertions, 1 deletions
diff --git a/src/database_interaction.c b/src/database_interaction.c
index 3acc81c..2b5a3f8 100644
--- a/src/database_interaction.c
+++ b/src/database_interaction.c
@@ -74,6 +74,8 @@ sqlite3_stmt *select_filename_by_id,
*select_fileinfo_complete_table,
*select_fileinfo_complete_table_resolved;
+sqlite3_stmt *select_full_path;
+
sqlite3_stmt *insert_filename,
*insert_pathname,
*insert_hashes,
@@ -159,6 +161,7 @@ void dbi_close() {
LOCAL_FINALIZE(select_fileinfo_complete_table);
LOCAL_FINALIZE(select_fileinfo_complete_table_resolved);
+ LOCAL_FINALIZE(select_full_path);
LOCAL_FINALIZE(insert_filename);
LOCAL_FINALIZE(insert_pathname);
LOCAL_FINALIZE(insert_hashes);
@@ -260,6 +263,7 @@ int prepare_statements() {
LOCAL_PREP_STMT("SELECT paths.pathname, filenames.name, hashes.blake2, hashes.sha256, hashes.sha512, fileinfo.size, fileinfo.last_seen, fileinfo.stat_struct FROM fileinfo INNER JOIN paths ON fileinfo.p_id = paths.id INNER JOIN filenames ON fileinfo.fn_id = filenames.id INNER JOIN hashes ON fileinfo.h_id = hashes.id WHERE fileinfo.fn_id = ?;", &select_fileinfo_by_filename_id_resolved);
LOCAL_PREP_STMT("SELECT p_id, fn_id, h_id, size, last_seen, stat_struct FROM fileinfo ;", &select_fileinfo_complete_table);
+ LOCAL_PREP_STMT("SELECT paths.pathname, filenames.name FROM fileinfo INNER JOIN paths ON fileinfo.p_id = paths.id INNER JOIN filenames ON fileinfo.fn_id = filenames.id ;", &select_full_path);
/* INSERT */
LOCAL_PREP_STMT("INSERT INTO filenames (name) VALUES (?);", &insert_filename);
@@ -1281,7 +1285,44 @@ int dbi_print_identical_filenames(FILE *out) {
return rc;
}
+int dbi_print_fullpaths(FILE *out) {
+ int rc = 0;
+ int strc = 0;
+ FILE *fd = out;
+ const unsigned char *txt = NULL;
+ sqlite3_stmt *st = select_full_path;
+
+ DBCONN_CHECK(-1);
+
+ if (fd == NULL) { fd = stdout; }
+ sqlite3_clear_bindings(st);
+ sqlite3_reset(st);
+ do {
+ strc = sqlite3_step(st);
+
+ if (strc == SQLITE_DONE) {
+ break;
+ }
+
+ if (strc != SQLITE_ROW) {
+ LOGERR("ERROR: Failed step to get fileinfo content: %s\n", sqlite3_errmsg(dbconn));
+ return -1; /* drop-it */
+ }
+
+ txt = sqlite3_column_text(st, 0); /* paths.pathname */
+ fprintf(fd, "%s/", txt);
+ txt = sqlite3_column_text(st, 1); /* filenames.name */
+ fprintf(fd, "%s\n", txt);
+ } while (strc == SQLITE_ROW);
+
+
+ sqlite3_clear_bindings(st);
+ sqlite3_reset(st);
+
+ return rc;
+
+}
#if 0
*select_fileinfo_by_id,
diff --git a/src/duplicate_finder.c b/src/duplicate_finder.c
index c6843f0..51bac49 100644
--- a/src/duplicate_finder.c
+++ b/src/duplicate_finder.c
@@ -16,6 +16,7 @@
*/
#include <stdlib.h>
+#include <string.h>
#include "trace_macros.h"
#include "options.h"
@@ -30,6 +31,8 @@
/*=========== FUNCTIONS ===========*/
int analyze_db_content();
int scan (const char *path);
+int dump(int argc, char **argv, int pos);
+
/**
* The wrapper around automated DB content analysis.
@@ -72,8 +75,45 @@ int analyze_db_content() {
/**
+ * dump requested database content
+ * @param argv argv array from main()
+ * @param pos The position where to begin in the array
+ * @param argc The array size from main()
+ *
+ * @return EXIT_SUCCESS on success
+ * EXIT_FAILURE on failure
+ */
+int dump(int argc, char **argv, int pos) {
+ int i = pos;
+
+ if (pos >= argc) {
+ LOGERR("ERROR: Missing parameter\n");
+ return EXIT_FAILURE;
+ }
+
+ if ( ! dbi_open(option_sqlite_db_name) ) {
+ return EXIT_FAILURE;
+ }
+
+ for (i=pos; i<argc; i++) {
+ if (strcmp("fullpath", argv[i]) == 0) {
+ dbi_print_fullpaths(stdout);
+ }
+
+ if (option_show_non_duplicates ||
+ strcmp("fileinfos", argv[i]) == 0) {
+ dbi_print_fileinfo_resolved(stdout);
+ }
+ }
+
+ dbi_close();
+ return EXIT_SUCCESS;
+}
+
+/**
* Scan the given path...
*
+ * @path path to scan
* @return EXIT_SUCCESS on success
* EXIT_FAILURE on failure
*/
@@ -123,6 +163,10 @@ int main(int argc, char **argv) {
return scan((path_index == argc) ? "." : argv[path_index] );
}
+ if (option_mode == MODE_DUMP) {
+ return dump(argc, argv, path_index);
+ }
+
if (option_mode == MODE_ANALYZE_DB) {
return analyze_db_content();
}
diff --git a/src/options.c b/src/options.c
index 3c8023c..7bcd9b0 100644
--- a/src/options.c
+++ b/src/options.c
@@ -39,7 +39,7 @@ char *exec_name;
/* === IMPLEMENTATION === */
void usage(char *executable) {
- fprintf(stderr, "Call: %s OPTIONS scan|analyze [path]\n", executable);
+ fprintf(stderr, "Call: %s OPTIONS scan|analyze|dump PARAMETERS\n", executable);
fprintf(stderr, "\nOPTIONS are\n");
/* long name, short name, optional argument, explanation */
fprintf(stderr, " %-25s %2s %10s - %s\n", "--all", "-a", "",
@@ -54,6 +54,12 @@ void usage(char *executable) {
"If the kv storage file already exists replace it with a new one");
fprintf(stderr, " %-25s %2s %10s - %s\n", "--quiet", "-q", "",
"Don't print error messages or warnings");
+
+ fprintf(stderr, "\nParameters\n");
+ fprintf(stderr, " %-10s %-10s %s\n", "analyze", "", "Currently no parameter");
+ fprintf(stderr, " %-10s %-10s %s\n", "dump", "fullpath", "Print the full stored path of each files entry");
+ fprintf(stderr, " %-10s %-10s %s\n", "", "fileinfos", "Print all entries combined with hashes");
+ fprintf(stderr, " %-10s %-10s %s\n", "scan", "", "path in the FS below which files should be scanned");
}
@@ -160,6 +166,8 @@ int parse_arguments(int argc, char **argv) {
option_mode = MODE_SCAN;
} else if (strcmp("analyze", argv[optind]) == 0) {
option_mode = MODE_ANALYZE_DB;
+ } else if (strcmp("dump", argv[optind]) == 0) {
+ option_mode = MODE_DUMP;
} else {
LOGERR("ERROR: No valid mode given see --help or man.\n");
exit(EXIT_FAILURE);