summaryrefslogtreecommitdiffstats
path: root/rasmgr/rasmgr_rascontrol.cc
diff options
context:
space:
mode:
authorConstantin Jucovschi <cj@ubuntu.localdomain>2009-04-24 07:20:22 -0400
committerConstantin Jucovschi <cj@ubuntu.localdomain>2009-04-24 07:20:22 -0400
commit8f27e65bddd7d4b8515ce620fb485fdd78fcdf89 (patch)
treebd328a4dd4f92d32202241b5e3a7f36177792c5f /rasmgr/rasmgr_rascontrol.cc
downloadrasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.gz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.xz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.zip
Initial commitv8.0
Diffstat (limited to 'rasmgr/rasmgr_rascontrol.cc')
-rw-r--r--rasmgr/rasmgr_rascontrol.cc2187
1 files changed, 2187 insertions, 0 deletions
diff --git a/rasmgr/rasmgr_rascontrol.cc b/rasmgr/rasmgr_rascontrol.cc
new file mode 100644
index 0000000..3ec3822
--- /dev/null
+++ b/rasmgr/rasmgr_rascontrol.cc
@@ -0,0 +1,2187 @@
+/*
+* 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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * 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<userManager.countUsers();i++)
+ {
+ User &user=userManager[i];
+ //sprintf(answBuffer+strlen(answBuffer),"\r\n%d. %s (%ld)",i,u.getName(),u.getUserID());
+ sprintf(answBuffer+strlen(answBuffer),"\r\n%2d. %-20s ",i+1,user.getName());
+
+ if(isRights)
+ { sprintf(answBuffer+strlen(answBuffer)," [%s]",authorization.convertAdminRights(user.getAdminRights()));
+ sprintf(answBuffer+strlen(answBuffer)," -[%s]",authorization.convertDatabRights(user.getDefaultDBRights()));
+ }
+ }
+ }
+
+void RasControl::listRasHosts()
+ {
+ checkPermission(admR_info);
+ checkUnexpectedTokens();
+
+ sprintf(answBuffer,"List of server hosts:\r\n");
+ ServerHost::getDescriptionHeader(answBuffer+strlen(answBuffer));
+ for(int i=0;i<hostmanager.countHosts();i++)
+ {
+ sprintf(answBuffer+strlen(answBuffer),"\r\n%2d. ",i+1);
+ hostmanager[i].getDescription(answBuffer+strlen(answBuffer));
+
+ }
+ }
+
+void RasControl::listDBHosts()
+ {
+ checkPermission(admR_info);
+ checkUnexpectedTokens();
+
+ sprintf(answBuffer,"List of database hosts:\r\n");
+ sprintf(answBuffer+strlen(answBuffer)," Database Host Connection String Databases");
+
+ for(int i=0;i<dbHostManager.countHosts();i++)
+ {
+ DatabaseHost &dbh = dbHostManager[i];
+ sprintf(answBuffer+strlen(answBuffer),"\r\n%2d. %-15s %-30s",(i+1),dbh.getName(),dbh.getConnectionString());
+
+ for(int j=0;j<dbManager.countDatabases();j++)
+ {
+ if(dbManager[j].isConnectedToDBHost(dbh.getName()))
+ sprintf(answBuffer+strlen(answBuffer)," %s",dbManager[j].getName());
+ }
+ }
+ }
+
+
+void RasControl::listRasServers()
+ {
+ checkPermission(admR_info);
+ int answLen=0;
+ int maxAnswLen=MAXMSGOUTBUFF-100; // if there are many servers, we could get an overflow
+
+ bool fports= isFlag("-p");
+ bool fexec = isFlag("-x");
+
+ if(fports && fexec)
+ {
+ // error, not both of them together!
+ }
+
+
+ const char *srvName = getValueOf(RASMGRCMD_SRV);
+ if(srvName)
+ {
+ checkUnexpectedTokens();
+ RasServer &serv=getServer(srvName);
+
+ sprintf(answBuffer,"Status of server %s\r\n",srvName);
+ if(fports) RasServer::getDescriptionPortHeader(answBuffer+strlen(answBuffer));
+ else if(fexec) RasServer::getDescriptionExecHeader(answBuffer+strlen(answBuffer));
+ else RasServer::getDescriptionHeader(answBuffer+strlen(answBuffer));
+ strcat(answBuffer,"\r\n ");
+ if(fports) serv.getDescriptionPort(answBuffer+strlen(answBuffer));
+ else if(fexec) serv.getDescriptionExec(answBuffer+strlen(answBuffer));
+ else serv.getDescription(answBuffer+strlen(answBuffer));
+
+ return;
+ }
+
+ bool isHost = isFlag("-host");
+ const char *hostName = getValueOf("-host");
+ bool listAll = false;
+ if (isHost)
+ {
+ checkUnexpectedTokens();
+ checkNotNull(hostName,"host name");
+ getServerHost(hostName);
+
+ }
+ else
+ {
+
+ // no -host hostName, so check for -all
+ listAll = isFlag("-all");
+ checkUnexpectedTokens();
+ // normally we should generate an error if -all is not, but for compatibility...
+ // put the error here
+ }
+
+ if(hostName == NULL) sprintf(answBuffer,"List of servers:\r\n");
+ else sprintf(answBuffer,"List of servers on host %s:\r\n",hostName);
+
+ if(fports) RasServer::getDescriptionPortHeader(answBuffer+strlen(answBuffer));
+ else if(fexec) RasServer::getDescriptionExecHeader(answBuffer+strlen(answBuffer));
+ else RasServer::getDescriptionHeader(answBuffer+strlen(answBuffer));
+ int crnt=1;
+ for(int i=0;i<rasManager.countServers();i++)
+ {
+ answLen=strlen(answBuffer);
+
+ if(answLen >=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<dbManager.countDatabases();i++)
+ {
+ Database &db=dbManager[i];
+
+ if(dbhName)
+ { bool found=false;
+ for(int j=0; j < db.countConnectionsToDBHosts();j++)
+ { if(hostCmp(db.getDBHostName(j),dbhName))
+ { found=true;break;}
+ }
+ if(found == false)
+ continue;
+ }
+ sprintf(answBuffer+strlen(answBuffer),"\r\n%2d. ",crnt++);
+ db.getDescription(answBuffer+strlen(answBuffer));
+ }
+
+ }
+//******************************************************
+void RasControl::defineCommand()
+ {
+ const char *what = argc==1 ? "xxx":token[1].take();
+
+ if (strcasecmp(what,RASMGRCMD_SRV)==0)
+ {
+ defineRasServers();
+ configDirty = true;
+ }
+ else if(strcasecmp(what,RASMGRCMD_HOST)==0)
+ {
+ defineRasHosts();
+ configDirty = true;
+ }
+ else if(strcasecmp(what,"dbh")==0)
+ {
+ defineDBHosts();
+ configDirty = true;
+ }
+ else if(strcasecmp(what,"db")==0)
+ {
+ defineDatabases();
+ configDirty = true;
+ }
+ else if(strcasecmp(what,RASMGRCMD_USER)==0)
+ {
+ defineUsers();
+ authDirty = true;
+ }
+ else if(strcasecmp(what,RASMGRCMD_HELP)==0)
+ defineHelp();
+ else
+ errorInCommand("Wrong DEFINE command");
+ }
+
+void RasControl::defineUsers()
+ {
+ checkPermission(admR_acctrl);
+
+ const char *userName = getValueOf(RASMGRCMD_USER);
+ const char *plainPass = getValueIfFlag("-passwd");
+ const char *rString = getValueIfFlag("-rights",true);
+ int admRights =0;
+ int dtbRights =0;
+ checkUnexpectedTokens();
+ checkNotNull(userName,"user name");
+
+ for(int i=0;userName[i];i++)
+ if(userName[i]==':')
+ { errorInCommand("Invalid character (':') in user name.");
+ return;
+ }
+
+ if(rString)
+ {
+ admRights=authorization.convertAdminRights(rString);
+ dtbRights=authorization.convertDatabRights(rString);
+ if(admRights==-1 || dtbRights==-1)
+ { errorInCommand("Unknown right in command");
+ return;
+ }
+ }
+
+ if(userManager.insertNewUser(userName)==false)
+ { errorInCommand("User name should be unique.");
+ return;
+ }
+
+ User &user = userManager[userName];
+
+ if(plainPass) user.changePTPassword(plainPass);
+ if(rString) { user.setAdminRights(admRights);
+ user.setDefaultDBRights(dtbRights);
+ }
+
+ sprintf(answBuffer,"Defining user %s",userName);
+ }
+
+void RasControl::defineDBHosts()
+ {
+ checkPermission(admR_config);
+
+ const char *dbhName=getValueOf("dbh");
+ const char *connStr=getValueOf("-connect");
+
+ checkUnexpectedTokens();
+ checkNotNull(dbhName,"database host name");
+ checkNotNull(connStr,"connection string");
+
+ if(dbHostManager.insertNewHost(dbhName,connStr))
+ {
+ sprintf(answBuffer,"Defining database host %s with connection string: %s",dbhName,connStr);
+ }
+ else
+ {
+ sprintf(answBuffer,"Database host %s already defined.",dbhName);
+ }
+ }
+
+void RasControl::defineDatabases()
+ {
+ checkPermission(admR_config);
+
+ const char *dbName = getValueOf("db");
+ const char *dbhName = getValueOf("-dbh");
+ checkUnexpectedTokens();
+ checkNotNull(dbName,"database name");
+ // we don't accept hostless databases any more, define goes together with connect from now on
+ checkNotNull(dbhName,"database host name");
+ getDatabaseHost(dbhName);// just check if valid
+
+ bool defDB = dbManager.insertNewDatabase(dbName);
+ Database &db = dbManager[dbName];
+
+ bool connDB = db.connectToDBHost(dbhName);
+
+ if(defDB)
+ {
+ sprintf(answBuffer,"Defining database %s on database host %s",dbName,dbhName);
+ }
+ else
+ { //database was already defined
+ if(connDB) sprintf(answBuffer,"Defining a mirrored instance of database %s on database host %s.",dbName,dbhName);
+ else sprintf(answBuffer,"Database %s already defined on database host %s.",dbName,dbhName);
+ }
+
+ }
+
+void RasControl::defineRasHosts()
+ {
+ checkPermission(admR_config);
+
+ const char *hostName=getValueOf(RASMGRCMD_HOST);
+ const char *netName =getValueOf("-net");
+ const char *portStr =getValueOf("-port");
+ checkUnexpectedTokens();
+
+ checkNotNull(hostName,"host name");
+
+ checkNotNull(netName,"-net parameter");
+
+ long listenPort;
+ if(portStr) listenPort=convertToULong(portStr,"port");
+ else listenPort=DEFAULT_PORT;
+
+ if(hostmanager.insertNewHost(hostName,netName,listenPort)==false)
+ { sprintf(answBuffer,"Error: Host %s already defined.",hostName);
+ return;
+ }
+ else
+ { sprintf(answBuffer,"Defining server host %s port=%d",hostName,listenPort);
+ }
+ }
+
+void RasControl::defineRasServers()
+ {
+ checkPermission(admR_config);
+ bool inConfigFile = authorization.isInConfigFile();
+
+ const char *serverName=getValueOf(RASMGRCMD_SRV);
+ const char *hostName =getValueOf("-host");
+ const char *portStr =getValueOf("-port");
+ const char *sTypeStr =getValueOf("-type");
+ const char *dbhName =getValueOf("-dbh");
+
+ const char *autoRestart = getValueIfFlag("-autorestart");
+ const char *countString = getValueIfFlag("-countdown");
+ const char *execString = getValueIfFlag("-exec");
+ bool isExtra = isFlag("-xp");
+ // make the -xp string first
+ char extraString[300]; extraString[0]=0;
+
+ if(isExtra)
+ {
+ bool found=false;
+ for(int i=0;i<argc;i++)
+ {
+ if(!found)
+ { if(strcasecmp(token[i].argv,"-xp")==0) found=true;
+ }
+ else
+ { strcat(extraString,token[i].take());
+ strcat(extraString," ");
+ }
+ }
+ }
+
+ checkUnexpectedTokens();
+
+ checkNotNull(serverName,"server name");
+
+ if(!sTypeStr)
+ { errorInCommand("Missing server type, specify one of r (RPC), h (HTTP) or n (RNP).");
+ return;
+ }
+
+ char serverType=0;
+ if(strcasecmp(sTypeStr,"r")==0) { serverType=SERVERTYPE_FLAG_RPC;}
+ if(strcasecmp(sTypeStr,"h")==0) { serverType=SERVERTYPE_FLAG_HTTP;}
+ if(strcasecmp(sTypeStr,"n")==0) { serverType=SERVERTYPE_FLAG_RNP;}
+ if(!serverType)
+ { errorInCommand("Illegal server type, use one of [r|h|n].");
+ return;
+ }
+
+ checkNotNull(hostName,"host name");
+ checkNotNull(portStr,"port number");
+
+ if(inConfigFile == false)
+ { // we accept connectionless servers in config file, because we do not remove
+ // the connected servers when we remove a database host
+ checkNotNull(dbhName,"database host name");
+ getDatabaseHost(dbhName);// just check if valid
+
+ }
+
+ long listenPort=convertToULong(portStr,"port");
+
+ if(autoRestart)
+ {
+ if(strcasecmp(autoRestart,"on")==0)
+ ;
+ else if(strcasecmp(autoRestart,"off")==0)
+ ;
+ else
+ {
+ errorInCommand("Incorrect autorestart option, use one of [on|off].");
+ return;
+ }
+ }
+
+ getServerHost(hostName);// just check
+ if(rasManager.insertNewServer(serverName,hostName,serverType,listenPort)==false)
+ { sprintf(answBuffer,"Error: server name already existing.");
+ return;
+ }
+
+ if(inConfigFile && !dbhName) return;
+
+ RasServer &srv = rasManager[serverName];
+ srv.connectToDBHost(dbhName);
+ // if ok, write what you defined
+
+ // we put this options in the config file with the change srv command, so it's ok that it could return before
+ if(countString) srv.changeCountDown(convertToULong(countString,"countdown"));
+
+ if(extraString) srv.changeExtraParam(extraString);
+
+ if(autoRestart) srv.changeAutoRestart( strcasecmp(autoRestart,"on")==0 ? true:false);
+
+ if(execString) srv.changeExecutableName(execString);
+
+ if(serverType==SERVERTYPE_FLAG_RPC)
+ sprintf(answBuffer,"Defining deprecated server %s of type RPC on host %s port=%#x",serverName,hostName,listenPort);
+
+ if(serverType==SERVERTYPE_FLAG_HTTP)
+ sprintf(answBuffer,"Defining deprecated server %s of type HTTP on host %s port=%d",serverName,hostName,listenPort);
+
+ if(serverType==SERVERTYPE_FLAG_RNP)
+ sprintf(answBuffer,"Defining server %s of type RNP on host %s port=%d",serverName,hostName,listenPort);
+
+ }
+
+//----------------------------------------
+void RasControl::removeCommand()
+ {
+ const char *what = argc==1 ? "xxx":token[1].take();
+
+ if (strcasecmp(what,RASMGRCMD_SRV)==0) removeRasServers();
+
+ else if(strcasecmp(what,RASMGRCMD_HOST)==0) removeRasHosts();
+
+ else if(strcasecmp(what,"dbh")==0) removeDBHosts();
+
+ else if(strcasecmp(what,"db")==0) removeDatabases();
+
+ else if(strcasecmp(what,RASMGRCMD_USER)==0) removeUsers();
+
+ else if(strcasecmp(what,RASMGRCMD_HELP)==0) removeHelp();
+
+ else errorInCommand("Error in REMOVE command");
+ }
+
+void RasControl::removeUsers()
+ {
+ checkPermission(admR_acctrl);
+
+ const char *userName=getValueOf(RASMGRCMD_USER);
+ checkUnexpectedTokens();
+
+ checkNotNull(userName,"user name");
+
+ User &user=getUser(userName);
+
+ if(user.getUserID()==0)
+ { errorInCommand("You cannot remove the rasadmin.");
+ return;
+ }
+
+ if(userManager.removeUser(userName)==false)
+ { errorInCommand("Cannot remove user, don't know why");
+ return;
+ }
+ sprintf(answBuffer,"User %s removed",userName);
+ }
+
+void RasControl::removeRasHosts()
+ {
+ checkPermission(admR_config);
+
+ const char *hostName=getValueOf(RASMGRCMD_HOST);
+ checkUnexpectedTokens();
+
+ checkNotNull(hostName,"host name");
+
+ ServerHost &host = getServerHost(hostName);
+
+ if(host.isInternal()==true)
+ { errorInCommand("You cannot remove the master rasmgr host.");
+ return;
+ }
+
+ if(hostmanager.removeHost(hostName)==false)
+ { errorInCommand("Cannot remove host, it still has defined servers.");
+ return;
+ }
+ sprintf(answBuffer,"Host %s removed",hostName);
+ }
+
+void RasControl::removeRasServers()
+ {
+ checkPermission(admR_config);
+
+ const char *srvName=getValueOf(RASMGRCMD_SRV);
+ checkUnexpectedTokens();
+
+ checkNotNull(srvName,"server name");
+
+ RasServer &srv = getServer(srvName);
+
+ if(srv.isUp())
+ { errorInCommand("Cannot remove the server, it's still up.");
+ return;
+ }
+
+ if(rasManager.removeServer(srvName)==false)
+ { errorInCommand("Cannot remove the server, is probably still up.");
+ return;
+ }
+ sprintf(answBuffer,"Server %s removed",srvName);
+ }
+
+void RasControl::removeDBHosts()
+ {
+ checkPermission(admR_config);
+
+ const char *dbhName=getValueOf("dbh");
+ checkUnexpectedTokens();
+
+ checkNotNull(dbhName,"database host name");
+
+ getDatabaseHost(dbhName);
+
+ if(dbHostManager.removeHost(dbhName)==false)
+ { errorInCommand("Cannot remove the database host, is probably still busy.");
+ return;
+ }
+ sprintf(answBuffer,"Database host %s removed",dbhName);
+
+ // now remove all databases not connected to any database host
+ for(int i=0;i<dbManager.countDatabases();i++)
+ {
+ if(dbManager[i].countConnectionsToDBHosts()==0)
+ { dbManager.removeDatabase(dbManager[i].getName());
+ i--; // you understand why
+ }
+ }
+ }
+void RasControl::removeDatabases()
+ {
+ checkPermission(admR_config);
+
+ const char *dbName = getValueOf("db");
+ const char *dbhName = getValueOf("-dbh");
+ checkUnexpectedTokens();
+
+ checkNotNull(dbName,"database name");
+
+ Database &db= getDatabase(dbName);
+
+ checkNotNull(dbhName,"database host name");
+
+ getDatabaseHost(dbhName);
+
+ if(db.isBusy())
+ { errorInCommand("Database is busy.");
+ return;
+ }
+
+ if(db.disconnectFromDBHost(dbhName) == false)
+ { sprintf(answBuffer,"No database %s on database host %s.",dbName,dbhName);
+ return;
+ }
+
+ if(db.countConnectionsToDBHosts() !=0 )
+ {
+ sprintf(answBuffer,"Database %s removed from database host %s",dbName,dbhName);
+ // this means disconnected
+ }
+ else
+ if(dbManager.removeDatabase(dbName))
+ { sprintf(answBuffer,"Database %s removed from database host %s",dbName,dbhName);
+ // this time removed completely
+ }
+ else
+ { errorInCommand("Cannot remove the database, but why? (There shouldn't be any reason for that)");
+ }
+ }
+
+//--------------------------------------------
+void RasControl::changeCommand()
+ {
+ const char *what = argc==1 ? "xxx":token[1].take();
+
+ if (strcasecmp(what,RASMGRCMD_USER)==0)
+ {
+ changeUser();
+ authDirty = true;
+ }
+ else if(strcasecmp(what,RASMGRCMD_SRV)==0)
+ {
+ changeRasServer();
+ configDirty = true;
+ }
+ else if(strcasecmp(what,"dbh")==0)
+ {
+ changeDBHost();
+ configDirty = true;
+ }
+ else if(strcasecmp(what,"db")==0)
+ {
+ changeDB();
+ configDirty = true;
+ }
+ else if(strcasecmp(what,RASMGRCMD_HOST)==0)
+ {
+ changeHost();
+ configDirty = true;
+ }
+ else if(strcasecmp(what,RASMGRCMD_HELP)==0)
+ changeHelp();
+ else
+ errorInCommand("Error in CHANGE command");
+
+ }
+void RasControl::changeHost()
+ {
+ checkPermission(admR_config);
+ // we accept all this parameters, but we make all changes or none
+ const char *hostName=getValueOf(RASMGRCMD_HOST);
+
+ const char *uselocal = getValueIfFlag("-uselocalhost");
+ const char *newName = getValueIfFlag("-name");
+ const char *newNet = getValueIfFlag("-net");
+ const char *newPort = getValueIfFlag("-port");
+
+ checkUnexpectedTokens();
+
+ // This means changes were requested
+ bool chUseLoc = false;
+ bool chName = false;
+ bool chNet = false;
+ bool chPort = false;
+
+ checkNotNull(hostName,"server host name");
+
+ ServerHost &sh= getServerHost(hostName);
+
+ answBuffer[0]=0;
+ int changes = 0;
+ int port = 0;
+
+ if(uselocal)
+ {
+ chUseLoc = true;
+ if(sh.isInternal()==false)
+ { errorInCommand("Option '-uselocalhost' is meaningfull only on master rasmgr host");
+ return;
+ }
+ else
+ {
+ if (strcasecmp(uselocal,"on" )==0); // ok
+ else if(strcasecmp(uselocal,"off")==0); // ok
+ else { errorInCommand("Option '-uselocalhost' - wrong parameter");
+ return;
+ }
+ }
+ }
+
+ if(newName)
+ {
+ if(hostmanager.acceptChangeName(hostName,newName)==false)
+ { errorInCommand("The new name is not unique.");
+ return;
+ }
+
+ chName = true;
+ }
+
+ if(newNet ) { chNet = true;
+ if(sh.isUp()){ errorInCommand("You cannot change the network address of a RasMgr while it is up.");
+ return;
+ }
+ }
+
+ if(newPort) { chPort = true;
+ if(sh.isUp()){ errorInCommand("You cannot change the listen port of a RasMgr while it is up.");
+ return;
+ }
+
+ port = convertToULong(newPort,"port");
+ }
+
+
+
+ if(chUseLoc) { changes++; sh.useLocalHost( strcasecmp(uselocal,"on") ==0 ? true : false); }
+
+ if(chName) { changes++; sh.changeName(newName); }
+
+ if(chNet) { changes++; sh.changeNetName(newNet);}
+
+ if(chPort) { changes++; sh.changeListenPort(port);}
+
+ if(changes) sprintf(answBuffer,"Ready");
+ else errorInCommand("Change what?");
+
+ }
+
+void RasControl::changeDBHost()
+ {
+ checkPermission(admR_config);
+ const char *dbhName = getValueOf("dbh");
+ const char *newName = getValueIfFlag("-name");
+ const char *connString = getValueIfFlag("-connect");
+ checkUnexpectedTokens();
+
+ checkNotNull(dbhName,"database host name");
+
+ DatabaseHost &dbh= getDatabaseHost(dbhName);
+
+ if(newName)
+ {
+ if(dbHostManager.acceptChangeName(dbhName,newName)==false)
+ { errorInCommand("The new name is not unique.");
+ return;
+ }
+
+ dbh.changeName(newName);
+ }
+ else if(connString) dbh.changeConnectionString(connString);
+
+ else { errorInCommand("Change what?");
+ return;
+ }
+
+ sprintf(answBuffer,"Ready");
+
+ }
+
+void RasControl::changeDB()
+ {
+ checkPermission(admR_config);
+ const char *dbName = getValueOf("db");
+ const char *dbNewName = getValueIfFlag("-name");
+
+ checkUnexpectedTokens();
+
+ checkNotNull(dbName,"database name");
+
+ Database &db= getDatabase(dbName);
+
+ if(dbNewName)
+ {
+ if(dbManager.acceptChangeName(dbName,dbNewName)==false)
+ { errorInCommand("The new name is not unique.");
+ return;
+ }
+ db.changeName(dbNewName);
+ }
+ else
+ { errorInCommand("Change what?");
+ return;
+ }
+
+ sprintf(answBuffer,"Ready");
+
+ }
+
+/** the version supporting only one server - the documented one
+void RasControl::changeRasServer()
+ {
+ checkPermission(admR_config);
+
+ const char *serverName = getValueOf(RASMGRCMD_SRV);
+ const char *newServerName = getValueIfFlag("-name");
+ const char *portString = getValueIfFlag("-port");
+ const char *autoRestart = getValueIfFlag("-autorestart");
+ const char *countString = getValueIfFlag("-countdown");
+ const char *dbhName = getValueIfFlag("-dbh");
+ bool isExtra = isFlag("-xp");
+ bool autorestartValue;
+ // make the -xp string first
+ char extraString[300]; extraString[0]=0;
+ if(isExtra)
+ {
+ bool found=false;
+ for(int i=0;i<argc;i++)
+ {
+ if(!found)
+ { if(strcasecmp(token[i].argv,"-xp")==0) found=true;
+ }
+ else
+ { strcat(extraString,token[i].take());
+ strcat(extraString," ");
+ }
+ }
+ }
+ // so we touch all tokens
+ checkUnexpectedTokens();
+
+ checkNotNull(serverName,"server name");
+
+ RasServer &r= getServer(serverName);
+
+ if(dbhName) getDatabaseHost(dbhName);
+
+ if(autoRestart)
+ { if(strcasecmp(autoRestart,"on")==0) autorestartValue=true;
+ else if(strcasecmp(autoRestart,"off")==0) autorestartValue=false;
+ else { errorInCommand("Incorect autorestart option");
+ return;
+ }
+ }
+
+ if(newServerName && r.isUp()==false) )
+ { errorInCommand("Cannot change the name of a running server.");
+ return;
+ }
+
+ // from here, it cannot fail any more
+ if(autoRestart) r.changeAutoRestart(autorestartValue);
+
+ if(dbhName)
+ { r.disconnectFromDBHost();
+ r.connectToDBHost(dbhName);
+ }
+ if(newServerName) r.changeName(newServerName);
+
+ if(portString) r.changePort(strtoul(portString,(char**)NULL,0));
+
+ if(countString) r.changeCountDown(strtoul(countString,(char**)NULL,0));
+
+ if(isExtra) r.changeExtraParam(extraString);
+
+ sprintf(answBuffer,"Ready");
+
+ }
+*/
+
+// The version supporting change srv [s| -hos h | -all ] { rest of params }
+void RasControl::changeRasServer()
+ {
+ checkPermission(admR_config);
+
+// first, see if params are ok
+
+ // only if "srv name": const char *newServerName = getValueIfFlag("-name");
+ // only if "srv name": const char *portString = getValueIfFlag("-port");
+ const char *autoRestart = getValueIfFlag("-autorestart");
+ const char *countString = getValueIfFlag("-countdown");
+ const char *execString = getValueIfFlag("-exec");
+ const char *dbhName = getValueIfFlag("-dbh");
+ bool isExtra = isFlag("-xp");
+ int countChanges = 0;
+ // make the -xp string first
+ char extraString[300]; extraString[0]=0;
+
+ if(isExtra)
+ {
+ bool found=false;
+ for(int i=0;i<argc;i++)
+ {
+ if(!found)
+ { if(strcasecmp(token[i].argv,"-xp")==0) found=true;
+ }
+ else
+ { strcat(extraString,token[i].take());
+ strcat(extraString," ");
+ }
+ }
+ countChanges++;
+ }
+ // so we touch all tokens
+
+
+ if(dbhName) { getDatabaseHost(dbhName); countChanges++; }
+
+ if(autoRestart)
+ { if(strcasecmp(autoRestart,"on")==0) ;
+ else if(strcasecmp(autoRestart,"off")==0) ;
+ else { errorInCommand("Incorect autorestart option");
+ return;
+ }
+ countChanges++;
+ }
+ if(countString) countChanges++;
+ if(execString) countChanges++;
+
+ // ok, the existing params are ok
+
+ const char *serverName = getValueOf(RASMGRCMD_SRV);
+ if(serverName)
+ {
+ // permitted only here
+ const char *newType = getValueIfFlag("-type");
+ const char *newServerName = getValueIfFlag("-name");
+ const char *portString = getValueIfFlag("-port");
+
+ checkUnexpectedTokens();
+ RasServer &r = getServer(serverName);
+ char serverType=0;
+ if(newType)
+ {
+ if(strcasecmp(newType,"r")==0) { serverType=SERVERTYPE_FLAG_RPC;}
+ if(strcasecmp(newType,"h")==0) { serverType=SERVERTYPE_FLAG_HTTP;}
+ if(strcasecmp(newType,"n")==0) { serverType=SERVERTYPE_FLAG_RNP;}
+ if(!serverType) { errorInCommand("Unknown server type.");
+ return;
+ }
+ else countChanges++;
+ }
+ if(newServerName)
+ {
+ if(r.isUp()) { errorInCommand("Cannot change the name of a running server.");
+ return;
+ }
+ if(rasManager.acceptChangeName(serverName,newServerName)==false)
+ { errorInCommand("The new name is not unique.");
+ return;
+ }
+ countChanges++;
+ }
+ if(portString) countChanges++;
+ //------------
+ if(countChanges==0) { errorInCommand("Change what?");
+ return;
+ }
+
+ if(newType) r.changeType(serverType);
+ if(portString) r.changePort(convertToULong(portString,"port"));
+
+ changeRasServer(serverName,dbhName,countString,(isExtra ? extraString : NULL), autoRestart, execString);
+
+ if(newServerName) r.changeName(newServerName);
+
+ sprintf(answBuffer,"Ready");
+ return;
+ }
+
+ const char *hostName = getValueOf("-host");
+ if(hostName)
+ {
+ ServerHost &host=getServerHost(hostName);
+ checkUnexpectedTokens();
+ }
+
+ bool flagAll = isFlag("-all");
+ checkUnexpectedTokens();
+
+ if(hostName == NULL && flagAll == false)
+ { errorInCommand("No server specified");
+ return;
+ }
+
+ if(countChanges==0) { errorInCommand("Change what?");
+ return;
+ }
+
+ for(int i=0;i<rasManager.countServers();i++)
+ {
+ serverName = rasManager[i].getName();
+ if(hostName)
+ if(!hostCmp(hostName,rasManager[i].getHostName()))
+ continue;
+ changeRasServer(serverName,dbhName,countString,(isExtra ? extraString : NULL), autoRestart, execString);
+ }
+
+ sprintf(answBuffer,"Ready");
+
+ }
+
+void RasControl::changeRasServer(const char *serverName, const char *dbhName, const char *countString, const char *extraString, const char *autoRestart, const char* execName)
+ {
+ // called only by by changedServer, after verification of parameters
+ RasServer &r = getServer(serverName);
+
+ if(dbhName)
+ { r.disconnectFromDBHost();
+ r.connectToDBHost(dbhName);
+ }
+
+ if(countString) r.changeCountDown(convertToULong(countString,"countdown"));
+
+ if(extraString) r.changeExtraParam(extraString);
+
+ if(autoRestart) r.changeAutoRestart( strcasecmp(autoRestart,"on")==0 ? true:false);
+
+ if(execName) r.changeExecutableName(execName);
+ }
+
+void RasControl::changeUser()
+ {
+ const char *userName = getValueOf(RASMGRCMD_USER);
+ const char *newName = getValueIfFlag("-name");
+ const char *plainPass = getValueIfFlag("-passwd");
+ const char *encrPass = getValueIfFlag("-encrPasswd");
+ const char *rString = getValueIfFlag("-rights",true);
+ checkUnexpectedTokens();
+
+ // encr passwd has priority
+ const char *newPass = encrPass ? encrPass:plainPass;
+ bool takeEncrPass = encrPass ? true:false;
+
+ bool okChName =false;
+ bool okChPasswd=false;
+ bool okChRights=false;
+ int admRights = 0;
+ int dtbRights = 0;
+
+ //for name change you need acces Control (you cannot change rasadmin)
+ //for passwd change you need also acces Control, or, without, only yourself.(only rasadmin can change his passwd)
+ if(userName==0)
+ { errorInCommand("You should provide a valid user name.");
+ return;
+ }
+ User &u=getUser(userName);
+
+ if(newName!=0)
+ { checkPermission(admR_acctrl);
+ if(strcmp(userName,"rasadmin")==0)
+ { errorInCommand("You cannot change rasadmin's name.");
+ return;
+ }
+ if(userManager.acceptChangeName(userName,newName)==false)
+ { errorInCommand("The new name is not unique.");
+ return;
+ }
+
+ okChName=true;
+ }
+
+ if(newPass!=0)
+ { if (strcmp(userName ,authorization.getUserName())==0) okChPasswd=true; // may change your own passwd
+
+ else if(strcmp("rasadmin",authorization.getUserName())==0) okChPasswd=true; // rasadmin may change all passwd
+
+ else if(authorization.hasAdminRights(admR_acctrl))
+ { if (strcmp("rasadmin",userName)!=0) okChPasswd=true; // may change all passwd, except rasadmin's one
+ else
+ { errorInCommand("You don't have permission to change rasadmin's password.");
+ return;
+ }
+ }
+ else { errorInCommand("You don't have permission for this operation.");
+ return;
+ }
+
+ }
+ if(rString!=0)
+ { checkPermission(admR_acctrl);
+ admRights=authorization.convertAdminRights(rString);
+ dtbRights=authorization.convertDatabRights(rString);
+
+ if(admRights==-1 || dtbRights==-1)
+ { errorInCommand("Unknown right in command");
+ return;
+ }
+
+ okChRights = true;
+ }
+
+ // we don't talk so much, just say 'Ready' answBuffer[0]=0;
+ int changes =0;
+
+ if(okChName)
+ { u.changeName(newName);
+ //sprintf(answBuffer,"User name changed: %s is now %s\r\n",userName,newName);
+ changes++;
+ }
+ if(okChPasswd)
+ { if(answBuffer[0]!=0) strcat(answBuffer,"\r\n");
+
+ if(takeEncrPass) u.changePassword(newPass);
+ else u.changePTPassword(newPass);
+ //sprintf(answBuffer+strlen(answBuffer),"Password for user %s was changed\r\n",userName);
+ changes++;
+ }
+ if(okChRights)
+ { User &user = u; // this is v1.1, is will not live long...
+ const char *warning = user.getUserID()!=0 ? "": (admRights=admR_full,"You cannot change rasadmin's system rights\r\n");
+ //^sorry, trick
+ user.setAdminRights(admRights);
+ user.setDefaultDBRights(dtbRights);
+ //sprintf(answBuffer+strlen(answBuffer),"%sRights of user %s set to [%s]-[%s]\r\n", warning,userName,authorization.convertAdminRights(admRights),authorization.convertDatabRights(dtbRights));
+ changes++;
+ }
+
+ if(okChRights || okChPasswd) masterCommunicator.commitAuthFile();
+
+ if(changes==0) errorInCommand("Change what?");
+ else strcpy(answBuffer,"Ready");
+
+ }
+//---------------------------------------------
+void RasControl::upCommand()
+ {
+ const char *what = argc==1 ? "xxx":token[1].take();
+
+ if(strcasecmp(what,RASMGRCMD_SRV)==0) upRasServers();
+
+ else if(strcasecmp(what,RASMGRCMD_HELP)==0) upHelp();
+
+ else errorInCommand("Error in UP command");
+
+ }
+
+void RasControl::upRasServers()
+ {
+ ENTER( "RasControl::upRasServers()" );
+
+ checkPermission(admR_sysup);
+
+ const char *srvName =getValueOf(RASMGRCMD_SRV);
+
+ if(srvName) // up a specified server
+ {
+ bool flagForce = config.isDebugSupport() ? isFlag("-force") : false;
+ bool flagDebug = config.isDebugSupport() ? isFlag("-debug") : false;
+
+ checkUnexpectedTokens();
+
+ TALK( "server name: " << srvName );
+ RasServer &r=getServer(srvName);
+
+ // just debug
+ if(flagForce && r.isUp())
+ { r.forceAvailable();
+ sprintf(answBuffer,"Server forced to be available again");
+ LEAVE( "RasControl::upRasServers() -- " << answBuffer );
+ return;
+ }
+
+ if(r.isUp())
+ { errorInCommand("Server is already up.");
+ LEAVE( "RasControl::upRasServers() -- " << answBuffer );
+ return;
+ }
+ int rasp = flagDebug ? r.startServerInDebugger(answBuffer):r.startServer();
+
+ switch(rasp)
+ { case 0: if(flagDebug==false) sprintf(answBuffer,"Server started");
+ break;
+ case -1: errorInCommand("Server is not connected to a database host.");
+ break;
+ case -2: errorInCommand("License violation.");
+ break;
+ case -3:
+ case -4: errorInCommand("Cannot contact the slave rasmgr.");
+ break;
+ case -5: errorInCommand("Server host is down.");
+ break;
+ }
+ LEAVE( "RasControl::upRasServers()" );
+ return;
+ }
+
+ const char *hostName=getValueOf("-host");
+ if(hostName)
+ {
+ checkUnexpectedTokens();
+
+ int rasp = upAllServersOnHost(hostName);
+ switch(rasp)
+ {
+ //case -1: errorInCommand("Wrong server host name."); break;
+ case -2: errorInCommand("Server host is down."); break;
+
+ default: sprintf(answBuffer,"Started %d servers on host %s",rasp,hostName);
+ break;
+
+ }
+ LEAVE( "RasControl::upRasServers()" );
+ return;
+ }
+
+ bool flagAll = isFlag("-all");
+
+ if(flagAll)
+ {
+ checkUnexpectedTokens();
+
+ int countUpSrv = 0;
+ int countUpHosts = 0;
+ for(int i=0;i<hostmanager.countHosts();i++)
+ {
+ int rasp = upAllServersOnHost(hostmanager[i].getName());
+
+ if(rasp>=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;i<rasManager.countServers();i++)
+ {
+ RasServer &r=rasManager[i];
+ if(r.isUp()) continue;
+ if(!hostCmp(hostName,r.getHostName())) continue;
+
+ if(r.startServer()==0) countStart++;
+ }
+ // sprintf(answBuffer,"Started %d servers on host %s",countStart,hostName);
+ return countStart;
+ }
+//--------------------------------------------------------
+void RasControl::downCommand()
+ {
+ const char *what = argc==1 ? "xxx":token[1].take();
+
+ if (strcasecmp(what,RASMGRCMD_HOST)==0) downRasHosts();
+
+ else if(strcasecmp(what,RASMGRCMD_SRV)==0) downRasServers();
+
+ else if(strcasecmp(what,RASMGRCMD_HELP)==0) downHelp();
+
+ else errorInCommand("Error in DOWN command");
+
+ }
+
+void RasControl::downRasServers()
+ {
+ checkPermission(admR_sysup);
+
+ const char *srvName=getValueOf(RASMGRCMD_SRV);
+
+ if(srvName)
+ {
+ bool killFlag=isFlag("-kill");
+ bool forceFlag=isFlag("-force");
+ checkUnexpectedTokens();
+
+ RasServer &r= getServer(srvName);
+ if(r.isUp()==false && r.isStarting()==false)
+ { errorInCommand("Server is already down.");
+ return;
+ }
+
+ int res=killFlag ? r.killServer():r.downServer(forceFlag);
+
+ if(res<0)
+ { errorInCommand("Cannot contact the slave rasmgr.");
+ return;
+ }
+
+ if(killFlag) sprintf(answBuffer,"Server %s was killed",srvName);
+ else sprintf(answBuffer,"Server %s is going down",srvName);
+
+ return;
+ }
+
+ const char *hostName=getValueOf("-host");
+
+ if(hostName)
+ {
+ checkUnexpectedTokens();
+
+ int rasp=downAllServersOnHost(hostName);
+ switch(rasp)
+ {
+// case -1 : errorInCommand("Error in server host name.");
+// break;
+ case -2 : errorInCommand("Server host is down.");
+ break;
+ case 0 : sprintf(answBuffer,"On host %s all servers are already down",hostName);
+ break;
+ default : // means >0
+ 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<hostmanager.countHosts();i++)
+ {
+ int rasp = downAllServersOnHost(hostmanager[i].getName());
+
+ if(rasp>=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;i<rasManager.countServers();i++)
+ {
+ RasServer &r=rasManager[i];
+ if(r.isUp()==false && r.isStarting()==false) continue;
+
+ if(!hostCmp(hostName,r.getHostName()))
+ continue;
+ r.downServer(false);
+ countDownServers++;
+ }
+ return countDownServers;
+ }
+
+void RasControl::downRasHosts()
+ { // this is the new stop command, but this version is incipient
+ checkPermission(admR_sysup);
+
+ const char *hostName=getValueOf(RASMGRCMD_HOST);
+
+ if(hostName)
+ {
+ checkUnexpectedTokens();
+ int rasp = downRasHost(hostName);
+ switch(rasp)
+ {
+ case 0: sprintf(answBuffer,"Server host %s is going down", hostName);
+ break;
+// case -1: errorInCommand("Wrong server host name.");
+// break;
+ case -2: errorInCommand("Sorry, you should down all servers on this host first.");
+ break;
+ case -3: errorInCommand("Sorry, you should down all slave hosts first, the master should be the last one.");
+ break;
+ }
+ return;
+ }
+
+ bool flagAll = isFlag("-all");
+
+ if(flagAll)
+ {
+ checkUnexpectedTokens();
+ if(rasManager.countUpServers()!=0)
+ { errorInCommand("Sorry, you should down all servers first.");
+ return;
+ }
+
+ for(int i=1;i<hostmanager.countHosts();i++)
+ { //yes, from 1, master the last!
+ downRasHost(hostmanager[i].getName());
+ }
+ //now the master
+ masterCommunicator.shouldExit();
+ sprintf(answBuffer,"All hosts are down, bye");
+ return;
+ }
+
+ errorInCommand("Down what?");
+ return;
+ }
+
+int RasControl::downRasHost(const char *hostName)
+ {
+ ServerHost &sh= getServerHost(hostName);
+
+ if(sh.getStartedServers())
+ { //errorInCommand("Sorry, you should down all servers on this host first.");
+ return -2;
+ }
+
+ if(sh.isInternal() && hostmanager.countUpHosts()>1)
+ {// 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."<<std::endl;
+ sprintf(answBuffer,"rasmgr was succesfully reset.");
+ }
+
+//-----------------------------------------
+
+void RasControl::checkCommand()
+ {
+ const char *what = argc==1 ? "xxx":token[1].take();
+
+ if (strcasecmp(what,RASMGRCMD_HOST)==0) checkRasHosts();
+
+ else if(strcasecmp(what,RASMGRCMD_HELP)==0) checkHelp();
+
+ else errorInCommand("Error in CHECK command");
+
+ }
+
+void RasControl::checkRasHosts()
+ {
+ checkPermission(admR_sysup);
+
+ const char *hostName=getValueOf(RASMGRCMD_HOST);
+
+ if(hostName)
+ {
+ checkUnexpectedTokens();
+
+ ServerHost &sh=getServerHost(hostName);
+
+ sh.checkStatus();
+ sprintf(answBuffer,"The host %s is %s",sh.getName(),(sh.isUp() ? "up":"down"));
+ return;
+ }
+
+ bool flagAll = isFlag("-all");
+
+ if(flagAll)
+ {
+ checkUnexpectedTokens();
+ for(int i=0;i<hostmanager.countHosts();i++)
+ { hostmanager[i].checkStatus();
+ }
+ sprintf(answBuffer,"Checking status of all hosts ... done");
+ return;
+ }
+ errorInCommand("Check what?");
+ }
+
+
+
+
+//###---###---###---###---###---###---###---###---###---###---###
+void RasControl::errorInCommand(const char *errText)
+ {
+ sprintf(answBuffer,"Error: %s",errText);
+ }
+
+bool RasControl::isCommand( const char *key )
+ {
+ if(argc)
+ return (strcasecmp(token[0].argv,key)==0) ? true:false;
+ else
+ return (strcmp("#",key)==0) ? true:false;
+ }
+
+void RasControl::splitRequest(const char* reqMessage)
+ {
+ argc=0;
+ commandBuffer[0]=' ';
+ strncpy(commandBuffer+1,reqMessage,MAXMSG-1);
+ commandBuffer[MAXMSG]=0;
+
+ TALK("RasControl::splitRequest: (a) Com="<<commandBuffer);
+
+ char *temp = commandBuffer;
+
+ for(argc=0;argc<30;argc++)
+ {
+ token[argc].set(strtok(temp," \r\n\t\0"));
+ temp=NULL;
+
+ if(token[argc].argv == NULL) break;
+ if(token[argc].argv[0] == '#')
+ { token[argc].argv=NULL; // from here, comment
+ break;
+ }
+ }
+
+ }
+
+bool RasControl::isFlag(const char *flag, int pos)
+ {
+ if(pos<0) // doesn't matter
+ { for(int i=1;i<argc;i++) // flags are from 1->, 0 is the command itself
+ {
+ if(strcasecmp(flag,token[i].argv)==0)
+ {
+ token[i].used=true;
+ return true;
+ }
+ }
+ return false;
+ }
+ if(pos>1 && pos<argc)
+ {
+ if(strcasecmp(flag,token[pos].argv)==0)
+ {
+ token[pos].used=true;
+ return true;
+ }
+ }
+ return false;
+ }
+
+const char * RasControl::getValueOf(const char *flag, bool acceptMinus)
+ {
+ //no,not always if(flag[0]!='-') return NULL; // all flags start with '-'
+
+ for(int i=1;i<argc-1;i++)
+ {
+ if(strcasecmp(flag,token[i].argv)==0)
+ {
+ token[i].used=true;
+
+ if(acceptMinus)
+ { if(token[i+1].argv[0]=='-' && token[i+1].argv[1]!=0) return NULL; // values don't start with '-' (we don't have minus-signs)
+ } // except in void right string
+ else
+ { if(token[i+1].argv[0]=='-') return NULL;
+ }
+ token[i+1].used=true;
+ return token[i+1].argv;
+ }
+ }
+
+ if(strcasecmp(flag,token[argc-1].argv)==0) token[argc-1].used=true;
+
+ return NULL; // not found;
+ }
+const char * RasControl::getValueIfFlag(const char *flag,bool acceptMinus)
+ {
+ if(isFlag(flag)==false) return NULL;
+
+ const char *r = getValueOf(flag,acceptMinus);
+
+ if(r==NULL)
+ {
+ static char temp[30];
+ sprintf(temp,"'%s' value",flag);
+ throw RCErrorMissingParam(temp);
+ }
+ return r;
+ }
+
+void RasControl::checkUnexpectedTokens()
+ {
+ for(int i=2;i<argc;i++)
+ {
+ if(token[i].used == false) throw RCErrorUnexpToken(token[i].argv);
+ }
+ }
+void RasControl::checkPermission(int reqRights)
+ {
+ if(authorization.hasAdminRights(reqRights)==false)
+ throw RCErrorNoPermission();
+ }
+
+void RasControl::checkNotNull(const char *ptr, const char *what)
+ {
+ if(ptr==NULL) throw RCErrorMissingParam(what);
+ }
+
+RasServer& RasControl::getServer(const char *name)
+ {
+ RasServer &srv = rasManager[name];
+ if(srv.isValid()==false) throw RCErrorInvalidName("server");
+ return srv;
+ }
+Database& RasControl::getDatabase(const char *name)
+ {
+ Database &db = dbManager[name];
+ if(db.isValid()==false) throw RCErrorInvalidName(RASMGRCMD_DATABASE);
+ return db;
+ }
+DatabaseHost& RasControl::getDatabaseHost(const char *name)
+ {
+ DatabaseHost &dbh = dbHostManager[name];
+ if(dbh.isValid()==false) throw RCErrorInvalidName("database host");
+ return dbh;
+ }
+ServerHost& RasControl::getServerHost(const char *name)
+ {
+ TALK( "RasControl::getServerHost( " << name << " )" );
+ ServerHost &host = hostmanager[name];
+ if(host.isValid()==false) throw RCErrorInvalidName("server host");
+ return host;
+ }
+User& RasControl::getUser(const char *name)
+ {
+ User &user = userManager[name];
+ if(user.isValid()==false) throw RCErrorInvalidName(RASMGRCMD_USER);
+ return user;
+ }
+
+unsigned long RasControl::convertToULong(const char *stringValue,const char *what)
+ {
+ char *end;
+ unsigned long rasp = strtoul(stringValue,&end,0);
+
+ if(strlen(end)!=0) throw RCErrorIncorNumberValue(what);
+
+ return rasp;
+ }
+
+void RasControl::Token::set(char *p)
+ {
+ argv = p;
+ used = false;
+ }
+const char* RasControl::Token::take()
+ {
+ used=true;
+ return argv;
+ }
+
+//######### OBSOLETE in v1.1, but keep them, because could be usefull one day ################################
+
+#ifdef INCLUDE_HIDDEN_COMMANDS
+// removed in version 1.1, reimplemented in v1.3, but kept unofficial
+
+void RasControl::listRights()
+ {
+ const char *userName = getValueOf("-user");
+
+ if(userName==NULL)
+ {
+ errorInCommand("You have to provide an user name");
+ //checkPermission(admR_info);
+ // list global Initial Rights
+ // gi rights hidden in version 1.1 sprintf(answBuffer,"Initial global rights are set to: [%s]-[%s]:",authorization.convertGlobalInitAdminRights(),
+ // authorization.convertGlobalInitDatabRights());
+ return;
+ }
+ User &user=userManager[userName];
+
+ if(strcmp(userName,authorization.getUserName())!=0)
+ { checkPermission(admR_info);
+ }
+ if(user.isValid()==false)
+ { errorInCommand("Unknown user");
+ //sprintf(answBuffer,"Unknown user %s",userName);
+ return;
+ }
+ //std::cout<<"list rights of user "<<userName<<" "<<user.getAdminRights()<<" "<<user.getDefaultDBRights()<<std::endl;
+ sprintf(answBuffer,"List of rights defined for user %s",userName);
+ sprintf(answBuffer+strlen(answBuffer),"\r\n administrative rights: [%s]",authorization.convertAdminRights(user.getAdminRights()));
+ sprintf(answBuffer+strlen(answBuffer),"\r\n default database rights: [%s]",authorization.convertDatabRights(user.getDefaultDBRights()));
+
+ //sprintf(answBuffer+strlen(answBuffer),"\r\n List of defined rights on databases:");
+
+
+ for(int i=0;i<dbManager.countDatabases();i++)
+ {
+ const char *dbName=dbManager[i].getName();
+
+ if(user.isTrusteeOn(dbName))
+ {
+ int rights=user.getEffectiveDatabaseRights(dbName);
+ sprintf(answBuffer+strlen(answBuffer),"\r\n database %-20s [%s]",dbName,authorization.convertDatabRights(rights));
+ }
+ }
+
+ }
+
+
+
+void RasControl::grantCommand()
+ {
+ if(argc==1 || strcasecmp(token[1].argv,RASMGRCMD_HELP)==0)
+ { //grantHelp();
+ return;
+ }
+ checkPermission(admR_acctrl);
+
+ const char *rString = token[1].take();
+
+ const char *userName= getValueOf("-user");
+
+ const char *dbName = getValueOf("-db");
+
+ bool gi=isFlag("-gi");
+
+ int admRights=authorization.convertAdminRights(rString);
+ int dtbRights=authorization.convertDatabRights(rString);
+
+ if(admRights==-1 || dtbRights==-1)
+ { errorInCommand("Unknown right in command");
+ return;
+ }
+
+ if(userName!=NULL)
+ { User &user=userManager[userName];
+ if(user.isValid()==false)
+ { errorInCommand("Unknown user");
+ return;
+ }
+
+ if(dbName!=NULL)
+ { if(user.setDatabaseRights(dbName,dtbRights)==false)
+ errorInCommand("Unknown database name");
+
+ else sprintf(answBuffer,"Granted %s to user %s for database %s",rString,userName,dbName);
+ }
+ else
+ { const char *warning = user.getUserID()!=0 ? "": (admRights=admR_full,"You cannot change rasadmin's system rights\r\n");
+ //^sorry, trick
+ user.setAdminRights(admRights);
+ user.setDefaultDBRights(dtbRights);
+ sprintf(answBuffer,"%sGranted [%s]-[%s] to user %s",warning,authorization.convertAdminRights(admRights),authorization.convertDatabRights(dtbRights),userName);
+ }
+ }
+ else
+ { if(gi)
+ { authorization.setGlobalInitAdminRights(admRights);
+ authorization.setGlobalInitDatabRights(dtbRights);
+ sprintf(answBuffer,"Set global initial rights to [%s]-[%s]",authorization.convertAdminRights(admRights),authorization.convertDatabRights(dtbRights));
+ }
+ else
+ { errorInCommand("Error in GRANT command");
+ }
+ }
+ }
+
+// removed in version 1.1
+void RasControl::revokeCommand()
+ {
+ if(argc==1 || strcasecmp(token[1].argv,RASMGRCMD_HELP)==0)
+ { //revokeHelp();
+ return;
+ }
+ checkPermission(admR_acctrl);
+
+ const char *userName= token[1].take();
+
+ const char *dbName = getValueOf("-db");
+
+ User &user=userManager[userName];
+ if(user.isValid()==false)
+ { errorInCommand("Unknown user");
+ return;
+ }
+
+ if(dbName!=NULL)
+ {
+ if(user.removeDatabaseRights(dbName)==false)
+ errorInCommand("Unknown database name");
+
+ else sprintf(answBuffer,"Rights of user %s for database %s revoked",userName,dbName);
+ }
+ else
+ { errorInCommand("Error in REVOKE command");
+ }
+ }
+
+#endif
+
+/*
+--------
+from list servers
+
+ bool fdbh = isFlag("-dbh",2);
+ const char *dbhName = getValueOf("-dbh");
+ if(fdbh) listRasServersOnDBH(dbhName);
+
+ else if(fdb) listRasServersDatabase(dbName);
+
+ else if(hostName)
+ {
+ sprintf(answBuffer,"List of servers on host %s:",hostName);
+
+ int crnt=0;
+ for(int i=0;i<rasManager.countServers();i++)
+ {
+ answLen=strlen(answBuffer);
+
+ if(answLen >=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<dbManager.countDatabases();i++)
+ {
+ Database &refTemp=dbManager[i];
+
+ if( dbhName && refTemp.isConnectedToDBHost(dbhName) )
+ { sprintf(answBuffer+strlen(answBuffer),"\r\n%2d. %s ",crnt++,refTemp.getName());
+ }
+
+ if( !dbhName )
+ { sprintf(answBuffer+strlen(answBuffer),"\r\n%2d. %s",crnt++,refTemp.getName());
+
+ for(int j=0;j<refTemp.countConnectionsToDBHosts();j++)
+ sprintf(answBuffer+strlen(answBuffer),"\r\n %s ",refTemp.getDBHostName(j));
+ }
+ }
+ }
+ else if(isFlag("-srv",2))
+ {
+ const char *srvName=getValueOf("-srv");
+
+ if(srvName)
+ sprintf(answBuffer,"List of databases accesible by server: %s",srvName);
+ else sprintf(answBuffer,"List of databases:");
+
+ int crnt=0;
+ for(int i=0;i<dbManager.countDatabases();i++)
+ {
+ Database &refTemp=dbManager[i];
+
+ if( srvName && refTemp.isConnectedToRasServer(srvName) )
+ { sprintf(answBuffer+strlen(answBuffer),"\r\n%2d. %s ",crnt++,refTemp.getName());
+ }
+
+ if( !srvName )
+ { sprintf(answBuffer+strlen(answBuffer),"\r\n%2d. %s",crnt++,refTemp.getName());
+
+ for(int j=0;j<refTemp.countConnectionsToRasServers();j++)
+ sprintf(answBuffer+strlen(answBuffer),"\r\n %s ",refTemp.getRasServerName(j));
+
+ }
+ }
+ }
+
+ else
+ { sprintf(answBuffer,"List of databases:");
+ int crnt=0;
+ for(int i=0;i<dbManager.countDatabases();i++)
+ {
+ Database &refTemp=dbManager[i];
+
+ sprintf(answBuffer+strlen(answBuffer),"\r\n%2d. %s ",crnt++,refTemp.getName());//,refTemp.isValid());
+
+ sprintf(answBuffer+strlen(answBuffer),"(%dw + %dr) ",refTemp.getWriteTransactionCount(),refTemp.getReadTransactionCount());
+
+ }
+ }
+
+---------
+
+*/
+