int main(int argc, char *argv[]) { FLAGS_logtostderr = true; // Ugliness in gflags' api; to be able to use program name google::SetArgv(argc, const_cast<const char **>(argv)); google::SetVersionString(Protocol::getFullVersion()); std::string usage("WDT Warp-speed Data Transfer. v "); usage.append(google::VersionString()); usage.append(". Sample usage:\n\t"); usage.append(google::ProgramInvocationShortName()); usage.append(" # for a server/receiver\n\t"); usage.append(google::ProgramInvocationShortName()); usage.append(" -destination host # for a sender"); google::SetUsageMessage(usage); google::ParseCommandLineFlags(&argc, &argv, true); google::InitGoogleLogging(argv[0]); signal(SIGPIPE, SIG_IGN); #define STANDALONE_APP #define ASSIGN_OPT #include FLAGS_INCLUDE_FILE //nolint LOG(INFO) << "Running WDT " << Protocol::getFullVersion(); ErrorCode retCode = OK; // Odd ball case of log parsing if (FLAGS_parse_transfer_log) { // Log parsing mode TransferLogManager transferLogManager; transferLogManager.setRootDir(FLAGS_directory); if (!transferLogManager.parseAndPrint()) { LOG(ERROR) << "Transfer log parsing failed"; return ERROR; } return OK; } // General case : Sender or Receiver const auto &options = WdtOptions::get(); WdtTransferRequest req(options.start_port, options.num_ports, FLAGS_directory); req.transferId = FLAGS_transfer_id; if (FLAGS_protocol_version > 0) { req.protocolVersion = FLAGS_protocol_version; } if (FLAGS_destination.empty() && FLAGS_connection_url.empty()) { Receiver receiver(req); WdtTransferRequest augmentedReq = receiver.init(); if (augmentedReq.errorCode == ERROR) { LOG(ERROR) << "Error setting up receiver"; return augmentedReq.errorCode; } LOG(INFO) << "Starting receiver with connection url "; std::cout << augmentedReq.generateUrl() << std::endl; std::cout.flush(); setUpAbort(receiver); if (!FLAGS_recovery_id.empty()) { WdtOptions::getMutable().enable_download_resumption = true; receiver.setRecoveryId(FLAGS_recovery_id); } if (!FLAGS_run_as_daemon) { receiver.transferAsync(); std::unique_ptr<TransferReport> report = receiver.finish(); retCode = report->getSummary().getErrorCode(); } else { retCode = receiver.runForever(); // not reached } } else { // Sender mode std::vector<FileInfo> fileInfo; if (FLAGS_files) { // Each line should have the filename and optionally // the filesize separated by a single space std::string line; while (std::getline(std::cin, line)) { std::vector<std::string> fields; folly::split('\t', line, fields, true); if (fields.empty() || fields.size() > 2) { LOG(FATAL) << "Invalid input in stdin: " << line; } int64_t filesize = fields.size() > 1 ? folly::to<int64_t>(fields[1]) : -1; fileInfo.emplace_back(fields[0], filesize); } } req.hostName = FLAGS_destination; if (!FLAGS_connection_url.empty()) { LOG(INFO) << "Input url: " << FLAGS_connection_url; // TODO: merge instead req = WdtTransferRequest(FLAGS_connection_url); req.directory = FLAGS_directory; // re-set it for now } Sender sender(req); WdtTransferRequest processedRequest = sender.init(); LOG(INFO) << "Starting sender with details " << processedRequest.generateUrl(true); ADDITIONAL_SENDER_SETUP setUpAbort(sender); sender.setIncludeRegex(FLAGS_include_regex); sender.setExcludeRegex(FLAGS_exclude_regex); sender.setPruneDirRegex(FLAGS_prune_dir_regex); std::unique_ptr<TransferReport> report = sender.transfer(); retCode = report->getSummary().getErrorCode(); } cancelAbort(); return retCode; }
int main(int argc, char *argv[]) { FLAGS_logtostderr = true; // Ugliness in gflags' api; to be able to use program name google::SetArgv(argc, const_cast<const char **>(argv)); google::SetVersionString(Protocol::getFullVersion()); std::string usage("WDT Warp-speed Data Transfer. v "); usage.append(google::VersionString()); usage.append(". Sample usage:\n\t"); usage.append(google::ProgramInvocationShortName()); usage.append(" # for a server/receiver\n\t"); usage.append(google::ProgramInvocationShortName()); usage.append(" -connection_url url_produced_by_receiver # for a sender"); google::SetUsageMessage(usage); google::gflags_exitfunc = [](int code) { if (FLAGS_exit_on_bad_flags) { exit(code); } badGflagFound = true; }; google::ParseCommandLineFlags(&argc, &argv, true); google::InitGoogleLogging(argv[0]); if (badGflagFound) { LOG(ERROR) << "Continuing despite bad flags"; } signal(SIGPIPE, SIG_IGN); FLAGS::initializeFromFlags(); if (FLAGS_print_options) { FLAGS::printOptions(std::cout); return 0; } ErrorCode retCode = OK; // Odd ball case of log parsing if (FLAGS_parse_transfer_log) { // Log parsing mode WdtOptions::getMutable().enable_download_resumption = true; TransferLogManager transferLogManager; transferLogManager.setRootDir(FLAGS_directory); transferLogManager.openLog(); bool success = transferLogManager.parseAndPrint(); LOG_IF(ERROR, success) << "Transfer log parsing failed"; transferLogManager.closeLog(); return success ? OK : ERROR; } // General case : Sender or Receiver const auto &options = WdtOptions::get(); std::unique_ptr<WdtTransferRequest> reqPtr; if (FLAGS_connection_url.empty()) { reqPtr = folly::make_unique<WdtTransferRequest>( options.start_port, options.num_ports, FLAGS_directory); reqPtr->hostName = FLAGS_destination; reqPtr->transferId = FLAGS_transfer_id; } else { LOG(INFO) << "Input url: " << FLAGS_connection_url; reqPtr = folly::make_unique<WdtTransferRequest>(FLAGS_connection_url); if (reqPtr->errorCode != OK) { LOG(ERROR) << "Invalid url " << errorCodeToStr(reqPtr->errorCode); return ERROR; } reqPtr->directory = FLAGS_directory; } WdtTransferRequest &req = *reqPtr; if (FLAGS_protocol_version > 0) { req.protocolVersion = FLAGS_protocol_version; } if (FLAGS_destination.empty() && FLAGS_connection_url.empty()) { Receiver receiver(req); WdtTransferRequest augmentedReq = receiver.init(); if (FLAGS_treat_fewer_port_as_error && augmentedReq.errorCode == FEWER_PORTS) { LOG(ERROR) << "Receiver could not bind to all the ports"; return FEWER_PORTS; } if (augmentedReq.errorCode == ERROR) { LOG(ERROR) << "Error setting up receiver"; return ERROR; } LOG(INFO) << "Starting receiver with connection url "; std::cout << augmentedReq.generateUrl() << std::endl; std::cout.flush(); setUpAbort(receiver); if (!FLAGS_recovery_id.empty()) { WdtOptions::getMutable().enable_download_resumption = true; receiver.setRecoveryId(FLAGS_recovery_id); } if (!FLAGS_run_as_daemon) { retCode = receiver.transferAsync(); if (retCode == OK) { std::unique_ptr<TransferReport> report = receiver.finish(); retCode = report->getSummary().getErrorCode(); } } else { retCode = receiver.runForever(); // not reached } } else { // Sender mode if (!FLAGS_manifest.empty()) { // Each line should have the filename and optionally // the filesize separated by a single space if (FLAGS_manifest == "-") { readManifest(std::cin, req); } else { std::ifstream fin(FLAGS_manifest); readManifest(fin, req); fin.close(); } LOG(INFO) << "Using files lists, number of files " << req.fileInfo.size(); } Sender sender(req); WdtTransferRequest processedRequest = sender.init(); LOG(INFO) << "Starting sender with details " << processedRequest.generateUrl(true); ADDITIONAL_SENDER_SETUP setUpAbort(sender); std::unique_ptr<TransferReport> report = sender.transfer(); retCode = report->getSummary().getErrorCode(); } cancelAbort(); LOG(INFO) << "Returning with code " << retCode << " " << errorCodeToStr(retCode); return retCode; }