/*
* This file is part of rasdaman community.
*
* Rasdaman community is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Rasdaman community is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rasdaman community. If not, see .
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
rasdaman GmbH.
*
* For more information please see
* or contact Peter Baumann via .
/
/**
* SOURCE: rasmgr_config.cc
*
* MODULE: rasmgr
* CLASS: Configuration, RasmgrLicense
*
* PURPOSE:
* Config info from commandline, environment and license
*
* COMMENTS:
* none
*
*/
using namespace std;
#include "globals.hh" // DEFAULT_HOSTNAME, DEFAULT_PORT, RASMGR_CONF_FILE
#include "rasmgr_config.hh"
#include "rasmgr.hh"
#include "rasmgr_host.hh"
#include "rasmgr_dbm.hh"
#include "rasmgr_srv.hh"
#include "ras_crypto.hh"
#include "rasmgr_users.hh"
#include "rasmgr_comm.hh"
#include "rasmgr_rascontrol.hh"
#include // mkstemp()
#include
#include
#include "debug.hh"
extern bool hostCmp( const char *h1, const char *h2);
Configuration::Configuration():
cmlInter (CommandLineParser::getInstance()),
cmlName (cmlInter.addStringParameter(CommandLineParser::noShortName, "name", " symbolic name of this rasmgr (slave only, default: the host name)")),
cmlHostName (cmlInter.addStringParameter(CommandLineParser::noShortName, "hostname", " the advertized host name (master only, default: same as UNIX command 'hostname')")),
cmlPort (cmlInter.addLongParameter(CommandLineParser::noShortName, "port", " listen port number", DEFAULT_PORT)),
cmlPollFrequ (cmlInter.addLongParameter(CommandLineParser::noShortName, "poll", " polling timeout (in seconds) for rasmgr listen port", DEFAULT_POLLING_FREQUENCY )),
cmlMaster (cmlInter.addStringParameter(CommandLineParser::noShortName, "master", " host of rasmgr master (slave only)")),
cmlMasterPort (cmlInter.addLongParameter(CommandLineParser::noShortName, "mport", " listen port number of rasmgr master (slave only)", DEFAULT_PORT)),
cmlQuiet (cmlInter.addFlagParameter( 'q', CommandLineParser::noLongName, "quiet: don't log requests (default: log requests to stdout)")),
#ifdef RMANDEBUG // was: NO_OFFICIAL_RELEASE
cmlTest (cmlInter.addFlagParameter(CommandLineParser::noShortName, "test", "test mode")),
cmlDSup (cmlInter.addFlagParameter(CommandLineParser::noShortName, "dsup", "debug mode")),
cmlRandTest (cmlInter.addFlagParameter(CommandLineParser::noShortName, "rgt", "random generator test")),
cmlRth (cmlInter.addFlagParameter(CommandLineParser::noShortName, "rth", "disable rthl test")),
cmlMultiWT (cmlInter.addFlagParameter(CommandLineParser::noShortName, "amw", "allow multiple write transactions")),
#endif // RMANDEBUG
cmlHelp (cmlInter.addFlagParameter('h', RASMGRCMD_HELP, "print this help"))
{
ENTER( "Configuration::Configuration: enter." );
int ghnResult = gethostname(hostName, sizeof(hostName) );
if (ghnResult != 0) // cannot get hostname?
{
int ghnErrno = errno;
std::cout << "Error: cannot get hostname of my machine: error " << ghnErrno << "; will use '" << DEFAULT_HOSTNAME << "' as heuristic." << endl;
strcpy( hostName, DEFAULT_HOSTNAME );
}
strcpy(slaveName,hostName);
strcpy(publicHostName,hostName);
listenPort=DEFAULT_PORT;
masterPort=DEFAULT_PORT;
masterName[0]=0;
pollFrequency = DEFAULT_POLLING_FREQUENCY;
configFileName[0]=0;
slave = false;
if (sizeof(configFileName) < strlen(CONFDIR) + strlen(RASMGR_CONF_FILE) + 2)
{
std::cout << "Error: configuration path length exceeds system limits: '" << CONFDIR << "/" << RASMGR_CONF_FILE << "'" << endl;
LEAVE( "Configuration::Configuration: leave." );
return;
}
sprintf( configFileName, "%s/%s", CONFDIR, RASMGR_CONF_FILE );
altConfigFileName[0] = '\0';
testModus = false;
debugSupport = false;
rtHlTest = true; // by default RasMgr tests at runtime if it's the only one
allowMultiWT = false; // rasmgr doesn't allow multiple write transactions for a db
LEAVE( "Configuration::Configuration: leave." );
}
bool Configuration::readConfigFile()
{
//insert internal host, it's not in config file
hostmanager.insertInternalHost();
char inBuffer[MAXMSG];
char outBuffer[MAXMSG];
bool result = true;
bool fileIsOpen = false;
ENTER( "Configuration::readConfigFile: enter. Looking for config file " << configFileName );
VLOG << "Inspecting config file " << configFileName << "...";
std::ifstream ifs(configFileName); // open config file
if(ifs)
fileIsOpen = true;
else
{
TALK( "Configuration::readConfigFile: cannot open config file." );
std::cout << "Warning: cannot open config file " << configFileName << endl;
fileIsOpen = false;
}
result = true; // was: false, but I want to allow a missing file
if (fileIsOpen)
{
authorization.startConfigFile();
while( ! ifs.eof() ) // was: while(1), I simplified this
// processRequest() will get an additional empty line at eof, but this is harmless
{
ifs.getline(inBuffer,MAXMSG);
// if(!strlen(inBuffer) && ifs.eof()) // FIXME: what happens if last line in file is empty?
// {
// TALK( "Configuration::readConfigFile: strlen(inBuffer)=" << strlen(inBuffer) << ", eof=" << ifs.eof());
// break;
// }
TALK( "Configuration::readConfigFile: processing line: " << inBuffer );
rascontrol.processRequest(inBuffer,outBuffer);
}
authorization.endConfigFile();
ifs.close(); // close config file handle
}
if (result == true && fileIsOpen)
VLOG << "ok" << endl;
LEAVE( "Configuration::readConfigFile: leave. result=" << result );
return true;
}
// return name of alternate config file;
// takes value from preceding saveAltConfigFile() call.
const char *Configuration::getAltConfigFileName()
{
return altConfigFileName;
}
// in future this is not used directly, but through saveOrigConfigFile() and saveAltConfigFile() wrappers below
bool Configuration::saveConfigFile()
{
ENTER( "Configuration::saveConfigFile: enter." );
std::ofstream ofs(configFileName);
if(!ofs)
{
LEAVE( "Configuration::saveConfigFile: leave. cannot open config file " << configFileName << " for writing." );
return false;
}
ofs << "# rasmgr config file (v1.1)" << std::endl;
ofs << "# warning: do not edit this file, it may be overwritten by rasmgr!" << std::endl;
ofs << "#" << std::endl;
int i;
//serverhosts
for(i=0;i 0)
ofs<<"define host "< if we have to we change it here
if( ! hostCmp(xx.getName(),config.getHostName()) )
ofs << "change host "< strlen(cmlHostName.getValueAsString()))
strcpy(publicHostName,cmlHostName.getValueAsString());
else
{
VLOG << "Error: host name exceeds length limit of " << sizeof(hostName) << " characters." << std::endl;
result = false;
}
}
if( (result==true) && cmlPort.isPresent() )
{
try
{
listenPort = cmlPort.getValueAsLong();
}
catch(CmlException& err)
{
VLOG << "Error converting port parameter " << cmlPort.getLongName() << " to integer: " << err.what() << std::endl;
result = false;
}
}
if( (result==true) && cmlMaster.isPresent() )
{
slave = true;
strcpy(masterName,cmlMaster.getValueAsString());
}
if( (result==true) && cmlMasterPort.isPresent() )
{
try
{
masterPort = cmlMasterPort.getValueAsLong();
}
catch(CmlException& err)
{
VLOG << "Error converting " << cmlMasterPort.getLongName() << " to integer: " << err.what() << std::endl;
result = false;
}
}
if( (result==true) && cmlPollFrequ.isPresent() )
{
try
{
pollFrequency = cmlPollFrequ.getValueAsLong();
}
catch(CmlException& err)
{
VLOG << "Error converting " << cmlPollFrequ.getLongName() << " to integer: " << err.what() << std::endl;
result = false;
}
if (result == true && pollFrequency <= 0)
{
VLOG << "Error: poll frequency must be a positive integer." << std::endl;
result = false;
}
}
if( (result==true) && cmlName.isPresent() )
{
if (sizeof(slaveName) > strlen(cmlName.getValueAsString()))
strcpy(slaveName,cmlName.getValueAsString());
else
{
VLOG << "Error: slave name exceeds length limit of " << sizeof(slaveName) << " characters." << std::endl;
result = false;
}
}
#ifdef RMANDEBUG // was: NO_OFFICIAL_RELEASE
testModus = cmlTest.isPresent();
debugSupport=cmlDSup.isPresent();
rtHlTest=cmlRth.isPresent();
if( (result==true) && cmlRandTest.isPresent() )
{
std::cout<<"Random generator test..."<<(randomGenerator.insideTest() ? "PASSED":"FAILED" )<