Reimplementation of Pijul in C, for education, fun and absolutely no profit
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>

#include <sys/mman.h>

#include "common.h"
#include "types.h"
#include "scaffold.h"
#include "db.h"

static void
dumpbytes(u8 *mem, usize len)
{
	usize i;

	printf("%02x", mem[0]);
	for (i = 1; i < len; i++) {
		printf(" %02x", mem[i]);
	}
	printf("\n");
}

static void
readglobalheader(u8 *mem, struct globalheader *gh)
{
	dumpbytes(mem, sizeof(struct globalheader));

	// FIXME: Does not work for big-endian systems
	*gh = *((struct globalheader *)mem);
}

static void
printglobalheader(struct globalheader *gh, size i, bool currentroot)
{
	printf("--- root page %lu ---\n", i);
	printf("version = %u root = %u %s nroots = %u\n", gh->version, gh->root,
	       currentroot ? "(current)" : "", gh->nroots);
	printf("CRC = 0x%04x (%u)\n", gh->crc, gh->crc);
	printf("length = %lu (0x%08lx)\n", gh->length, gh->length);
	printf("freedb = %lu (0x%08lx)\n", gh->freedb, gh->freedb);
	printf("rcdb = %lu\n", gh->rcdb);
}

void
dbrun(char *db)
{
	int fd;
	u8 *addr;
	u8 nroots, curroot;
	size i;
	struct globalheader gh;

	printf("opening %s\n", db);

	fd = open(db, O_RDONLY);
	if (fd == -1)
		die("open:%s", strerror(errno));

	addr = mmap(NULL, PAGESZ, PROT_READ, MAP_PRIVATE, fd, 0);
	if (addr == MAP_FAILED)
		die("mmap:%s", strerror(errno));

	readglobalheader(addr, &gh);
	munmap(addr, PAGESZ);
	nroots = gh.nroots;
	curroot = gh.root;

	printglobalheader(&gh, 0, curroot == 0);

	// for nroots-1 times, read the i << 12'th page
	for (i = 1; i < nroots; i++) {
		addr = mmap(NULL, PAGESZ, PROT_READ, MAP_PRIVATE, fd, i << 12);
		if (addr == MAP_FAILED)
			die("mmap:%s", strerror(errno));
		readglobalheader(addr, &gh);
		munmap(addr, PAGESZ);

		printglobalheader(&gh, i, curroot == i);
	}

	close(fd);
}