/** * 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 #if !defined(_WIN32) #include #define USE_SIGNAL #endif #include #include #include #include #include #include #include namespace pva = pvxs; namespace { DEFINE_LOGGER(out, "pvxvct"); epicsEvent done; #ifdef USE_SIGNAL void alldone(int num) { (void)num; done.signal(); } #endif // 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_printf(out, PLVL_DEBUG, "Bind: %s\n", baddr.tostring().c_str()); } #ifdef USE_SIGNAL signal(SIGINT, alldone); signal(SIGTERM, alldone); signal(SIGQUIT, alldone); #endif done.wait(); log_printf(out, PLVL_INFO, "Done\n"); errlogFlush(); return 0; }catch(std::runtime_error& e) { errlogFlush(); std::cerr<<"Error: "<