/*
* 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_rascontrol.cc
*
* MODULE: rasmgr
* CLASS: RasControl
*
* PURPOSE:
* Decodes, verifies and executes the commands
*
* COMMENTS:
* None
*
*/
using namespace std;
#include "globals.hh" // DEFAULT_PORT
#include "rasmgr_rascontrol.hh"
#include "rasmgr_config.hh"
#include "rasmgr_master.hh"
#include "rasmgr_srv.hh"
#include "rasmgr_users.hh"
#include "rasmgr_error.hh"
#ifndef RMANVERSION
#error "Please specify RAMNVERSION variable!"
#endif
#ifndef COMPDATE
#error "Please specify the COMPDATE variable!"
/*
COMPDATE=`date +"%d.%m.%Y %H:%M:%S"`
and -DCOMPDATE="\"$(COMPDATE)\"" when compiling
*/
#endif
//#include "rasmgr_rascontrol_help.cc"
#include "debug.hh"
extern bool hostCmp( const char *h1, const char *h2);
// function to migrate -xp parameters, only for v5.1, remove after
void migrateExtraParams(const char *orig, char *migrated);
int RasControl::processRequest(char* reqMessage, char *answMessage)
{
ENTER( "RasControl::processRequest: enter. rascontrol msg: " << reqMessage );
splitRequest(reqMessage);
const char *command=argc ? token[0].take() : "#";
try
{
if(command)
{
TALK( "RasControl::processRequest: command=" << command );
if (isCommand(RASMGRCMD_HELLO)) helloCommand();
else if(isCommand(RASMGRCMD_HELP)) helpCommand();
else if(isCommand(RASMGRCMD_LIST)) listCommand();
else if(isCommand(RASMGRCMD_DEFINE)) defineCommand();
else if(isCommand(RASMGRCMD_REMOVE)) removeCommand();
else if(isCommand(RASMGRCMD_CHECK)) checkCommand();
else if(isCommand(RASMGRCMD_UP)) upCommand();
else if(isCommand(RASMGRCMD_DOWN)) downCommand();
else if(isCommand(RASMGRCMD_CHANGE)) changeCommand();
else if(isCommand(RASMGRCMD_SAVE)) saveCommand();
else if(isCommand(RASMGRCMD_EXIT)) exitCommand();
else if(isCommand(RASMGRCMD_RESET)) resetCommand();
#ifdef INCLUDE_HIDDEN_COMMANDS
// both are unofficial, PB doesn't like them, but I do
else if(isCommand(RASMGRCMD_GRANT)) grantCommand();
else if(isCommand(RASMGRCMD_REVOKE)) revokeCommand();
//################
#endif
else if(isCommand("#")) sprintf(answBuffer," "); // comment
else
{
errorInCommand("Invalid command; try HELP." );
cout << "Invalid command word: " << command << endl;
}
}
else
{
cout << "Error in request: " << reqMessage << endl;
errorInCommand("Error in request." );
}
}
catch(RCError& e)
{
strcpy(answBuffer,"Error: ");
e.getString(answBuffer + strlen(answBuffer));
cout << answBuffer << endl;
}
LEAVE( "RasControl::processRequest: leave. answerBuffer: " << answBuffer );
return prepareAnswer(answMessage);
}
// set dirty flags
// used to differentiate between config file read and real changes thru rascontrol
void RasControl::setConfigDirty( bool isDirty )
{
configDirty = isDirty;
}
void RasControl::setAuthDirty( bool isDirty )
{
authDirty = isDirty;
}
int RasControl::prepareAnswer(char *answMessage)
{
sprintf(answMessage,"HTTP/1.1 200 OK\r\nContent-type: text/plain\r\nContent-length: %d\r\n\r\n%s",strlen(answBuffer)+1,answBuffer);
return strlen(answMessage)+1;
}
//*************************************************
void RasControl::helloCommand()
{
sprintf(answBuffer,"Hello %s, you are connected to %s",authorization.getUserName(),config.getHostName());
}
//*************************************************
void RasControl::exitCommand()
{
bool configResult = false;
bool authResult = false;
ENTER( "RasControl::exitCommand: enter" );
(void) strcpy( answBuffer, "Exiting rascontrol session." );
if (configDirty)
configResult = config.saveAltConfigFile();
if (authDirty)
authResult = authorization.saveAltAuthFile();
sprintf(answBuffer, "Exiting rascontrol session.%s\n%s%s%s%s%s%s%s%s%s%s",
((argc <= 1) ? "" : " Ignoring extra parameters."),
(!configDirty ? "" : "Configuration file was changed but not saved, storing rescue copy to " ),
(!configDirty ? "" : config.getAltConfigFileName() ),
(!configDirty ? "" : "..." ),
(!configDirty ? "" : (configResult ? "ok" : "failed") ),
(!configDirty ? "" : "\n" ),
(!authDirty ? "" : "Authorisation file was changed but not saved, storing rescue copy to " ),
(!authDirty ? "" : authorization.getAltAuthFileName() ),
(!authDirty ? "" : "..." ),
(!authDirty ? "" : (authResult ? "ok" : "failed") ),
(!authDirty ? "" : "\n" ) );
// (!configDirty ? "" : "Configuration was changed but not saved, storing rescue copy to " << config.getAltConfigFileName() << "..." << (configResult ? "ok" : "failed") << "." << endl),
// (!authDirty ? "" : "Authorisation was changed but not saved, storing rescue copy to " << authorization.getAltAuthFileName() << "..." << (authResult ? "ok" : "failed") << "." << endl) );
LEAVE( "RasControl::exitCommand: leave. answBuffer=" << answBuffer );
}
void RasControl::listCommand()
{
const char *listwhat = argc==1 ? "xxx":token[1].take();
if (strcasecmp(listwhat,RASMGRCMD_SRV)==0) listRasServers();
else if(strcasecmp(listwhat,"version")==0) listVersion();
else if(strcasecmp(listwhat,"modus" )==0) listModus();
else if(strcasecmp(listwhat,RASMGRCMD_USER )==0) listUsers();
else if(strcasecmp(listwhat,RASMGRCMD_HOST)==0) listRasHosts();
else if(strcasecmp(listwhat,"dbh")==0) listDBHosts();
else if(strcasecmp(listwhat,"db")==0) listDatabases();
#ifdef INCLUDE_HIDDEN_COMMANDS
else if(strcasecmp(listwhat,"rights")==0) listRights();// unofficial
#endif
else if(strcasecmp(listwhat,RASMGRCMD_HELP)==0) listHelp();
else errorInCommand("Illegal LIST modifier. Try HELP LIST." );
}
void RasControl::listModus()
{
checkPermission(admR_info);
checkUnexpectedTokens();
const char *modus = config.isTestModus() ? "test" :"normal";
sprintf(answBuffer,"rasmgr running in %s modus",modus);
}
void RasControl::listVersion()
{
checkPermission(admR_info);
checkUnexpectedTokens();
// Version 1.1 is 1.0 with changes P.B. wanted, 06.03.2001
// Version 1.2 is 1.1 with changes P.B. wanted, 17.04.2001
// Version 1.3 with "list srv -x" and "-hostname" parameter
// Version 1.4 with migration of command line options from v5.0 to v5.1
// Version 1.5 with new cmds, bug fixes in socket communication
sprintf(answBuffer,"rasdaman v%1f (rasmgr v1.5, compiled on %s)", RMANVERSION/1000, COMPDATE);
#ifdef INCLUDE_HIDDEN_COMMANDS
strcat(answBuffer," ('inside only'-version)");
#endif
}
void RasControl::listUsers()
{
checkPermission(admR_info);
bool isRights = isFlag("-rights");
checkUnexpectedTokens();
sprintf(answBuffer,"List of defined users:");
for(int i=0;i=maxAnswLen)
{ sprintf(answBuffer+answLen,"\r\n(Answer too long, overflow!)");
break;
}
if(hostName)
if(!hostCmp(hostName,rasManager[i].getHostName()))
continue;
sprintf(answBuffer+answLen,"\r\n%2d. ",crnt++);
if(fports) rasManager[i].getDescriptionPort(answBuffer+strlen(answBuffer));
else if(fexec) rasManager[i].getDescriptionExec(answBuffer+strlen(answBuffer));
else rasManager[i].getDescription(answBuffer+strlen(answBuffer));
}
}
void RasControl::listDatabases()
{
checkPermission(admR_info);
const char* dbName = getValueOf("db");
if(dbName)
{
checkUnexpectedTokens();
Database &db = getDatabase(dbName);
sprintf(answBuffer,"List database: %s\r\n",dbName);
Database::getDescriptionHeader(answBuffer+strlen(answBuffer));
strcat(answBuffer,"\r\n ");
db.getDescription(answBuffer+strlen(answBuffer));
return;
}
bool flagDBH = isFlag("-dbh");
const char* dbhName = getValueOf("-dbh");
if(flagDBH)
{
checkUnexpectedTokens();
checkNotNull(dbhName,"database host name");
getDatabaseHost(dbhName);
}
bool flagAll = isFlag("-all");
// if flagALL is not, we should generate an error message, but we list all silently
checkUnexpectedTokens();
if(dbhName)
sprintf(answBuffer,"List of databases on host: %s\r\n",dbhName);
else sprintf(answBuffer,"List of databases:\r\n");// blanks necesary for nice output
Database::getDescriptionHeader(answBuffer+strlen(answBuffer));
int crnt=1;
for(int i=0;i=0) { countUpSrv+=rasp;countUpHosts++;}
}
sprintf(answBuffer,"Started %d servers on %d hosts",countUpSrv,countUpHosts);
LEAVE( "RasControl::upRasServers() -- " << answBuffer );
return;
}
errorInCommand("Up what?");
LEAVE( "RasControl::upRasServers()" );
}
int RasControl::upAllServersOnHost(const char*hostName)
{
//return value is negativ =>error
//return value is positiv =>nr of started servers
ServerHost &sh= getServerHost(hostName);
if(sh.checkStatus() == false)
{ //errorInCommand("Server host is down.");
return -2;
}
int countStart=0;
int alreadyUp = sh.getStartedServers();
for(int i=0;i0
sprintf(answBuffer,"%d servers on host %s are going down",rasp,hostName);
break;
}
return;
}
bool flagAll = isFlag("-all");
if(flagAll)
{
checkUnexpectedTokens();
int countDownSrv = 0;
int countDownHosts = 0;
for(int i=0;i=0) { countDownSrv+=rasp;countDownHosts++;}
}
sprintf(answBuffer,"%d servers on %d hosts are going down",countDownSrv,countDownHosts);
return;
}
errorInCommand("Down what?");
}
int RasControl::downAllServersOnHost(const char *hostName)
{
ServerHost &sh= getServerHost(hostName);
if(sh.checkStatus()==false)
{ //errorInCommand("Server host is down.");
return -2;
}
int countDownServers=0;
for(int i=0;i1)
{// errorInCommand("Sorry, you should down all slave hosts first, the master should be the last one.");
return -3;
}
if(sh.isInternal()) masterCommunicator.shouldExit();
else { // later, sorry
sh.downHost();
}
return 0;
}
//----------------------------------------------------
void RasControl::saveCommand()
{
checkPermission(admR_config);
checkUnexpectedTokens();
bool resultConf = config.saveOrigConfigFile();
bool resultAuth = authorization.saveOrigAuthFile();
// this has been done by the lines above: -- PB 2003-jun-08
// masterCommunicator.commitChanges();
sprintf(answBuffer,"Saving configuration file...%s. Saving authorization file...%s.",
(resultConf==true ? "ok" : "failed"),
(resultAuth==true ? "ok" : "failed") );
}
//----------------------------------------------------
void RasControl::resetCommand()
{
checkPermission(admR_config);
checkUnexpectedTokens();
if(config.isTestModus()==false)
{ errorInCommand("This operation is possible only in test modus.");
return;
}
if(rasManager.reset()==false)
{ errorInCommand("Resetting not possible, there are active servers.");
return;
}
dbHostManager.reset();
dbManager.reset();
hostmanager.reset();
hostmanager.insertInternalHost();
userManager.reset();
userManager.loadDefaults();
VLOG <<"rasmgr was succesfully reset."<, 0 is the command itself
{
if(strcasecmp(flag,token[i].argv)==0)
{
token[i].used=true;
return true;
}
}
return false;
}
if(pos>1 && pos=maxAnswLen)
{ sprintf(answBuffer+answLen,"\r\n(Answer too long, overflow danger!)");
break;
}
if(strcmp(hostName,rasManager[i].getHostName())!=0) continue;
sprintf(answBuffer+answLen,"\r\n%2d. ",crnt++);
if(fports) rasManager[i].getDescriptionPort(answBuffer+strlen(answBuffer));
else rasManager[i].getDescription(answBuffer+strlen(answBuffer));
}
}
else
---------
from list db
if(isFlag("-dbh",2))
{
const char *dbhName=getValueOf("-dbh");
if(dbhName)
sprintf(answBuffer,"List of databases on host: %s",dbhName);
else sprintf(answBuffer,"List of databases:");
int crnt=0;
for(int i=0;i