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 |