109 lines
3.1 KiB
C
109 lines
3.1 KiB
C
//
|
|
// Created by haraldwolff on 08.08.22.
|
|
//
|
|
|
|
#include <stdlib.h>
|
|
#include <sys/socket.h>
|
|
|
|
#include <blksync.h>
|
|
#include <bs_comm.h>
|
|
#include <bs_engine.h>
|
|
|
|
int bs_comm_handshake(bs_engine_t *engine) {
|
|
|
|
if (!engine->file.handle)
|
|
{
|
|
int s = bs_engine_open_file(engine);
|
|
if (s)
|
|
fatal("could not open file %s\n", engine->file.filename);
|
|
}
|
|
|
|
bs_hello_t hello, remote;
|
|
memset(&hello, 0, sizeof(hello));
|
|
|
|
hello.magic = bs_magic;
|
|
hello.bs_flags = engine->bs_flags;
|
|
hello.filesize = engine->file.size;
|
|
hello.blocksize = engine->parameters.blocksize;
|
|
|
|
if (send(engine->comm.remote, &hello, sizeof(hello), 0) < 0)
|
|
return -1;
|
|
|
|
if (recv(engine->comm.remote, &remote, sizeof(remote), 0) < 0)
|
|
return -1;
|
|
|
|
bs_flags_t mine, yours;
|
|
mine = hello.bs_flags & (BS_RECEIVER | BS_SENDER);
|
|
yours = remote.bs_flags & (BS_RECEIVER | BS_SENDER);
|
|
|
|
if (yours == (BS_RECEIVER | BS_SENDER))
|
|
{
|
|
fprintf(stderr, "remote wants to be receiver and sender.\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (!mine && !yours)
|
|
{
|
|
mine = engine->tool_flags & BS_LISTENER ? BS_RECEIVER : BS_SENDER;
|
|
} else if (!mine)
|
|
{
|
|
mine = (~yours) & (BS_SENDER | BS_RECEIVER);
|
|
}
|
|
|
|
if (mine == yours) {
|
|
fprintf(stderr, "remote wants to be same like me, can't work.\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
engine->bs_flags |= mine;
|
|
|
|
if ((engine->bs_flags & BS_COMPRESSION_MASK) & ~(BS_COMPRESSION_BZ2))
|
|
{
|
|
fprintf(stderr, "unknown compression bs_flags\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if ((engine->bs_flags & BS_PROTO_MASK) & ~(BS_LINEAR | BS_MERKLE))
|
|
{
|
|
fprintf(stderr, "unknown protocol bs_flags\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (!engine->parameters.blocksize)
|
|
engine->parameters.blocksize = remote.blocksize ? remote.blocksize : defaultBlocksize;
|
|
else if (remote.blocksize && (engine->parameters.blocksize != remote.blocksize))
|
|
{
|
|
fprintf(stderr, "incompatible block sizes\n");
|
|
exit(EXIT_FAILURE);
|
|
} else if (engine->parameters.blocksize > MAX_MSG_PAYLOAD_LENGTH){
|
|
fatal("requested blocksize too large. (%d > %d)", remote.blocksize, MAX_MSG_PAYLOAD_LENGTH);
|
|
}
|
|
|
|
if ((engine->bs_flags & BS_COMPRESSION_MASK) && (remote.bs_flags & BS_COMPRESSION_MASK) && ((engine->bs_flags & BS_COMPRESSION_MASK) != (remote.bs_flags & BS_COMPRESSION_MASK))){
|
|
fprintf(stderr, "incomatible compression modes\n");
|
|
exit(EXIT_FAILURE);
|
|
} else if (!(engine->bs_flags & BS_COMPRESSION_MASK)){
|
|
engine->bs_flags |= remote.bs_flags & BS_COMPRESSION_MASK;
|
|
}
|
|
|
|
if ((engine->bs_flags & BS_PROTO_MASK) && (remote.bs_flags & BS_PROTO_MASK) && ((engine->bs_flags & BS_PROTO_MASK) != (remote.bs_flags & BS_PROTO_MASK))){
|
|
fprintf(stderr, "incomatible protocol modes\n");
|
|
exit(EXIT_FAILURE);
|
|
} else if (!(engine->bs_flags & BS_PROTO_MASK)){
|
|
engine->bs_flags |= remote.bs_flags & BS_PROTO_MASK;
|
|
}
|
|
|
|
if (!(engine->bs_flags & BS_PROTO_MASK))
|
|
engine->bs_flags |= BS_LINEAR;
|
|
|
|
if ((engine->bs_flags & BS_RECEIVER) && (engine->file.size != remote.filesize)){
|
|
fprintf(stdout, "truncate needed to %ld bytes (0x%lx)\n", remote.filesize, remote.filesize);
|
|
fflush(stdout);
|
|
|
|
if (bs_engine_truncate_file(engine, remote.filesize))
|
|
fatal("could not truncate file %s ( %s )", engine->file.filename, strerror(errno));
|
|
}
|
|
|
|
return 0;
|
|
}
|