// // Created by haraldwolff on 08.08.22. // #include #include #include #include #include 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; }