/ Check-in [fa97d895]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Updates to the showjournal.c utility in order to bring it up to version 3.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:fa97d895463be6fd963c29b4525c2664193e36ec
User & Date: drh 2010-10-01 13:28:43
Context
2010-10-01
17:23
Add #ifndef USE_SYSTEM_SQLITE...#endif around the bundled SQLite library for the TCL bindings. check-in: 8d85584a user: drh tags: trunk
15:11
Not true: For a zeroblob, the Mem.z pointer can be null: The Mem.z pointer can never been NULL for a string or blob, even a zero-length string or blob. Assert this fact. Closed-Leaf check-in: efda3104 user: drh tags: mistake
13:28
Updates to the showjournal.c utility in order to bring it up to version 3. check-in: fa97d895 user: drh tags: trunk
2010-09-30
20:33
Merge experimental into trunk: Refactor the text-to-numeric conversion routines to work without zero-terminators and in UTF16 as well as UTF8. Avoid invalidating strings with doing affinity conversions. check-in: 07ee080e user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to tool/showjournal.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16



17
18
19
20
21
22

23



24
25
26
27
28
29
30
31
32






33
34
35

36
37
38



























































39
40
41
42
43
44
45
46
47


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62



63
64
65
66
67
68
69
70
71
72
73

74
75
76
/*
** A utility for printing an SQLite database journal.
*/
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>


static int pagesize = 1024;
static int db = -1;
static int mxPage = 0;




static void out_of_memory(void){
  fprintf(stderr,"Out of memory...\n");
  exit(1);
}

static print_page(int iPg){

  unsigned char *aData;



  int i, j;
  aData = malloc(pagesize);
  if( aData==0 ) out_of_memory();
  read(db, aData, pagesize);
  fprintf(stdout, "Page %d:\n", iPg);
  for(i=0; i<pagesize; i += 16){
    fprintf(stdout, " %03x: ",i);
    for(j=0; j<16; j++){
      fprintf(stdout,"%02x ", aData[i+j]);






    }
    for(j=0; j<16; j++){
      fprintf(stdout,"%c", isprint(aData[i+j]) ? aData[i+j] : '.');

    }
    fprintf(stdout,"\n");
  }



























































  free(aData);
}

int main(int argc, char **argv){
  struct stat sbuf;
  unsigned int u;
  int rc;
  unsigned char zBuf[10];
  unsigned char zBuf2[sizeof(u)];


  if( argc!=2 ){
    fprintf(stderr,"Usage: %s FILENAME\n", argv[0]);
    exit(1);
  }
  db = open(argv[1], O_RDONLY);
  if( db<0 ){
    fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]);
    exit(1);
  }
  read(db, zBuf, 8);
  if( zBuf[7]==0xd6 ){
    read(db, &u, sizeof(u));
    printf("Records in Journal: %u\n", u);
    read(db, &u, sizeof(u));
    printf("Magic Number: 0x%08x\n", u);



  }
  read(db, zBuf2, sizeof(zBuf2));
  u = zBuf2[0]<<24 | zBuf2[1]<<16 | zBuf2[2]<<8 | zBuf2[3];
  printf("Database Size: %u\n", u);
  while( read(db, zBuf2, sizeof(zBuf2))==sizeof(zBuf2) ){
    u = zBuf2[0]<<24 | zBuf2[1]<<16 | zBuf2[2]<<8 | zBuf2[3];
    print_page(u);
    if( zBuf[7]==0xd6 ){
      read(db, &u, sizeof(u));
      printf("Checksum: 0x%08x\n", u);
    }

  }
  close(db);
}





|
|
|
|
|
|
|
|
|
|
|
>
>
>





<
>
|
>
>
>
|
|
|
<
<
<
|
|
|
>
>
>
>
>
>
|
<
<
>
|
<
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




<
<

<
<
>
>




|
|



|
|
|
|
|
|
>
>
>
|
<
<
<
|
|
|
|
<
<

>

|

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32



33
34
35
36
37
38
39
40
41
42


43
44

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108


109


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130



131
132
133
134


135
136
137
138
139
/*
** A utility for printing an SQLite database journal.
*/
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

/*
** state information
*/
static int pageSize = 1024;
static int sectorSize = 512;
static FILE *db = 0;
static int showPageContent = 0;
static int fileSize = 0;
static unsigned cksumNonce = 0;

/* Report a memory allocation error */
static void out_of_memory(void){
  fprintf(stderr,"Out of memory...\n");
  exit(1);
}


/*
** Read N bytes of memory starting at iOfst into space obtained
** from malloc().
*/
static char *read_content(int N, int iOfst){
  int got;
  char *pBuf = malloc(N);
  if( pBuf==0 ) out_of_memory();



  fseek(db, iOfst, SEEK_SET);
  got = fread(pBuf, 1, N, db);
  if( got<0 ){
    fprintf(stderr, "I/O error reading %d bytes from %d\n", N, iOfst);
    memset(pBuf, 0, N);
  }else if( got<N ){
    fprintf(stderr, "Short read: got only %d of %d bytes from %d\n",
                     got, N, iOfst);
    memset(&pBuf[got], 0, N-got);
  }


  return pBuf;
}


/* Print a line of decode output showing a 4-byte integer.
*/
static unsigned print_decode_line(
  unsigned char *aData,      /* Content being decoded */
  int ofst, int nByte,       /* Start and size of decode */
  const char *zMsg           /* Message to append */
){
  int i, j;
  unsigned val = aData[ofst];
  char zBuf[100];
  sprintf(zBuf, " %03x: %02x", ofst, aData[ofst]);
  i = strlen(zBuf);
  for(j=1; j<4; j++){
    if( j>=nByte ){
      sprintf(&zBuf[i], "   ");
    }else{
      sprintf(&zBuf[i], " %02x", aData[ofst+j]);
      val = val*256 + aData[ofst+j];
    }
    i += strlen(&zBuf[i]);
  }
  sprintf(&zBuf[i], "   %10u", val);
  printf("%s  %s\n", zBuf, zMsg);
  return val;
}

/*
** Read and print a journal header.  Store key information (page size, etc)
** in global variables.
*/
static unsigned decode_journal_header(int iOfst){
  char *pHdr = read_content(64, iOfst);
  unsigned nPage;
  printf("Header at offset %d:\n", iOfst);
  print_decode_line(pHdr, 0, 4, "Header part 1 (3654616569)");
  print_decode_line(pHdr, 4, 4, "Header part 2 (547447767)");
  nPage =
  print_decode_line(pHdr, 8, 4, "page count");
  cksumNonce =
  print_decode_line(pHdr, 12, 4, "chksum nonce");
  print_decode_line(pHdr, 16, 4, "initial database size in pages");
  sectorSize =
  print_decode_line(pHdr, 20, 4, "sector size");
  pageSize =
  print_decode_line(pHdr, 24, 4, "page size");
  print_decode_line(pHdr, 28, 4, "zero");
  print_decode_line(pHdr, 32, 4, "zero");
  print_decode_line(pHdr, 36, 4, "zero");
  print_decode_line(pHdr, 40, 4, "zero");
  free(pHdr);
  return nPage;
}

static void print_page(int iOfst){
  unsigned char *aData;
  char zTitle[50];
  aData = read_content(pageSize+8, iOfst);
  sprintf(zTitle, "page number for page at offset %d", iOfst);
  print_decode_line(aData, 0, 4, zTitle);
  free(aData);
}

int main(int argc, char **argv){


  int rc;


  int nPage, cnt;
  int iOfst;
  if( argc!=2 ){
    fprintf(stderr,"Usage: %s FILENAME\n", argv[0]);
    exit(1);
  }
  db = fopen(argv[1], "rb");
  if( db==0 ){
    fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]);
    exit(1);
  }
  fseek(db, 0, SEEK_END);
  fileSize = ftell(db);
  printf("journal file size: %d bytes\n", fileSize);
  fseek(db, 0, SEEK_SET);
  iOfst = 0;
  while( iOfst<fileSize ){
    cnt = nPage = (int)decode_journal_header(iOfst);
    if( cnt==0 ){
      cnt = (fileSize - sectorSize)/(pageSize+8);
    }



    iOfst += sectorSize;
    while( cnt && iOfst<fileSize ){
      print_page(iOfst);
      iOfst += pageSize+8;


    }
    iOfst = (iOfst/sectorSize + 1)*sectorSize;
  }
  fclose(db);
}