diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/findkey.c | 24 | ||||
-rw-r--r-- | src/gdbm.h.in | 4 | ||||
-rw-r--r-- | src/gdbmdefs.h | 17 | ||||
-rw-r--r-- | src/gdbmerrno.c | 3 | ||||
-rw-r--r-- | src/gdbmtool.c | 27 | ||||
-rw-r--r-- | src/mmap.c | 22 | ||||
-rw-r--r-- | src/recover.c | 32 | ||||
-rw-r--r-- | src/systems.h | 1 |
8 files changed, 112 insertions, 18 deletions
diff --git a/src/findkey.c b/src/findkey.c index 7638b04..bd9fd83 100644 --- a/src/findkey.c +++ b/src/findkey.c | |||
@@ -24,3 +24,17 @@ | |||
24 | 24 | ||
25 | 25 | int | |
26 | gdbm_bucket_element_valid_p (GDBM_FILE dbf, int elem_loc) | ||
27 | { | ||
28 | return | ||
29 | elem_loc < dbf->header->bucket_elems | ||
30 | && dbf->bucket->h_table[elem_loc].hash_value != -1 | ||
31 | && dbf->bucket->h_table[elem_loc].key_size >= 0 | ||
32 | && off_t_sum_ok (dbf->bucket->h_table[elem_loc].data_pointer, | ||
33 | dbf->bucket->h_table[elem_loc].key_size) | ||
34 | && dbf->bucket->h_table[elem_loc].data_size >= 0 | ||
35 | && off_t_sum_ok (dbf->bucket->h_table[elem_loc].data_pointer | ||
36 | + dbf->bucket->h_table[elem_loc].key_size, | ||
37 | dbf->bucket->h_table[elem_loc].data_size); | ||
38 | } | ||
39 | |||
26 | /* Read the data found in bucket entry ELEM_LOC in file DBF and | 40 | /* Read the data found in bucket entry ELEM_LOC in file DBF and |
@@ -36,3 +50,3 @@ _gdbm_read_entry (GDBM_FILE dbf, int elem_loc) | |||
36 | data_cache_elem *data_ca; | 50 | data_cache_elem *data_ca; |
37 | 51 | ||
38 | /* Is it already in the cache? */ | 52 | /* Is it already in the cache? */ |
@@ -41,2 +55,8 @@ _gdbm_read_entry (GDBM_FILE dbf, int elem_loc) | |||
41 | 55 | ||
56 | if (!gdbm_bucket_element_valid_p (dbf, elem_loc)) | ||
57 | { | ||
58 | GDBM_SET_ERRNO (dbf, GDBM_BAD_HASH_TABLE, TRUE); | ||
59 | return NULL; | ||
60 | } | ||
61 | |||
42 | /* Set sizes and pointers. */ | 62 | /* Set sizes and pointers. */ |
diff --git a/src/gdbm.h.in b/src/gdbm.h.in index 61d5707..e576c69 100644 --- a/src/gdbm.h.in +++ b/src/gdbm.h.in | |||
@@ -154,2 +154,3 @@ typedef struct gdbm_recovery_s | |||
154 | size_t failed_buckets; | 154 | size_t failed_buckets; |
155 | size_t duplicate_keys; | ||
155 | char *backup_name; | 156 | char *backup_name; |
@@ -224,5 +225,6 @@ extern int gdbm_copy_meta (GDBM_FILE dst, GDBM_FILE src); | |||
224 | # define GDBM_BAD_AVAIL 34 | 225 | # define GDBM_BAD_AVAIL 34 |
226 | # define GDBM_BAD_HASH_TABLE 35 | ||
225 | 227 | ||
226 | # define _GDBM_MIN_ERRNO 0 | 228 | # define _GDBM_MIN_ERRNO 0 |
227 | # define _GDBM_MAX_ERRNO GDBM_BAD_AVAIL | 229 | # define _GDBM_MAX_ERRNO GDBM_BAD_HASH_TABLE |
228 | 230 | ||
diff --git a/src/gdbmdefs.h b/src/gdbmdefs.h index 5305b0d..1bb519b 100644 --- a/src/gdbmdefs.h +++ b/src/gdbmdefs.h | |||
@@ -28,2 +28,18 @@ | |||
28 | 28 | ||
29 | /* The width in bits of the integer type or expression T. */ | ||
30 | #define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) | ||
31 | |||
32 | #define SIGNED_TYPE_MAXIMUM(t) \ | ||
33 | ((t) ((((t) 1 << (TYPE_WIDTH (t) - 2)) - 1) * 2 + 1)) | ||
34 | |||
35 | /* Maximum value for off_t */ | ||
36 | #define OFF_T_MAX SIGNED_TYPE_MAXIMUM (off_t) | ||
37 | |||
38 | /* Return true if A can be added to B without integer overflow */ | ||
39 | static inline off_t | ||
40 | off_t_sum_ok (off_t a, off_t b) | ||
41 | { | ||
42 | return OFF_T_MAX - a >= b; | ||
43 | } | ||
44 | |||
29 | /* The type definitions are next. */ | 45 | /* The type definitions are next. */ |
@@ -95,2 +111,3 @@ typedef struct | |||
95 | 111 | ||
112 | extern int gdbm_bucket_element_valid_p (GDBM_FILE dbf, int elem_loc); | ||
96 | 113 | ||
diff --git a/src/gdbmerrno.c b/src/gdbmerrno.c index 896bf70..52cfe30 100644 --- a/src/gdbmerrno.c +++ b/src/gdbmerrno.c | |||
@@ -136,3 +136,4 @@ const char * const gdbm_errlist[_GDBM_MAX_ERRNO+1] = { | |||
136 | [GDBM_BAD_HEADER] = N_("Malformed database file header"), | 136 | [GDBM_BAD_HEADER] = N_("Malformed database file header"), |
137 | [GDBM_BAD_AVAIL] = N_("Malforemd avail_block") | 137 | [GDBM_BAD_AVAIL] = N_("Malformed avail_block"), |
138 | [GDBM_BAD_HASH_TABLE] = N_("Malformed hash table") | ||
138 | }; | 139 | }; |
diff --git a/src/gdbmtool.c b/src/gdbmtool.c index 33bdf93..9c6eebe 100644 --- a/src/gdbmtool.c +++ b/src/gdbmtool.c | |||
@@ -554,3 +554,3 @@ err_printer (void *data GDBM_ARG_UNUSED, char const *fmt, ...) | |||
554 | 554 | ||
555 | /* recover verbose backup max-failed-keys=N max-failed-buckets=N max-failures=N */ | 555 | /* recover sumamry verbose backup max-failed-keys=N max-failed-buckets=N max-failures=N */ |
556 | void | 556 | void |
@@ -563,4 +563,5 @@ recover_handler (struct handler_param *param) | |||
563 | char *p; | 563 | char *p; |
564 | int summary = 0; | ||
564 | 565 | ||
565 | for (i = 1; i < param->argc; i++) | 566 | for (i = 0; i < param->argc; i++) |
566 | { | 567 | { |
@@ -572,2 +573,6 @@ recover_handler (struct handler_param *param) | |||
572 | } | 573 | } |
574 | else if (strcmp (arg, "summary") == 0) | ||
575 | { | ||
576 | summary = 1; | ||
577 | } | ||
573 | else if (strcmp (arg, "backup") == 0) | 578 | else if (strcmp (arg, "backup") == 0) |
@@ -619,2 +624,15 @@ recover_handler (struct handler_param *param) | |||
619 | fprintf (param->fp, _("Recovery succeeded.\n")); | 624 | fprintf (param->fp, _("Recovery succeeded.\n")); |
625 | if (summary) | ||
626 | { | ||
627 | fprintf (param->fp, | ||
628 | _("Keys recovered: %lu, failed: %lu, duplicate: %lu\n"), | ||
629 | (unsigned long) rcvr.recovered_keys, | ||
630 | (unsigned long) rcvr.failed_keys, | ||
631 | (unsigned long) rcvr.duplicate_keys); | ||
632 | fprintf (param->fp, | ||
633 | _("Buckets recovered: %lu, failed: %lu\n"), | ||
634 | (unsigned long) rcvr.recovered_buckets, | ||
635 | (unsigned long) rcvr.failed_buckets); | ||
636 | } | ||
637 | |||
620 | if (rcvr.backup_name) | 638 | if (rcvr.backup_name) |
@@ -927,3 +945,3 @@ export_handler (struct handler_param *param) | |||
927 | 945 | ||
928 | for (i = 1; i < param->argc; i++) | 946 | for (i = 0; i < param->argc; i++) |
929 | { | 947 | { |
@@ -961,3 +979,3 @@ import_handler (struct handler_param *param) | |||
961 | 979 | ||
962 | for (i = 1; i < param->argc; i++) | 980 | for (i = 0; i < param->argc; i++) |
963 | { | 981 | { |
@@ -1222,2 +1240,3 @@ struct command command_tab[] = { | |||
1222 | { { "[verbose]", GDBM_ARG_STRING }, | 1240 | { { "[verbose]", GDBM_ARG_STRING }, |
1241 | { "[summary]", GDBM_ARG_STRING }, | ||
1223 | { "[backup]", GDBM_ARG_STRING }, | 1242 | { "[backup]", GDBM_ARG_STRING }, |
@@ -46,4 +46,11 @@ | |||
46 | /* Return the sum of the currently mapped size and DELTA */ | 46 | /* Return the sum of the currently mapped size and DELTA */ |
47 | # define SUM_FILE_SIZE(dbf, delta) \ | 47 | static inline off_t |
48 | ((dbf)->mapped_off + (dbf)->mapped_size + (delta)) | 48 | SUM_FILE_SIZE (GDBM_FILE dbf, off_t delta) |
49 | { | ||
50 | if (delta >= 0 | ||
51 | && off_t_sum_ok (dbf->mapped_off, dbf->mapped_size) | ||
52 | && off_t_sum_ok (dbf->mapped_off + dbf->mapped_size, delta)) | ||
53 | return dbf->mapped_off + dbf->mapped_size + delta; | ||
54 | return -1; | ||
55 | } | ||
49 | 56 | ||
@@ -184,2 +191,13 @@ _gdbm_mapped_remap (GDBM_FILE dbf, off_t size, int flag) | |||
184 | 191 | ||
192 | if (size < 0) | ||
193 | { | ||
194 | errno = EINVAL; | ||
195 | GDBM_SET_ERRNO (dbf, GDBM_FILE_SEEK_ERROR, TRUE); | ||
196 | return -1; | ||
197 | } | ||
198 | |||
199 | if (size < dbf->mapped_size) | ||
200 | /* Nothing to do */ | ||
201 | return 0; | ||
202 | |||
185 | if (_gdbm_file_size (dbf, &file_size)) | 203 | if (_gdbm_file_size (dbf, &file_size)) |
diff --git a/src/recover.c b/src/recover.c index d6d4ff9..721c23f 100644 --- a/src/recover.c +++ b/src/recover.c | |||
@@ -314,11 +314,26 @@ run_recovery (GDBM_FILE dbf, GDBM_FILE new_dbf, gdbm_recovery *rcvr, int flags) | |||
314 | { | 314 | { |
315 | if (flags & GDBM_RCVR_ERRFUN) | 315 | switch (gdbm_last_errno (new_dbf)) |
316 | rcvr->errfun (rcvr->data, | 316 | { |
317 | _("fatal: can't store element %d:%d (%lu:%d): %s"), | 317 | case GDBM_CANNOT_REPLACE: |
318 | bucket_dir, i, | 318 | rcvr->duplicate_keys++; |
319 | (unsigned long) dbf->bucket->h_table[i].data_pointer, | 319 | if (flags & GDBM_RCVR_ERRFUN) |
320 | dbf->bucket->h_table[i].key_size | 320 | rcvr->errfun (rcvr->data, |
321 | _("ignoring duplicate key %d:%d (%lu:%d)"), | ||
322 | bucket_dir, i, | ||
323 | (unsigned long) dbf->bucket->h_table[i].data_pointer, | ||
324 | dbf->bucket->h_table[i].key_size | ||
325 | + dbf->bucket->h_table[i].data_size); | ||
326 | break; | ||
327 | |||
328 | default: | ||
329 | if (flags & GDBM_RCVR_ERRFUN) | ||
330 | rcvr->errfun (rcvr->data, | ||
331 | _("fatal: can't store element %d:%d (%lu:%d): %s"), | ||
332 | bucket_dir, i, | ||
333 | (unsigned long) dbf->bucket->h_table[i].data_pointer, | ||
334 | dbf->bucket->h_table[i].key_size | ||
321 | + dbf->bucket->h_table[i].data_size, | 335 | + dbf->bucket->h_table[i].data_size, |
322 | gdbm_db_strerror (new_dbf)); | 336 | gdbm_db_strerror (new_dbf)); |
323 | return -1; | 337 | return -1; |
338 | } | ||
324 | } | 339 | } |
@@ -358,2 +373,3 @@ gdbm_recover (GDBM_FILE dbf, gdbm_recovery *rcvr, int flags) | |||
358 | rcvr->failed_buckets = 0; | 373 | rcvr->failed_buckets = 0; |
374 | rcvr->duplicate_keys = 0; | ||
359 | rcvr->backup_name = NULL; | 375 | rcvr->backup_name = NULL; |
diff --git a/src/systems.h b/src/systems.h index 66955dd..c678573 100644 --- a/src/systems.h +++ b/src/systems.h | |||
@@ -35,2 +35,3 @@ | |||
35 | #include <errno.h> | 35 | #include <errno.h> |
36 | #include <limits.h> | ||
36 | 37 | ||