OLD | NEW |
| (Empty) |
1 /* | |
2 ** 2013-10-01 | |
3 ** | |
4 ** The author disclaims copyright to this source code. In place of | |
5 ** a legal notice, here is a blessing: | |
6 ** | |
7 ** May you do good and not evil. | |
8 ** May you find forgiveness for yourself and forgive others. | |
9 ** May you share freely, never taking more than you give. | |
10 ** | |
11 ****************************************************************************** | |
12 ** | |
13 ** Compute hash signatures for every page of a database file. This utility | |
14 ** program is useful for analyzing the output logs generated by the | |
15 ** ext/misc/vfslog.c extension. | |
16 */ | |
17 #include <stdio.h> | |
18 #include <string.h> | |
19 #include <assert.h> | |
20 #include <stdlib.h> | |
21 | |
22 /* | |
23 ** Compute signature for a block of content. | |
24 ** | |
25 ** For blocks of 16 or fewer bytes, the signature is just a hex dump of | |
26 ** the entire block. | |
27 ** | |
28 ** For blocks of more than 16 bytes, the signature is a hex dump of the | |
29 ** first 8 bytes followed by a 64-bit has of the entire block. | |
30 */ | |
31 static void vlogSignature(unsigned char *p, int n, char *zCksum){ | |
32 unsigned int s0 = 0, s1 = 0; | |
33 unsigned int *pI; | |
34 int i; | |
35 if( n<=16 ){ | |
36 for(i=0; i<n; i++) sprintf(zCksum+i*2, "%02x", p[i]); | |
37 }else{ | |
38 pI = (unsigned int*)p; | |
39 for(i=0; i<n-7; i+=8){ | |
40 s0 += pI[0] + s1; | |
41 s1 += pI[1] + s0; | |
42 pI += 2; | |
43 } | |
44 for(i=0; i<8; i++) sprintf(zCksum+i*2, "%02x", p[i]); | |
45 sprintf(zCksum+i*2, "-%08x%08x", s0, s1); | |
46 } | |
47 } | |
48 | |
49 /* | |
50 ** Open a file. Find its page size. Read each page, and compute and | |
51 ** display the page signature. | |
52 */ | |
53 static void computeSigs(const char *zFilename){ | |
54 FILE *in = fopen(zFilename, "rb"); | |
55 unsigned pgsz; | |
56 size_t got; | |
57 unsigned n; | |
58 unsigned char aBuf[50]; | |
59 unsigned char aPage[65536]; | |
60 | |
61 if( in==0 ){ | |
62 fprintf(stderr, "cannot open \"%s\"\n", zFilename); | |
63 return; | |
64 } | |
65 got = fread(aBuf, 1, sizeof(aBuf), in); | |
66 if( got!=sizeof(aBuf) ){ | |
67 goto endComputeSigs; | |
68 } | |
69 pgsz = aBuf[16]*256 + aBuf[17]; | |
70 if( pgsz==1 ) pgsz = 65536; | |
71 if( (pgsz & (pgsz-1))!=0 ){ | |
72 fprintf(stderr, "invalid page size: %02x%02x\n", aBuf[16], aBuf[17]); | |
73 goto endComputeSigs; | |
74 } | |
75 rewind(in); | |
76 for(n=1; (got=fread(aPage, 1, pgsz, in))==pgsz; n++){ | |
77 vlogSignature(aPage, pgsz, aBuf); | |
78 printf("%4d: %s\n", n, aBuf); | |
79 } | |
80 | |
81 endComputeSigs: | |
82 fclose(in); | |
83 } | |
84 | |
85 /* | |
86 ** Find page signatures for all named files. | |
87 */ | |
88 int main(int argc, char **argv){ | |
89 int i; | |
90 for(i=1; i<argc; i++) computeSigs(argv[i]); | |
91 return 0; | |
92 } | |
OLD | NEW |