aboutsummaryrefslogtreecommitdiff
path: root/src/recover.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-05-24 11:35:24 +0300
committerSergey Poznyakoff <gray@gnu.org>2018-05-24 11:35:24 +0300
commit371bb85fe378ffd0ed6ddc81985d450cef5835a3 (patch)
tree6ab2d142b7aa1f9b29ec50b891c8293774964209 /src/recover.c
parentf82d0b213fd2cdce80dc891906fba8d589115664 (diff)
downloadgdbm-371bb85fe378ffd0ed6ddc81985d450cef5835a3.tar.gz
gdbm-371bb85fe378ffd0ed6ddc81985d450cef5835a3.tar.bz2
More error checking; improve gdbm_recover
* Makefile.am (set-dist-date): New rule (dist-hook): Catch FIXMEs in NEWS. * NEWS: Updated. * src/findkey.c (gdbm_bucket_element_valid_p): New function. (_gdbm_read_entry): Validate the retrieved bucket element. * src/gdbm.h.in (gdbm_recovery): New member: duplicate_keys. (GDBM_BAD_HASH_TABLE): New error code. * src/gdbmdefs.h (TYPE_WIDTH,SIGNED_TYPE_MAXIMUM) (OFF_T_MAX): New defines. (off_t_sum_ok): New function. (gdbm_bucket_element_valid_p): New prototype. * src/gdbmerrno.c: Support for GDBM_BAD_HASH_TABLE code. * src/gdbmtool.c (recover_handler): Fix argument counting. New argument 'summary' prints statistics summary at the end of the run. (export_handler,import_handler): Fix argument counting. * src/mmap.c (SUM_FILE_SIZE): Rewrite as inlined function. Add error checking. (_gdbm_mapped_remap): More error checking. * src/recover.c (run_recovery): Don't bail out on GDBM_CANNOT_REPLACE. (gdbm_recover): Initialize duplicate_keys * src/systems.h: Include limits.h
Diffstat (limited to 'src/recover.c')
-rw-r--r--src/recover.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/recover.c b/src/recover.c
index d6d4ff9..721c23f 100644
--- a/src/recover.c
+++ b/src/recover.c
@@ -303,37 +303,52 @@ run_recovery (GDBM_FILE dbf, GDBM_FILE new_dbf, gdbm_recovery *rcvr, int flags)
return -1;
continue;
}
key.dptr = dptr;
key.dsize = dbf->bucket->h_table[i].key_size;
data.dptr = dptr + key.dsize;
data.dsize = dbf->bucket->h_table[i].data_size;
if (gdbm_store (new_dbf, key, data, GDBM_INSERT) != 0)
{
+ switch (gdbm_last_errno (new_dbf))
+ {
+ case GDBM_CANNOT_REPLACE:
+ rcvr->duplicate_keys++;
+ if (flags & GDBM_RCVR_ERRFUN)
+ rcvr->errfun (rcvr->data,
+ _("ignoring duplicate key %d:%d (%lu:%d)"),
+ bucket_dir, i,
+ (unsigned long) dbf->bucket->h_table[i].data_pointer,
+ dbf->bucket->h_table[i].key_size
+ + dbf->bucket->h_table[i].data_size);
+ break;
+
+ default:
if (flags & GDBM_RCVR_ERRFUN)
rcvr->errfun (rcvr->data,
_("fatal: can't store element %d:%d (%lu:%d): %s"),
bucket_dir, i,
(unsigned long) dbf->bucket->h_table[i].data_pointer,
dbf->bucket->h_table[i].key_size
+ dbf->bucket->h_table[i].data_size,
gdbm_db_strerror (new_dbf));
return -1;
}
}
}
}
+ }
return 0;
}
int
gdbm_recover (GDBM_FILE dbf, gdbm_recovery *rcvr, int flags)
{
GDBM_FILE new_dbf; /* The new file. */
char *new_name; /* A temporary name. */
size_t len;
int fd;
int rc;
@@ -347,24 +362,25 @@ gdbm_recover (GDBM_FILE dbf, gdbm_recovery *rcvr, int flags)
}
/* Initialize gdbm_recovery structure */
if (!rcvr)
{
rcvr = &rs;
flags = 0;
}
rcvr->recovered_keys = 0;
rcvr->recovered_buckets = 0;
rcvr->failed_keys = 0;
rcvr->failed_buckets = 0;
+ rcvr->duplicate_keys = 0;
rcvr->backup_name = NULL;
rc = 0;
if ((flags & GDBM_RCVR_FORCE) || check_db (dbf))
{
len = strlen (dbf->name);
new_name = malloc (len + sizeof (TMPSUF));
if (!new_name)
{
GDBM_SET_ERRNO (NULL, GDBM_MALLOC_ERROR, FALSE);
return -1;
}

Return to:

Send suggestions and report system problems to the System administrator.