added command line and configuration file arguments to choose

the address and port to listen on or connect to.  changed the
default port and put it in ProtocolTypes.h.  the HTTP port is
now no longer opened unless the --http argument is supplied
or the config file includes it.
This commit is contained in:
crs
2002-06-09 16:53:25 +00:00
parent 8b2a282eb5
commit 555aa19eb2
14 changed files with 376 additions and 62 deletions

View File

@@ -1,4 +1,5 @@
#include "CConfig.h"
#include "ProtocolTypes.h"
#include "stdistream.h"
#include "stdostream.h"
#include <assert.h>
@@ -156,6 +157,16 @@ bool CConfig::disconnect(const CString& srcName,
return true;
}
void CConfig::setSynergyAddress(const CNetworkAddress& addr)
{
m_synergyAddress = addr;
}
void CConfig::setHTTPAddress(const CNetworkAddress& addr)
{
m_httpAddress = addr;
}
bool CConfig::isValidScreenName(const CString& name) const
{
// name is valid if matches validname
@@ -245,6 +256,16 @@ CString CConfig::getNeighbor(const CString& srcName,
srcSide - kFirstDirection]);
}
const CNetworkAddress& CConfig::getSynergyAddress() const
{
return m_synergyAddress;
}
const CNetworkAddress& CConfig::getHTTPAddress() const
{
return m_httpAddress;
}
const char* CConfig::dirName(EDirection dir)
{
static const char* s_name[] = { "left", "right", "top", "bottom" };
@@ -277,6 +298,7 @@ bool CConfig::readLine(std::istream& s, CString& line)
void CConfig::readSection(std::istream& s)
{
static const char s_section[] = "section:";
static const char s_network[] = "network";
static const char s_screens[] = "screens";
static const char s_links[] = "links";
static const char s_aliases[] = "aliases";
@@ -304,7 +326,10 @@ void CConfig::readSection(std::istream& s)
}
// read section
if (name == s_screens) {
if (name == s_network) {
readSectionNetwork(s);
}
else if (name == s_screens) {
readSectionScreens(s);
}
else if (name == s_links) {
@@ -318,6 +343,61 @@ void CConfig::readSection(std::istream& s)
}
}
void CConfig::readSectionNetwork(std::istream& s)
{
CString line;
CString name;
while (readLine(s, line)) {
// check for end of section
if (line == "end") {
return;
}
// parse argument: `<name>=<value>'
CString::size_type i = line.find_first_of(" \t=");
if (i == 0) {
throw XConfigRead("missing argument name");
}
if (i == CString::npos) {
throw XConfigRead("missing = in argument");
}
CString name = line.substr(0, i);
i = line.find_first_not_of(" \t", i);
if (i == CString::npos || line[i] != '=') {
throw XConfigRead("missing = in argument");
}
i = line.find_first_not_of(" \t", i + 1);
CString value;
if (i != CString::npos) {
value = line.substr(i);
}
if (value.empty()) {
throw XConfigRead("missing value after =");
}
if (name == "address") {
try {
m_synergyAddress = CNetworkAddress(value, kDefaultPort);
}
catch (XSocketAddress&) {
throw XConfigRead("invalid address argument");
}
}
else if (name == "http") {
try {
m_httpAddress = CNetworkAddress(value, kDefaultPort + 1);
}
catch (XSocketAddress&) {
throw XConfigRead("invalid http argument");
}
}
else {
throw XConfigRead("unknown argument");
}
}
throw XConfigRead("unexpected end of screens section");
}
void CConfig::readSectionScreens(std::istream& s)
{
CString line;
@@ -493,6 +573,18 @@ std::istream& operator>>(std::istream& s, CConfig& config)
std::ostream& operator<<(std::ostream& s, const CConfig& config)
{
// network section
s << "section: network" << std::endl;
if (config.m_synergyAddress.isValid()) {
s << "\taddress=" << config.m_synergyAddress.getHostname().c_str() <<
std::endl;
}
if (config.m_httpAddress.isValid()) {
s << "\thttp=" << config.m_httpAddress.getHostname().c_str() <<
std::endl;
}
s << "end" << std::endl;
// screens section
s << "section: screens" << std::endl;
for (CConfig::const_iterator screen = config.begin();

View File

@@ -3,6 +3,7 @@
#include "BasicTypes.h"
#include "CString.h"
#include "CNetworkAddress.h"
#include "XBase.h"
#include <iosfwd>
#include "stdmap.h"
@@ -96,6 +97,11 @@ public:
bool disconnect(const CString& srcName,
EDirection srcSide);
// set the synergy and http listen addresses. there are no
// default addresses.
void setSynergyAddress(const CNetworkAddress&);
void setHTTPAddress(const CNetworkAddress&);
// accessors
// returns true iff the given name is a valid screen name.
@@ -120,6 +126,10 @@ public:
// screen name.
CString getNeighbor(const CString&, EDirection) const;
// get the listen addresses
const CNetworkAddress& getSynergyAddress() const;
const CNetworkAddress& getHTTPAddress() const;
// read/write a configuration. operator>> will throw XConfigRead
// on error.
friend std::istream& operator>>(std::istream&, CConfig&);
@@ -131,6 +141,7 @@ public:
private:
static bool readLine(std::istream&, CString&);
void readSection(std::istream&);
void readSectionNetwork(std::istream&);
void readSectionScreens(std::istream&);
void readSectionLinks(std::istream&);
void readSectionAliases(std::istream&);
@@ -140,6 +151,8 @@ private:
CCellMap m_map;
CNameMap m_nameToCanonicalName;
CNetworkAddress m_synergyAddress;
CNetworkAddress m_httpAddress;
};
class XConfigRead : public XBase {

View File

@@ -308,6 +308,7 @@ void CHTTPServer::doProcessPostEditMap(
// convert temporary screen map into a regular map
CConfig config;
m_server->getConfig(&config);
screens.convertTo(config);
// set new screen map on server
@@ -719,6 +720,8 @@ bool CHTTPServer::CScreenArray::convertFrom(
void CHTTPServer::CScreenArray::convertTo(
CConfig& config) const
{
config.removeAllScreens();
// add screens and find smallest box containing all screens
SInt32 x0 = m_w, x1 = 0, y0 = m_h, y1 = 0;
for (SInt32 y = 0; y < m_h; ++y) {

View File

@@ -83,13 +83,15 @@ void CServer::run()
}
}
// start listening for HTTP requests
m_httpServer = new CHTTPServer(this);
CThread(new TMethodJob<CServer>(this, &CServer::acceptHTTPClients));
// start listening for new clients
CThread(new TMethodJob<CServer>(this, &CServer::acceptClients));
// start listening for HTTP requests
if (m_config.getHTTPAddress().isValid()) {
m_httpServer = new CHTTPServer(this);
CThread(new TMethodJob<CServer>(this, &CServer::acceptHTTPClients));
}
// handle events
log((CLOG_DEBUG "starting event handling"));
m_primary->run();
@@ -982,11 +984,10 @@ void CServer::acceptClients(void*)
// bind to the desired port. keep retrying if we can't bind
// the address immediately.
CStopwatch timer;
CNetworkAddress addr(50001 /* FIXME -- m_port */);
for (;;) {
try {
log((CLOG_DEBUG1 "binding listen socket"));
listen->bind(addr);
listen->bind(m_config.getSynergyAddress());
break;
}
catch (XSocketAddressInUse&) {
@@ -1166,11 +1167,10 @@ void CServer::acceptHTTPClients(void*)
// bind to the desired port. keep retrying if we can't bind
// the address immediately.
CStopwatch timer;
CNetworkAddress addr(50002 /* FIXME -- m_httpPort */);
for (;;) {
try {
log((CLOG_DEBUG1 "binding listen socket"));
listen->bind(addr);
log((CLOG_DEBUG1 "binding HTTP listen socket"));
listen->bind(m_config.getHTTPAddress());
break;
}
catch (XSocketAddressInUse&) {

View File

@@ -6,6 +6,7 @@
#include "MouseTypes.h"
#include "CConfig.h"
#include "CClipboard.h"
#include "CNetworkAddress.h"
#include "CCondVar.h"
#include "CMutex.h"
#include "CString.h"

View File

@@ -39,6 +39,8 @@ static bool s_install = false;
static bool s_uninstall = false;
static const char* s_configFile = NULL;
static const char* s_logFilter = NULL;
static CNetworkAddress s_synergyAddress;
static CNetworkAddress s_httpAddress;
static CConfig s_config;
@@ -67,6 +69,7 @@ static void logLock(bool lock)
static CServer* s_server = NULL;
#include <signal.h>
static int realMain(CMutex* mutex)
{
// s_serverLock should have mutex locked on entry
@@ -82,15 +85,27 @@ static int realMain(CMutex* mutex)
bool locked = true;
try {
// initialize network library
CNetwork::init();
// if configuration has no screens then add this system
// as the default
if (s_config.begin() == s_config.end()) {
s_config.addScreen("primary");
}
// set the contact address, if provided, in the config.
// otherwise, if the config doesn't have an address, use
// the default.
if (s_synergyAddress.isValid()) {
s_config.setSynergyAddress(s_synergyAddress);
}
else if (!s_config.getSynergyAddress().isValid()) {
s_config.setSynergyAddress(CNetworkAddress(kDefaultPort));
}
// set HTTP address is provided
if (s_httpAddress.isValid()) {
s_config.setHTTPAddress(s_httpAddress);
}
// create server
s_server = new CServer();
@@ -195,6 +210,7 @@ static void help()
"\n"
"Start the synergy mouse/keyboard sharing server.\n"
"\n"
" -a, --address <address> listen for clients on the given address.\n"
" -c, --config <pathname> use the named configuration file instead\n"
" where ~ represents the user's home directory.\n"
" -d, --debug <level> filter out log messages with priorty below level.\n"
@@ -212,6 +228,11 @@ static void help()
"\n"
"* marks defaults.\n"
"\n"
"The argument for --address is of the form: [<hostname>][:<port>]. The\n"
"hostname must be the address or hostname of an interface on the system.\n"
"The default is to listen on all interfaces. The port overrides the\n"
"default port, %d.\n"
"\n"
"If no configuration file pathname is provided then the first of the\n"
"following to load sets the configuration:\n"
" %s\n"
@@ -222,6 +243,7 @@ static void help()
"Where log messages go depends on the platform and whether or not the\n"
"server is running as a "DAEMON".",
pname,
kDefaultPort,
platform.addPathComponent(
platform.getUserDirectory(),
CONFIG_NAME).c_str(),
@@ -265,6 +287,32 @@ static void parse(int argc, const char** argv)
s_logFilter = argv[++i];
}
else if (isArg(i, argc, argv, "-a", "--address", 1)) {
// save listen address
try {
s_synergyAddress = CNetworkAddress(argv[i + 1], kDefaultPort);
}
catch (XSocketAddress&) {
log((CLOG_PRINT "%s: invalid address for `%s'" BYE,
pname, argv[i], pname));
bye(2);
}
++i;
}
else if (isArg(i, argc, argv, NULL, "--http", 1)) {
// save listen address
try {
s_httpAddress = CNetworkAddress(argv[i + 1], kDefaultPort + 1);
}
catch (XSocketAddress&) {
log((CLOG_PRINT "%s: invalid address for `%s'" BYE,
pname, argv[i], pname));
bye(2);
}
++i;
}
else if (isArg(i, argc, argv, "-c", "--config", 1)) {
// save configuration file path
s_configFile = argv[++i];
@@ -527,6 +575,9 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
// get program name
pname = platform.getBasename(__argv[0]);
// initialize network library
CNetwork::init();
// parse command line without reporting errors but recording if
// the app would've exited. this is too avoid showing a dialog
// box if we're being started as a service because we shouldn't
@@ -649,6 +700,9 @@ int main(int argc, char** argv)
// get program name
pname = platform.getBasename(argv[0]);
// initialize network library
CNetwork::init();
// parse command line
parse(argc, const_cast<const char**>(argv));