int DoBdiff( const char *srcPath, const char *tgtPath, const char *name ) { long savings; foff buffsize; int i; // if( !MsgInit() ) exit( EXIT_FAILURE ); /* initialize static variables each time */ SimilarRegions = NULL; DiffRegions = NULL; HoleRegions = NULL; SimilarSize = 0; NumHoles = 0; NumDiffs = 0; DiffSize = 0; HolesInRegion = 0; HoleHeaders = 0; for( i = 0; i < 3; i += 1 ) { HoleCount[i] = 0; } init_diff(); newName = name; EndOld = FileSize( srcPath, &OldCorrection ); EndNew = FileSize( tgtPath, &NewCorrection ); buffsize = ( EndOld > EndNew ) ? ( EndOld ) : ( EndNew ); buffsize += sizeof( PATCH_LEVEL ); OldFile = ReadIn( srcPath, buffsize, EndOld ); NewFile = ReadIn( tgtPath, buffsize, EndNew ); ScanSyncString( SyncString ); FindRegions(); if( NumHoles == 0 && DiffSize == 0 && EndOld == EndNew ) { printf( "Patch file not created - files are identical\n" ); MsgFini(); exit( EXIT_SUCCESS ); } MakeHoleArray(); SortHoleArray(); ProcessHoleArray( 0 ); savings = HolesToDiffs(); WritePatchFile( "", newName ); FreeHoleArray(); VerifyCorrect( tgtPath ); print_stats( savings ); MsgFini(); return ( EXIT_SUCCESS ); }
void main( int argc, char **argv ) { long savings; foff buffsize; algorithm alg; if( !MsgInit() ) exit( EXIT_FAILURE ); alg = ParseArgs( argc, argv ); EndOld = FileSize( argv[1], &OldCorrection ); EndNew = FileSize( argv[2], &NewCorrection ); buffsize = ( EndOld > EndNew ) ? ( EndOld ) : ( EndNew ); buffsize += sizeof( PATCH_LEVEL ); OldFile = ReadIn( argv[1], buffsize, EndOld ); NewFile = ReadIn( argv[2], buffsize, EndNew ); ScanSyncString( SyncString ); switch( alg ) { case ALG_NOTHING: FindRegions(); break; #ifdef USE_DBGINFO case ALG_ONLY_NEW: case ALG_BOTH: SymbolicDiff( alg, argv[1], argv[2] ); break; #endif } if( NumHoles == 0 && DiffSize == 0 && EndOld == EndNew ) { printf( "Patch file not created - files are identical\n" ); MsgFini(); exit( EXIT_SUCCESS ); } MakeHoleArray(); SortHoleArray(); ProcessHoleArray( 0 ); savings = HolesToDiffs(); WritePatchFile( argv[3], newName ); FreeHoleArray(); VerifyCorrect( argv[2] ); print_stats( savings ); MsgFini(); exit( EXIT_SUCCESS ); }
PATCH_RET_CODE Execute( byte *dest ) { char *tmp; #else PATCH_RET_CODE Execute( void ) { char tmp[4]; #if defined(__386__) #if defined(_WPATCH) extern MY_FILE NewFile; #define InNew( offset ) ( Input( &NewFile, tmp, offset, \ sizeof(hole)), \ *(hole*)tmp ) #define OutNew( off, x, type ) *(type*)tmp = (x); \ Output( &NewFile, tmp, \ off, sizeof( type ) ); #else extern byte *NewFile; #define OutNew( off, x, type ) *(type*)(NewFile+off) = (x); #define InNew( off ) *(hole*)(NewFile+off) #endif #elif defined(BDUMP) #define InNew( offset ) 1 #define OutNew( off, x, type ) ( x ) #undef Dump #define Dump( x ) printf x #undef DOPROMPT #undef DOBACKUP #define DOPROMPT 0 #define DOBACKUP 0 #else extern MY_FILE NewFile; extern void Input( MY_FILE *file, void *tmp, foff off, size_t len ); #define InNew( offset ) ( Input( &NewFile, tmp, offset, \ sizeof(hole)), \ *(hole*)tmp ) extern void Output( MY_FILE *file, void *tmp, foff off, size_t len ); #define OutNew( off, x, type ) *(type*)tmp = (x); \ Output( &NewFile, tmp, \ off, sizeof( type ) ); #endif #endif patch_cmd cmd; byte next; hole diff; foff size; foff incr; foff iters; foff old_size; foff new_size; foff checksum; foff new_offset; foff old_offset; char ch; int havenew; PATCH_RET_CODE ret; PATCH_RET_CODE ret2; #ifdef BDIFF char *dummy = NULL; #endif havenew = 1; #ifdef BDIFF InitPatch( &dummy ); #endif old_size = InPatch( foff ); new_size = InPatch( foff ); checksum = InPatch( foff ); ret = OpenOld( old_size, DOPROMPT, new_size, checksum ); if( ret != PATCH_RET_OKAY ) goto error1; ret = OpenNew( new_size ); if( ret != PATCH_RET_OKAY ) goto error2; InitHoles(); for( ;; ) { #if defined( INSTALL_PROGRAM ) #if defined( WINNT ) || defined( WIN ) || defined( OS2 ) if( StatusCancelled() ) { ret = PATCH_RET_CANCEL; goto error3; } #endif #endif cmd = InPatch( patch_cmd ); if( cmd == CMD_DONE ) break; switch( cmd ) { case CMD_DIFFS: new_offset = InPatch( foff ); size = InPatch( foff ); Dump(( "Different new-%8.8lx size-%8.8lx\n", new_offset, size )); while( size != 0 ) { OutNew( new_offset, InPatch( byte ), byte ); ++new_offset; --size; } break; case CMD_SAMES: new_offset = InPatch( foff ); old_offset = InPatch( foff ); size = InPatch( foff ); Dump(( "Similar new-%8.8lx old-%8.8lx size-%8.8lx\n", new_offset, old_offset, size)); while( size != 0 ) { OutNew( new_offset, InOld( old_offset ), byte ); ++new_offset; ++old_offset; --size; } break; case CMD_ITER_HOLES: new_offset = InPatch( foff ); diff = InPatch( hole ); iters = InPatch( foff ); incr = InPatch( foff ); ch = InPatch( byte ); Dump(( "IterHole new-%8.8lx diff-%8.8lx iter-%8.8lx inc-%8.8lx\n", new_offset, diff, iters, incr )); while( iters != 0 ) { AddHole( new_offset, diff ); new_offset += incr; --iters; } break; case CMD_HOLES: new_offset = InPatch( foff ); diff = InPatch( hole ); for( ;; ) { Dump(( "Hole new-%8.8lx diff-%8.8lx\n",new_offset,diff)); AddHole( new_offset, diff ); next = InPatch( byte ); if( next == 0 ) break; if( ( next & 0x80 ) == 0 ) { new_offset += (foff)next & 0x7f; } else if( ( next & 0x40 ) == 0 ) { new_offset += ( (foff)next & 0x3f ) << 8; new_offset += (foff)InPatch( byte ); } else { new_offset += ( (foff)next & 0x3f ) << 16; new_offset += (foff)InPatch(byte) << 8; new_offset += (foff)InPatch(byte); } } break; default: PatchError( ERR_BAD_PATCHFILE, PatchName ); ret = PATCH_BAD_PATCH_FILE; goto error3; } } ret = PATCH_RET_OKAY; FlushHoles(); error3: FreeHoleArray(); ret2 = CloseNew( new_size, checksum, &havenew ); if( ret == PATCH_RET_OKAY ) { ret = ret2; } error2: CloseOld( havenew && DOPROMPT, DOBACKUP ); error1: ClosePatch(); return( ret ); }