summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hurst <tom@hur.st>2023-11-17 08:30:06 +0100
committerFernando ApesteguĂ­a <fernape@FreeBSD.org>2023-11-17 19:28:15 +0100
commitefcf734590eaaf1dee0bac5fc758680925501d15 (patch)
tree074dc8849f3a45491b369f9214ff37b18c46c65e
parentsysutils/eza: Update to 0.16.0 (diff)
sysutils/jdupes: Update to 1.27.3_1
ChangeLog: https://www.jdupes.com/2023/11/10/news-fix-for-v1-27-3-libjodycode-4-work/ Apply a fix for the jdupes hash database feature to avoid potential database loss, resulting from disk-full situations and other write failures. PR: 275128 Reported by: tom@hur.st (maintainer) MFH: 2023Q4 (bugfix)
-rw-r--r--sysutils/jdupes/Makefile1
-rw-r--r--sysutils/jdupes/files/patch-hashdb.c114
2 files changed, 115 insertions, 0 deletions
diff --git a/sysutils/jdupes/Makefile b/sysutils/jdupes/Makefile
index ebb0aed66e32..c2eedc8de39d 100644
--- a/sysutils/jdupes/Makefile
+++ b/sysutils/jdupes/Makefile
@@ -1,6 +1,7 @@
PORTNAME= jdupes
DISTVERSIONPREFIX= v
DISTVERSION= 1.27.3
+PORTREVISION= 1
CATEGORIES= sysutils
MAINTAINER= tom@hur.st
diff --git a/sysutils/jdupes/files/patch-hashdb.c b/sysutils/jdupes/files/patch-hashdb.c
new file mode 100644
index 000000000000..bc631af357c2
--- /dev/null
+++ b/sysutils/jdupes/files/patch-hashdb.c
@@ -0,0 +1,114 @@
+--- hashdb.c.orig 2023-08-27 01:12:34 UTC
++++ hashdb.c
+@@ -31,6 +31,7 @@ static hashdb_t *hashdb[HT_SIZE];
+ static int hashdb_init = 0;
+ static int hashdb_algo = 0;
+ static int hashdb_dirty = 0;
++static int new_hashdb = 0;
+
+ /* Pivot direction for rebalance */
+ enum pivot { PIVOT_LEFT, PIVOT_RIGHT };
+@@ -68,20 +69,35 @@ int save_hash_database(const char * const restrict dbn
+ {
+ FILE *db = NULL;
+ uint64_t cnt = 0;
++ char *dbtemp;
+
+ if (dbname == NULL) goto error_hashdb_null;
+ LOUD(fprintf(stderr, "save_hash_database('%s')\n", dbname);)
+ /* Don't save the hash database if it wasn't changed */
+ if (hashdb_dirty == 0 && destroy == 0) return 0;
+ if (hashdb_dirty == 1) {
++
+ errno = 0;
+- db = fopen(dbname, "w+b");
++ dbtemp = malloc(strlen(dbname) + 5);
++ if (dbtemp == NULL) goto error_hashdb_alloc;
++ strcpy(dbtemp, dbname);
++ strcat(dbtemp, ".tmp");
++ /* Try to remove any existing temporary database, ignoring errors */
++ remove(dbtemp);
++ db = fopen(dbtemp, "rb");
+ if (db == NULL) goto error_hashdb_open;
+ }
+
+- if (write_hashdb_entry(db, NULL, &cnt, destroy) != 0) goto error_hashdb_write;
+ if (hashdb_dirty == 1) {
++ if (write_hashdb_entry(db, NULL, &cnt, destroy) != 0) goto error_hashdb_write;
+ fclose(db);
++ if (new_hashdb == 0) {
++ errno = 0;
++ if (remove(dbname) != 0) {
++ if (errno != ENOENT) goto error_hashdb_remove;
++ }
++ }
++ if (rename(dbtemp, dbname) != 0) goto error_hashdb_rename;
+ LOUD(if (hashdb_dirty == 1) fprintf(stderr, "Wrote %" PRIu64 " items to hash databse '%s'\n", cnt, dbname);)
+ hashdb_dirty = 0;
+ }
+@@ -92,12 +108,22 @@ error_hashdb_null:
+ fprintf(stderr, "error: internal failure: NULL pointer for hashdb\n");
+ return -1;
+ error_hashdb_open:
+- fprintf(stderr, "error: cannot open hashdb '%s' for writing: %s\n", dbname, strerror(errno));
++ fprintf(stderr, "error: cannot open temp hashdb '%s' for writing: %s\n", dbtemp, strerror(errno));
+ return -2;
+ error_hashdb_write:
+- fprintf(stderr, "error: writing failed to hashdb '%s': %s\n", dbname, strerror(errno));
++ fprintf(stderr, "error: write failed to temp hashdb '%s': %s\n", dbtemp, strerror(errno));
+ fclose(db);
+ return -3;
++error_hashdb_alloc:
++ fprintf(stderr, "error: cannot allocate memory for temporary hashdb name\n");
++ return -4;
++error_hashdb_remove:
++ fprintf(stderr, "error: cannot delete old hashdb '%s': %s\n", dbname, strerror(errno));
++ remove(dbtemp);
++ return -5;
++error_hashdb_rename:
++ fprintf(stderr, "error: cannot rename temporary hashdb '%s' to '%s'; leaving it alone: %s\n", dbtemp, dbname, strerror(errno));
++ return -6;
+ }
+
+
+@@ -435,31 +461,40 @@ int64_t load_hash_database(char *dbname)
+ entry->hashcount = hashcount;
+ }
+
++ fclose(db);
+ return linenum - 1;
+
+ warn_hashdb_open:
+ fprintf(stderr, "Creating a new hash database '%s'\n", dbname);
++ fclose(db);
++ new_hashdb = 1;
+ return 0;
+ error_hashdb_read:
+ fprintf(stderr, "error reading hash database '%s': %s\n", dbname, strerror(errno));
++ fclose(db);
+ return -1;
+ error_hashdb_header:
+ fprintf(stderr, "error in header of hash database '%s'\n", dbname);
++ fclose(db);
+ return -2;
+ error_hashdb_version:
+ fprintf(stderr, "error: bad db version %u in hash database '%s'\n", db_ver, dbname);
++ fclose(db);
+ return -3;
+ error_hashdb_line:
+ fprintf(stderr, "\nerror: bad line %" PRId64 " in hash database '%s':\n\n%s\n\n", linenum, dbname, line);
++ fclose(db);
+ return -4;
+ error_hashdb_add:
+ fprintf(stderr, "error: internal failure allocating a hashdb entry\n");
++ fclose(db);
+ return -5;
+ error_hashdb_null:
+ fprintf(stderr, "error: internal failure: NULL pointer for hashdb\n");
+ return -6;
+ warn_hashdb_algo:
+ fprintf(stderr, "warning: hashdb uses a different hash algorithm than selected; not loading\n");
++ fclose(db);
+ return -7;
+ }
+