summaryrefslogtreecommitdiffstats
path: root/servers/admin_sys_ctl_server_lin/src
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-09-17 23:55:55 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-09-17 23:55:55 -0500
commitb140795f1f54f64dc704f9e3055b00d4aee20c3c (patch)
tree682a9031e9ba48865d1c99223ad01089968cee6e /servers/admin_sys_ctl_server_lin/src
parent5e3618366d86220c66e38d764aa80db1314ceabc (diff)
downloadulab-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.cpp291
-rw-r--r--servers/admin_sys_ctl_server_lin/src/admin_sys_ctl.h20
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;