+ unsigned int key_vbn = 0;
+ unsigned int key_off = 0;
+
+ idxlen = get_idxlen (idx, is_elfidx);
+
+ if (is_elfidx && idx->namlen > MAX_KEYLEN)
+ {
+ /* If the key (ie name) is too long, write it in the kbn block. */
+ unsigned int kl = idx->namlen;
+ unsigned int kl_chunk;
+ const char *key = idx->name;
+
+ /* Write the key in the kbn, chunk after chunk. */
+ do
+ {
+ if (kbn_sz < sizeof (struct vms_kbn))
+ {
+ /* Not enough room in the kbn block. */
+ if (abfd != NULL)
+ {
+ /* Write it to the disk (if there is one). */
+ if (kbn_vbn != 0)
+ {
+ if (vms_write_block (abfd, kbn_vbn, kbn_blk) != TRUE)
+ return FALSE;
+ }
+ else
+ {
+ kbn_blk = bfd_malloc (VMS_BLOCK_SIZE);
+ if (kbn_blk == NULL)
+ return FALSE;
+ }
+ *(unsigned short *)kbn_blk = 0;
+ }
+ /* Allocate a new block for the keys. */
+ kbn_vbn = (*vbn)++;
+ kbn_sz = VMS_BLOCK_SIZE - 2;
+ }
+ /* Size of the chunk written to the current key block. */
+ if (kl + sizeof (struct vms_kbn) > kbn_sz)
+ kl_chunk = kbn_sz - sizeof (struct vms_kbn);
+ else
+ kl_chunk = kl;
+
+ if (kbn_blk != NULL)
+ {
+ struct vms_kbn *kbn;
+
+ kbn = (struct vms_kbn *)(kbn_blk + VMS_BLOCK_SIZE - kbn_sz);
+
+ if (key_vbn == 0)
+ {
+ /* Save the rfa of the first chunk. */
+ key_vbn = kbn_vbn;
+ key_off = VMS_BLOCK_SIZE - kbn_sz;
+ }
+
+ bfd_putl16 (kl_chunk, kbn->keylen);
+ if (kl_chunk == kl)
+ {
+ /* No next chunk. */
+ bfd_putl32 (0, kbn->rfa.vbn);
+ bfd_putl16 (0, kbn->rfa.offset);
+ }
+ else
+ {
+ /* Next chunk will be at the start of the next block. */
+ bfd_putl32 (*vbn, kbn->rfa.vbn);
+ bfd_putl16 (2, kbn->rfa.offset);
+ }
+ memcpy ((char *)(kbn + 1), key, kl_chunk);
+ key += kl_chunk;
+ }
+ kl -= kl_chunk;
+ kl_chunk = (kl_chunk + 1) & ~1; /* Always align. */
+ kbn_sz -= kl_chunk + sizeof (struct vms_kbn);
+ }
+ while (kl > 0);
+ }