ref: 64e312636599ea2c86f21dc1176dca7da77bd74a
dir: /dba.c/
/*
* dba dbm analysis/recovery
*/
#include <u.h>
#include <libc.h>
#include <stdio.h>
#include "sdbm.h"
char *progname;
extern void oops(char *, char *);
extern int okpage(char *);
void sdump(int);
int pagestat(char *);
void
main(int argc, char **argv)
{
int n;
char *p;
char *name;
int pagf;
progname = argv[0];
if (argc != 2) oops("usage: %s dbname\n", progname); /* keeps compiler quiet */
if (p = argv[1]) {
name = (char *) malloc((n = strlen(p)) + 5);
strcpy(name, p);
strcpy(name + n, ".pag");
if ((pagf = open(name, OREAD)) < 0)
oops("cannot open %s.", name);
sdump(pagf);
}
else
oops("usage: %s dbname\n", progname);
exits(0);
}
void
sdump(int pagf)
{
int b;
int n = 0;
int t = 0;
int o = 0;
int e;
char pag[PBLKSIZ];
char num[16];
while ((b = read(pagf, pag, PBLKSIZ)) > 0) {
printf("#%d: ", n);
if (!okpage(pag))
printf("bad\n");
else {
printf("ok. ");
if (!(e = pagestat(pag)))
o++;
else
t += e;
}
n++;
}
if (b == 0)
printf("%d pages (%d holes): %d entries\n", n, o, t);
else
{
snprintf(num, 15, "%d", n);
oops("read failed: block %d", num);
}
}
int
pagestat(char *pag)
{
register n;
register free;
register short *ino = (short *) pag;
if (!(n = ino[0]))
printf("no entries.\n");
else {
free = ino[n] - (n + 1) * sizeof(short);
printf("%3d entries %2d%% used free %d.\n",
n / 2, ((PBLKSIZ - free) * 100) / PBLKSIZ, free);
}
return n / 2;
}