| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #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; |
| } |
|
|