15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A utility for printing an SQLite database journal. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ctype.h> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** state information 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int pageSize = 1024; 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int sectorSize = 512; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static FILE *db = 0; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int showPageContent = 0; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fileSize = 0; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned cksumNonce = 0; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Report a memory allocation error */ 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void out_of_memory(void){ 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Out of memory...\n"); 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Read N bytes of memory starting at iOfst into space obtained 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** from malloc(). 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char *read_content(int N, int iOfst){ 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int got; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *pBuf = malloc(N); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pBuf==0 ) out_of_memory(); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fseek(db, iOfst, SEEK_SET); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) got = fread(pBuf, 1, N, db); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( got<0 ){ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "I/O error reading %d bytes from %d\n", N, iOfst); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(pBuf, 0, N); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( got<N ){ 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Short read: got only %d of %d bytes from %d\n", 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) got, N, iOfst); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&pBuf[got], 0, N-got); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pBuf; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Print a line of decode output showing a 4-byte integer. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned print_decode_line( 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char *aData, /* Content being decoded */ 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ofst, int nByte, /* Start and size of decode */ 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zMsg /* Message to append */ 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned val = aData[ofst]; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char zBuf[100]; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf(zBuf, " %03x: %02x", ofst, aData[ofst]); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = strlen(zBuf); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=1; j<4; j++){ 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j>=nByte ){ 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf(&zBuf[i], " "); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf(&zBuf[i], " %02x", aData[ofst+j]); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val = val*256 + aData[ofst+j]; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i += strlen(&zBuf[i]); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf(&zBuf[i], " %10u", val); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("%s %s\n", zBuf, zMsg); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return val; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Read and print a journal header. Store key information (page size, etc) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in global variables. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned decode_journal_header(int iOfst){ 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *pHdr = read_content(64, iOfst); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned nPage; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Header at offset %d:\n", iOfst); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_decode_line(pHdr, 0, 4, "Header part 1 (3654616569)"); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_decode_line(pHdr, 4, 4, "Header part 2 (547447767)"); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nPage = 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_decode_line(pHdr, 8, 4, "page count"); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cksumNonce = 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_decode_line(pHdr, 12, 4, "chksum nonce"); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_decode_line(pHdr, 16, 4, "initial database size in pages"); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sectorSize = 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_decode_line(pHdr, 20, 4, "sector size"); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pageSize = 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_decode_line(pHdr, 24, 4, "page size"); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_decode_line(pHdr, 28, 4, "zero"); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_decode_line(pHdr, 32, 4, "zero"); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_decode_line(pHdr, 36, 4, "zero"); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_decode_line(pHdr, 40, 4, "zero"); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(pHdr); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return nPage; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void print_page(int iOfst){ 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char *aData; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char zTitle[50]; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aData = read_content(pageSize+8, iOfst); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf(zTitle, "page number for page at offset %d", iOfst); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_decode_line(aData, 0, 4, zTitle); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(aData); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char **argv){ 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nPage, cnt; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iOfst; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc!=2 ){ 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Usage: %s FILENAME\n", argv[0]); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db = fopen(argv[1], "rb"); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( db==0 ){ 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fseek(db, 0, SEEK_END); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fileSize = ftell(db); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("journal file size: %d bytes\n", fileSize); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fseek(db, 0, SEEK_SET); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iOfst = 0; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( iOfst<fileSize ){ 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cnt = nPage = (int)decode_journal_header(iOfst); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cnt==0 ){ 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cnt = (fileSize - sectorSize)/(pageSize+8); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iOfst += sectorSize; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( cnt && iOfst<fileSize ){ 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_page(iOfst); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iOfst += pageSize+8; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iOfst = (iOfst/sectorSize + 1)*sectorSize; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fclose(db); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 140