diff options
| author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-09-17 23:55:55 -0500 |
|---|---|---|
| committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-09-17 23:55:55 -0500 |
| commit | b140795f1f54f64dc704f9e3055b00d4aee20c3c (patch) | |
| tree | 682a9031e9ba48865d1c99223ad01089968cee6e /servers/admin_sys_ctl_server_lin/src | |
| parent | 5e3618366d86220c66e38d764aa80db1314ceabc (diff) | |
| download | ulab-b140795f1f54f64dc704f9e3055b00d4aee20c3c.tar.gz ulab-b140795f1f54f64dc704f9e3055b00d4aee20c3c.zip | |
Add preliminary database connections to admin server
Diffstat (limited to 'servers/admin_sys_ctl_server_lin/src')
| -rw-r--r-- | servers/admin_sys_ctl_server_lin/src/admin_sys_ctl.cpp | 291 | ||||
| -rw-r--r-- | servers/admin_sys_ctl_server_lin/src/admin_sys_ctl.h | 20 |
2 files changed, 166 insertions, 145 deletions
diff --git a/servers/admin_sys_ctl_server_lin/src/admin_sys_ctl.cpp b/servers/admin_sys_ctl_server_lin/src/admin_sys_ctl.cpp index b6fb9d7..3cce4b5 100644 --- a/servers/admin_sys_ctl_server_lin/src/admin_sys_ctl.cpp +++ b/servers/admin_sys_ctl_server_lin/src/admin_sys_ctl.cpp @@ -56,12 +56,7 @@ struct exit_exception { }; enum connectionStates { - StateIdle = 0, - StateGetFileSize = 1, - StateGetFileContents = 2, - StateStartProgramming = 3, - StateCheckProgrammingStatus = 4, - StateProgammingFinished = 5 + StateIdle = 0 }; /* @@ -70,8 +65,7 @@ enum connectionStates { instance of this class. */ SysCtlSocket::SysCtlSocket(int sock, TQObject *parent, const char *name) : - TDEKerberosServerSocket(parent, name), m_criticalSection(0), m_loopTimer(NULL), m_config(static_cast<SysCtlServer*>(parent)->m_config), m_commandLoopState(StateIdle), - m_progpipe(NULL), m_progpipefd(-1), m_progErrorFlag(false), m_progDoneFlag(false) + TDEKerberosServerSocket(parent, name), m_criticalSection(0), m_loopTimer(NULL), m_config(static_cast<SysCtlServer*>(parent)->m_config), m_terminals_database(NULL), m_workspaces_database(NULL), m_commandLoopState(StateIdle) { // Initialize timers @@ -85,6 +79,10 @@ SysCtlSocket::SysCtlSocket(int sock, TQObject *parent, const char *name) : connect(this, SIGNAL(connectionClosed()), SLOT(connectionClosedHandler())); connect(this, SIGNAL(connectionClosed()), parent, SLOT(remoteConnectionClosed())); setSocket(sock); + + if (connectToDatabase() != 0) { + exit(1); + } } SysCtlSocket::~SysCtlSocket() { @@ -168,7 +166,7 @@ void SysCtlSocket::commandLoop() { try { transferred_data = false; if (state() == TQSocket::Connected) { - if ((m_commandLoopState == StateIdle) || (m_commandLoopState == StateStartProgramming) || (m_commandLoopState == StateCheckProgrammingStatus) || (m_commandLoopState == StateProgammingFinished)) { + if (m_commandLoopState == StateIdle) { // Certain commands can come in at any time during some operations if (canReadLine()) { processPendingData(); @@ -178,146 +176,89 @@ void SysCtlSocket::commandLoop() { ds.setPrintableData(true); TQString command; ds >> command; - clearFrameTail(); - if (command == "STATUS") { - if (m_logMessages != "") { - ds << TQString("LOGMESSAGES"); - writeEndOfFrame(); - ds << m_logMessages; - writeEndOfFrame(); - m_logMessages = ""; - } - else if (m_progErrorFlag) { - ds << TQString("ERROR"); - m_progErrorFlag = false; - writeEndOfFrame(); - } - else if (m_progDoneFlag) { - ds << TQString("DONE"); - ds << m_progRetCode; - m_progDoneFlag = false; - writeEndOfFrame(); - } - else if (m_commandLoopState == StateIdle) { - ds << TQString("IDLE"); + if (command == "USERS") { + TQString subCommand; + ds >> subCommand; + if (subCommand == "TERMINALS") { + clearFrameTail(); + TQSqlCursor databaseActivityCursor("sessions", TRUE, m_terminals_database); + databaseActivityCursor.select(); + while (databaseActivityCursor.next()) { + TQ_UINT32 protocolVersion = 1; + TQDateTime loginStamp; + TQDateTime activityStamp; + loginStamp.setTime_t(databaseActivityCursor.value("stamp_start").toInt()); + activityStamp.setTime_t(databaseActivityCursor.value("stamp_statechange").toInt()); + + ds << protocolVersion; + ds << databaseActivityCursor.value("pk").toInt(); + ds << databaseActivityCursor.value("username").toString(); + ds << databaseActivityCursor.value("servername").toString(); + ds << databaseActivityCursor.value("server_pid").toInt(); + ds << databaseActivityCursor.value("wm_pid").toInt(); + ds << databaseActivityCursor.value("state").toInt(); + ds << databaseActivityCursor.value("display").toInt(); + ds << loginStamp; + ds << activityStamp; + } writeEndOfFrame(); } - else if ((m_commandLoopState == StateStartProgramming) || (m_commandLoopState == StateCheckProgrammingStatus) || (m_commandLoopState == StateProgammingFinished)) { - ds << TQString("PROGRAMMING"); + else if (subCommand == "WORKSPACES") { + clearFrameTail(); + TQSqlCursor databaseActivityCursor("activity", TRUE, m_workspaces_database); + databaseActivityCursor.select(); + while (databaseActivityCursor.next()) { + TQ_UINT32 protocolVersion = 1; + TQDateTime loginStamp; + loginStamp.setTime_t(databaseActivityCursor.value("logontime").toInt()); + + ds << protocolVersion; + ds << databaseActivityCursor.value("pk").toInt(); + ds << databaseActivityCursor.value("station").toInt(); + ds << databaseActivityCursor.value("username").toString(); + ds << databaseActivityCursor.value("realmname").toString(); + ds << databaseActivityCursor.value("serverid").toInt(); + ds << loginStamp; + } writeEndOfFrame(); } else { - ds << TQString("UNKNOWN"); - writeEndOfFrame(); + clearFrameTail(); } } - else if (m_commandLoopState == StateIdle) { - if (command == "FILE") { - m_commandLoopState = StateGetFileSize; + else if (command == "SESSION") { + TQString subCommand; + TQString sessionID; + ds >> subCommand; + ds >> sessionID; + if (subCommand == "LOGOFF_TERMINAL") { + TQ_UINT32 delay; + ds >> delay; + clearFrameTail(); + // FIXME + } + else if (subCommand == "CANCEL_LOGOFF_TERMINAL") { + clearFrameTail(); + // FIXME } - else if (command == "PROGRAM") { - m_commandLoopState = StateStartProgramming; + else if (subCommand == "KILL_TERMINAL") { + clearFrameTail(); + // FIXME + } + else if (subCommand == "KILL_WORKSPACE") { + clearFrameTail(); + // FIXME } else { - printf("[WARNING] Received unknown command '%s'\n\r", command.ascii()); + clearFrameTail(); } } - transferred_data = true; - } - } - if (m_commandLoopState == StateGetFileSize) { - if (canReadLine()) { - processPendingData(); - } - if (canReadFrame()) { - TQDataStream ds(this); - ds.setPrintableData(true); - ds >> m_programmingFileSize; - clearFrameTail(); - m_servClientTimeout->start(NETWORK_COMM_TIMEOUT_MS, TRUE); - m_commandLoopState = StateGetFileContents; - } - } - else if (m_commandLoopState == StateGetFileContents) { - if (canReadLine()) { - m_servClientTimeout->start(NETWORK_COMM_TIMEOUT_MS, TRUE); - processPendingData(); - } - if (bytesAvailable() >= m_programmingFileSize) { - TQByteArray fileContents(m_programmingFileSize); - readBlock(fileContents.data(), fileContents.size()); - m_programmingFileName = TQString("/tmp/%1#%2.dat").arg(m_remoteHost).arg(port()); - TQFile outputFile(m_programmingFileName); - if (outputFile.open(IO_ReadWrite)) { - outputFile.writeBlock(fileContents); - outputFile.flush(); - outputFile.close(); + else { + clearFrameTail(); } transferred_data = true; - m_commandLoopState = StateIdle; - } - else { - if (!m_servClientTimeout->isActive()) { - m_progErrorFlag = true; - transferred_data = true; - m_commandLoopState = StateIdle; - } - } - } - else if (m_commandLoopState == StateStartProgramming) { - // Start programming! - - // Open programming process - m_config->setGroup("Programming"); - TQString programmingScript = m_config->readEntry("script"); - programmingScript.replace("%f", m_programmingFileName); - if (!programmingScript.contains("2>&1")) { - programmingScript.append(" 2>&1"); - } - if ((m_progpipe = popen(programmingScript.ascii(), "r")) == NULL) { - m_logMessages.append(TQString("The system was unable to execute '%1'\nPlease contact your system administrator with this information").arg(programmingScript)); - m_progErrorFlag = true; - transferred_data = true; - m_commandLoopState = StateIdle; - } - else { - m_progpipefd = fileno(m_progpipe); - fcntl(m_progpipefd, F_SETFL, O_NONBLOCK); - } - m_commandLoopState = StateCheckProgrammingStatus; - } - else if (m_commandLoopState == StateCheckProgrammingStatus) { - // Check programming status - TQCString buf; - buf.resize(8192); - ssize_t r = read(m_progpipefd, buf.data(), buf.size()); - if ((r == -1) && (errno == EAGAIN)) { - // No data available yet - } - else if (r > 0) { - // Data was received - buf.data()[r] = 0; - m_logMessages.append(buf); - } - else { - // Process terminated - m_commandLoopState = StateProgammingFinished; } } - else if (m_commandLoopState == StateProgammingFinished) { - // Programming process terminated; get exit code and clean up - if (m_progpipe) { - m_progRetCode = pclose(m_progpipe); - } - else { - m_progRetCode = -1; - } - m_progpipe = NULL; - m_progpipefd = -1; - - m_progDoneFlag = true; - m_commandLoopState = StateIdle; - } } m_criticalSection--; if (transferred_data) { @@ -344,13 +285,32 @@ int SysCtlSocket::enterCommandLoop() { return 0; } +int SysCtlSocket::connectToDatabase() { + if ((m_terminals_database) && (m_workspaces_database)) { + return -2; + } + + m_terminals_database = TQSqlDatabase::database("terminals"); + m_workspaces_database = TQSqlDatabase::database("workspaces"); + if ((!m_terminals_database) || (!m_workspaces_database)) { + printf("[ERROR] Databases were not constructed by the application\n\r"); fflush(stdout); + return -1; + } + + return 0; +} + /* The SysCtlServer class handles new connections to the server. For every client that connects, it creates a new SysCtlSocket -- that instance is now responsible for the communication with that client. */ SysCtlServer::SysCtlServer(TQObject* parent, int port, KSimpleConfig* config) : - TQServerSocket( port, 1, parent ), m_config(config), m_numberOfConnections(0) { + TQServerSocket( port, 1, parent ), m_config(config), m_numberOfConnections(0), m_terminals_database(NULL), m_workspaces_database(NULL), m_sqlPingTimer(NULL) { + + if (connectToDatabase() != 0) { + exit(1); + } if ( !ok() ) { printf("[ERROR] Failed to bind to port %d\n\r", port); @@ -361,7 +321,68 @@ SysCtlServer::SysCtlServer(TQObject* parent, int port, KSimpleConfig* config) : } SysCtlServer::~SysCtlServer() { - // + if (m_sqlPingTimer) { + m_sqlPingTimer->stop(); + delete m_sqlPingTimer; + m_sqlPingTimer = NULL; + } + if (m_terminals_database) { + TQSqlDatabase::removeDatabase(m_terminals_database); + m_terminals_database = NULL; + } + if (m_workspaces_database) { + TQSqlDatabase::removeDatabase(m_workspaces_database); + m_workspaces_database = NULL; + } +} + +int SysCtlServer::connectToDatabase() { + m_config->setGroup("Terminals Database"); + + m_terminals_database = TQSqlDatabase::addDatabase(m_config->readEntry("driver"), "terminals"); + m_terminals_database->setDatabaseName(m_config->readEntry("database")); + m_terminals_database->setUserName(m_config->readEntry("username")); + m_terminals_database->setPassword(m_config->readEntry("password")); + m_terminals_database->setHostName(m_config->readEntry("server")); + + if(!m_terminals_database->open()) { + printf("[ERROR] Failed to connect to control database on server '%s' [%s]\n\r", m_terminals_database->hostName().ascii(), m_terminals_database->lastError().text().ascii()); fflush(stdout); + TQSqlDatabase::removeDatabase(m_terminals_database); + m_terminals_database = NULL; + return -1; + } + + m_config->setGroup("Workspaces Database"); + + m_workspaces_database = TQSqlDatabase::addDatabase(m_config->readEntry("driver"), "workspaces"); + m_workspaces_database->setDatabaseName(m_config->readEntry("database")); + m_workspaces_database->setUserName(m_config->readEntry("username")); + m_workspaces_database->setPassword(m_config->readEntry("password")); + m_workspaces_database->setHostName(m_config->readEntry("server")); + + if(!m_workspaces_database->open()) { + printf("[ERROR] Failed to connect to control database on server '%s' [%s]\n\r", m_workspaces_database->hostName().ascii(), m_workspaces_database->lastError().text().ascii()); fflush(stdout); + TQSqlDatabase::removeDatabase(m_workspaces_database); + m_workspaces_database = NULL; + return -1; + } + + // FIXME + // We currently have no way to handle something as simple as the database server going offline! + + // Start database ping process + m_sqlPingTimer = new TQTimer(); + connect(m_sqlPingTimer, SIGNAL(timeout()), this, SLOT(pingSQLServer())); + m_sqlPingTimer->start(60*1000); + + return 0; +} + +void SysCtlServer::pingSQLServer() { + TQSqlQuery terminals_query(TQString::null, m_terminals_database); + terminals_query.exec("SELECT * FROM sessions"); + TQSqlQuery workspaces_query(TQString::null, m_workspaces_database); + workspaces_query.exec("SELECT * FROM activity"); } void SysCtlServer::newConnection(int socket) { diff --git a/servers/admin_sys_ctl_server_lin/src/admin_sys_ctl.h b/servers/admin_sys_ctl_server_lin/src/admin_sys_ctl.h index 73f5f69..818d966 100644 --- a/servers/admin_sys_ctl_server_lin/src/admin_sys_ctl.h +++ b/servers/admin_sys_ctl_server_lin/src/admin_sys_ctl.h @@ -28,6 +28,8 @@ #include <tqlabel.h> #include <tqpushbutton.h> #include <tqtextstream.h> +#include <tqsqldatabase.h> +#include <tqsqlcursor.h> #include <ksimpleconfig.h> @@ -55,6 +57,7 @@ class SysCtlSocket : public TDEKerberosServerSocket void finishKerberosHandshake(); void connectionClosedHandler(); void commandLoop(); + int connectToDatabase(); private: int line; @@ -66,18 +69,10 @@ class SysCtlSocket : public TDEKerberosServerSocket TQTimer* m_servClientTimeout; KSimpleConfig* m_config; + TQSqlDatabase* m_terminals_database; + TQSqlDatabase* m_workspaces_database; int m_commandLoopState; - TQ_ULONG m_programmingFileSize; - TQString m_programmingFileName; - FILE *m_progpipe; - int m_progpipefd; - - bool m_progErrorFlag; - bool m_progDoneFlag; - TQ_INT32 m_progRetCode; - TQString m_logMessages; - friend class SysCtlServer; }; @@ -93,6 +88,8 @@ class SysCtlServer : public TQServerSocket private slots: void remoteConnectionClosed(); + int connectToDatabase(); + void pingSQLServer(); signals: void newConnect(SysCtlSocket*); @@ -100,6 +97,9 @@ class SysCtlServer : public TQServerSocket private: KSimpleConfig* m_config; int m_numberOfConnections; + TQSqlDatabase* m_terminals_database; + TQSqlDatabase* m_workspaces_database; + TQTimer* m_sqlPingTimer; friend class SysCtlSocket; |
