#include "merger.h" #include #define TestBit(A,k) ( A[(k/32)] & (1 << (k%32)) ) int fhImage; int fhCow; off_t *filePointers; uint64_t imageBlockCount; uint64_t size; bool merger( char *imageFilePath, char *cowFilePath ) { if( !loadFiles( imageFilePath, cowFilePath ) ) { return false; } if ( merge() ) { printf("File Merged"); return true; } return false; } bool loadFiles(char *imageFilePath, char *cowFilePath) { if ( ( fhImage = open ( imageFilePath, O_RDWR ) ) == -1 ) { printf( "Could not open Image.\n" ); return false; } if ( ( fhCow = open ( cowFilePath, O_RDONLY ) ) == -1 ) { printf( "Could not open Cow File.\n" ); close( fhImage ); return false; } cow_metadata metadata; read( fhCow, &metadata, sizeof( cow_metadata ) ); fixup_cow_metadata( metadata ); char *buffer = malloc(sizeof(char) * ( metadata.nameLenght + 1 ) ); read( fhCow, buffer, metadata.nameLenght * sizeof( char ) ); size = metadata.imageSize; printf( "Version: %u\n",metadata.version ); printf( "Länge: %i \n", metadata.nameLenght ); printf( "Image Name: %s\n", buffer ); printf( "Size: %"PRIu64"\n", size ); printf( "pageSize: %i\n", metadata.pageSize ); free( buffer ); //TODO Image Validation imageBlockCount = ( size + (4096*256)-1 ) / (4096*256); off_t mmapStart = lseek( fhCow, 0L, SEEK_CUR ); int maxPageSize = 8192; mmapStart = ( ( mmapStart + maxPageSize - 1) / maxPageSize ) * maxPageSize; printf( "mmapStart: %"PRIu64"\n", mmapStart ); filePointers = mmap( NULL, imageBlockCount * sizeof(uint64_t), PROT_READ, MAP_SHARED, fhCow, mmapStart); if(filePointers == MAP_FAILED ) { printf("Error creating mmap in COW File.\n%s\nBye.\n ", strerror(errno) ); close( fhCow ); close( fhImage ); return false; } return true; } bool merge() { uint64_t mergedBlocks = 0; for( uint64_t i = 0; i < imageBlockCount; i++ ) { printf( "Merged %"PRIu64" of %"PRIu64" Blocks \n", i, imageBlockCount ); off_t pointer = (off_t) filePointers[i]; if( pointer != 0) { int blockState[8]; lseek( fhCow, filePointers[i], SEEK_SET ); read( fhCow, &blockState, sizeof(int) * 8 ); for( int j = 0; j < 256; j++ ) { if( TestBit( blockState, j ) ) { lseek( fhCow, ((off_t) filePointers[i] + ( 4096 * ( j + 1) ) ), SEEK_SET ); char buff[4096] = {0}; if( read(fhCow, &buff, 4096) < 0) { printf("Error on reading Cow File." " BigBlock: %"PRIu64"n", i ); return false; } lseek( fhImage, ( i * 4096 * 256) + ( 4096 * j ), SEEK_SET ); if( write( fhImage, &buff, 4096 ) < 0) { printf("Error on writing to File." " BigBlock: %"PRIu64"\n", i ); return false; } mergedBlocks++; } } } } printf( "Merged %"PRIu64" Blocks\n", mergedBlocks ); ftruncate( fhImage, size); return true; }