/* * 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" )<