/** * Copyright - See the COPYRIGHT that is included with this distribution. * pvxs is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace pva = pvxs; namespace { DEFINE_LOGGER(out, "pvxvct"); // parse hostname, IP, or IP+netmask std::tuple parsePeer(const char *optarg) { // nameorip // nameorip/## // nameorip/###.###.###.### // static is safe as we only use from main() thread static std::regex netname("([^/:]*)(?:/([0-9.]+))?"); std::cmatch match; if(!std::regex_match(optarg, match, netname)) { throw std::runtime_error(pva::SB()<<"Expected host name or IP range. not "<>nbit).good()) { throw std::runtime_error(pva::SB()<<"Expected number of bits. not "<> peers; std::set pvnames; } opts; std::vector bindaddrs; { int opt; while ((opt = getopt(argc, argv, "hCSH:B:P:")) != -1) { switch(opt) { case 'h': usage(argv[0]); return 0; default: usage(argv[0]); std::cerr<<"\nUnknown argument: "<sa, &slen)) { throw std::runtime_error(pva::SB()<<"Expected address[:port] to bind. Not "<, std::unique_ptr>> listeners; listeners.reserve(bindaddrs.size()); for(auto& baddr : bindaddrs) { auto manager = pva::UDPManager::instance(); listeners.emplace_back(manager.onSearch(baddr, searchCB), manager.onBeacon(baddr, beaconCB)); listeners.back().first->start(); listeners.back().second->start(); log_debug_printf(out, "Bind: %s\n", baddr.tostring().c_str()); } epicsEvent done; pva::SigInt handle([&done](){ done.trigger(); }); done.wait(); log_info_printf(out, "Done\n%s", ""); errlogFlush(); return 0; }catch(std::runtime_error& e) { errlogFlush(); std::cerr<<"Error: "<