View | Details | Raw Unified | Return to bug 275128
Collapse All | Expand All

(-)b/sysutils/jdupes/Makefile (+1 lines)
Lines 1-6 Link Here
1
PORTNAME=	jdupes
1
PORTNAME=	jdupes
2
DISTVERSIONPREFIX=	v
2
DISTVERSIONPREFIX=	v
3
DISTVERSION=	1.27.3
3
DISTVERSION=	1.27.3
4
PORTREVISION=	1
4
CATEGORIES=	sysutils
5
CATEGORIES=	sysutils
5
6
6
MAINTAINER=	tom@hur.st
7
MAINTAINER=	tom@hur.st
(-)b/sysutils/jdupes/files/patch-hashdb.c (-1 / +114 lines)
Added Link Here
0
- 
1
--- hashdb.c.orig	2023-08-27 01:12:34 UTC
2
+++ hashdb.c
3
@@ -31,6 +31,7 @@ static hashdb_t *hashdb[HT_SIZE];
4
 static int hashdb_init = 0;
5
 static int hashdb_algo = 0;
6
 static int hashdb_dirty = 0;
7
+static int new_hashdb = 0;
8
 
9
 /* Pivot direction for rebalance */
10
 enum pivot { PIVOT_LEFT, PIVOT_RIGHT };
11
@@ -68,20 +69,35 @@ int save_hash_database(const char * const restrict dbn
12
 {
13
   FILE *db = NULL;
14
   uint64_t cnt = 0;
15
+  char *dbtemp;
16
 
17
   if (dbname == NULL) goto error_hashdb_null;
18
   LOUD(fprintf(stderr, "save_hash_database('%s')\n", dbname);)
19
   /* Don't save the hash database if it wasn't changed */
20
   if (hashdb_dirty == 0 && destroy == 0) return 0;
21
   if (hashdb_dirty == 1) {
22
+
23
     errno = 0;
24
-    db = fopen(dbname, "w+b");
25
+    dbtemp = malloc(strlen(dbname) + 5);
26
+    if (dbtemp == NULL) goto error_hashdb_alloc;
27
+    strcpy(dbtemp, dbname);
28
+    strcat(dbtemp, ".tmp");
29
+    /* Try to remove any existing temporary database, ignoring errors */
30
+    remove(dbtemp);
31
+    db = fopen(dbtemp, "rb");
32
     if (db == NULL) goto error_hashdb_open;
33
   }
34
 
35
-  if (write_hashdb_entry(db, NULL, &cnt, destroy) != 0) goto error_hashdb_write;
36
   if (hashdb_dirty == 1) {
37
+    if (write_hashdb_entry(db, NULL, &cnt, destroy) != 0) goto error_hashdb_write;
38
     fclose(db);
39
+    if (new_hashdb == 0) {
40
+      errno = 0;
41
+      if (remove(dbname) != 0) {
42
+        if (errno != ENOENT) goto error_hashdb_remove;
43
+      }
44
+    }
45
+    if (rename(dbtemp, dbname) != 0) goto error_hashdb_rename;
46
     LOUD(if (hashdb_dirty == 1) fprintf(stderr, "Wrote %" PRIu64 " items to hash databse '%s'\n", cnt, dbname);)
47
     hashdb_dirty = 0;
48
   }
49
@@ -92,12 +108,22 @@ error_hashdb_null:
50
   fprintf(stderr, "error: internal failure: NULL pointer for hashdb\n");
51
   return -1;
52
 error_hashdb_open:
53
-  fprintf(stderr, "error: cannot open hashdb '%s' for writing: %s\n", dbname, strerror(errno));
54
+  fprintf(stderr, "error: cannot open temp hashdb '%s' for writing: %s\n", dbtemp, strerror(errno));
55
   return -2;
56
 error_hashdb_write:
57
-  fprintf(stderr, "error: writing failed to hashdb '%s': %s\n", dbname, strerror(errno));
58
+  fprintf(stderr, "error: write failed to temp hashdb '%s': %s\n", dbtemp, strerror(errno));
59
   fclose(db);
60
   return -3;
61
+error_hashdb_alloc:
62
+  fprintf(stderr, "error: cannot allocate memory for temporary hashdb name\n");
63
+  return -4;
64
+error_hashdb_remove:
65
+  fprintf(stderr, "error: cannot delete old hashdb '%s': %s\n", dbname, strerror(errno));
66
+  remove(dbtemp);
67
+  return -5;
68
+error_hashdb_rename:
69
+  fprintf(stderr, "error: cannot rename temporary hashdb '%s' to '%s'; leaving it alone: %s\n", dbtemp, dbname, strerror(errno));
70
+  return -6;
71
 }
72
 
73
 
74
@@ -435,31 +461,40 @@ int64_t load_hash_database(char *dbname)
75
     entry->hashcount = hashcount;
76
   }
77
 
78
+  fclose(db);
79
   return linenum - 1;
80
 
81
 warn_hashdb_open:
82
   fprintf(stderr, "Creating a new hash database '%s'\n", dbname);
83
+  fclose(db);
84
+  new_hashdb = 1;
85
   return 0;
86
 error_hashdb_read:
87
   fprintf(stderr, "error reading hash database '%s': %s\n", dbname, strerror(errno));
88
+  fclose(db);
89
   return -1;
90
 error_hashdb_header:
91
   fprintf(stderr, "error in header of hash database '%s'\n", dbname);
92
+  fclose(db);
93
   return -2;
94
 error_hashdb_version:
95
   fprintf(stderr, "error: bad db version %u in hash database '%s'\n", db_ver, dbname);
96
+  fclose(db);
97
   return -3;
98
 error_hashdb_line:
99
   fprintf(stderr, "\nerror: bad line %" PRId64 " in hash database '%s':\n\n%s\n\n", linenum, dbname, line);
100
+  fclose(db);
101
   return -4;
102
 error_hashdb_add:
103
   fprintf(stderr, "error: internal failure allocating a hashdb entry\n");
104
+  fclose(db);
105
   return -5;
106
 error_hashdb_null:
107
   fprintf(stderr, "error: internal failure: NULL pointer for hashdb\n");
108
   return -6;
109
 warn_hashdb_algo:
110
   fprintf(stderr, "warning: hashdb uses a different hash algorithm than selected; not loading\n");
111
+  fclose(db);
112
   return -7;
113
 }
114
  

Return to bug 275128