| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | #include <stdio.h> |
| | #include <string.h> |
| | #include <stdlib.h> |
| | #include <ctype.h> |
| | |
| | |
| | static int allZero(unsigned char *aLine){ |
| | int i; |
| | for(i=0; i<16 && aLine[i]==0; i++){} |
| | return i==16; |
| | } |
| |
|
| | int main(int argc, char **argv){ |
| | int pgsz = 0; |
| | int forCli = 0; |
| | int bSQL = 0; |
| | long szFile; |
| | FILE *in; |
| | int nSQL; |
| | int i, j; |
| | int nErr = 0; |
| | const char *zInputFile = 0; |
| | const char *zBaseName = 0; |
| | int lastPage = 0; |
| | int iPage; |
| | unsigned char *aData = 0; |
| | unsigned char *aLine; |
| | unsigned char *aHdr; |
| | unsigned char bShow[256]; |
| | memset(bShow, '.', sizeof(bShow)); |
| | for(i=' '; i<='~'; i++){ |
| | if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = (unsigned char)i; |
| | } |
| | for(i=1; i<argc; i++){ |
| | if( argv[i][0]=='-' ){ |
| | const char *z = argv[i]; |
| | z++; |
| | if( z[0]=='-' ) z++; |
| | if( strcmp(z,"pagesize")==0 ){ |
| | i++; |
| | pgsz = atoi(argv[i]); |
| | if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ){ |
| | fprintf(stderr, "Page size must be a power of two between" |
| | " 512 and 65536.\n"); |
| | nErr++; |
| | } |
| | continue; |
| | }else if( strcmp(z,"for-cli")==0 ){ |
| | forCli = 1; |
| | continue; |
| | }else if( strcmp(z,"script")==0 ){ |
| | forCli = 1; |
| | bSQL = 1; |
| | continue; |
| | } |
| | fprintf(stderr, "Unknown option: %s\n", argv[i]); |
| | nErr++; |
| | }else if( zInputFile ){ |
| | fprintf(stderr, "Already using a different input file: [%s]\n", argv[i]); |
| | nErr++; |
| | }else{ |
| | zInputFile = argv[i]; |
| | } |
| | } |
| | if( zInputFile==0 ){ |
| | fprintf(stderr, "No input file specified.\n"); |
| | nErr++; |
| | } |
| | if( nErr ){ |
| | fprintf(stderr, |
| | "Usage: %s [--pagesize N] [--script] [--for-cli] FILENAME\n", argv[0]); |
| | exit(1); |
| | } |
| | in = fopen(zInputFile, "rb"); |
| | if( in==0 ){ |
| | fprintf(stderr, "Cannot open input file [%s]\n", zInputFile); |
| | exit(1); |
| | } |
| | fseek(in, 0, SEEK_END); |
| | szFile = ftell(in); |
| | rewind(in); |
| | if( szFile<100 ){ |
| | fprintf(stderr, "File too short. Minimum size is 100 bytes.\n"); |
| | exit(1); |
| | } |
| | aData = malloc( szFile+16 ); |
| | if( aData==0 ){ |
| | fprintf(stderr, "Failed to allocate %ld bytes\n", szFile); |
| | exit(1); |
| | } |
| | if( fread(aData, szFile, 1, in)!=1 ){ |
| | fprintf(stderr, "Cannot read file info memory\n"); |
| | exit(1); |
| | } |
| | memset(aData+szFile, 0, 16); |
| | fclose(in); |
| | if( bSQL ){ |
| | for(i=0; i<szFile && aData[i]!=0; i++){} |
| | if( i==szFile ){ |
| | fprintf(stderr, "No zero terminator on SQL script\n"); |
| | exit(1); |
| | } |
| | nSQL = i+1; |
| | if( szFile - nSQL<100 ){ |
| | fprintf(stderr, "Less than 100 bytes in the database\n"); |
| | exit(1); |
| | } |
| | }else{ |
| | nSQL = 0; |
| | } |
| | aHdr = aData + nSQL; |
| | if( pgsz==0 ){ |
| | pgsz = (aHdr[16]<<8) | aHdr[17]; |
| | if( pgsz==1 ) pgsz = 65536; |
| | if( pgsz<512 || (pgsz&(pgsz-1))!=0 ){ |
| | fprintf(stderr, "Invalid page size in header: %d\n", pgsz); |
| | exit(1); |
| | } |
| | } |
| | zBaseName = zInputFile; |
| | for(i=0; zInputFile[i]; i++){ |
| | if( zInputFile[i]=='/' && zInputFile[i+1]!=0 ) zBaseName = zInputFile+i+1; |
| | } |
| | if( forCli ){ |
| | printf(".open --hexdb\n"); |
| | } |
| | printf("| size %d pagesize %d filename %s\n",(int)szFile,pgsz,zBaseName); |
| | for(i=nSQL; i<szFile; i+=16){ |
| | aLine = aData+i; |
| | if( allZero(aLine) ) continue; |
| | iPage = i/pgsz + 1; |
| | if( lastPage!=iPage ){ |
| | printf("| page %d offset %d\n", iPage, (iPage-1)*pgsz); |
| | lastPage = iPage; |
| | } |
| | printf("| %5d:", i-(iPage-1)*pgsz); |
| | for(j=0; j<16; j++) printf(" %02x", aLine[j]); |
| | printf(" "); |
| | for(j=0; j<16; j++){ |
| | unsigned char c = (unsigned char)aLine[j]; |
| | fputc( bShow[c], stdout); |
| | } |
| | fputc('\n', stdout); |
| | } |
| | printf("| end %s\n", zBaseName); |
| | if( nSQL>0 ){ |
| | printf("%s\n", aData); |
| | } |
| | free( aData ); |
| | return 0; |
| | } |
| |
|