mirror of
				https://github.com/sqlite/sqlite.git
				synced 2025-10-24 09:53:10 +03:00 
			
		
		
		
	human-readable format. FossilOrigin-Name: f6304fd142c998aba44f02c6018223af2630671b4791d750b70a59ab1adb8d6d
		
			
				
	
	
		
			159 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
| ** A utility for printing content from the wal-index or "shm" file.
 | |
| */
 | |
| #include <stdio.h>
 | |
| #include <ctype.h>
 | |
| #include <sys/types.h>
 | |
| #include <sys/stat.h>
 | |
| #include <fcntl.h>
 | |
| #include <assert.h>
 | |
| 
 | |
| #define ISDIGIT(X)  isdigit((unsigned char)(X))
 | |
| #define ISPRINT(X)  isprint((unsigned char)(X))
 | |
| 
 | |
| #if !defined(_MSC_VER)
 | |
| #include <unistd.h>
 | |
| #include <sys/types.h>
 | |
| #else
 | |
| #include <io.h>
 | |
| #endif
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| 
 | |
| static int fd = -1;             /* The open SHM file */
 | |
| 
 | |
| /* Report an out-of-memory error and die.
 | |
| */
 | |
| static void out_of_memory(void){
 | |
|   fprintf(stderr,"Out of memory...\n");
 | |
|   exit(1);
 | |
| }
 | |
| 
 | |
| /*
 | |
| ** Read content from the file.
 | |
| **
 | |
| ** Space to hold the content is obtained from malloc() and needs to be
 | |
| ** freed by the caller.
 | |
| */
 | |
| static unsigned char *getContent(int ofst, int nByte){
 | |
|   unsigned char *aData;
 | |
|   aData = malloc(nByte);
 | |
|   if( aData==0 ) out_of_memory();
 | |
|   lseek(fd, ofst, SEEK_SET);
 | |
|   read(fd, aData, nByte);
 | |
|   return aData;
 | |
| }
 | |
| 
 | |
| /*
 | |
| ** Flags values
 | |
| */
 | |
| #define FG_HEX     1    /* Show as hex */
 | |
| #define FG_NBO     2    /* Native byte order */
 | |
| #define FG_PGSZ    4    /* Show as page-size */
 | |
| 
 | |
| /* Print a line of decode output showing a 4-byte integer.
 | |
| */
 | |
| static void print_decode_line(
 | |
|   unsigned char *aData,      /* Content being decoded */
 | |
|   int ofst, int nByte,       /* Start and size of decode */
 | |
|   unsigned flg,              /* Display flags */
 | |
|   const char *zMsg           /* Message to append */
 | |
| ){
 | |
|   int i, j;
 | |
|   int val = aData[ofst];
 | |
|   char zBuf[100];
 | |
|   sprintf(zBuf, " %03x: %02x", ofst, aData[ofst]);
 | |
|   i = (int)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 += (int)strlen(&zBuf[i]);
 | |
|   }
 | |
|   if( nByte==8 ){
 | |
|     for(j=4; j<8; j++){
 | |
|       sprintf(&zBuf[i], " %02x", aData[ofst+j]);
 | |
|       i += (int)strlen(&zBuf[i]);
 | |
|     }
 | |
|   }
 | |
|   if( flg & FG_NBO ){
 | |
|     assert( nByte==4 );
 | |
|     memcpy(&val, aData+ofst, 4);
 | |
|   }
 | |
|   sprintf(&zBuf[i], "            ");
 | |
|   i += 12;
 | |
|   if( flg & FG_PGSZ ){
 | |
|     unsigned short sz;
 | |
|     memcpy(&sz, aData+ofst, 2);
 | |
|     sprintf(&zBuf[i], "   %9d", sz==1 ? 65536 : sz);
 | |
|   }else if( flg & FG_HEX ){
 | |
|     sprintf(&zBuf[i], "  0x%08x", val);
 | |
|   }else if( nByte<8 ){
 | |
|     sprintf(&zBuf[i], "   %9d", val);
 | |
|   }
 | |
|   printf("%s  %s\n", zBuf, zMsg);
 | |
| }
 | |
| 
 | |
| /*
 | |
| ** Print an instance of the WalIndexHdr object.  ix is either 0 or 1
 | |
| ** to select which header to print.
 | |
| */
 | |
| static void print_index_hdr(unsigned char *aData, int ix){
 | |
|   int i;
 | |
|   assert( ix==0 || ix==1 );
 | |
|   i = ix ? 48 : 0;
 | |
|   print_decode_line(aData, 0+i, 4, FG_NBO,  "Wal-index version");
 | |
|   print_decode_line(aData, 4+i, 4, 0,       "unused padding");
 | |
|   print_decode_line(aData, 8+i, 4, FG_NBO,  "transaction counter");
 | |
|   print_decode_line(aData,12+i, 1, 0,       "1 when initialized");
 | |
|   print_decode_line(aData,13+i, 1, 0,       "true if WAL cksums are bigendian");
 | |
|   print_decode_line(aData,14+i, 2, FG_PGSZ, "database page size");
 | |
|   print_decode_line(aData,16+i, 4, FG_NBO,  "mxFrame");
 | |
|   print_decode_line(aData,20+i, 4, FG_NBO,  "Size of database in pages");
 | |
|   print_decode_line(aData,24+i, 8, 0, "Cksum of last frame in -wal");
 | |
|   print_decode_line(aData,32+i, 8, 0,  "Salt values from the -wal");
 | |
|   print_decode_line(aData,40+i, 8, 0,  "Cksum over all prior fields");
 | |
| }
 | |
| 
 | |
| /*
 | |
| ** Print the WalCkptInfo object
 | |
| */
 | |
| static void print_ckpt_info(unsigned char *aData){
 | |
|   const int i = 96;
 | |
|   int j;
 | |
|   print_decode_line(aData, 0+i, 4, FG_NBO,  "nBackfill");
 | |
|   for(j=0; j<5; j++){
 | |
|     char zLabel[100];
 | |
|     sprintf(zLabel, "aReadMark[%d]", j);
 | |
|     print_decode_line(aData, 4*j+4+i, 4, FG_NBO, zLabel);
 | |
|   }
 | |
|   print_decode_line(aData,24+i, 8, 0,       "aLock");
 | |
|   print_decode_line(aData,32+i, 4, FG_NBO,  "nBackfillAttempted");
 | |
|   print_decode_line(aData,36+i, 4, FG_NBO,  "notUsed0");
 | |
| }
 | |
| 
 | |
| 
 | |
| int main(int argc, char **argv){
 | |
|   unsigned char *aData;
 | |
|   if( argc<2 ){
 | |
|     fprintf(stderr,"Usage: %s FILENAME\n", argv[0]);
 | |
|     exit(1);
 | |
|   }
 | |
|   fd = open(argv[1], O_RDONLY);
 | |
|   if( fd<0 ){
 | |
|     fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]);
 | |
|     exit(1);
 | |
|   }
 | |
|   aData = getContent(0, 136);
 | |
|   print_index_hdr(aData, 0);
 | |
|   print_index_hdr(aData, 1);
 | |
|   print_ckpt_info(aData);
 | |
|   free(aData);
 | |
|   close(fd);
 | |
|   return 0;
 | |
| }
 |