Consultor Eletrônico



Kbase 17970: A 'C' program to display a Database block in ASCII.
Autor   Progress Software Corporation - Progress
Acesso   Público
Publicação   27/05/1998
A 'C' program to display a Database block in ASCII.

INTRODUCTION:
=============

This Knowledgebase contains a 'C' program which views the contence of
a Database block in hexadecimal and ASCII.


WHY YOU NEED TO KNOW THIS:
===========================

If a Database block becomes corrupt it is hard to determine what is
stored in the block. A way to view the block contence is to dump
the block from the Database repair util but that will give only a
hexadecimal dump which is not easy to read.


PROCEDURAL APPROACH:
====================

Compile the source with your system's C compiler:
cc viewblock.c -o viewblock OR make viewblock

Use the following syntax:
viewblock <database name> dbkey

Use your favorite pager to page the output.
Example: viewblock demo 128 | pg


Restriction: Only single volume databases.

The program:

#include <stdio.h>
#include <math.h>

long lseek();
void
syserr(msg)
char *msg;
{
extern int errno, sys_nerr;
extern char *sys_errlist[];

fprintf(stderr, "\nERROR: %s (%d", msg, errno);
if (errno > 0 && errno < sys_nerr)
fprintf(stderr, "; %s)\n", sys_errlist[errno]);
else
fprintf(stderr,")\n");
exit(1);
}

FILE *fpdb;
short int blocksize;

main(argc,argv)
int argc;
char *argv[];
{
FILE *fopen(), *fplock;
char dbname[70], lockfile[70];
short int dbversion;
long int dbblocks, dbkey=0, blocknum=0, dbwater=0, offset;

if (argc < 3) /* Te weinig opties: error */
{
printf("%s: Usage: %s <database> dbkey.\n",argv[0],argv[0]);
exit(1);
}

if (argc > 3) /* Te veel opties: error */
{
printf("%s: Too many options.\n",argv[0]);
exit(1);
}

strcpy(dbname,argv[1]);
strcat(dbname,".db");
if (( fpdb = fopen(dbname, "rb" )) == NULL)
{
printf("%s: Could not find or open file %s\n",argv[0],dbname);
syserr("");
exit(1);
}

strcpy(lockfile,argv[1]);
strcat(lockfile,".lk");
printf("\n Blockview. Version 1.0 by Peter de Jong.\n
\n");
if (( fplock = fopen(lockfile,"r")) != NULL)
{
printf("WARNING: The lockfile %s exists!\n\n",lockfile);
fclose(fplock);
}

printf(" Database name: %s\n",dbname);

if (fseek(fpdb, 16, 0) == -1)
syserr("fseek");
if (fread(&dbversion, 1, 2, fpdb) != 2)
syserr("fread");
printf(" Database version number: %d\n",dbversion);

if (fseek(fpdb, 18, 0) == -1)
syserr("fseek");
if (fread(&blocksize, 1, 2, fpdb) != 2)
syserr("fread");
blocksize = (blocksize * 512);
printf(" Database blocksize: %d\n",blocksize);

if (fseek(fpdb, 24, 0) == -1)
syserr("fseek");
if (fread(&dbblocks, 1, 4, fpdb) != 4)
syserr("fread");
printf(" Number of blocks in database: %d\n",dbblocks);

if (dbblocks == 0) {
printf("\nERROR: Multi Volume database or masterblock corrupted.\n
Number of database blocks = %d.\n",dbblocks);
exit(1);
if (fseek(fpdb, 48, 0) == -1)
syserr("fseek");
if (fread(&dbwater, 1, 4, fpdb) != 4)
syserr("fread");
printf(" Database blocks used: %d\n",dbwater);

/* MAINLOOP */
dbkey = atoi(argv[2]);

if (dbkey % 32 || dbkey < 1)
{
printf("\nERROR: %d is not a multiple of 32.\n",dbkey);
exit(1);
}

printf(" Database key (dbkey): %d\n",dbkey);

if (dbkey > (dbwater * 32))
{
printf("\nERROR: %d is too large for the database.\n",dbkey);
exit(1);
}
offset = (((dbkey / 32) -1) * blocksize);
printf(" file offset: %d\n\n", offset);

if (fseek(fpdb, offset, 0) == -1)
syserr("fseek");

hd(fpdb,blocksize);

/* Cleaning up */
fclose(fpdb);
exit(0);
} /* main */

hd(fpdb,blocksize)
FILE *fpdb; {
int i; char w;
int offset, cnt, hi, lo, word[8];
offset = 0;
cnt = 8;

while (cnt == 8) {
puthex(offset, 4);
putchar(':');
putchar(' ');
for (cnt = 0; cnt < 8; ) {
if ((hi = getc(fpdb)) == EOF) break;
offset++;
if ((lo = getc(fpdb)) == EOF) {
word[cnt++] = (hi << 8);
break;
}
else {
word[cnt++] = (hi << 8) + lo;
offset++;
}
for (i = 0; i < cnt; i++) {
puthex(word[i], 4);
putchar(' ');
}
for ( ; i < 8; i++) printf(" ");
printf(" | ");
for (i = 0; i < cnt; i++) {
putcx(word[i] >> 8);
putcx(word[i]);
}
putchar('\n');
/* Leave after displaying the db block */
if (offset > blocksize) return;
}
if (cnt != 0) {
puthex(offset, 4);
putchar('\n');
}
}

puthex(n, size) {
if (size > 1) puthex(n >> 4, size - 1);
putchar("0123456789ABCDEF"[n & 15]);
}

putcx(c) {
c = c & 255;
if (c >= 32 && c <= 127) putchar(c);
else putchar('.');
}
/* EOF */


NOTE: This program is tested on most major UNIX systems, this does not
imply it will compile and run on your system.
This program is not supported. Tested on V6, V7 & V8 Databases.


PJO 27 May 1998