5dff07f
diff --git a/dbm/sdbm/sdbm.c b/dbm/sdbm/sdbm.c
5dff07f
index a1ce695..a62b009 100644
5dff07f
--- a/dbm/sdbm/sdbm.c
5dff07f
+++ b/dbm/sdbm/sdbm.c
5dff07f
@@ -40,7 +40,7 @@
5dff07f
  */
5dff07f
 static int getdbit (apr_sdbm_t *, long);
5dff07f
 static apr_status_t setdbit(apr_sdbm_t *, long);
5dff07f
-static apr_status_t getpage(apr_sdbm_t *db, long);
5dff07f
+static apr_status_t getpage(apr_sdbm_t *db, long, int, int);
5dff07f
 static apr_status_t getnext(apr_sdbm_datum_t *key, apr_sdbm_t *db);
5dff07f
 static apr_status_t makroom(apr_sdbm_t *, long, int);
5dff07f
 
5dff07f
@@ -93,6 +93,7 @@ static apr_status_t prep(apr_sdbm_t **pdb, const char *dirname, const char *pagn
5dff07f
 
5dff07f
     db = malloc(sizeof(*db));
5dff07f
     memset(db, 0, sizeof(*db));
5dff07f
+    db->pagbno = -1L;
5dff07f
 
5dff07f
     db->pool = p;
5dff07f
 
5dff07f
@@ -193,7 +194,7 @@ APU_DECLARE(apr_status_t) apr_sdbm_fetch(apr_sdbm_t *db, apr_sdbm_datum_t *val,
5dff07f
     if ((status = apr_sdbm_lock(db, APR_FLOCK_SHARED)) != APR_SUCCESS)
5dff07f
         return status;
5dff07f
 
5dff07f
-    if ((status = getpage(db, exhash(key))) == APR_SUCCESS) {
5dff07f
+    if ((status = getpage(db, exhash(key), 0, 1)) == APR_SUCCESS) {
5dff07f
         *val = getpair(db->pagbuf, key);
5dff07f
         /* ### do we want a not-found result? */
5dff07f
     }
5dff07f
@@ -227,7 +228,7 @@ APU_DECLARE(apr_status_t) apr_sdbm_delete(apr_sdbm_t *db,
5dff07f
     if ((status = apr_sdbm_lock(db, APR_FLOCK_EXCLUSIVE)) != APR_SUCCESS)
5dff07f
         return status;
5dff07f
 
5dff07f
-    if ((status = getpage(db, exhash(key))) == APR_SUCCESS) {
5dff07f
+    if ((status = getpage(db, exhash(key), 0, 1)) == APR_SUCCESS) {
5dff07f
         if (!delpair(db->pagbuf, key))
5dff07f
             /* ### should we define some APRUTIL codes? */
5dff07f
             status = APR_EGENERAL;
5dff07f
@@ -261,7 +262,7 @@ APU_DECLARE(apr_status_t) apr_sdbm_store(apr_sdbm_t *db, apr_sdbm_datum_t key,
5dff07f
     if ((status = apr_sdbm_lock(db, APR_FLOCK_EXCLUSIVE)) != APR_SUCCESS)
5dff07f
         return status;
5dff07f
 
5dff07f
-    if ((status = getpage(db, (hash = exhash(key)))) == APR_SUCCESS) {
5dff07f
+    if ((status = getpage(db, (hash = exhash(key)), 0, 1)) == APR_SUCCESS) {
5dff07f
 
5dff07f
         /*
5dff07f
          * if we need to replace, delete the key/data pair
5dff07f
@@ -376,17 +377,19 @@ static apr_status_t makroom(apr_sdbm_t *db, long hash, int need)
5dff07f
 
5dff07f
 /* Reads 'len' bytes from file 'f' at offset 'off' into buf.
5dff07f
  * 'off' is given relative to the start of the file.
5dff07f
- * If EOF is returned while reading, this is taken as success.
5dff07f
+ * If 'create' is asked and EOF is returned while reading, this is taken
5dff07f
+ * as success (i.e. a cleared buffer is returned).
5dff07f
  */
5dff07f
 static apr_status_t read_from(apr_file_t *f, void *buf, 
5dff07f
-             apr_off_t off, apr_size_t len)
5dff07f
+                              apr_off_t off, apr_size_t len,
5dff07f
+                              int create)
5dff07f
 {
5dff07f
     apr_status_t status;
5dff07f
 
5dff07f
     if ((status = apr_file_seek(f, APR_SET, &off)) != APR_SUCCESS ||
5dff07f
         ((status = apr_file_read_full(f, buf, len, NULL)) != APR_SUCCESS)) {
5dff07f
         /* if EOF is reached, pretend we read all zero's */
5dff07f
-        if (status == APR_EOF) {
5dff07f
+        if (status == APR_EOF && create) {
5dff07f
             memset(buf, 0, len);
5dff07f
             status = APR_SUCCESS;
5dff07f
         }
5dff07f
@@ -410,9 +413,7 @@ APU_DECLARE(apr_status_t) apr_sdbm_firstkey(apr_sdbm_t *db,
5dff07f
     /*
5dff07f
      * start at page 0
5dff07f
      */
5dff07f
-    if ((status = read_from(db->pagf, db->pagbuf, OFF_PAG(0), PBLKSIZ))
5dff07f
-                == APR_SUCCESS) {
5dff07f
-        db->pagbno = 0;
5dff07f
+    if ((status = getpage(db, 0, 1, 1)) == APR_SUCCESS) {
5dff07f
         db->blkptr = 0;
5dff07f
         db->keyptr = 0;
5dff07f
         status = getnext(key, db);
5dff07f
@@ -441,24 +442,28 @@ APU_DECLARE(apr_status_t) apr_sdbm_nextkey(apr_sdbm_t *db,
5dff07f
 /*
5dff07f
  * all important binary tree traversal
5dff07f
  */
5dff07f
-static apr_status_t getpage(apr_sdbm_t *db, long hash)
5dff07f
+static apr_status_t getpage(apr_sdbm_t *db, long hash, int by_num, int create)
5dff07f
 {
5dff07f
-    register int hbit;
5dff07f
-    register long dbit;
5dff07f
-    register long pagb;
5dff07f
     apr_status_t status;
5dff07f
+    register long pagb;
5dff07f
 
5dff07f
-    dbit = 0;
5dff07f
-    hbit = 0;
5dff07f
-    while (dbit < db->maxbno && getdbit(db, dbit))
5dff07f
-    dbit = 2 * dbit + ((hash & (1 << hbit++)) ? 2 : 1);
5dff07f
+    if (by_num) {
5dff07f
+        pagb = hash;
5dff07f
+    }
5dff07f
+    else {
5dff07f
+        register int hbit = 0;
5dff07f
+        register long dbit = 0;
5dff07f
 
5dff07f
-    debug(("dbit: %d...", dbit));
5dff07f
+        while (dbit < db->maxbno && getdbit(db, dbit))
5dff07f
+            dbit = 2 * dbit + ((hash & (1 << hbit++)) ? 2 : 1);
5dff07f
+        debug(("dbit: %d...", dbit));
5dff07f
 
5dff07f
-    db->curbit = dbit;
5dff07f
-    db->hmask = masks[hbit];
5dff07f
+        db->curbit = dbit;
5dff07f
+        db->hmask = masks[hbit];
5dff07f
+
5dff07f
+        pagb = hash & db->hmask;
5dff07f
+    }
5dff07f
 
5dff07f
-    pagb = hash & db->hmask;
5dff07f
     /*
5dff07f
      * see if the block we need is already in memory.
5dff07f
      * note: this lookaside cache has about 10% hit rate.
5dff07f
@@ -470,12 +475,14 @@ static apr_status_t getpage(apr_sdbm_t *db, long hash)
5dff07f
          * ### joe: this assumption was surely never correct? but
5dff07f
          * ### we make it so in read_from anyway.
5dff07f
          */
5dff07f
-        if ((status = read_from(db->pagf, db->pagbuf, OFF_PAG(pagb), PBLKSIZ)) 
5dff07f
-                    != APR_SUCCESS)
5dff07f
+        if ((status = read_from(db->pagf, db->pagbuf,
5dff07f
+                                OFF_PAG(pagb), PBLKSIZ,
5dff07f
+                                create)) != APR_SUCCESS)
5dff07f
             return status;
5dff07f
 
5dff07f
         if (!chkpage(db->pagbuf))
5dff07f
             return APR_ENOSPC; /* ### better error? */
5dff07f
+
5dff07f
         db->pagbno = pagb;
5dff07f
 
5dff07f
         debug(("pag read: %d\n", pagb));
5dff07f
@@ -492,8 +499,9 @@ static int getdbit(apr_sdbm_t *db, long dbit)
5dff07f
     dirb = c / DBLKSIZ;
5dff07f
 
5dff07f
     if (dirb != db->dirbno) {
5dff07f
-        if (read_from(db->dirf, db->dirbuf, OFF_DIR(dirb), DBLKSIZ)
5dff07f
-                    != APR_SUCCESS)
5dff07f
+        if (read_from(db->dirf, db->dirbuf,
5dff07f
+                      OFF_DIR(dirb), DBLKSIZ,
5dff07f
+                      1) != APR_SUCCESS)
5dff07f
             return 0;
5dff07f
 
5dff07f
         db->dirbno = dirb;
5dff07f
@@ -515,8 +523,9 @@ static apr_status_t setdbit(apr_sdbm_t *db, long dbit)
5dff07f
     dirb = c / DBLKSIZ;
5dff07f
 
5dff07f
     if (dirb != db->dirbno) {
5dff07f
-        if ((status = read_from(db->dirf, db->dirbuf, OFF_DIR(dirb), DBLKSIZ))
5dff07f
-                    != APR_SUCCESS)
5dff07f
+        if ((status = read_from(db->dirf, db->dirbuf,
5dff07f
+                                OFF_DIR(dirb), DBLKSIZ,
5dff07f
+                                1)) != APR_SUCCESS)
5dff07f
             return status;
5dff07f
 
5dff07f
         db->dirbno = dirb;
5dff07f
@@ -553,21 +562,12 @@ static apr_status_t getnext(apr_sdbm_datum_t *key, apr_sdbm_t *db)
5dff07f
          * try the next one... If we lost our position on the
5dff07f
          * file, we will have to seek.
5dff07f
          */
5dff07f
+        db->blkptr++;
5dff07f
         db->keyptr = 0;
5dff07f
-        if (db->pagbno != db->blkptr++) {
5dff07f
-            apr_off_t off = OFF_PAG(db->blkptr);
5dff07f
-            if ((status = apr_file_seek(db->pagf, APR_SET, &off))
5dff07f
-                        != APR_SUCCESS)
5dff07f
-                return status;
5dff07f
-        }
5dff07f
 
5dff07f
-        db->pagbno = db->blkptr;
5dff07f
         /* ### EOF acceptable here too? */
5dff07f
-        if ((status = apr_file_read_full(db->pagf, db->pagbuf, PBLKSIZ, NULL))
5dff07f
-                    != APR_SUCCESS)
5dff07f
+        if ((status = getpage(db, db->blkptr, 1, 0)) != APR_SUCCESS)
5dff07f
             return status;
5dff07f
-        if (!chkpage(db->pagbuf))
5dff07f
-            return APR_EGENERAL;     /* ### need better error */
5dff07f
     }
5dff07f
 
5dff07f
     /* NOTREACHED */
5dff07f
diff --git a/dbm/sdbm/sdbm_pair.c b/dbm/sdbm/sdbm_pair.c
5dff07f
index 2130200..af70614 100644
5dff07f
--- a/dbm/sdbm/sdbm_pair.c
5dff07f
+++ b/dbm/sdbm/sdbm_pair.c
5dff07f
@@ -308,7 +308,8 @@ char *pag;
5dff07f
 	if (n > 0) {
5dff07f
 		off = PBLKSIZ;
5dff07f
 		for (ino++; n > 0; ino += 2) {
5dff07f
-			if (ino[0] > off || ino[1] > off ||
5dff07f
+			 if (ino[0] < 0 || ino[0] > off ||
5dff07f
+			    ino[1] < 0 || ino[1] > off ||
5dff07f
 			    ino[1] > ino[0])
5dff07f
 				return 0;
5dff07f
 			off = ino[1];