sparse-tools/src/bs_send.c

126 lines
3.3 KiB
C

//
// Created by haraldwolff on 07.08.22.
//
#include <blksync.h>
#include <hash.h>
#include <time.h>
int bs_sender(bsync_engine_t *engine){
uint32_t _magic = 0, _version = 0;
uint64_t _filesize = 0;
uint32_t _blocksize = 0;
write( engine->clientSocket, &magic, sizeof(magic));
write( engine->clientSocket, &version, sizeof(version));
write( engine->clientSocket, &engine->filesize, sizeof(engine->filesize));
write( engine->clientSocket, &engine->blocksize, sizeof(engine->blocksize));
read( engine->clientSocket, &_magic, sizeof(_magic));
read( engine->clientSocket, &_version, sizeof(_version));
read( engine->clientSocket, &_filesize, sizeof(_filesize));
read( engine->clientSocket, &_blocksize, sizeof(_blocksize));
if (magic != _magic){
fprintf(stderr, "magic missmatch (0x%08x != 0x%08x)\n", magic, _magic);
exit(EXIT_FAILURE);
}
if (version != _version){
fprintf(stderr, "version missmatch\n");
exit(EXIT_FAILURE);
}
if (engine->filesize != _filesize)
{
fprintf(stderr, "filesizes don't match (%ld != %ld)\n", engine->filesize, _filesize);
exit(EXIT_FAILURE);
}
if ((engine->blocksize != 0) && (engine->blocksize != _blocksize))
{
fprintf(stderr, "blocksizes don't match (%d != %d)\n", engine->blocksize, _blocksize);
exit(EXIT_FAILURE);
}
if (engine->blocksize == 0)
engine->blocksize = _blocksize;
fprintf(stdout, "size: %ld bytes, blocksize: %d bytes\n", engine->filesize, engine->blocksize);
char *block = malloc(engine->blocksize);
if (!block)
{
fprintf(stderr, "no memory available for block");
exit(EXIT_FAILURE);
}
long offset = 0;
long residual;
if (engine->ds_flags & DS_VERBOSE){
fprintf( stderr, "about to start...\n");
dump_engine(engine);
}
while (-1){
if (bs_recv( engine->clientSocket, &offset, sizeof(offset))==-1){
fprintf(stderr, "could not receive offset\n");
exit(EXIT_FAILURE);
}
if (offset == -1ul)
break;
residual = engine->filesize - offset;
int32_t size = residual > engine->blocksize ? engine->blocksize : residual;
uint64_t blockhash, remotehash;
if (bs_recv( engine->clientSocket, &remotehash, sizeof(remotehash))==-1){
fprintf(stderr, "could not receive block hash at offset 0x%lx\n", offset);
exit(EXIT_FAILURE);
}
if (read_block(engine, offset, block, size) != size)
exit(EXIT_FAILURE);
blockhash = dhash( block, size);
int percent = 100 * offset / engine->filesize;
if (remotehash != blockhash){
/*
fprintf(stdout, "offset: %d bytes @ 0x%lx (%d%%) [0x%lx] differs \n", size, offset, percent, blockhash);
fflush(stdout);
*/
if (
(bs_send( engine->clientSocket, &offset, sizeof(offset))==-1) ||
(bs_send( engine->clientSocket, block, size)==-1)
){
fprintf(stderr,"could not send block at offset 0x%lx\n", offset);
fprintf(stderr,"errno=%d (%s)", errno, strerror(errno));
exit(EXIT_FAILURE);
}
engine->stat_blocks++;
engine->stat_block_bytes += size;
engine->last_offset = offset;
}
time_t t = time(NULL);
if (engine->t_last_update != t)
dump_engine_state(engine);
offset += size;
residual -= size;
}
offset = -1l;
if (bs_send(engine->clientSocket, &offset, sizeof(offset)) == -1)
{
fprintf(stderr, "could not send end mark\n");
exit(EXIT_FAILURE);
}
fprintf( stdout, "\n");
}