1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-10-25 04:17:20 +02:00
Files
SqMod/vendor/POCO/DNSSD/samples/DNSSDBrowser/src/DNSSDBrowser.cpp
Sandu Liviu Catalin f2b7499f85 Update libraries and make it build on windows.
Still gets some warnings because compilers have changed. But should work.
2025-06-25 22:34:23 +03:00

437 lines
15 KiB
C++

//
// DNSSDBrowser.cpp
//
// $Id: //poco/1.7/DNSSD/samples/DNSSDBrowser/src/DNSSDBrowser.cpp#1 $
//
// This sample demonstrates the DNSSDBrowser and DNSSDResponder classes.
//
// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Util/ServerApplication.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/HelpFormatter.h"
#include "Poco/Util/IntValidator.h"
#include "Poco/DNSSD/DNSSDResponder.h"
#include "Poco/DNSSD/DNSSDBrowser.h"
#if POCO_OS == POCO_OS_LINUX && !defined(POCO_DNSSD_USE_BONJOUR)
#include "Poco/DNSSD/Avahi/Avahi.h"
#else
#include "Poco/DNSSD/Bonjour/Bonjour.h"
#endif
#include "Poco/Delegate.h"
#include "Poco/NumberParser.h"
#include "Poco/Thread.h"
#include <set>
#include <iostream>
using Poco::Util::Application;
using Poco::Util::ServerApplication;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::OptionCallback;
using Poco::Util::HelpFormatter;
using Poco::DNSSD::DNSSDResponder;
using Poco::DNSSD::Service;
using Poco::DNSSD::BrowseHandle;
using Poco::DNSSD::ServiceHandle;
class DNSSDBrowserApp: public ServerApplication
{
public:
DNSSDBrowserApp():
_helpRequested(false),
_autoResolve(false),
_enumerateDomains(false),
_port(0),
_interface(0)
{
Poco::DNSSD::initializeDNSSD();
}
~DNSSDBrowserApp()
{
Poco::DNSSD::uninitializeDNSSD();
}
protected:
void initialize(Application& self)
{
loadConfiguration(); // load default configuration files, if present
ServerApplication::initialize(self);
}
void uninitialize()
{
ServerApplication::uninitialize();
}
void defineOptions(OptionSet& options)
{
ServerApplication::defineOptions(options);
options.addOption(
Option("help", "h", "Display help information on command line arguments.")
.required(false)
.repeatable(false)
.callback(OptionCallback<DNSSDBrowserApp>(this, &DNSSDBrowserApp::handleHelp)));
options.addOption(
Option("browse", "b",
"Browse for services with the type given in the argument (e.g., _ftp._tcp). "
"Can be specified multiple times to browse for different types of services.")
.required(false)
.repeatable(true)
.argument("<service-type>")
.callback(OptionCallback<DNSSDBrowserApp>(this, &DNSSDBrowserApp::handleBrowse)));
options.addOption(
Option("resolve", "r",
"Automatically resolve all discovered services.")
.required(false)
.repeatable(false)
.callback(OptionCallback<DNSSDBrowserApp>(this, &DNSSDBrowserApp::handleResolve)));
options.addOption(
Option("domain", "d",
"Specify the domain to browse, or register a service in. "
"If not specified, the default domain will be used.")
.required(false)
.repeatable(false)
.argument("<domain>")
.callback(OptionCallback<DNSSDBrowserApp>(this, &DNSSDBrowserApp::handleDomain)));
options.addOption(
Option("enumerate-domains", "e", "Enumerate browse- and registration-domains.")
.required(false)
.repeatable(false)
.callback(OptionCallback<DNSSDBrowserApp>(this, &DNSSDBrowserApp::handleEnumerate)));
options.addOption(
Option("register", "R",
"Register a service with the given type (e.g., _ftp._tcp).")
.required(false)
.repeatable(false)
.argument("<service-type>")
.callback(OptionCallback<DNSSDBrowserApp>(this, &DNSSDBrowserApp::handleRegister)));
options.addOption(
Option("name", "n",
"Specify the service name for the service to be registered. "
"If not specified, the name of the machine will be used.")
.required(false)
.repeatable(false)
.argument("<name>")
.callback(OptionCallback<DNSSDBrowserApp>(this, &DNSSDBrowserApp::handleName)));
options.addOption(
Option("host", "H",
"Specify the host name for the service to be registered. "
"If not specified, the machine's host name will be used.")
.required(false)
.repeatable(false)
.argument("<host>")
.callback(OptionCallback<DNSSDBrowserApp>(this, &DNSSDBrowserApp::handleHost)));
options.addOption(
Option("port", "p",
"Specify the port number for the service to be registered. "
"If not specified, the service will be registered with port 0.")
.required(false)
.repeatable(false)
.argument("<port>")
.validator(new Poco::Util::IntValidator(0, 65535))
.callback(OptionCallback<DNSSDBrowserApp>(this, &DNSSDBrowserApp::handlePort)));
options.addOption(
Option("txt", "t",
"Specify a key-value pair for a registered service's TXT record. "
"Can be given multiple times.")
.required(false)
.repeatable(true)
.argument("<key><[=value]>")
.callback(OptionCallback<DNSSDBrowserApp>(this, &DNSSDBrowserApp::handleTXT)));
options.addOption(
Option("interface", "i",
"Specify a specific network interface for browsing and registration, by its "
"interface index. Specify 0 to browse/register on all interfaces (default).")
.required(false)
.repeatable(false)
.argument("<intf-index>")
.validator(new Poco::Util::IntValidator(0, 16))
.callback(OptionCallback<DNSSDBrowserApp>(this, &DNSSDBrowserApp::handleInterface)));
}
void handleHelp(const std::string& name, const std::string& value)
{
_helpRequested = true;
stopOptionsProcessing();
}
void handleBrowse(const std::string& name, const std::string& value)
{
_browseTypes.insert(value);
}
void handleResolve(const std::string& name, const std::string& value)
{
_autoResolve = true;
}
void handleDomain(const std::string& name, const std::string& value)
{
_domain = value;
}
void handleEnumerate(const std::string& name, const std::string& value)
{
_enumerateDomains = true;
}
void handleRegister(const std::string& name, const std::string& value)
{
_registeredService = value;
}
void handleName(const std::string& name, const std::string& value)
{
_name = value;
}
void handleHost(const std::string& name, const std::string& value)
{
_host = value;
}
void handlePort(const std::string& name, const std::string& value)
{
_port = static_cast<Poco::UInt16>(Poco::NumberParser::parseUnsigned(value));
}
void handleTXT(const std::string& name, const std::string& value)
{
std::string::size_type pos = value.find('=');
if (pos != std::string::npos)
{
_properties.add(value.substr(0, pos), value.substr(pos + 1));
}
else
{
_properties.add(value, "");
}
}
void handleInterface(const std::string& name, const std::string& value)
{
_interface = Poco::NumberParser::parse(value);
}
void displayHelp()
{
HelpFormatter helpFormatter(options());
helpFormatter.setCommand(commandName());
helpFormatter.setUsage("OPTIONS");
helpFormatter.setHeader(
"\n"
"A sample application demonstrating the use of the DNSSDBrowser and DNSSDResponder classes. "
"The following command line options are supported:");
helpFormatter.setFooter(
"For more information, please see the Applied Informatics C++ Libraries "
"and Tools documentation at <http://docs.appinf.com>."
);
helpFormatter.setIndent(8);
helpFormatter.format(std::cout);
}
void onError(const void* sender, const Poco::DNSSD::DNSSDBrowser::ErrorEventArgs& args)
{
std::cout << args.error.message() << " (" << args.error.code() << ")" << std::endl;
}
void onServiceFound(const void* sender, const Poco::DNSSD::DNSSDBrowser::ServiceEventArgs& args)
{
std::cout << "Service Found: \n"
<< " Name: " << args.service.name() << "\n"
<< " Domain: " << args.service.domain() << "\n"
<< " Type: " << args.service.type() << "\n"
<< " Interface: " << args.service.networkInterface() << "\n" << std::endl;
if (_autoResolve)
{
reinterpret_cast<Poco::DNSSD::DNSSDBrowser*>(const_cast<void*>(sender))->resolve(args.service);
}
}
void onServiceRemoved(const void* sender, const Poco::DNSSD::DNSSDBrowser::ServiceEventArgs& args)
{
std::cout << "Service Removed: \n"
<< " Name: " << args.service.name() << "\n"
<< " Domain: " << args.service.domain() << "\n"
<< " Type: " << args.service.type() << "\n"
<< " Interface: " << args.service.networkInterface() << "\n" << std::endl;
}
void onServiceResolved(const void* sender, const Poco::DNSSD::DNSSDBrowser::ServiceEventArgs& args)
{
std::cout << "Service Resolved: \n"
<< " Name: " << args.service.name() << "\n"
<< " Full Name: " << args.service.fullName() << "\n"
<< " Domain: " << args.service.domain() << "\n"
<< " Type: " << args.service.type() << "\n"
<< " Interface: " << args.service.networkInterface() << "\n"
<< " Host: " << args.service.host() << "\n"
<< " Port: " << args.service.port() << "\n"
<< " Properties: \n";
for (Poco::DNSSD::Service::Properties::ConstIterator it = args.service.properties().begin(); it != args.service.properties().end(); ++it)
{
std::cout << " " << it->first << ": " << it->second << "\n";
}
std::cout << std::endl;
reinterpret_cast<Poco::DNSSD::DNSSDBrowser*>(const_cast<void*>(sender))->resolveHost(args.service.host());
}
void onHostResolved(const void* sender, const Poco::DNSSD::DNSSDBrowser::ResolveHostEventArgs& args)
{
std::cout << "Host Resolved: \n"
<< " Host: " << args.host << "\n"
<< " Interface: " << args.networkInterface << "\n"
<< " Address: " << args.address.toString() << "\n"
<< " TTL: " << args.ttl << "\n" << std::endl;
}
void onBrowseDomainFound(const void* sender, const Poco::DNSSD::DNSSDBrowser::DomainEventArgs& args)
{
std::cout << "Browse Domain Found:\n"
<< " Name: " << args.domain.name() << "\n"
<< " Interface: " << args.domain.networkInterface() << "\n"
<< " Default: " << args.domain.isDefault() << "\n" << std::endl;
}
void onBrowseDomainRemoved(const void* sender, const Poco::DNSSD::DNSSDBrowser::DomainEventArgs& args)
{
std::cout << "Browse Domain Removed:\n"
<< " Name: " << args.domain.name() << "\n"
<< " Interface: " << args.domain.networkInterface() << "\n"
<< " Default: " << args.domain.isDefault() << "\n" << std::endl;
}
void onRegistrationDomainFound(const void* sender, const Poco::DNSSD::DNSSDBrowser::DomainEventArgs& args)
{
std::cout << "Registration Domain Found:\n"
<< " Name: " << args.domain.name() << "\n"
<< " Interface: " << args.domain.networkInterface() << "\n"
<< " Default: " << args.domain.isDefault() << "\n" << std::endl;
}
void onRegistrationDomainRemoved(const void* sender, const Poco::DNSSD::DNSSDBrowser::DomainEventArgs& args)
{
std::cout << "Registration Domain Removed:\n"
<< " Name: " << args.domain.name() << "\n"
<< " Interface: " << args.domain.networkInterface() << "\n"
<< " Default: " << args.domain.isDefault() << "\n" << std::endl;
}
int main(const std::vector<std::string>& args)
{
if (_helpRequested || (_browseTypes.empty() && _registeredService.empty() && !_enumerateDomains))
{
displayHelp();
}
else
{
DNSSDResponder dnssdResponder;
dnssdResponder.browser().browseError += Poco::delegate(this, &DNSSDBrowserApp::onError);
dnssdResponder.browser().resolveError += Poco::delegate(this, &DNSSDBrowserApp::onError);
dnssdResponder.browser().serviceFound += Poco::delegate(this, &DNSSDBrowserApp::onServiceFound);
dnssdResponder.browser().serviceRemoved += Poco::delegate(this, &DNSSDBrowserApp::onServiceRemoved);
dnssdResponder.browser().serviceResolved += Poco::delegate(this, &DNSSDBrowserApp::onServiceResolved);
dnssdResponder.browser().browseDomainError += Poco::delegate(this, &DNSSDBrowserApp::onError);
dnssdResponder.browser().browseDomainFound += Poco::delegate(this, &DNSSDBrowserApp::onBrowseDomainFound);
dnssdResponder.browser().browseDomainRemoved += Poco::delegate(this, &DNSSDBrowserApp::onBrowseDomainRemoved);
dnssdResponder.browser().registrationDomainError += Poco::delegate(this, &DNSSDBrowserApp::onError);
dnssdResponder.browser().registrationDomainFound += Poco::delegate(this, &DNSSDBrowserApp::onRegistrationDomainFound);
dnssdResponder.browser().registrationDomainRemoved += Poco::delegate(this, &DNSSDBrowserApp::onRegistrationDomainRemoved);
dnssdResponder.browser().hostResolveError += Poco::delegate(this, &DNSSDBrowserApp::onError);
dnssdResponder.browser().hostResolved += Poco::delegate(this, &DNSSDBrowserApp::onHostResolved);
std::vector<BrowseHandle> browseHandles;
for (std::set<std::string>::const_iterator it = _browseTypes.begin(); it != _browseTypes.end(); ++it)
{
browseHandles.push_back(dnssdResponder.browser().browse(*it, _domain, 0, _interface));
}
if (_enumerateDomains)
{
browseHandles.push_back(dnssdResponder.browser().enumerateBrowseDomains(_interface));
browseHandles.push_back(dnssdResponder.browser().enumerateRegistrationDomains(_interface));
}
ServiceHandle serviceHandle;
if (!_registeredService.empty())
{
Service service(_interface, _name, "", _registeredService, _domain, _host, _port, _properties);
serviceHandle = dnssdResponder.registerService(service);
}
dnssdResponder.start();
waitForTerminationRequest();
if (serviceHandle.isValid())
{
dnssdResponder.unregisterService(serviceHandle);
Poco::Thread::sleep(2500); // allow time for delivery of remove event
}
for (std::vector<BrowseHandle>::iterator it = browseHandles.begin(); it != browseHandles.end(); ++it)
{
dnssdResponder.browser().cancel(*it);
}
dnssdResponder.stop();
dnssdResponder.browser().browseError -= Poco::delegate(this, &DNSSDBrowserApp::onError);
dnssdResponder.browser().resolveError -= Poco::delegate(this, &DNSSDBrowserApp::onError);
dnssdResponder.browser().serviceFound -= Poco::delegate(this, &DNSSDBrowserApp::onServiceFound);
dnssdResponder.browser().serviceRemoved -= Poco::delegate(this, &DNSSDBrowserApp::onServiceRemoved);
dnssdResponder.browser().serviceResolved -= Poco::delegate(this, &DNSSDBrowserApp::onServiceResolved);
dnssdResponder.browser().browseDomainError -= Poco::delegate(this, &DNSSDBrowserApp::onError);
dnssdResponder.browser().browseDomainFound -= Poco::delegate(this, &DNSSDBrowserApp::onBrowseDomainFound);
dnssdResponder.browser().browseDomainRemoved -= Poco::delegate(this, &DNSSDBrowserApp::onBrowseDomainRemoved);
dnssdResponder.browser().registrationDomainError -= Poco::delegate(this, &DNSSDBrowserApp::onError);
dnssdResponder.browser().registrationDomainFound -= Poco::delegate(this, &DNSSDBrowserApp::onRegistrationDomainFound);
dnssdResponder.browser().registrationDomainRemoved -= Poco::delegate(this, &DNSSDBrowserApp::onRegistrationDomainRemoved);
dnssdResponder.browser().hostResolveError -= Poco::delegate(this, &DNSSDBrowserApp::onError);
dnssdResponder.browser().hostResolved -= Poco::delegate(this, &DNSSDBrowserApp::onHostResolved);
}
return Application::EXIT_OK;
}
private:
bool _helpRequested;
bool _autoResolve;
bool _enumerateDomains;
std::set<std::string> _browseTypes;
std::string _domain;
std::string _registeredService;
std::string _name;
std::string _host;
Service::Properties _properties;
Poco::UInt16 _port;
Poco::Int32 _interface;
};
POCO_SERVER_MAIN(DNSSDBrowserApp)