| 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 |