+ isamb->file[i].cache_entries = 0;
+ }
+
+ for (i = 0; i < isamb->no_cat; i++)
+ {
+ char fname[DST_BUF_SIZE];
+ char hbuf[DST_BUF_SIZE];
+
+ sprintf(fname, "%s%c", name, i+'A');
+ if (cache)
+ isamb->file[i].bf = bf_open(bfs, fname, ISAMB_CACHE_ENTRY_SIZE,
+ writeflag);
+ else
+ isamb->file[i].bf = bf_open(bfs, fname, sizes[i], writeflag);
+
+ if (!isamb->file[i].bf)
+ {
+ isamb_close(isamb);
+ return 0;
+ }
+
+ /* fill-in default values (for empty isamb) */
+ isamb->file[i].head.first_block = ISAMB_CACHE_ENTRY_SIZE/sizes[i]+1;
+ isamb->file[i].head.last_block = isamb->file[i].head.first_block;
+ isamb->file[i].head.block_size = sizes[i];
+ assert(sizes[i] <= ISAMB_CACHE_ENTRY_SIZE);
+#if ISAMB_PTR_CODEC
+ if (i == isamb->no_cat-1 || sizes[i] > 128)
+ isamb->file[i].head.block_offset = 8;
+ else
+ isamb->file[i].head.block_offset = 4;
+#else
+ isamb->file[i].head.block_offset = 11;
+#endif
+ isamb->file[i].head.block_max =
+ sizes[i] - isamb->file[i].head.block_offset;
+ isamb->file[i].head.free_list = 0;
+ if (bf_read(isamb->file[i].bf, 0, 0, 0, hbuf))
+ {
+ /* got header assume "isamb"major minor len can fit in 16 bytes */
+ zint zint_tmp;
+ int major, minor, len, pos = 0;
+ int left;
+ const char *src = 0;
+ if (memcmp(hbuf, "isamb", 5))
+ {
+ yaz_log(YLOG_WARN, "bad isamb header for file %s", fname);
+ isamb_close(isamb);
+ return 0;
+ }
+ if (sscanf(hbuf+5, "%d %d %d", &major, &minor, &len) != 3)
+ {
+ yaz_log(YLOG_WARN, "bad isamb header for file %s", fname);
+ isamb_close(isamb);
+ return 0;
+ }
+ if (major != ISAMB_MAJOR_VERSION)
+ {
+ yaz_log(YLOG_WARN, "bad major version for file %s %d, must be %d",
+ fname, major, ISAMB_MAJOR_VERSION);
+ isamb_close(isamb);
+ return 0;
+ }
+ for (left = len - sizes[i]; left > 0; left = left - sizes[i])
+ {
+ pos++;
+ if (!bf_read(isamb->file[i].bf, pos, 0, 0, hbuf + pos*sizes[i]))
+ {
+ yaz_log(YLOG_WARN, "truncated isamb header for "
+ "file=%s len=%d pos=%d",
+ fname, len, pos);
+ isamb_close(isamb);
+ return 0;
+ }
+ }
+ src = hbuf + 16;
+ decode_ptr(&src, &isamb->file[i].head.first_block);
+ decode_ptr(&src, &isamb->file[i].head.last_block);
+ decode_ptr(&src, &zint_tmp);
+ isamb->file[i].head.block_size = (int) zint_tmp;
+ decode_ptr(&src, &zint_tmp);
+ isamb->file[i].head.block_max = (int) zint_tmp;
+ decode_ptr(&src, &isamb->file[i].head.free_list);
+ if (isamb->minor_version >= ISAMB_MINOR_VERSION_WITH_ROOT)
+ decode_ptr(&src, &isamb->root_ptr);
+ }
+ assert(isamb->file[i].head.block_size >= isamb->file[i].head.block_offset);
+ /* must rewrite the header if root ptr is in use (bug #1017) */
+ if (use_root_ptr && writeflag)
+ isamb->file[i].head_dirty = 1;
+ else
+ isamb->file[i].head_dirty = 0;
+ assert(isamb->file[i].head.block_size == sizes[i]);