#include "merger.h" #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; } unsigned int version ; read(fhCow,&version,sizeof(unsigned int)); read(fhCow,&size,sizeof(uint64_t)); int l; read(fhCow,&l,sizeof(int)); char *buffer = malloc(sizeof(char)*(l+1)); read(fhCow,buffer,l*sizeof(char)); buffer[l]='\0'; int pageSize; read(fhCow,&pageSize,sizeof(int)); printf("Version: %u\n",version); printf("länge: %i \n",l); printf("Image Name: %s\n",buffer); printf("Size: %ld\n", (long)size); printf("pageSize: %i\n", (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; filePointers = mmap(NULL,imageBlockCount*sizeof(off_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 %llu of %llu 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,filePointers[i]+(4096*(j+1)),SEEK_SET); char buff[4096] = {0}; if(read(fhCow, &buff, 4096) < 0){ printf("Error on reading Cow File. BigBlock: %llu\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: %llu\n",i); return false; } } } mergedBlocks++; } } printf("Merged %llu Blocks\n",mergedBlocks); ftruncate(fhImage, size); return true; }