+ uns page = d->find_page;
+ uns pos = d->find_pos;
+ byte *K, *V;
+ uns c, Kl, Vl;
+ struct page *p;
+ struct sdbm_bucket *b;
+
+ for(;;)
+ {
+ if (!pos)
+ {
+ if (page >= d->file_size)
+ break;
+ if (page == d->root->dir_start)
+ page += (4*d->dir_size + d->page_size - 1) >> d->page_order;
+ else if (page == d->root->free_pool[d->find_free_list].first)
+ page += d->root->free_pool[d->find_free_list++].count;
+ else
+ pos = 4;
+ continue;
+ }
+ p = READ_PAGE(d, page);
+ b = (void *) p->data;
+ if (pos - 4 >= b->used)
+ {
+ pos = 0;
+ page++;
+ pgc_put(d->cache, p);
+ continue;
+ }
+ c = sdbm_get_entry(d, p->data + pos, &K, &Kl, &V, &Vl);
+ d->find_page = page;
+ d->find_pos = pos + c;
+ c = sdbm_put_user(K, Kl, key, keylen) ||
+ sdbm_put_user(V, Vl, val, vallen);
+ pgc_put(d->cache, p);
+ return c ? SDBM_ERROR_TOO_LARGE : 1;
+ }
+ d->find_page = page;
+ d->find_pos = pos;