17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate ** A utility for printing an SQLite database journal.
37c478bd9Sstevel@tonic-gate */
47c478bd9Sstevel@tonic-gate #include <stdio.h>
57c478bd9Sstevel@tonic-gate #include <ctype.h>
67c478bd9Sstevel@tonic-gate #include <sys/types.h>
77c478bd9Sstevel@tonic-gate #include <sys/stat.h>
87c478bd9Sstevel@tonic-gate #include <fcntl.h>
97c478bd9Sstevel@tonic-gate #include <unistd.h>
107c478bd9Sstevel@tonic-gate #include <stdlib.h>
117c478bd9Sstevel@tonic-gate
127c478bd9Sstevel@tonic-gate
137c478bd9Sstevel@tonic-gate static int pagesize = 1024;
147c478bd9Sstevel@tonic-gate static int db = -1;
157c478bd9Sstevel@tonic-gate static int mxPage = 0;
167c478bd9Sstevel@tonic-gate
out_of_memory(void)177c478bd9Sstevel@tonic-gate static void out_of_memory(void){
187c478bd9Sstevel@tonic-gate fprintf(stderr,"Out of memory...\n");
197c478bd9Sstevel@tonic-gate exit(1);
207c478bd9Sstevel@tonic-gate }
217c478bd9Sstevel@tonic-gate
print_page(int iPg)227c478bd9Sstevel@tonic-gate static print_page(int iPg){
237c478bd9Sstevel@tonic-gate unsigned char *aData;
247c478bd9Sstevel@tonic-gate int i, j;
257c478bd9Sstevel@tonic-gate aData = malloc(pagesize);
267c478bd9Sstevel@tonic-gate if( aData==0 ) out_of_memory();
277c478bd9Sstevel@tonic-gate read(db, aData, pagesize);
287c478bd9Sstevel@tonic-gate fprintf(stdout, "Page %d:\n", iPg);
297c478bd9Sstevel@tonic-gate for(i=0; i<pagesize; i += 16){
307c478bd9Sstevel@tonic-gate fprintf(stdout, " %03x: ",i);
317c478bd9Sstevel@tonic-gate for(j=0; j<16; j++){
327c478bd9Sstevel@tonic-gate fprintf(stdout,"%02x ", aData[i+j]);
337c478bd9Sstevel@tonic-gate }
347c478bd9Sstevel@tonic-gate for(j=0; j<16; j++){
357c478bd9Sstevel@tonic-gate fprintf(stdout,"%c", isprint(aData[i+j]) ? aData[i+j] : '.');
367c478bd9Sstevel@tonic-gate }
377c478bd9Sstevel@tonic-gate fprintf(stdout,"\n");
387c478bd9Sstevel@tonic-gate }
397c478bd9Sstevel@tonic-gate free(aData);
407c478bd9Sstevel@tonic-gate }
417c478bd9Sstevel@tonic-gate
main(int argc,char ** argv)427c478bd9Sstevel@tonic-gate int main(int argc, char **argv){
437c478bd9Sstevel@tonic-gate struct stat sbuf;
447c478bd9Sstevel@tonic-gate unsigned int u;
457c478bd9Sstevel@tonic-gate int rc;
467c478bd9Sstevel@tonic-gate unsigned char zBuf[10];
477c478bd9Sstevel@tonic-gate unsigned char zBuf2[sizeof(u)];
487c478bd9Sstevel@tonic-gate if( argc!=2 ){
497c478bd9Sstevel@tonic-gate fprintf(stderr,"Usage: %s FILENAME\n", argv[0]);
507c478bd9Sstevel@tonic-gate exit(1);
517c478bd9Sstevel@tonic-gate }
527c478bd9Sstevel@tonic-gate db = open(argv[1], O_RDONLY);
537c478bd9Sstevel@tonic-gate if( db<0 ){
547c478bd9Sstevel@tonic-gate fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]);
557c478bd9Sstevel@tonic-gate exit(1);
567c478bd9Sstevel@tonic-gate }
577c478bd9Sstevel@tonic-gate read(db, zBuf, 8);
587c478bd9Sstevel@tonic-gate if( zBuf[7]==0xd6 ){
597c478bd9Sstevel@tonic-gate read(db, &u, sizeof(u));
607c478bd9Sstevel@tonic-gate printf("Records in Journal: %u\n", u);
617c478bd9Sstevel@tonic-gate read(db, &u, sizeof(u));
627c478bd9Sstevel@tonic-gate printf("Magic Number: 0x%08x\n", u);
637c478bd9Sstevel@tonic-gate }
647c478bd9Sstevel@tonic-gate read(db, zBuf2, sizeof(zBuf2));
657c478bd9Sstevel@tonic-gate u = zBuf2[0]<<24 | zBuf2[1]<<16 | zBuf2[2]<<8 | zBuf2[3];
667c478bd9Sstevel@tonic-gate printf("Database Size: %u\n", u);
677c478bd9Sstevel@tonic-gate while( read(db, zBuf2, sizeof(zBuf2))==sizeof(zBuf2) ){
687c478bd9Sstevel@tonic-gate u = zBuf2[0]<<24 | zBuf2[1]<<16 | zBuf2[2]<<8 | zBuf2[3];
697c478bd9Sstevel@tonic-gate print_page(u);
707c478bd9Sstevel@tonic-gate if( zBuf[7]==0xd6 ){
717c478bd9Sstevel@tonic-gate read(db, &u, sizeof(u));
727c478bd9Sstevel@tonic-gate printf("Checksum: 0x%08x\n", u);
737c478bd9Sstevel@tonic-gate }
747c478bd9Sstevel@tonic-gate }
757c478bd9Sstevel@tonic-gate close(db);
767c478bd9Sstevel@tonic-gate }
77