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