/* * dba dbm analysis/recovery */ #include #ifdef LiamSysV # include #else # include #endif #include "sdbm.h" #define empty(page) (((short *) page)[0] == 0) static char *progname; int main(argc, argv) char **argv; { int n; char *p; char *name; int pagf; progname = argv[0]; if (p = argv[1]) { name = (char *) malloc((n = strlen(p)) + 5); strcpy(name, p); strcpy(name + n, ".pag"); if ((pagf = open(name, O_RDONLY)) < 0) oops("cannot open %s.", name); sdump(pagf); } else oops("usage: %s dbname", progname); return 0; } sdump(pagf) int pagf; { register r; register n = 0; register o = 0; char pag[PBLKSIZ]; while ((r = read(pagf, pag, PBLKSIZ)) > 0) { if (!chkpage(pag)) fprintf(stderr, "%d: bad page.\n", n); else if (empty(pag)) o++; else dispage(pag); n++; } if (r == 0) fprintf(stderr, "%d pages (%d holes).\n", n, o); else oops("read failed: block %d", n); } dispage(pag) char *pag; { register i, n; register off; register short *ino = (short *) pag; off = PBLKSIZ; for (i = 1; i < ino[0]; i += 2) { for (n = ino[i]; n < off; n++) if (pag[n] != 0) putchar(pag[n]); putchar('\t'); off = ino[i]; for (n = ino[i + 1]; n < off; n++) if (pag[n] != 0) putchar(pag[n]); putchar('\n'); off = ino[i + 1]; } } chkpage(pag) char *pag; { register unsigned n; register off; register short *ino = (short *) pag; if ((n = ino[0]) > PBLKSIZ / sizeof(short)) return (0); if (!n) return (1); off = PBLKSIZ; for (ino++; n; ino += 2) { if (ino[0] > off || ino[1] > off || ino[1] > ino[0]) return (0); off = ino[1]; n -= 2; } return (1); } oops(s1, s2) register char *s1; register char *s2; { extern int errno, sys_nerr; extern char *sys_errlist[]; extern char *progname; if (progname) printf("%s: ", progname); printf(s1, s2); if (errno > 0 && errno < sys_nerr) printf(" (%s)", sys_errlist[errno]); printf("\n"); exit(1); }