+static void read_indx (Records p, int sysno, void *buf, int itemsize)
+{
+ int r;
+ off_t pos = (sysno-1)*itemsize + sizeof(p->head);
+
+ if (lseek (p->index_fd, pos, SEEK_SET) == (pos) -1)
+ {
+ logf (LOG_FATAL|LOG_ERRNO, "seek in %s to pos %ld",
+ p->index_fname, (long) pos);
+ exit (1);
+ }
+ r = read (p->index_fd, buf, itemsize);
+ if (r != itemsize)
+ {
+ if (r == -1)
+ logf (LOG_FATAL|LOG_ERRNO, "read in %s at pos %ld",
+ p->index_fname, (long) pos);
+ else
+ logf (LOG_FATAL, "read in %s at pos %ld",
+ p->index_fname, (long) pos);
+ exit (1);
+ }
+}
+
+static void rec_write_single (Records p, Record rec)
+{
+ struct record_index_entry entry;
+ int r, i, size = 0, got;
+ char *cptr;
+ off_t pos = (rec->sysno-1)*sizeof(entry) + sizeof(p->head);
+
+ for (i = 0; i < REC_NO_INFO; i++)
+ if (!rec->info[i])
+ size++;
+ else
+ size += strlen(rec->info[i])+1;
+
+ entry.u.used.offset = p->head.data_size;
+ entry.u.used.size = size;
+ p->head.data_size += size;
+ p->head.data_used += size;
+
+ if (lseek (p->index_fd, pos, SEEK_SET) == (pos) -1)
+ {
+ logf (LOG_FATAL|LOG_ERRNO, "seek in %s to pos %ld",
+ p->index_fname, (long) pos);
+ exit (1);
+ }
+ r = write (p->index_fd, &entry, sizeof(entry));
+ if (r != sizeof(entry))
+ {
+ if (r == -1)
+ logf (LOG_FATAL|LOG_ERRNO, "write of %s at pos %ld",
+ p->index_fname, (long) pos);
+ else
+ logf (LOG_FATAL, "write of %s at pos %ld",
+ p->index_fname, (long) pos);
+ exit (1);
+ }
+ if (lseek (p->data_fd, entry.u.used.offset, SEEK_SET) == -1)
+ {
+ logf (LOG_FATAL|LOG_ERRNO, "lseek in %s to pos %ld",
+ p->data_fname, entry.u.used.offset);
+ exit (1);
+ }
+ if (p->tmp_size < entry.u.used.size)
+ {
+ free (p->tmp_buf);
+ p->tmp_size = entry.u.used.size + 16384;
+ if (!(p->tmp_buf = malloc (p->tmp_size)))
+ {
+ logf (LOG_FATAL|LOG_ERRNO, "malloc");
+ exit (1);
+ }
+ }
+ cptr = p->tmp_buf;
+ for (i = 0; i < REC_NO_INFO; i++)
+ if (!rec->info[i])
+ *cptr++ = '\0';
+ else
+ {
+ strcpy (cptr, rec->info[i]);
+ cptr += strlen(rec->info[i]) + 1;
+ }
+ for (got = 0; got < entry.u.used.size; got += r)
+ {
+ r = write (p->data_fd, p->tmp_buf + got, entry.u.used.size - got);
+ if (r <= 0)
+ {
+ logf (LOG_FATAL|LOG_ERRNO, "write of %s", p->data_fname);
+ exit (1);
+ }
+ got += r;
+ }
+}
+
+static void rec_cache_flush (Records p)
+{
+ int i;
+ for (i = 0; i<p->cache_cur; i++)
+ {
+ struct record_cache_entry *e = p->record_cache + i;
+ if (e->dirty)
+ rec_write_single (p, e->rec);
+ rec_rm (e->rec);
+ }
+ p->cache_cur = 0;
+}
+
+static Record *rec_cache_lookup (Records p, int sysno, int dirty)
+{
+ int i;
+ for (i = 0; i<p->cache_cur; i++)
+ {
+ struct record_cache_entry *e = p->record_cache + i;
+ if (e->rec->sysno == sysno)
+ {
+ if (dirty)
+ e->dirty = 1;
+ return &e->rec;
+ }
+ }
+ return NULL;
+}
+
+static void rec_cache_insert (Records p, Record rec, int dirty)