Projects
Mega:24.09
fdupes
Sign Up
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 2
View file
_service:tar_scm:fdupes.spec
Changed
@@ -3,7 +3,7 @@ Name: fdupes Epoch: 1 -Version: 2.2.1 +Version: 2.3.1 Release: 1 Summary: Identifying duplicate files residing within specified directories @@ -17,6 +17,7 @@ BuildRequires: automake BuildRequires: ncurses-devel BuildRequires: pcre2-devel +BuildRequires: sqlite-devel %description FDUPES is a program for identifying duplicate files residing within specified @@ -30,7 +31,7 @@ # From README. %{__cat} << EOF > LICENSE -FDUPES Copyright (c) 1999 Adrian Lopez +FDUPES Copyright (c) 1999-2022 Adrian Lopez Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files @@ -81,6 +82,14 @@ %{_mandir}/man7/%{name}*.7* %changelog +* Tue Jul 02 2024 yaoxin <yao_xin001@hoperun.com> - 1:2.3.1-1 +- Update to 2.3.1 + * Fix buffer overflow bug in getrealpath() function. + * Add --cache option to speed up file comparisons. + * Use nanosecond precision for file times, if available. + * Fix compilation issue on OpenBSD. + * Other changes like fixing typos, wording, etc. + * Wed May 10 2023 xu_ping <707078654@qq.com> - 1:2.2.1-1 - Upgrade package to 2.2.1 version
View file
_service
Changed
@@ -2,7 +2,7 @@ <service name="tar_scm"> <param name="scm">git</param> <param name="url">git@gitee.com:src-openeuler/fdupes.git</param> - <param name="revision">master</param> + <param name="revision">openEuler-24.09</param> <param name="exclude">*</param> <param name="extract">*</param> </service>
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/CHANGES -> _service:tar_scm:fdupes-2.3.1.tar.gz/CHANGES
Changed
@@ -6,6 +6,17 @@ those who've otherwise worked on that item. For a list of contributors names and identifiers please see the CONTRIBUTORS file. +Changes from 2.3.0 to 2.3.1: + + - Fix buffer overflow bug in getrealpath() function. + +Changes from 2.2.1 to 2.3.0: + + - Add --cache option to speed up file comparisons. + - Use nanosecond precision for file times, if available. + - Fix compilation issue on OpenBSD. + - Other changes like fixing typos, wording, etc. + Changes from 2.2.0 to 2.2.1: - Fix bug in code meant to skip over the current log file when --log
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/Makefile.am -> _service:tar_scm:fdupes-2.3.1.tar.gz/Makefile.am
Changed
@@ -47,7 +47,19 @@ positive_wcwidth.c\ positive_wcwidth.h dist_man7_MANS = fdupes-help.7 +endif +if WITH_SQLITE +fdupes_SOURCES += getrealpath.c\ + getrealpath.h\ + sdirname.c\ + sdirname.h\ + sbasename.c\ + sbasename.h\ + xdgbase.c\ + xdgbase.h\ + hashdb.c\ + hashdb.h endif EXTRA_DIST = testdir CHANGES CONTRIBUTORS
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/Makefile.in -> _service:tar_scm:fdupes-2.3.1.tar.gz/Makefile.in
Changed
@@ -109,6 +109,17 @@ @WITH_NCURSES_TRUE@ positive_wcwidth.c\ @WITH_NCURSES_TRUE@ positive_wcwidth.h +@WITH_SQLITE_TRUE@am__append_2 = getrealpath.c\ +@WITH_SQLITE_TRUE@ getrealpath.h\ +@WITH_SQLITE_TRUE@ sdirname.c\ +@WITH_SQLITE_TRUE@ sdirname.h\ +@WITH_SQLITE_TRUE@ sbasename.c\ +@WITH_SQLITE_TRUE@ sbasename.h\ +@WITH_SQLITE_TRUE@ xdgbase.c\ +@WITH_SQLITE_TRUE@ xdgbase.h\ +@WITH_SQLITE_TRUE@ hashdb.c\ +@WITH_SQLITE_TRUE@ hashdb.h + subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac @@ -136,7 +147,9 @@ ncurses-print.c ncurses-print.h ncurses-prompt.c \ ncurses-prompt.h ncurses-status.c ncurses-status.h \ commandidentifier.c commandidentifier.h wcs.c wcs.h \ - positive_wcwidth.c positive_wcwidth.h + positive_wcwidth.c positive_wcwidth.h getrealpath.c \ + getrealpath.h sdirname.c sdirname.h sbasename.c sbasename.h \ + xdgbase.c xdgbase.h hashdb.c hashdb.h am__dirstamp = $(am__leading_dot)dirstamp @WITH_NCURSES_TRUE@am__objects_1 = fileaction.$(OBJEXT) \ @WITH_NCURSES_TRUE@ ncurses-commands.$(OBJEXT) \ @@ -147,11 +160,14 @@ @WITH_NCURSES_TRUE@ ncurses-status.$(OBJEXT) \ @WITH_NCURSES_TRUE@ commandidentifier.$(OBJEXT) wcs.$(OBJEXT) \ @WITH_NCURSES_TRUE@ positive_wcwidth.$(OBJEXT) +@WITH_SQLITE_TRUE@am__objects_2 = getrealpath.$(OBJEXT) \ +@WITH_SQLITE_TRUE@ sdirname.$(OBJEXT) sbasename.$(OBJEXT) \ +@WITH_SQLITE_TRUE@ xdgbase.$(OBJEXT) hashdb.$(OBJEXT) am_fdupes_OBJECTS = fdupes.$(OBJEXT) errormsg.$(OBJEXT) dir.$(OBJEXT) \ log.$(OBJEXT) fmatch.$(OBJEXT) sigint.$(OBJEXT) \ flags.$(OBJEXT) confirmmatch.$(OBJEXT) \ removeifnotchanged.$(OBJEXT) mbstowcs_escape_invalid.$(OBJEXT) \ - md5/md5.$(OBJEXT) $(am__objects_1) + md5/md5.$(OBJEXT) $(am__objects_1) $(am__objects_2) fdupes_OBJECTS = $(am_fdupes_OBJECTS) fdupes_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) @@ -173,15 +189,17 @@ ./$(DEPDIR)/confirmmatch.Po ./$(DEPDIR)/dir.Po \ ./$(DEPDIR)/errormsg.Po ./$(DEPDIR)/fdupes.Po \ ./$(DEPDIR)/fileaction.Po ./$(DEPDIR)/flags.Po \ - ./$(DEPDIR)/fmatch.Po ./$(DEPDIR)/log.Po \ + ./$(DEPDIR)/fmatch.Po ./$(DEPDIR)/getrealpath.Po \ + ./$(DEPDIR)/hashdb.Po ./$(DEPDIR)/log.Po \ ./$(DEPDIR)/mbstowcs_escape_invalid.Po \ ./$(DEPDIR)/ncurses-commands.Po \ ./$(DEPDIR)/ncurses-getcommand.Po \ ./$(DEPDIR)/ncurses-interface.Po ./$(DEPDIR)/ncurses-print.Po \ ./$(DEPDIR)/ncurses-prompt.Po ./$(DEPDIR)/ncurses-status.Po \ ./$(DEPDIR)/positive_wcwidth.Po \ - ./$(DEPDIR)/removeifnotchanged.Po ./$(DEPDIR)/sigint.Po \ - ./$(DEPDIR)/wcs.Po md5/$(DEPDIR)/md5.Po + ./$(DEPDIR)/removeifnotchanged.Po ./$(DEPDIR)/sbasename.Po \ + ./$(DEPDIR)/sdirname.Po ./$(DEPDIR)/sigint.Po \ + ./$(DEPDIR)/wcs.Po ./$(DEPDIR)/xdgbase.Po md5/$(DEPDIR)/md5.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -372,7 +390,8 @@ log.c log.h fmatch.c fmatch.h sigint.c sigint.h flags.c \ flags.h confirmmatch.c confirmmatch.h removeifnotchanged.c \ removeifnotchanged.h mbstowcs_escape_invalid.c \ - mbstowcs_escape_invalid.h md5/md5.c md5/md5.h $(am__append_1) + mbstowcs_escape_invalid.h md5/md5.c md5/md5.h $(am__append_1) \ + $(am__append_2) dist_man1_MANS = fdupes.1 @WITH_NCURSES_TRUE@dist_man7_MANS = fdupes-help.7 EXTRA_DIST = testdir CHANGES CONTRIBUTORS @@ -498,6 +517,8 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileaction.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flags.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmatch.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getrealpath.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hashdb.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbstowcs_escape_invalid.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ncurses-commands.Po@am__quote@ # am--include-marker @@ -508,8 +529,11 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ncurses-status.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/positive_wcwidth.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/removeifnotchanged.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sbasename.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sdirname.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sigint.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wcs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdgbase.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@md5/$(DEPDIR)/md5.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @@ -897,6 +921,8 @@ -rm -f ./$(DEPDIR)/fileaction.Po -rm -f ./$(DEPDIR)/flags.Po -rm -f ./$(DEPDIR)/fmatch.Po + -rm -f ./$(DEPDIR)/getrealpath.Po + -rm -f ./$(DEPDIR)/hashdb.Po -rm -f ./$(DEPDIR)/log.Po -rm -f ./$(DEPDIR)/mbstowcs_escape_invalid.Po -rm -f ./$(DEPDIR)/ncurses-commands.Po @@ -907,8 +933,11 @@ -rm -f ./$(DEPDIR)/ncurses-status.Po -rm -f ./$(DEPDIR)/positive_wcwidth.Po -rm -f ./$(DEPDIR)/removeifnotchanged.Po + -rm -f ./$(DEPDIR)/sbasename.Po + -rm -f ./$(DEPDIR)/sdirname.Po -rm -f ./$(DEPDIR)/sigint.Po -rm -f ./$(DEPDIR)/wcs.Po + -rm -f ./$(DEPDIR)/xdgbase.Po -rm -f md5/$(DEPDIR)/md5.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ @@ -965,6 +994,8 @@ -rm -f ./$(DEPDIR)/fileaction.Po -rm -f ./$(DEPDIR)/flags.Po -rm -f ./$(DEPDIR)/fmatch.Po + -rm -f ./$(DEPDIR)/getrealpath.Po + -rm -f ./$(DEPDIR)/hashdb.Po -rm -f ./$(DEPDIR)/log.Po -rm -f ./$(DEPDIR)/mbstowcs_escape_invalid.Po -rm -f ./$(DEPDIR)/ncurses-commands.Po @@ -975,8 +1006,11 @@ -rm -f ./$(DEPDIR)/ncurses-status.Po -rm -f ./$(DEPDIR)/positive_wcwidth.Po -rm -f ./$(DEPDIR)/removeifnotchanged.Po + -rm -f ./$(DEPDIR)/sbasename.Po + -rm -f ./$(DEPDIR)/sdirname.Po -rm -f ./$(DEPDIR)/sigint.Po -rm -f ./$(DEPDIR)/wcs.Po + -rm -f ./$(DEPDIR)/xdgbase.Po -rm -f md5/$(DEPDIR)/md5.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/README -> _service:tar_scm:fdupes-2.3.1.tar.gz/README
Changed
@@ -19,6 +19,19 @@ option will change this behavior -G --minsize=SIZE consider only files greater than or equal to SIZE bytes -L --maxsize=SIZE consider only files less than or equal to SIZE bytes + -c --cache speed up file comparisons by keeping track of their + signatures in a database; additional parameters may be + provided using one or more cache parameters (as below) + -x cache.OPTION supply an optional cache parameter, where OPTION is one + of the keywords below and multiple options may be + supplied via successive -x arguments: + readonly read but do not update file signatures + prune look through entire cache and delete orphaned entries + clear clear all entries from cache + vacuum reduce size of DB file, if possible + (note that the options prune, clear, and vacuum may be + employed without supplying a DIRECTORY argument, and + will take effect even if readonly is also specified) -n --noempty exclude zero-length files from consideration -A --nohidden exclude hidden files from consideration -f --omitfirst omit the first file in each set of matches
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/config.h.in -> _service:tar_scm:fdupes-2.3.1.tar.gz/config.h.in
Changed
@@ -3,6 +3,15 @@ /* number of bytes to read per read call */ #undef CHUNK_SIZE +/* default subdirectory for fdupes config files */ +#undef FDUPES_CACHE_DIRECTORY + +/* directory permissions for fdupes config directory */ +#undef FDUPES_CACHE_DIRECTORY_PERMISSIONS + +/* filename for fdupes hash database */ +#undef FDUPES_HASH_DATABASE_NAME + /* Define to 1 if you have the <getopt.h> header file. */ #undef HAVE_GETOPT_H @@ -15,6 +24,9 @@ /* Define to 1 if you have the <ncursesw/curses.h> header file. */ #undef HAVE_NCURSESW_CURSES_H +/* stat supports nanosecond precision */ +#undef HAVE_NSEC_TIMES + /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H @@ -45,6 +57,9 @@ /* Do not compile against ncurses */ #undef NO_NCURSES +/* Do not compile against sqlite */ +#undef NO_SQLITE + /* Name of package */ #undef PACKAGE @@ -84,7 +99,7 @@ /* enable strtoll */ #undef _ISOC99_SOURCE -/* enable certain functions in wchar.h */ +/* enable certain X/Open and POSIX features */ #undef _XOPEN_SOURCE /* enable certain functions in curses.h */
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/configure -> _service:tar_scm:fdupes-2.3.1.tar.gz/configure
Changed
@@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for fdupes 2.2.1. +# Generated by GNU Autoconf 2.69 for fdupes 2.3.1. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ # Identity of this package. PACKAGE_NAME='fdupes' PACKAGE_TARNAME='fdupes' -PACKAGE_VERSION='2.2.1' -PACKAGE_STRING='fdupes 2.2.1' +PACKAGE_VERSION='2.3.1' +PACKAGE_STRING='fdupes 2.3.1' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -622,6 +622,8 @@ am__EXEEXT_TRUE LTLIBOBJS LIBOBJS +WITH_SQLITE_FALSE +WITH_SQLITE_TRUE WITH_NCURSES_FALSE WITH_NCURSES_TRUE NCURSES_LIBS @@ -719,8 +721,9 @@ ac_user_opts=' enable_option_checking enable_silent_rules -with_ncurses enable_dependency_tracking +with_ncurses +with_sqlite ' ac_precious_vars='build_alias host_alias @@ -1286,7 +1289,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures fdupes 2.2.1 to adapt to many kinds of systems. +\`configure' configures fdupes 2.3.1 to adapt to many kinds of systems. Usage: $0 OPTION... VAR=VALUE... @@ -1353,7 +1356,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of fdupes 2.2.1:";; + short | recursive ) echo "Configuration of fdupes 2.3.1:";; esac cat <<\_ACEOF @@ -1372,6 +1375,7 @@ --with-PACKAGE=ARG use PACKAGE ARG=yes --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-ncurses Do not use ncurses interface + --without-sqlite Do not use sqlite database Some influential environment variables: PKG_CONFIG path to pkg-config utility @@ -1458,7 +1462,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -fdupes configure 2.2.1 +fdupes configure 2.3.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1756,7 +1760,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by fdupes $as_me 2.2.1, which was +It was created by fdupes $as_me 2.3.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2620,7 +2624,7 @@ # Define the identity of the package. PACKAGE='fdupes' - VERSION='2.2.1' + VERSION='2.3.1' cat >>confdefs.h <<_ACEOF @@ -2840,13 +2844,6 @@ fi fi - -# Check whether --with-ncurses was given. -if test "${with_ncurses+set}" = set; then : - withval=$with_ncurses; -fi - - DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" @@ -3887,6 +3884,47 @@ +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #define _XOPEN_SOURCE 700 + #include <sys/types.h> + #include <sys/stat.h> + #include <unistd.h> + +int +main () +{ + + struct stat st; + st.st_ctim.tv_nsec = 0; + st.st_mtim.tv_nsec = 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +$as_echo "#define HAVE_NSEC_TIMES 1" >>confdefs.h + + +$as_echo "#define _XOPEN_SOURCE 700" >>confdefs.h + + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +# +# NCURSES library +# + +# Check whether --with-ncurses was given. +if test "${with_ncurses+set}" = set; then : + withval=$with_ncurses; +fi + + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -4297,7 +4335,6 @@ done - if test x"$with_ncurses" != x"no"; then : pkg_failed=no @@ -4603,7 +4640,7 @@ LIBS="$LIBS $NCURSES_LIBS" fi -$as_echo "#define _XOPEN_SOURCE /**/" >>confdefs.h +$as_echo "#define _XOPEN_SOURCE 700" >>confdefs.h $as_echo "#define _XOPEN_SOURCE_EXTENDED /**/" >>confdefs.h @@ -4688,6 +4725,91 @@ fi +# +# SQLITE library +# + +# Check whether --with-sqlite was given. +if test "${with_sqlite+set}" = set; then : + withval=$with_sqlite; +fi + + +if test x"$with_sqlite" != x"no"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sqlite3_prepare_v2" >&5 +$as_echo_n "checking for library containing sqlite3_prepare_v2... " >&6; } +if ${ac_cv_search_sqlite3_prepare_v2+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C"
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/configure.ac -> _service:tar_scm:fdupes-2.3.1.tar.gz/configure.ac
Changed
@@ -1,4 +1,4 @@ -AC_INIT(fdupes, 2.2.1) +AC_INIT(fdupes, 2.3.1) AM_INIT_AUTOMAKE(foreign subdir-objects) @@ -8,17 +8,33 @@ PKG_PROG_PKG_CONFIG +AC_COMPILE_IFELSE(AC_LANG_PROGRAM( + #define _XOPEN_SOURCE 700 + #include <sys/types.h> + #include <sys/stat.h> + #include <unistd.h> +, + struct stat st; + st.st_ctim.tv_nsec = 0; + st.st_mtim.tv_nsec = 0; +), + AC_DEFINE(HAVE_NSEC_TIMES, 1, stat supports nanosecond precision) + AC_DEFINE(_XOPEN_SOURCE, 700, enable certain X/Open and POSIX features) +) + +# +# NCURSES library +# AC_ARG_WITH(ncurses, AS_HELP_STRING(--without-ncurses, Do not use ncurses interface)) AC_CHECK_HEADERS(getopt.h ncursesw/curses.h) - AS_IF(test x"$with_ncurses" != x"no", PKG_CHECK_MODULES(NCURSES, ncursesw, LIBS="$LIBS $NCURSES_LIBS", AC_SEARCH_LIBS(wget_wch, ncursesw ncurses curses, , AC_ERROR(ncurses library not found (or lacks wide character support))) AC_SEARCH_LIBS(keypad, ncursesw tinfow ncurses tinfo curses, , AC_ERROR(ncurses library not found (lacks keypad support))) ) - AC_DEFINE(_XOPEN_SOURCE, , enable certain functions in wchar.h) + AC_DEFINE(_XOPEN_SOURCE, 700, enable certain X/Open and POSIX features) AC_DEFINE(_XOPEN_SOURCE_EXTENDED, , enable certain functions in curses.h) AC_DEFINE(_ISOC99_SOURCE, , enable strtoll) AC_SEARCH_LIBS(pcre2_match_32, pcre2-32, , AC_ERROR(pcre2 library not found)) @@ -29,6 +45,19 @@ AM_CONDITIONAL(WITH_NCURSES, test x"$with_ncurses" != x"no") +# +# SQLITE library +# +AC_ARG_WITH(sqlite, AS_HELP_STRING(--without-sqlite, Do not use sqlite database)) + +AS_IF(test x"$with_sqlite" != x"no", + AC_SEARCH_LIBS(sqlite3_prepare_v2, sqlite3, , AC_ERROR(sqlite3 library not found)), + + AC_DEFINE(NO_SQLITE, , Do not compile against sqlite) + ) + +AM_CONDITIONAL(WITH_SQLITE, test x"$with_sqlite" != x"no") + unescaped_program_transform_name=`echo "${program_transform_name}"|sed -e "s&\\\\$\\\\$&\\\\$&g"` transformed_program_name=`echo "${PACKAGE_NAME}"|sed -e "${unescaped_program_transform_name}"|sed -e "s&\\\\\\\\&\\\\\\\\\\\\\\\\&g"` transformed_manpage_name=`echo "${PACKAGE_NAME}-help"|sed -e "${unescaped_program_transform_name}"` @@ -41,6 +70,10 @@ AC_DEFINE(PARTIAL_MD5_SIZE, 4096, maximum number of bytes to use when calculating partial hashes) AC_DEFINE(INPUT_SIZE, 256, size of command buffer (plain interactive mode only)) +AC_DEFINE(FDUPES_CACHE_DIRECTORY, "fdupes", default subdirectory for fdupes config files) +AC_DEFINE(FDUPES_CACHE_DIRECTORY_PERMISSIONS, 0700, directory permissions for fdupes config directory) +AC_DEFINE(FDUPES_HASH_DATABASE_NAME, "hash.db", filename for fdupes hash database) + AC_CONFIG_FILES(Makefile) AC_PROG_CC AC_OUTPUT
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/confirmmatch.c -> _service:tar_scm:fdupes-2.3.1.tar.gz/confirmmatch.c
Changed
@@ -20,7 +20,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" +#include "sigint.h" #include "confirmmatch.h" +#include <stdlib.h> #include <memory.h> /* Do a bit-for-bit comparison in case two different files produce the @@ -37,6 +39,12 @@ fseek(file2, 0, SEEK_SET); do { + if (got_sigint) { + fclose(file1); + fclose(file2); + exit(0); + } + r1 = fread(c1, sizeof(unsigned char), sizeof(c1), file1); r2 = fread(c2, sizeof(unsigned char), sizeof(c2), file2);
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/fdupes.1 -> _service:tar_scm:fdupes-2.3.1.tar.gz/fdupes.1
Changed
@@ -19,89 +19,119 @@ .SH OPTIONS .TP .B -r --recurse -for every directory given follow subdirectories encountered within +For every directory given follow subdirectories encountered within. .TP .B -R --recurse: -for each directory given after this option follow subdirectories +For each directory given after this option follow subdirectories encountered within (note the ':' at the end of option; see the -Examples section below for further explanation) +Examples section below for further explanation). .TP .B -s --symlinks -follow symlinked directories +Follow symlinked directories. .TP .B -H --hardlinks -normally, when two or more files point to the same disk area they are -treated as non-duplicates; this option will change this behavior +Normally, when two or more files point to the same disk area they are +treated as non-duplicates; this option will change this behavior. .TP .B -G --minsize\fR=\fISIZE\fR -consider only files greater than or equal to SIZE in bytes +Consider only files greater than or equal to SIZE in bytes. .TP -.B -L --maxsize=\fR=\fISIZE\fR -consider only files less than or equal to SIZE in bytes +.B -L --maxsize\fR=\fISIZE\fR +Consider only files less than or equal to SIZE in bytes. +.TP +.B -c --cache +Speed up file comparisons by keeping track of their signatures in a +database; additional parameters may be provided using one or more +cache parameters (as indicated below). Please note that this option +may not be available on some systems. +.TP +.B -x cache.\fIOPTION\fR +Supply an optional cache parameter, where OPTION is one of the keywords +below and multiple options may be supplied via successive -x arguments: + + \fIreadonly\fR + read but do not update file signatures + + \fIprune\fR + look through entire cache and delete orphaned entries + + \fIclear\fR + clear all entries from cache + + \fIvacuum\fR + reduce size of DB file, if possible + +The options prune, clear, and vacuum may be employed without +supplying a DIRECTORY argument, and will take effect even if readonly +is also specified. The order of operations is always clear, prune, +update signatures (unless readonly), and vacuum. .TP .B -n --noempty -exclude zero-length files from consideration +Exclude zero-length files from consideration. .TP .B -A --nohidden -exclude hidden files from consideration +Exclude hidden files from consideration. .TP .B -f --omitfirst -omit the first file in each set of matches +Omit the first file in each set of matches. .TP .B -1 --sameline -list each set of matches on a single line +List each set of matches on a single line. .TP .B -S --size -show size of duplicate files +Show size of duplicate files. .TP .B -t --time -show modification time of duplicate files +Show modification time of duplicate files. .TP .B -m --summarize -summarize duplicate file information +Summarize duplicate file information. .TP .B -q --quiet -hide progress indicator +Hide progress indicator. .TP .B -d --delete -prompt user for files to preserve, deleting all others (see +Prompt user for files to preserve, deleting all others (see .B CAVEATS -below) +below). .TP .B -D --deferconfirmation -in interactive mode, defer byte-for-byte confirmation of -duplicates until just before file deletion +In interactive mode, defer byte-for-byte confirmation of +duplicates until just before file deletion. .TP .B -P --plain -with --delete, use line-based prompt (as with older versions of -fdupes) instead of screen-mode interface +With --delete, use a line-based prompt (as with older versions of +fdupes) instead of the new screen-mode interface. On installations +where the screen-mode interface is not supported, fdupes will +default to a line-based prompt. .TP .B -N --noprompt -when used together with \-\-delete, preserve the first file in each -set of duplicates and delete the others without prompting the user +When used together with \-\-delete, preserve the first file in each +set of duplicates and delete the others without prompting the user. .TP .B -I --immediate -delete duplicates as they are encountered, without -grouping into sets; implies --noprompt +Delete duplicates as they are encountered, without +grouping into sets; implies --noprompt. .TP .B -p --permissions -don't consider files with different owner/group or permission bits as duplicates +Don't consider files with different owner/group or permission bits as duplicates. .TP .B -o --order\fR=\fIWORD\fR -order files according to WORD: -time - sort by modification time, ctime - sort by status change time, name - sort by filename +Order files according to WORD: +time - sort by modification time, ctime - sort by status change time, name - sort by +filename. .TP .B -i --reverse -reverse order while sorting +Reverse order while sorting. .TP .B -l --log\fR=\fILOGFILE\fR -log file deletion choices to LOGFILE +Log file deletion choices to LOGFILE. .TP .B -v --version -display fdupes version +Display fdupes version. .TP .B -h --help -displays help +Display help. .SH NOTES Unless .B -1 @@ -121,10 +151,10 @@ .SH EXAMPLES .TP .B fdupes a --recurse: b -will follow subdirectories under b, but not those under a. +Will follow subdirectories under b, but not those under a. .TP .B fdupes a --recurse b -will follow subdirectories under both a and b. +Will follow subdirectories under both a and b. .SH CAVEATS When using
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/fdupes.c -> _service:tar_scm:fdupes-2.3.1.tar.gz/fdupes.c
Changed
@@ -19,6 +19,11 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +// todo: indicate error when options that dont ignore DIRECTORY are specified? +// todo: detect entries that have changed FROM S_ISREG to S_ISDIR? +// todo: got_sigint path bypasses free()-ing of certain structures +// todo: free oldargv on error + #include "config.h" #include <stdio.h> #include <stdarg.h> @@ -50,18 +55,30 @@ #include "sigint.h" #include "flags.h" #include "removeifnotchanged.h" +#ifndef NO_SQLITE +#define FDUPES_DATABASE_DIRECTORY FDUPES_CACHE_DIRECTORY "/" FDUPES_HASH_DATABASE_NAME + #include "hashdb.h" + #include "getrealpath.h" + #include "xdgbase.h" +#endif + +char *program_name; long long minsize = -1; long long maxsize = -1; +#ifndef NO_SQLITE +sqlite3 *db; +#endif + +struct log_info *loginfo; + typedef enum { ORDER_MTIME = 0, ORDER_CTIME, ORDER_NAME } ordertype_t; -char *program_name; - ordertype_t ordertype = ORDER_MTIME; #define MD5_DIGEST_LENGTH 16 @@ -165,8 +182,8 @@ } /* Find the first non-option argument after specified option. */ -int nonoptafter(char *option, int argc, char **oldargv, - char **newargv, int optind) +int nonoptafter(char *option, int argc, char **oldargv, + char **newargv, int optind, int *foundoption) { int x; int targetind; @@ -174,7 +191,9 @@ int startat = 1; targetind = findarg(option, 1, argc, oldargv); - + + *foundoption = targetind < argc; + for (x = optind; x < argc; x++) { testind = findarg(newargvx, startat, argc, oldargv); if (testind > targetind) return x; @@ -191,8 +210,56 @@ file->device = info->st_dev; file->ctime = info->st_ctime; file->mtime = info->st_mtime; +#ifdef HAVE_NSEC_TIMES + file->ctime_nsec = info->st_ctim.tv_nsec; + file->mtime_nsec = info->st_mtim.tv_nsec; +#else + file->ctime_nsec = 0; + file->mtime_nsec = 0; +#endif +} + +#ifndef NO_SQLITE +int delist_hash_if_orphaned(const sqlite3_int64 directoryid, const char *filename, const char *directory) +{ + const char *path; + char *fullpath; + + if (got_sigint) + return 0; + + fullpath = malloc(strlen(directory) + strlen(filename) + 2); + if (fullpath == 0) { + errormsg("out of memory!\n"); + exit(1); + } + + strcpy(fullpath, directory); + strcat(fullpath, "/"); + strcat(fullpath, filename); + + if (access(fullpath, F_OK) != 0) + hashdb_deletehash(db, directoryid, filename); + + free(fullpath); + + return 1; } +int delist_directory_if_missing(const sqlite3_int64 directoryid, const char *name, const char *full_path, const sqlite3_int64 parent) +{ + struct stat st; + + if (got_sigint) + return 0; + + if (lstat(full_path, &st) != 0 || !S_ISDIR(st.st_mode)) + return hashdb_deletedirectory(db, directoryid); + + return 1; +} +#endif + int grokdir(char *dir, file_t **filelistp, struct stat *logfile_status) { DIR *cd; @@ -200,11 +267,16 @@ struct dirent *dirinfo; int lastchar; int filecount = 0; + int filesadded; struct stat info; struct stat linfo; static int progress = 0; static char indicator = "-\\|/"; char *fullname, *name; + char *fullpath = 0; +#ifndef NO_SQLITE + sqlite3_int64 pathid = 0; +#endif cd = opendir(dir); @@ -213,7 +285,26 @@ return 0; } +#ifndef NO_SQLITE + if (db != 0) { + fullpath = getrealpath(dir, 0); + + if (fullpath && !ISFLAG(flags, F_READONLYCACHE)) { + if (hashdb_getdirectoryid(db, fullpath, &pathid)) { + hashdb_foreachdirectory(db, &pathid, delist_directory_if_missing); + hashdb_foreachhash(db, &pathid, delist_hash_if_orphaned); + } + } + } +#endif + while ((dirinfo = readdir(cd)) != NULL) { + if (got_sigint) { + closedir(cd); + printf("\n"); + exit(0); + } + if (strcmp(dirinfo->d_name, ".") && strcmp(dirinfo->d_name, "..")) { if (!ISFLAG(flags, F_HIDEPROGRESS)) { fprintf(stderr, "\rBuilding file list %c ", indicatorprogress); @@ -296,8 +387,16 @@ } if (S_ISDIR(info.st_mode)) { - if (ISFLAG(flags, F_RECURSE) && (ISFLAG(flags, F_FOLLOWLINKS) || !S_ISLNK(linfo.st_mode))) - filecount += grokdir(newfile->d_name, filelistp, logfile_status); + if (ISFLAG(flags, F_RECURSE) && (ISFLAG(flags, F_FOLLOWLINKS) || !S_ISLNK(linfo.st_mode))) + { + filesadded = grokdir(newfile->d_name, filelistp, logfile_status); + filecount += filesadded; + +#ifndef NO_SQLITE + if (db != 0 && pathid == 0 && !ISFLAG(flags, F_READONLYCACHE) && filesadded > 0) + hashdb_savedirectory(db, fullpath); +#endif + } free(newfile->d_name); free(newfile); } else { @@ -313,6 +412,9 @@ } } + if (fullpath) + free(fullpath); + closedir(cd); return filecount; @@ -322,12 +424,18 @@ { off_t toread;
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/fdupes.h -> _service:tar_scm:fdupes-2.3.1.tar.gz/fdupes.h
Changed
@@ -22,6 +22,7 @@ #ifndef FDUPES_H #define FDUPES_H +#include "config.h" #include <sys/stat.h> #include "md5/md5.h" @@ -34,6 +35,8 @@ ino_t inode; time_t mtime; time_t ctime; + long mtime_nsec; + long ctime_nsec; int hasdupes; /* true only if file is first on duplicate chain */ struct _file *duplicates; struct _file *next;
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/flags.h -> _service:tar_scm:fdupes-2.3.1.tar.gz/flags.h
Changed
@@ -23,6 +23,12 @@ #define F_PLAINPROMPT 0x10000 #define F_SHOWTIME 0x20000 #define F_DEFERCONFIRMATION 0x40000 +#define F_CACHESIGNATURES 0x80000 +#define F_CLEARCACHE 0x100000 +#define F_PRUNECACHE 0x200000 +#define F_READONLYCACHE 0x400000 +#define F_VACUUMCACHE 0x800000 +#define F_SUMMARIZEFASTER 0x1000000 extern unsigned long flags;
View file
_service:tar_scm:fdupes-2.3.1.tar.gz/getrealpath.c
Added
@@ -0,0 +1,451 @@ +/* Copyright (c) 2022 Adrian Lopez + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. */ + +#include "config.h" +#include "getrealpath.h" +#include "dir.h" +#include "sdirname.h" +#include "sbasename.h" +#include <string.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#define ISFLAG(a,b) ((a & b) == b) + +#ifndef GETREALPATH_MAXSYMLINKS +#define GETREALPATH_MAXSYMLINKS 40 +#endif + +#define DEFAULT_LINK_ALLOCATION_SIZE 16 + +/* read link contents into buffer allocated via malloc() */ +char *getlink(const char *path, struct stat *s) +{ + char *link; + char *buffer; + size_t allocated; + int linksize; + + if (s->st_size > 0) + allocated = s->st_size + 1; + else + allocated = DEFAULT_LINK_ALLOCATION_SIZE; + + buffer = malloc(allocated); + if (buffer == 0) + return 0; + + do + { + link = buffer; + + linksize = readlink(path, link, allocated); + if (linksize == -1) + { + free(link); + return 0; + } + + if (linksize < allocated) + { + linklinksize = '\0'; + return link; + } + + if (stat(path, s) != 0) + { + free(link); + return 0; + } + + if (s->st_size != 0) + allocated = s->st_size + 1; + else + allocated *= 2; + } while (buffer = realloc(link, allocated)); + + free(link); + + return 0; +} + +/* replace destfrom .. through with contents of src */ +int replacestring(char *dest, size_t from, size_t through, size_t max, const char *src) +{ + size_t srclength; + size_t destlength; + size_t moveto; + size_t newlength; + + destlength = strlen(dest); + + if (through >= destlength || from > through) + return 0; + + srclength = strlen(src); + + newlength = destlength + srclength - (through - from + 1); + if (newlength > max) + return 0; + + memmove(dest + from + srclength, dest + through + 1, destlength - through); + + memcpy(dest + from, src, srclength); + + return 1; +} + +/* print the resolved absolute file name for the specified path */ +char *getrealpath(const char *path, unsigned int options) +{ + char *scratch; + char *cwd; + char *link; + char *newmem; + char *dirname; + char *basename; + char save; + size_t tail; + size_t next; + size_t pathlength; + size_t linklength; + size_t cwdlength; + size_t allocated; + size_t links; + size_t x; + struct stat st; + struct stat st0; + int pathexists; + + /* run stat on unmodified path, for later use */ + pathexists = stat(path, &st0) == 0; + if (!pathexists && !ISFLAG(options, GETREALPATH_IGNORE_MISSING_BASENAME)) + return 0; + + /* optionally ignore the last component if it does not exist */ + if (ISFLAG(options, GETREALPATH_IGNORE_MISSING_BASENAME) && !pathexists) + { + dirname = malloc(strlen(path) + 1); + if (dirname == 0) + return 0; + + basename = malloc(strlen(path) + 1); + if (basename == 0) + return 0; + + sdirname(dirname, path); + sbasename(basename, path); + + if (stat(dirname, &st0) != 0) + return 0; + + link = getrealpath(dirname, options ^ GETREALPATH_IGNORE_MISSING_BASENAME); + if (link == 0) + { + free(basename); + free(dirname); + return 0; + } + + scratch = malloc(strlen(link) + strlen(basename) + 2); + if (scratch == 0) + { + free(basename); + free(dirname); + return 0; + } + + strcpy(scratch, link); + strcat(scratch, "/"); + strcat(scratch, basename); + + if (stat(dirname, &st) != 0) + { + free(link); + free(basename); + free(dirname); + free(scratch); + return 0; + } + + free(link); + free(basename); + free(dirname); + + if + ( + st.st_dev != st0.st_dev || + st.st_ino != st0.st_ino + ) + { + free(scratch); + return 0;
View file
_service:tar_scm:fdupes-2.3.1.tar.gz/getrealpath.h
Added
@@ -0,0 +1,27 @@ +/* Copyright (c) 2022 Adrian Lopez + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. */ + +#ifndef GETREALPATH_H +#define GETREALPATH_H + +#define GETREALPATH_NONE 0b0 +#define GETREALPATH_IGNORE_MISSING_BASENAME 0b1 + +char *getrealpath(const char *path, unsigned int options); + +#endif \ No newline at end of file
View file
_service:tar_scm:fdupes-2.3.1.tar.gz/hashdb.c
Added
@@ -0,0 +1,752 @@ +/* FDUPES Copyright (c) 2022 Adrian Lopez + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "config.h" +#include <sqlite3.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <assert.h> +#include "hashdb.h" +#include "getrealpath.h" +#include "sbasename.h" +#include "sdirname.h" +#include "errormsg.h" + +#define DATABASE_VERSION 1 + +#define HASH_FUNCTION_MD5 1 + +#define HASH_FUNCTION HASH_FUNCTION_MD5 +#define HASH_FUNCTION_OUTPUT_LENGTH 16 + +void md5copy(md5_byte_t *to, const md5_byte_t *from); + +#define PREPARE_STATEMENT(a, b) sqlite3_prepare_v2(db, a, -1, hashdb__newstatement(&b), 0) + +#define HASHDB_MAX_STATEMENTS 32 + +sqlite3_stmt **hashdb_statementsHASHDB_MAX_STATEMENTS; + +size_t hashdb_statements_top; + +sqlite3_stmt *query_begintransaction = 0; +sqlite3_stmt *query_committransaction = 0; +sqlite3_stmt *query_rollbacktransaction = 0; +sqlite3_stmt *query_vacuum = 0; +sqlite3_stmt *query_getdirectoryid = 0; +sqlite3_stmt *query_insertdirectory = 0; +sqlite3_stmt *query_deletedirectory = 0; +sqlite3_stmt *query_cleardirectories = 0; +sqlite3_stmt *query_foreachdirectory = 0; +sqlite3_stmt *query_foreachdirectorywithin = 0; +sqlite3_stmt *query_loadhash = 0; +sqlite3_stmt *query_savehash = 0; +sqlite3_stmt *query_deletehash = 0; +sqlite3_stmt *query_deletehashforpath = 0; +sqlite3_stmt *query_foreachhash = 0; +sqlite3_stmt *query_foreachhashwithin = 0; + +sqlite3_stmt **hashdb__newstatement(sqlite3_stmt **statement) +{ + assert(hashdb_statements_top + 1 <= HASHDB_MAX_STATEMENTS); + + hashdb_statementshashdb_statements_top++ = statement; + + return statement; +} + +int hashdb__createtables(sqlite3 *db) +{ + int result; + + hashdb_begintransaction(db); + + result = sqlite3_exec(db, + "CREATE TABLE IF NOT EXISTS directories (" + " id INTEGER PRIMARY KEY," + " name TEXT," + " full_path TEXT UNIQUE," + " parent INTEGER REFERENCES directories(id) ON DELETE CASCADE" + ")", + 0, 0, 0); + + if (result != SQLITE_OK) + return result; + + result = sqlite3_exec(db, + "CREATE TABLE IF NOT EXISTS hashes (" + " directory_id INTEGER REFERENCES directories(id) ON DELETE CASCADE," + " filename TEXT," + " inode BLOB," + " size INTEGER," + " ctime BLOB," + " mtime BLOB," + " ctime_nsec INTEGER," + " mtime_nsec INTEGER," + " partial_hash BLOB," + " partial_hash_bytes INTEGER," + " hash BLOB," + " hash_function INTEGER," + " PRIMARY KEY (directory_id, filename)" + ")", + 0, 0, 0); + + if (result != SQLITE_OK) { + hashdb_rollbacktransaction(db); + return result; + } + + hashdb_committransaction(db); + + return SQLITE_OK; +} + +int hashdb__preparestatements(sqlite3 *db) +{ + int result; + + /* standard SQL commands */ + result = PREPARE_STATEMENT("BEGIN", query_begintransaction); + if (result != SQLITE_OK) + return result; + + result = PREPARE_STATEMENT("COMMIT", query_committransaction); + if (result != SQLITE_OK) + return result; + + result = PREPARE_STATEMENT("ROLLBACK", query_rollbacktransaction); + if (result != SQLITE_OK) + return result; + + result = PREPARE_STATEMENT("VACUUM", query_vacuum); + if (result != SQLITE_OK) + return result; + + /* directory operations */ + result = PREPARE_STATEMENT("SELECT id FROM directories WHERE full_path = ?", query_getdirectoryid); + if (result != SQLITE_OK) + return result; + + result = PREPARE_STATEMENT("INSERT INTO directories (name, full_path, parent) VALUES (?, ?, ?)", query_insertdirectory); + if (result != SQLITE_OK) + return result; + + result = PREPARE_STATEMENT("DELETE FROM directories WHERE id = ?", query_deletedirectory); + if (result != SQLITE_OK) + return result; + + result = PREPARE_STATEMENT("DELETE FROM directories", query_cleardirectories); + if (result != SQLITE_OK) + return result; + + result = PREPARE_STATEMENT("SELECT id, name, full_path, parent FROM directories", query_foreachdirectory); + if (result != SQLITE_OK) + return result; + + result = PREPARE_STATEMENT("SELECT id, name, full_path, parent FROM directories WHERE parent = :parent", query_foreachdirectorywithin); + if (result != SQLITE_OK) + return result; + + /* hash operations */ + result = PREPARE_STATEMENT("SELECT hashes.partial_hash, hashes.hash FROM hashes INNER JOIN directories ON hashes.directory_id = directories.id WHERE directories.full_path = ? AND hashes.filename = ? AND hashes.inode = ? AND hashes.size = ? AND hashes.ctime = ? AND hashes.mtime = ? AND hashes.ctime_nsec = ? AND hashes.mtime_nsec = ? AND hashes.partial_hash_bytes = ? AND hashes.hash_function = ?", query_loadhash); + if (result != SQLITE_OK) + return result; + + result = PREPARE_STATEMENT("INSERT OR REPLACE INTO hashes (directory_id, filename, inode, size, ctime, mtime, ctime_nsec, mtime_nsec, partial_hash, partial_hash_bytes, hash, hash_function) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", query_savehash); + if (result != SQLITE_OK) + return result; + + result = PREPARE_STATEMENT("DELETE FROM hashes WHERE directory_id = ? AND filename = ?", query_deletehash); + if (result != SQLITE_OK) + return result; + + result = PREPARE_STATEMENT("DELETE FROM hashes WHERE filename = ? AND directory_id IN (SELECT id FROM directories WHERE full_path = ?)", query_deletehashforpath); + if (result != SQLITE_OK) + return result; + + result = PREPARE_STATEMENT("SELECT hashes.directory_id, hashes.filename, directories.full_path AS directory FROM hashes INNER JOIN directories ON hashes.directory_id = directories.id", query_foreachhash); + if (result != SQLITE_OK) + return result; + + result = PREPARE_STATEMENT("SELECT hashes.directory_id, hashes.filename, directories.full_path AS directory FROM hashes INNER JOIN directories ON hashes.directory_id = directories.id WHERE directories.id = :directory_id", query_foreachhashwithin); + if (result != SQLITE_OK) + return result; + + return SQLITE_OK; +} + +void hashdb__finalizestatements() +{ + size_t s;
View file
_service:tar_scm:fdupes-2.3.1.tar.gz/hashdb.h
Added
@@ -0,0 +1,45 @@ +/* FDUPES Copyright (c) 2022 Adrian Lopez + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef HASHDB_H +#define HASHDB_H + +#include "fdupes.h" +#include <sqlite3.h> + +sqlite3 *hashdb_open(const char *path); +int hashdb_close(sqlite3 *db); +int hashdb_begintransaction(sqlite3 *db); +int hashdb_committransaction(sqlite3 *db); +int hashdb_rollbacktransaction(sqlite3 *db); +int hashdb_vacuum(sqlite3 *db); +int hashdb_getdirectoryid(sqlite3 *db, const char *path, sqlite3_int64 *directoryid); +int hashdb_savedirectory(sqlite3 *db, const char *path); +int hashdb_deletedirectory(sqlite3 *db, sqlite3_int64 id); +int hashdb_cleardirectories(sqlite3 *db); +int hashdb_foreachdirectory(sqlite3 *db, const sqlite3_int64 *parentid, int (*callback)(const sqlite3_int64, const char*, const char*, const sqlite3_int64)); +int hashdb_loadhash(sqlite3 *db, const file_t *entry, md5_byte_t **partialhash, md5_byte_t **fullhash); +int hashdb_savehash(sqlite3 *db, const file_t *entry, md5_byte_t *partialhash, md5_byte_t *fullhash); +int hashdb_foreachhash(sqlite3 *db, sqlite3_int64 *directoryid, int (*callback)(const sqlite3_int64, const char*, const char*)); +int hashdb_deletehash(sqlite3 *db, sqlite3_int64 directoryid, const char *filename); +int hashdb_deletehashforpath(sqlite3 *db, const char *path); + +#endif \ No newline at end of file
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/ncurses-commands.c -> _service:tar_scm:fdupes-2.3.1.tar.gz/ncurses-commands.c
Changed
@@ -30,9 +30,17 @@ #include "mbstowcs_escape_invalid.h" #include "log.h" #include "removeifnotchanged.h" +#ifndef NO_SQLITE + #include "hashdb.h" + #include "getrealpath.h" +#endif #include <wchar.h> #include <pcre2.h> +#ifndef NO_SQLITE +extern sqlite3 *db; +#endif + void set_file_action(struct groupfile *file, int new_action, size_t *deletion_tally); struct command_map command_list = { @@ -706,6 +714,7 @@ int ismatch; wchar_t *statuscopy; struct groupfile *firstnotdeleted; + char *deletepath; if (logfile != 0) loginfo = log_open(logfile, 0); @@ -749,6 +758,10 @@ if (loginfo) log_begin_set(loginfo); +#ifndef NO_SQLITE + hashdb_begintransaction(db); +#endif + /* delete files marked for deletion unless no files left undeleted */ if (deletecount < groupsg.filecount) { @@ -781,6 +794,20 @@ ismatch = 1; } +#ifndef NO_SQLITE + if (ismatch && db) + { + deletepath = getrealpath(groupsg.filesf.file->d_name, GETREALPATH_IGNORE_MISSING_BASENAME); + if (deletepath != 0) + { + if (!ISFLAG(flags, F_READONLYCACHE)) + hashdb_deletehashforpath(db, deletepath); + + free(deletepath); + } + } +#endif + if (ismatch && removeifnotchanged(groupsg.filesf.file, 0) == 0) { set_file_action(&groupsg.filesf, FILEACTION_DELIST, deletiontally); @@ -813,6 +840,10 @@ deletecount = 0; } +#ifndef NO_SQLITE + hashdb_committransaction(db); +#endif + if (loginfo) log_end_set(loginfo); @@ -941,5 +972,5 @@ *topline = 0; } - cmd_clear_all_selections(groups, *totalgroups, commandarguments, 0); -} \ No newline at end of file + return cmd_clear_all_selections(groups, *totalgroups, commandarguments, 0); +}
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/ncurses-getcommand.c -> _service:tar_scm:fdupes-2.3.1.tar.gz/ncurses-getcommand.c
Changed
@@ -22,6 +22,7 @@ #include "config.h" #include <stdlib.h> #include <signal.h> +#include <wctype.h> #include "ncurses-getcommand.h" #define KEY_ESCAPE 27
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/ncurses-interface.c -> _service:tar_scm:fdupes-2.3.1.tar.gz/ncurses-interface.c
Changed
@@ -23,6 +23,7 @@ #include <stdlib.h> #include <string.h> #include <wchar.h> +#include <wctype.h> #ifdef HAVE_NCURSESW_CURSES_H #include <ncursesw/curses.h> #else @@ -462,8 +463,6 @@ exit(1); } - register_sigint_handler(); - curfile = files; while (curfile) {
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/removeifnotchanged.c -> _service:tar_scm:fdupes-2.3.1.tar.gz/removeifnotchanged.c
Changed
@@ -1,3 +1,25 @@ +/* FDUPES Copyright (c) 2022 Adrian Lopez + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "config.h" #include "removeifnotchanged.h" #include <errno.h> #include <string.h> @@ -17,6 +39,10 @@ file->inode != st.st_ino || file->ctime != st.st_ctime || file->mtime != st.st_mtime || +#ifdef HAVE_NSEC_TIMES + file->ctime_nsec != st.st_ctim.tv_nsec || + file->mtime_nsec != st.st_mtim.tv_nsec || +#endif file->size != st.st_size) { if (errorstring != 0)
View file
_service:tar_scm:fdupes-2.2.1.tar.gz/removeifnotchanged.h -> _service:tar_scm:fdupes-2.3.1.tar.gz/removeifnotchanged.h
Changed
@@ -1,3 +1,24 @@ +/* FDUPES Copyright (c) 2022 Adrian Lopez + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + #ifndef REMOVEIFNOTCHANGED_H #define REMOVEIFNOTCHANGED_H
View file
_service:tar_scm:fdupes-2.3.1.tar.gz/sbasename.c
Added
@@ -0,0 +1,26 @@ +/* The contents of this file are in the public domain. +*/ +#include "sbasename.h" +#include <string.h> +#include <libgen.h> +#include <stdlib.h> + +char *sbasename(char *str, const char *path) +{ + char *name; + + if (str == 0) + { + str = malloc(strlen(path) + 1); + if (str == 0) + return 0; + } + + strcpy(str, path); + + name = basename(str); + + memmove(str, name, strlen(name) + 1); + + return str; +} \ No newline at end of file
View file
_service:tar_scm:fdupes-2.3.1.tar.gz/sbasename.h
Added
@@ -0,0 +1,10 @@ +/* The contents of this file are in the public domain. +*/ +#ifndef SNBASENAME_H +#define SNBASENAME_H + +#include <stddef.h> + +char *sbasename(char *str, const char *path); + +#endif \ No newline at end of file
View file
_service:tar_scm:fdupes-2.3.1.tar.gz/sdirname.c
Added
@@ -0,0 +1,26 @@ +/* The contents of this file are in the public domain. +*/ +#include "sdirname.h" +#include <string.h> +#include <libgen.h> +#include <stdlib.h> + +char *sdirname(char *str, const char *path) +{ + char *name; + + if (str == 0) + { + str = malloc(strlen(path) + 1); + if (str == 0) + return 0; + } + + strcpy(str, path); + + name = dirname(str); + + memmove(str, name, strlen(name) + 1); + + return str; +} \ No newline at end of file
View file
_service:tar_scm:fdupes-2.3.1.tar.gz/sdirname.h
Added
@@ -0,0 +1,10 @@ +/* The contents of this file are in the public domain. +*/ +#ifndef SNDIRNAME_H +#define SNDIRNAME_H + +#include <stddef.h> + +char *sdirname(char *str, const char *path); + +#endif \ No newline at end of file
View file
_service:tar_scm:fdupes-2.3.1.tar.gz/xdgbase.c
Added
@@ -0,0 +1,69 @@ +/* The contents of this file are in the public domain. +*/ +#include "config.h" +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <pwd.h> +#include <string.h> + +#define XDG_CACHE_HOME_BASENAME ".cache" +#define XDG_CACHE_HOME_PERMISSIONS 0700 + +char *getcachehome(int createdefault) +{ + char *cachedir; + char *homedir; + char *result; + size_t pathlength; + size_t defaultdirlength; + struct passwd *pw; + struct stat st; + + cachedir = getenv("XDG_CACHE_HOME"); + if (cachedir != 0) + { + pathlength = strlen(cachedir); + + result = malloc(pathlength + 1); + if (result == 0) + return 0; + + strcpy(result, cachedir); + } + else + { + homedir = getenv("HOME"); + if (homedir == 0) + { + pw = getpwuid(getuid()); + if (pw == 0) + return 0; + + homedir = pw->pw_dir; + } + + if (homedir == 0) + return 0; + + pathlength = strlen(homedir); + + defaultdirlength = strlen(XDG_CACHE_HOME_BASENAME); + + result = malloc(pathlength + defaultdirlength + 2); + if (result == 0) + return 0; + + memmove(result, homedir, pathlength); + memmove(result + pathlength + 1, XDG_CACHE_HOME_BASENAME, defaultdirlength); + + resultpathlength = '/'; + resultpathlength + defaultdirlength + 1 = '\0'; + + if (createdefault && stat(result, &st) != 0) + mkdir(result, XDG_CACHE_HOME_PERMISSIONS); + } + + return result; +} \ No newline at end of file
View file
_service:tar_scm:fdupes-2.3.1.tar.gz/xdgbase.h
Added
@@ -0,0 +1,8 @@ +/* The contents of this file are in the public domain. +*/ +#ifndef GETCONFIGDIR_H +#define GETCONFIGDIR_H + +char *getcachehome(int createdefault); + +#endif \ No newline at end of file
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2