aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/findkey.c20
-rw-r--r--src/gdbm.h.in4
-rw-r--r--src/gdbmdefs.h17
-rw-r--r--src/gdbmerrno.c3
-rw-r--r--src/gdbmtool.c27
-rw-r--r--src/mmap.c22
-rw-r--r--src/recover.c16
-rw-r--r--src/systems.h1
8 files changed, 102 insertions, 8 deletions
diff --git a/src/findkey.c b/src/findkey.c
index 7638b04..bd9fd83 100644
--- a/src/findkey.c
+++ b/src/findkey.c
@@ -13,41 +13,61 @@
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 15 GNU General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with GDBM. If not, see <http://www.gnu.org/licenses/>. */ 18 along with GDBM. If not, see <http://www.gnu.org/licenses/>. */
19 19
20/* Include system configuration before all else. */ 20/* Include system configuration before all else. */
21#include "autoconf.h" 21#include "autoconf.h"
22 22
23#include "gdbmdefs.h" 23#include "gdbmdefs.h"
24 24
25int
26gdbm_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}
25 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
27 return a pointer to it. Also, cache the read value. */ 41 return a pointer to it. Also, cache the read value. */
28 42
29char * 43char *
30_gdbm_read_entry (GDBM_FILE dbf, int elem_loc) 44_gdbm_read_entry (GDBM_FILE dbf, int elem_loc)
31{ 45{
32 int rc; 46 int rc;
33 int key_size; 47 int key_size;
34 int data_size; 48 int data_size;
35 off_t file_pos; 49 off_t file_pos;
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? */
39 if (dbf->cache_entry->ca_data.elem_loc == elem_loc) 53 if (dbf->cache_entry->ca_data.elem_loc == elem_loc)
40 return dbf->cache_entry->ca_data.dptr; 54 return dbf->cache_entry->ca_data.dptr;
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. */
43 key_size = dbf->bucket->h_table[elem_loc].key_size; 63 key_size = dbf->bucket->h_table[elem_loc].key_size;
44 data_size = dbf->bucket->h_table[elem_loc].data_size; 64 data_size = dbf->bucket->h_table[elem_loc].data_size;
45 data_ca = &dbf->cache_entry->ca_data; 65 data_ca = &dbf->cache_entry->ca_data;
46 66
47 /* Set up the cache. */ 67 /* Set up the cache. */
48 if (data_ca->dptr != NULL) free (data_ca->dptr); 68 if (data_ca->dptr != NULL) free (data_ca->dptr);
49 data_ca->key_size = key_size; 69 data_ca->key_size = key_size;
50 data_ca->data_size = data_size; 70 data_ca->data_size = data_size;
51 data_ca->elem_loc = elem_loc; 71 data_ca->elem_loc = elem_loc;
52 data_ca->hash_val = dbf->bucket->h_table[elem_loc].hash_value; 72 data_ca->hash_val = dbf->bucket->h_table[elem_loc].hash_value;
53 73
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
@@ -143,24 +143,25 @@ typedef struct gdbm_recovery_s
143 void *data; 143 void *data;
144 144
145 size_t max_failed_keys; 145 size_t max_failed_keys;
146 size_t max_failed_buckets; 146 size_t max_failed_buckets;
147 size_t max_failures; 147 size_t max_failures;
148 148
149 /* Output members. 149 /* Output members.
150 The gdbm_recover function fills these before returning. */ 150 The gdbm_recover function fills these before returning. */
151 size_t recovered_keys; 151 size_t recovered_keys;
152 size_t recovered_buckets; 152 size_t recovered_buckets;
153 size_t failed_keys; 153 size_t failed_keys;
154 size_t failed_buckets; 154 size_t failed_buckets;
155 size_t duplicate_keys;
155 char *backup_name; 156 char *backup_name;
156} gdbm_recovery; 157} gdbm_recovery;
157 158
158#define GDBM_RCVR_DEFAULT 0x00 /* Default settings */ 159#define GDBM_RCVR_DEFAULT 0x00 /* Default settings */
159#define GDBM_RCVR_ERRFUN 0x01 /* errfun is initialized */ 160#define GDBM_RCVR_ERRFUN 0x01 /* errfun is initialized */
160#define GDBM_RCVR_MAX_FAILED_KEYS 0x02 /* max_failed_keys is initialized */ 161#define GDBM_RCVR_MAX_FAILED_KEYS 0x02 /* max_failed_keys is initialized */
161#define GDBM_RCVR_MAX_FAILED_BUCKETS 0x04 /* max_failed_buckets is initialized */ 162#define GDBM_RCVR_MAX_FAILED_BUCKETS 0x04 /* max_failed_buckets is initialized */
162#define GDBM_RCVR_MAX_FAILURES 0x08 /* max_failures is initialized */ 163#define GDBM_RCVR_MAX_FAILURES 0x08 /* max_failures is initialized */
163#define GDBM_RCVR_BACKUP 0x10 /* Keep backup copy of the 164#define GDBM_RCVR_BACKUP 0x10 /* Keep backup copy of the
164 original database on success */ 165 original database on success */
165#define GDBM_RCVR_FORCE 0x20 /* Force recovery by skipping the 166#define GDBM_RCVR_FORCE 0x20 /* Force recovery by skipping the
166 check pass */ 167 check pass */
@@ -213,27 +214,28 @@ extern int gdbm_copy_meta (GDBM_FILE dst, GDBM_FILE src);
213# define GDBM_BAD_OPEN_FLAGS 23 214# define GDBM_BAD_OPEN_FLAGS 23
214# define GDBM_FILE_STAT_ERROR 24 215# define GDBM_FILE_STAT_ERROR 24
215# define GDBM_FILE_EOF 25 216# define GDBM_FILE_EOF 25
216# define GDBM_NO_DBNAME 26 217# define GDBM_NO_DBNAME 26
217# define GDBM_ERR_FILE_OWNER 27 218# define GDBM_ERR_FILE_OWNER 27
218# define GDBM_ERR_FILE_MODE 28 219# define GDBM_ERR_FILE_MODE 28
219# define GDBM_NEED_RECOVERY 29 220# define GDBM_NEED_RECOVERY 29
220# define GDBM_BACKUP_FAILED 30 221# define GDBM_BACKUP_FAILED 30
221# define GDBM_DIR_OVERFLOW 31 222# define GDBM_DIR_OVERFLOW 31
222# define GDBM_BAD_BUCKET 32 223# define GDBM_BAD_BUCKET 32
223# define GDBM_BAD_HEADER 33 224# define GDBM_BAD_HEADER 33
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
229/* This one was never used and will be removed in the future */ 231/* This one was never used and will be removed in the future */
230# define GDBM_UNKNOWN_UPDATE GDBM_UNKNOWN_ERROR 232# define GDBM_UNKNOWN_UPDATE GDBM_UNKNOWN_ERROR
231 233
232typedef int gdbm_error; 234typedef int gdbm_error;
233extern int *gdbm_errno_location (void); 235extern int *gdbm_errno_location (void);
234#define gdbm_errno (*gdbm_errno_location ()) 236#define gdbm_errno (*gdbm_errno_location ())
235extern const char * const gdbm_errlist[]; 237extern const char * const gdbm_errlist[];
236extern int const gdbm_syserr[]; 238extern int const gdbm_syserr[];
237 239
238extern gdbm_error gdbm_last_errno (GDBM_FILE dbf); 240extern gdbm_error gdbm_last_errno (GDBM_FILE dbf);
239extern int gdbm_last_syserr (GDBM_FILE dbf); 241extern int gdbm_last_syserr (GDBM_FILE dbf);
diff --git a/src/gdbmdefs.h b/src/gdbmdefs.h
index 5305b0d..1bb519b 100644
--- a/src/gdbmdefs.h
+++ b/src/gdbmdefs.h
@@ -17,24 +17,40 @@
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with GDBM. If not, see <http://www.gnu.org/licenses/>. */ 18 along with GDBM. If not, see <http://www.gnu.org/licenses/>. */
19 19
20#include "systems.h" 20#include "systems.h"
21#include "gdbmconst.h" 21#include "gdbmconst.h"
22#include "gdbm.h" 22#include "gdbm.h"
23#define DEFAULT_TEXT_DOMAIN PACKAGE 23#define DEFAULT_TEXT_DOMAIN PACKAGE
24#include "gettext.h" 24#include "gettext.h"
25 25
26#define _(s) gettext (s) 26#define _(s) gettext (s)
27#define N_(s) s 27#define N_(s) s
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 */
39static inline off_t
40off_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. */
30 46
31/* The available file space is stored in an "avail" table. The one with 47/* The available file space is stored in an "avail" table. The one with
32 most activity is contained in the file header. (See below.) When that 48 most activity is contained in the file header. (See below.) When that
33 one filles up, it is split in half and half is pushed on an "avail 49 one filles up, it is split in half and half is pushed on an "avail
34 stack." When the active avail table is empty and the "avail stack" is 50 stack." When the active avail table is empty and the "avail stack" is
35 not empty, the top of the stack is popped into the active avail table. */ 51 not empty, the top of the stack is popped into the active avail table. */
36 52
37/* The following structure is the element of the avaliable table. */ 53/* The following structure is the element of the avaliable table. */
38typedef struct 54typedef struct
39{ 55{
40 int av_size; /* The size of the available block. */ 56 int av_size; /* The size of the available block. */
@@ -84,24 +100,25 @@ typedef struct
84 key. */ 100 key. */
85 101
86typedef struct 102typedef struct
87{ 103{
88 int hash_value; /* The complete 31 bit value. */