summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Client/CommandManager.cpp40
-rw-r--r--src/Client/CommandManager.h1
-rw-r--r--src/Client/CommandParser.cpp61
-rw-r--r--src/Client/InformationManager.cpp90
-rw-r--r--src/Client/InformationManager.h88
-rw-r--r--src/Client/Makefile.am4
-rw-r--r--src/Client/Makefile.in8
-rw-r--r--src/Client/Requests/CoreStatusRequest.cpp1
-rw-r--r--src/Client/Requests/CoreStatusRequest.h8
-rw-r--r--src/Client/Requests/DaemonListRequest.cpp1
-rw-r--r--src/Client/Requests/DaemonListRequest.h8
-rw-r--r--src/Client/Requests/DaemonStatusRequest.cpp1
-rw-r--r--src/Client/Requests/DaemonStatusRequest.h8
-rw-r--r--src/Common/HostInfo.h10
-rw-r--r--src/Common/RequestManager.cpp4
-rw-r--r--src/Core/ConnectionManager.cpp15
-rw-r--r--src/Core/ConnectionManager.h4
-rw-r--r--src/Core/Requests/DaemonStateUpdateRequest.cpp43
-rw-r--r--src/Core/Requests/DaemonStateUpdateRequest.h47
-rw-r--r--src/Core/Requests/DaemonStatusRequest.cpp1
-rw-r--r--src/Core/Requests/DaemonStatusRequest.h8
-rw-r--r--src/Core/Requests/Makefile.am4
-rw-r--r--src/Core/Requests/Makefile.in8
-rw-r--r--src/Net/Packet.h3
-rw-r--r--src/Net/Packets/HostListPacket.cpp4
-rw-r--r--src/Net/Packets/HostListPacket.h2
-rw-r--r--src/Net/Packets/HostStatePacket.cpp50
-rw-r--r--src/Net/Packets/HostStatePacket.h74
-rw-r--r--src/Net/Packets/Makefile.am4
-rw-r--r--src/Net/Packets/Makefile.in7
-rw-r--r--src/madc.cpp16
31 files changed, 500 insertions, 123 deletions
diff --git a/src/Client/CommandManager.cpp b/src/Client/CommandManager.cpp
index 8a82a82..2a20b29 100644
--- a/src/Client/CommandManager.cpp
+++ b/src/Client/CommandManager.cpp
@@ -106,46 +106,6 @@ void CommandManager::daemonCommandRequestFinished(const Common::Request<> &reque
requestFinished();
}
-void CommandManager::daemonListRequestFinished(const Common::Request<Net::Packets::HostListPacket> &request, bool all) {
- try {
- const std::vector<Common::HostInfo>& hosts = request.getResult().getHostInfo();
-
- if(hosts.empty()) {
- std::cout << "The host list is empty." << std::endl << std::endl;
- }
- else {
- bool output = false;
-
- for(std::vector<Common::HostInfo>::const_iterator host = hosts.begin(); host != hosts.end(); ++host) {
- if(host->getStatus() == Common::HostInfo::INACTIVE && !all)
- continue;
-
- if(!output) {
- std::cout << (all ? "Host list:" : "Active hosts:") << std::endl;
- output = true;
- }
-
- std::cout << " " << host->getName();
-
- if(all)
- std::cout << " (" << (host->getStatus() == Common::HostInfo::RUNNING ? "running" : "inactive") << ")";
-
- std::cout << std::endl;
- }
-
- if(!output)
- std::cout << "No active hosts." << std::endl;
-
- std::cout << std::endl;
- }
- }
- catch(Common::Exception &exception) {
- Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str());
- }
-
- requestFinished();
-}
-
void CommandManager::daemonStatusRequestFinished(const Common::Request<Net::Packets::HostStatusPacket> &request) {
try {
const Net::Packets::HostStatusPacket &packet = request.getResult();
diff --git a/src/Client/CommandManager.h b/src/Client/CommandManager.h
index 6aea724..f93d07f 100644
--- a/src/Client/CommandManager.h
+++ b/src/Client/CommandManager.h
@@ -53,7 +53,6 @@ class CommandManager {
void coreStatusRequestFinished(const Common::Request<Net::Packets::HostStatusPacket> &request);
void daemonCommandRequestFinished(const Common::Request<> &request);
- void daemonListRequestFinished(const Common::Request<Net::Packets::HostListPacket> &request, bool all);
void daemonStatusRequestFinished(const Common::Request<Net::Packets::HostStatusPacket> &request);
void disconnectRequestFinished(const Common::Request<> &request);
diff --git a/src/Client/CommandParser.cpp b/src/Client/CommandParser.cpp
index 1a5a96c..1ba986f 100644
--- a/src/Client/CommandParser.cpp
+++ b/src/Client/CommandParser.cpp
@@ -18,9 +18,9 @@
*/
#include "CommandParser.h"
+#include "InformationManager.h"
#include "Requests/CoreStatusRequest.h"
#include "Requests/DaemonCommandRequest.h"
-#include "Requests/DaemonListRequest.h"
#include "Requests/DaemonStatusRequest.h"
#include <Common/Exception.h>
#include <Common/Logger.h>
@@ -40,7 +40,7 @@ const CommandParser::Command CommandParser::commands[] = {
{{"help", "?", 0}, "help [command]", "Displays usage information about commands", "Displays usage information about a command. If no command is given, a list of all available commands is displayed.", &CommandParser::helpCommand},
{{"list_hosts", "hosts", 0}, "list_hosts [-a]", "Lists the currently active hosts", "Lists the currently active hosts.\n\n -a\tAlso list inactive hosts", &CommandParser::listHostsCommand},
{{"reboot", 0}, "reboot host", "Reboots a host", "Reboots a host.", &CommandParser::rebootCommand},
- {{"shutdown", 0}, "shutdown host", "Shuts a host down", "Shuts a host down.", &CommandParser::shutdownCommand},
+ {{"shutdown", "halt", 0}, "shutdown host", "Shuts a host down", "Shuts a host down.", &CommandParser::shutdownCommand},
{{"status", "st", 0}, "status [host]", "Displays status information", "Displays host status information. If no host is given, server status information is displayed.", &CommandParser::statusCommand},
{{"exit", "quit", 0}, "exit", "Closes the connection and quits the client", "Closes the connection and quits the client.", &CommandParser::exitCommand},
{{0}, 0, 0, 0, 0}
@@ -95,36 +95,55 @@ void CommandParser::helpCommand(const std::vector<std::string> &args) {
}
void CommandParser::listHostsCommand(const std::vector<std::string> &args) {
+ const std::map<std::string, Common::HostInfo>& hosts = InformationManager::getInformationManager()->getDaemons();
+
if(args.size() == 1) {
- Common::RequestManager::getRequestManager()->sendRequest(connection,
- std::auto_ptr<Common::RequestBase>(
- new Requests::DaemonListRequest(
- sigc::bind(sigc::mem_fun(commandManager, &CommandManager::daemonListRequestFinished), false)
- )
- )
- );
+ if(hosts.empty()) {
+ std::cout << "The host list is empty." << std::endl << std::endl;
+ return;
+ }
+
+ bool output = false;
+
+ for(std::map<std::string, Common::HostInfo>::const_iterator host = hosts.begin(); host != hosts.end(); ++host) {
+ if(host->second.getState() == Common::HostInfo::INACTIVE)
+ continue;
+
+ if(!output) {
+ std::cout << "Active hosts:" << std::endl;
+ output = true;
+ }
+
+ std::cout << " " << host->first << std::endl;
+ }
+
+ if(!output)
+ std::cout << "No active hosts." << std::endl;
+
+ std::cout << std::endl;
}
else if(args.size() > 2) {
Common::Logger::logf(Common::Logger::ERROR, "%s: Too many arguments.", args[0].c_str());
printUsage("list_hosts");
- return;
}
else if(args[1] == "-a") {
- Common::RequestManager::getRequestManager()->sendRequest(connection,
- std::auto_ptr<Common::RequestBase>(
- new Requests::DaemonListRequest(
- sigc::bind(sigc::mem_fun(commandManager, &CommandManager::daemonListRequestFinished), true)
- )
- )
- );
+ if(hosts.empty()) {
+ std::cout << "The host list is empty." << std::endl << std::endl;
+ return;
+ }
+
+ std::cout << "Host list:" << std::endl;
+
+ for(std::map<std::string, Common::HostInfo>::const_iterator host = hosts.begin(); host != hosts.end(); ++host) {
+ std::cout << " " << host->first << " (" << (host->second.getState() == Common::HostInfo::RUNNING ? "running" : "inactive") << ")" << std::endl;
+ }
+
+ std::cout << std::endl;
}
else {
- Common::Logger::logf(Common::Logger::ERROR, "%s: Don't unterstand argument '%s'.", args[0].c_str(), args[1].c_str());
+ Common::Logger::logf(Common::Logger::ERROR, "%s: Don't understand argument '%s'.", args[0].c_str(), args[1].c_str());
printUsage("list_hosts");
- return;
}
-
- commandManager.activeRequests++;
}
void CommandParser::rebootCommand(const std::vector<std::string> &args) {
diff --git a/src/Client/InformationManager.cpp b/src/Client/InformationManager.cpp
new file mode 100644
index 0000000..8a3227c
--- /dev/null
+++ b/src/Client/InformationManager.cpp
@@ -0,0 +1,90 @@
+/*
+ * InformationManager.cpp
+ *
+ * Copyright (C) 2008 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "InformationManager.h"
+#include "Requests/DaemonListRequest.h"
+#include <Common/Logger.h>
+#include <Common/RequestManager.h>
+#include <Net/Packets/ErrorPacket.h>
+#include <Net/Packets/HostStatePacket.h>
+
+
+namespace Mad {
+namespace Client {
+
+std::auto_ptr<InformationManager> InformationManager::informationManager;
+
+
+void InformationManager::DaemonStateUpdateRequest::handlePacket(Net::Connection *connection, const Net::Packet &packet) {
+ if(packet.getType() != Net::Packet::DAEMON_STATE_UPDATE) {
+ Common::Logger::log(Common::Logger::ERROR, "Received an unexpected packet.");
+ connection->send(Net::Packets::ErrorPacket(Net::Packet::ERROR, packet.getRequestId(), Common::Exception(Common::Exception::UNEXPECTED_PACKET)));
+
+ signalFinished().emit();
+ return;
+ }
+
+ // TODO Require authentication
+
+ Net::Packets::HostStatePacket hostStatePacket(packet);
+
+ std::map<std::string, Common::HostInfo>::iterator host = informationManager->daemons.find(hostStatePacket.getName());
+ if(host != informationManager->daemons.end())
+ host->second.setState(hostStatePacket.getState());
+ else
+ Common::Logger::log(Common::Logger::WARNING, "Received a state update for an unknown host.");
+
+ connection->send(Net::Packet(Net::Packet::OK, packet.getRequestId()));
+
+ signalFinished().emit();
+}
+
+
+InformationManager::InformationManager(Net::Connection *connection) : initFinished(false) {
+ Common::RequestManager::getRequestManager()->sendRequest(connection,
+ std::auto_ptr<Common::RequestBase>(
+ new Requests::DaemonListRequest(sigc::mem_fun(this, &InformationManager::daemonListRequestFinished))
+ )
+ );
+
+ Common::RequestManager::getRequestManager()->registerPacketType<DaemonStateUpdateRequest>(Net::Packet::DAEMON_STATE_UPDATE);
+}
+
+InformationManager::~InformationManager() {
+ Common::RequestManager::getRequestManager()->unregisterPacketType(Net::Packet::DAEMON_STATE_UPDATE);
+}
+
+void InformationManager::daemonListRequestFinished(const Common::Request<Net::Packets::HostListPacket> &request) {
+ try {
+ const std::vector<Common::HostInfo> &hostInfo = request.getResult().getHostInfo();
+
+ for(std::vector<Common::HostInfo>::const_iterator daemon = hostInfo.begin(); daemon != hostInfo.end(); ++daemon) {
+ daemons.clear();
+ daemons.insert(std::make_pair(daemon->getName(), *daemon));
+ }
+
+ initFinished = true;
+ }
+ catch(Common::Exception &e) {
+ Common::Logger::logf(Common::Logger::CRITICAL, "Host list request failed: %s", e.strerror().c_str());
+ }
+}
+
+}
+}
diff --git a/src/Client/InformationManager.h b/src/Client/InformationManager.h
new file mode 100644
index 0000000..bf2d67a
--- /dev/null
+++ b/src/Client/InformationManager.h
@@ -0,0 +1,88 @@
+/*
+ * InformationManager.h
+ *
+ * Copyright (C) 2008 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAD_CLIENT_INFORMATIONMANAGER_H_
+#define MAD_CLIENT_INFORMATIONMANAGER_H_
+
+#include <map>
+#include <memory>
+
+#include <Common/HostInfo.h>
+#include <Common/Request.h>
+
+namespace Mad {
+
+namespace Net {
+class Connection;
+
+namespace Packets {
+class HostListPacket;
+}
+
+}
+
+namespace Client {
+
+class InformationManager {
+ private:
+ class DaemonStateUpdateRequest : public Common::RequestHandler {
+ protected:
+ virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet);
+
+ public:
+ DaemonStateUpdateRequest() {}
+ };
+
+ static std::auto_ptr<InformationManager> informationManager;
+
+ std::map<std::string, Common::HostInfo> daemons;
+ bool initFinished;
+
+ // Prevent shallow copy
+ InformationManager(const InformationManager &o);
+ InformationManager& operator=(const InformationManager &o);
+
+ InformationManager(Net::Connection *connection);
+
+ void daemonListRequestFinished(const Common::Request<Net::Packets::HostListPacket> &request);
+
+ public:
+ ~InformationManager();
+
+ static InformationManager* getInformationManager() {
+ return informationManager.get();
+ }
+
+ static void init(Net::Connection *connection) {
+ informationManager = std::auto_ptr<InformationManager>(new InformationManager(connection));
+ }
+
+ bool isInitialised() const {
+ return initFinished;
+ }
+
+ const std::map<std::string, Common::HostInfo>& getDaemons() const {
+ return daemons;
+ }
+};
+
+}
+}
+
+#endif /* MAD_CLIENT_INFORMATIONMANAGER_H_ */
diff --git a/src/Client/Makefile.am b/src/Client/Makefile.am
index cfbabd4..5de3bc6 100644
--- a/src/Client/Makefile.am
+++ b/src/Client/Makefile.am
@@ -1,7 +1,7 @@
SUBDIRS = Requests
noinst_LTLIBRARIES = libclient.la
-libclient_la_SOURCES = CommandManager.cpp CommandParser.cpp
+libclient_la_SOURCES = CommandManager.cpp CommandParser.cpp InformationManager.cpp
libclient_la_LIBADD = Requests/librequests.la
-noinst_HEADERS = CommandManager.h CommandParser.h
+noinst_HEADERS = CommandManager.h CommandParser.h InformationManager.h
diff --git a/src/Client/Makefile.in b/src/Client/Makefile.in
index b9e2d98..8d6b09e 100644
--- a/src/Client/Makefile.in
+++ b/src/Client/Makefile.in
@@ -48,7 +48,8 @@ CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libclient_la_DEPENDENCIES = Requests/librequests.la
-am_libclient_la_OBJECTS = CommandManager.lo CommandParser.lo
+am_libclient_la_OBJECTS = CommandManager.lo CommandParser.lo \
+ InformationManager.lo
libclient_la_OBJECTS = $(am_libclient_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -198,9 +199,9 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = Requests
noinst_LTLIBRARIES = libclient.la
-libclient_la_SOURCES = CommandManager.cpp CommandParser.cpp
+libclient_la_SOURCES = CommandManager.cpp CommandParser.cpp InformationManager.cpp
libclient_la_LIBADD = Requests/librequests.la
-noinst_HEADERS = CommandManager.h CommandParser.h
+noinst_HEADERS = CommandManager.h CommandParser.h InformationManager.h
all: all-recursive
.SUFFIXES:
@@ -254,6 +255,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CommandManager.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CommandParser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InformationManager.Plo@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/src/Client/Requests/CoreStatusRequest.cpp b/src/Client/Requests/CoreStatusRequest.cpp
index 35a63e2..69e3ecf 100644
--- a/src/Client/Requests/CoreStatusRequest.cpp
+++ b/src/Client/Requests/CoreStatusRequest.cpp
@@ -19,7 +19,6 @@
#include "CoreStatusRequest.h"
#include <Net/Connection.h>
-#include <Net/Packets/HostStatusPacket.h>
namespace Mad {
namespace Client {
diff --git a/src/Client/Requests/CoreStatusRequest.h b/src/Client/Requests/CoreStatusRequest.h
index 94aff9c..f57f4bf 100644
--- a/src/Client/Requests/CoreStatusRequest.h
+++ b/src/Client/Requests/CoreStatusRequest.h
@@ -21,15 +21,9 @@
#define MAD_CLIENT_REQUESTS_CORESTATUSREQUEST_H_
#include <Common/Request.h>
+#include <Net/Packets/HostStatusPacket.h>
namespace Mad {
-
-namespace Net {
-namespace Packets {
-class HostStatusPacket;
-}
-}
-
namespace Client {
namespace Requests {
diff --git a/src/Client/Requests/DaemonListRequest.cpp b/src/Client/Requests/DaemonListRequest.cpp
index 279d19c..690aaea 100644
--- a/src/Client/Requests/DaemonListRequest.cpp
+++ b/src/Client/Requests/DaemonListRequest.cpp
@@ -19,7 +19,6 @@
#include "DaemonListRequest.h"
#include <Net/Connection.h>
-#include <Net/Packets/HostListPacket.h>
namespace Mad {
namespace Client {
diff --git a/src/Client/Requests/DaemonListRequest.h b/src/Client/Requests/DaemonListRequest.h
index 625e430..fbf0e70 100644
--- a/src/Client/Requests/DaemonListRequest.h
+++ b/src/Client/Requests/DaemonListRequest.h
@@ -21,15 +21,9 @@
#define MAD_CLIENT_REQUEST_DAEMONLISTREQUEST_H_
#include <Common/Request.h>
+#include <Net/Packets/HostListPacket.h>
namespace Mad {
-
-namespace Net {
-namespace Packets {
-class HostListPacket;
-}
-}
-
namespace Client {
namespace Requests {
diff --git a/src/Client/Requests/DaemonStatusRequest.cpp b/src/Client/Requests/DaemonStatusRequest.cpp
index 9238ed6..94407b4 100644
--- a/src/Client/Requests/DaemonStatusRequest.cpp
+++ b/src/Client/Requests/DaemonStatusRequest.cpp
@@ -20,7 +20,6 @@
#include "DaemonStatusRequest.h"
#include <Net/Connection.h>
#include <Net/Packets/ErrorPacket.h>
-#include <Net/Packets/HostStatusPacket.h>
namespace Mad {
namespace Client {
diff --git a/src/Client/Requests/DaemonStatusRequest.h b/src/Client/Requests/DaemonStatusRequest.h
index cd71dfb..3190ca1 100644
--- a/src/Client/Requests/DaemonStatusRequest.h
+++ b/src/Client/Requests/DaemonStatusRequest.h
@@ -21,17 +21,11 @@
#define MAD_CLIENT_REQUESTS_DAEMONSTATUSREQUEST_H_
#include <Common/Request.h>
+#include <Net/Packets/HostStatusPacket.h>
#include <string>
namespace Mad {
-
-namespace Net {
-namespace Packets {
-class HostStatusPacket;
-}
-}
-
namespace Client {
namespace Requests {
diff --git a/src/Common/HostInfo.h b/src/Common/HostInfo.h
index db7f5d1..c036b5c 100644
--- a/src/Common/HostInfo.h
+++ b/src/Common/HostInfo.h
@@ -27,7 +27,7 @@ namespace Common {
class HostInfo {
public:
- enum Status {
+ enum State {
INACTIVE, RUNNING
};
@@ -35,10 +35,10 @@ class HostInfo {
std::string name;
std::string ip;
- Status status;
+ State state;
public:
- HostInfo(const std::string& name0 = std::string()) : name(name0), status(INACTIVE) {}
+ HostInfo(const std::string& name0 = std::string()) : name(name0), state(INACTIVE) {}
void setName(const std::string &newName) {name = newName;}
const std::string& getName() const {return name;}
@@ -46,8 +46,8 @@ class HostInfo {
void setIP(const std::string& newIp) {ip = newIp;}
const std::string& getIP() const {return ip;}
- void setStatus(Status newStatus) {status = newStatus;}
- Status getStatus() const {return status;}
+ void setState(State newState) {state = newState;}
+ State getState() const {return state;}
};
}
diff --git a/src/Common/RequestManager.cpp b/src/Common/RequestManager.cpp
index afe72b0..8d0c73c 100644
--- a/src/Common/RequestManager.cpp
+++ b/src/Common/RequestManager.cpp
@@ -102,8 +102,10 @@ void RequestManager::receiveHandler(Net::Connection *connection, const Net::Pack
bool RequestManager::sendRequest(Net::Connection *connection, std::auto_ptr<RequestBase> request) {
std::map<Net::Connection*,RequestMap*>::iterator it = requestMaps.find(connection);
- if(it == requestMaps.end())
+ if(it == requestMaps.end()) {
+ Logger::log(Logger::CRITICAL, "Trying to send a request over an unregistered connecion.");
return false;
+ }
RequestMap *requestMap = it->second;
diff --git a/src/Core/ConnectionManager.cpp b/src/Core/ConnectionManager.cpp
index faf6e29..c83f3aa 100644
--- a/src/Core/ConnectionManager.cpp
+++ b/src/Core/ConnectionManager.cpp
@@ -21,6 +21,7 @@
#include "ConfigManager.h"
#include <Common/Logger.h>
#include <Common/RequestHandlers/StatusRequestHandler.h>
+#include "Requests/DaemonStateUpdateRequest.h"
#include "RequestHandlers/DaemonCommandRequestHandler.h"
#include "RequestHandlers/DaemonListRequestHandler.h"
#include "RequestHandlers/DaemonStatusRequestHandler.h"
@@ -64,6 +65,16 @@ void ConnectionManager::refreshPollfds() {
}
}
+void ConnectionManager::updateState(const std::string &name, Common::HostInfo::State state) {
+ daemonInfo[name].setState(state);
+
+ for(std::list<Net::ServerConnection*>::iterator con = clientConnections.begin(); con != clientConnections.end(); ++con) {
+ Common::RequestManager::getRequestManager()->sendRequest(*con, std::auto_ptr<Common::RequestBase>(
+ new Requests::DaemonStateUpdateRequest(name, state)
+ ));
+ }
+}
+
ConnectionManager::ConnectionManager() {
Common::RequestManager::init(true);
@@ -137,7 +148,7 @@ void ConnectionManager::handleConnections(std::list<Net::ServerConnection*>& con
if(idCon->second == *con) {
idCon->second = 0;
- daemonInfo[idCon->first].setStatus(Common::HostInfo::INACTIVE);
+ updateState(idCon->first, Common::HostInfo::INACTIVE);
break;
}
}
@@ -200,7 +211,7 @@ void ConnectionManager::identifyDaemonConnection(Net::Connection *connection, co
}
idCon->second = *con;
- daemonInfo[idCon->first].setStatus(Common::HostInfo::RUNNING);
+ updateState(idCon->first, Common::HostInfo::RUNNING);
connection->setIdentified();
Common::Logger::logf("Identified as '%s'.", name.c_str());
diff --git a/src/Core/ConnectionManager.h b/src/Core/ConnectionManager.h
index 0832b5a..cd470d9 100644
--- a/src/Core/ConnectionManager.h
+++ b/src/Core/ConnectionManager.h
@@ -66,6 +66,8 @@ class ConnectionManager {
void handleConnections(std::list<Net::ServerConnection*> &connections);
+ void updateState(const std::string &name, Common::HostInfo::State state);
+
public:
static ConnectionManager* getConnectionManager() {
return connectionManager.get();
@@ -75,7 +77,7 @@ class ConnectionManager {
connectionManager = std::auto_ptr<ConnectionManager>(new ConnectionManager());
}
- virtual ~ConnectionManager();
+ ~ConnectionManager();
bool wait(int timeout) {
return (poll(pollfds.data(), pollfds.size(), timeout) > 0);
diff --git a/src/Core/Requests/DaemonStateUpdateRequest.cpp b/src/Core/Requests/DaemonStateUpdateRequest.cpp
new file mode 100644
index 0000000..00e0bdf
--- /dev/null
+++ b/src/Core/Requests/DaemonStateUpdateRequest.cpp
@@ -0,0 +1,43 @@
+/*
+ * DaemonStateUpdateRequest.cpp
+ *
+ * Copyright (C) 2008 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "DaemonStateUpdateRequest.h"
+#include <Net/Connection.h>
+#include <Net/Packets/HostStatePacket.h>
+
+namespace Mad {
+namespace Core {
+namespace Requests {
+
+void DaemonStateUpdateRequest::sendRequest(Net::Connection *connection, uint16_t requestId) {
+ connection->send(Net::Packets::HostStatePacket(Net::Packet::DAEMON_STATE_UPDATE, requestId, name, state));
+}
+
+void DaemonStateUpdateRequest::handlePacket(Net::Connection*, const Net::Packet &packet) {
+ if(packet.getType() != Net::Packet::OK) {
+ finishWithError(Common::Exception(Common::Exception::UNEXPECTED_PACKET));
+ return; // TODO Logging
+ }
+
+ finish();
+}
+
+}
+}
+}
diff --git a/src/Core/Requests/DaemonStateUpdateRequest.h b/src/Core/Requests/DaemonStateUpdateRequest.h
new file mode 100644
index 0000000..9a1c8f0
--- /dev/null
+++ b/src/Core/Requests/DaemonStateUpdateRequest.h
@@ -0,0 +1,47 @@
+/*
+ * DaemonStateUpdateRequest.h
+ *
+ * Copyright (C) 2008 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAD_CORE_REQUESTS_DAEMONSTATEUPDATEREQUEST_H_
+#define MAD_CORE_REQUESTS_DAEMONSTATEUPDATEREQUEST_H_
+
+#include <Common/Request.h>
+#include <Common/HostInfo.h>
+
+namespace Mad {
+namespace Core {
+namespace Requests {
+
+class DaemonStateUpdateRequest : public Common::Request<> {
+ private:
+ std::string name;
+ Common::HostInfo::State state;
+
+ protected:
+ virtual void sendRequest(Net::Connection *connection, uint16_t requestId);
+ virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet);
+
+ public:
+ DaemonStateUpdateRequest(const std::string &name0, Common::HostInfo::State state0) : Common::Request<>(slot_type()), name(name0), state(state0) {}
+};
+
+}
+}
+}
+
+#endif /* MAD_CORE_REQUESTS_DAEMONSTATEUPDATEREQUEST_H_ */
diff --git a/src/Core/Requests/DaemonStatusRequest.cpp b/src/Core/Requests/DaemonStatusRequest.cpp
index 1741731..3b028c9 100644
--- a/src/Core/Requests/DaemonStatusRequest.cpp
+++ b/src/Core/Requests/DaemonStatusRequest.cpp
@@ -19,7 +19,6 @@
#include "DaemonStatusRequest.h"
#include <Common/RequestManager.h>
-#include <Net/Packets/HostStatusPacket.h>
namespace Mad {
namespace Core {
diff --git a/src/Core/Requests/DaemonStatusRequest.h b/src/Core/Requests/DaemonStatusRequest.h
index baeb847..09cbc2b 100644
--- a/src/Core/Requests/DaemonStatusRequest.h
+++ b/src/Core/Requests/DaemonStatusRequest.h
@@ -21,15 +21,9 @@
#define MAD_CORE_REQUESTS_DAEMONSTATUSREQUEST_H_
#include <Common/Request.h>
+#include <Net/Packets/HostStatusPacket.h>
namespace Mad {
-
-namespace Net {
-namespace Packets {
-class HostStatusPacket;
-}
-}
-
namespace Core {
namespace Requests {
diff --git a/src/Core/Requests/Makefile.am b/src/Core/Requests/Makefile.am
index 2d08477..e69088b 100644
--- a/src/Core/Requests/Makefile.am
+++ b/src/Core/Requests/Makefile.am
@@ -1,4 +1,4 @@
noinst_LTLIBRARIES = librequests.la
-librequests_la_SOURCES = CommandRequest.cpp DaemonStatusRequest.cpp
+librequests_la_SOURCES = CommandRequest.cpp DaemonStateUpdateRequest.cpp DaemonStatusRequest.cpp
-noinst_HEADERS = CommandRequest.h DaemonStatusRequest.h
+noinst_HEADERS = CommandRequest.h DaemonStateUpdateRequest.h DaemonStatusRequest.h
diff --git a/src/Core/Requests/Makefile.in b/src/Core/Requests/Makefile.in
index 22ac701..e6367a2 100644
--- a/src/Core/Requests/Makefile.in
+++ b/src/Core/Requests/Makefile.in
@@ -48,7 +48,8 @@ CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
librequests_la_LIBADD =
-am_librequests_la_OBJECTS = CommandRequest.lo DaemonStatusRequest.lo
+am_librequests_la_OBJECTS = CommandRequest.lo \
+ DaemonStateUpdateRequest.lo DaemonStatusRequest.lo
librequests_la_OBJECTS = $(am_librequests_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -187,8 +188,8 @@ target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
noinst_LTLIBRARIES = librequests.la
-librequests_la_SOURCES = CommandRequest.cpp DaemonStatusRequest.cpp
-noinst_HEADERS = CommandRequest.h DaemonStatusRequest.h
+librequests_la_SOURCES = CommandRequest.cpp DaemonStateUpdateRequest.cpp DaemonStatusRequest.cpp
+noinst_HEADERS = CommandRequest.h DaemonStateUpdateRequest.h DaemonStatusRequest.h
all: all-am
.SUFFIXES:
@@ -241,6 +242,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CommandRequest.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DaemonStateUpdateRequest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DaemonStatusRequest.Plo@am__quote@
.cpp.o:
diff --git a/src/Net/Packet.h b/src/Net/Packet.h
index a3fe524..366746b 100644
--- a/src/Net/Packet.h
+++ b/src/Net/Packet.h
@@ -36,7 +36,8 @@ class Packet {
LIST_DAEMONS = 0x0020,
STATUS = 0x0030, DAEMON_STATUS = 0x0031,
COMMAND_SHUTDOWN = 0x0040, COMMAND_REBOOT = 0x0041,
- DAEMON_COMMAND_SHUTDOWN = 0x0050, DAEMON_COMMAND_REBOOT = 0x0051
+ DAEMON_COMMAND_SHUTDOWN = 0x0050, DAEMON_COMMAND_REBOOT = 0x0051,
+ DAEMON_STATE_UPDATE = 0x0060
};
struct Data {
diff --git a/src/Net/Packets/HostListPacket.cpp b/src/Net/Packets/HostListPacket.cpp
index 30a33b3..8c3d395 100644
--- a/src/Net/Packets/HostListPacket.cpp
+++ b/src/Net/Packets/HostListPacket.cpp
@@ -46,7 +46,7 @@ void HostListPacket::assemblePacket() {
*nHosts = htons(hostList.size());
for(size_t i = 0; i < hostList.size(); ++i) {
- hostData[i].status = htons((uint16_t)hostList[i].getStatus());
+ hostData[i].state = htons((uint16_t)hostList[i].getState());
}
}
@@ -69,7 +69,7 @@ void HostListPacket::parsePacket() {
std::istringstream stream(std::string(charData, getLength() - (sizeof(uint16_t)+sizeof(HostData)*hostList.size())));
for(size_t i = 0; i < hostList.size(); ++i) {
- hostList[i].setStatus((Common::HostInfo::Status)ntohs(hostData[i].status));
+ hostList[i].setState((Common::HostInfo::State)ntohs(hostData[i].state));
if(!stream.eof()) {
std::string str;
diff --git a/src/Net/Packets/HostListPacket.h b/src/Net/Packets/HostListPacket.h
index 4d0b2d0..2cec9b0 100644
--- a/src/Net/Packets/HostListPacket.h
+++ b/src/Net/Packets/HostListPacket.h
@@ -33,7 +33,7 @@ namespace Packets {
class HostListPacket : public Packet {
protected:
struct HostData {
- uint16_t status;
+ uint16_t state;
};
uint16_t *nHosts;
diff --git a/src/Net/Packets/HostStatePacket.cpp b/src/Net/Packets/HostStatePacket.cpp
new file mode 100644
index 0000000..d34d9d5
--- /dev/null
+++ b/src/Net/Packets/HostStatePacket.cpp
@@ -0,0 +1,50 @@
+/*
+ * HostStatePacket.cpp
+ *
+ * Copyright (C) 2008 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "HostStatePacket.h"
+
+namespace Mad {
+namespace Net {
+namespace Packets {
+
+HostStatePacket::HostStatePacket(Type type, uint16_t requestId, const std::string &name, Common::HostInfo::State state)
+: Packet(type, requestId)
+{
+ setLength(sizeof(HostStateData) + name.length());
+ hostStateData = (HostStateData*)&rawData->data;
+
+ hostStateData->state = htons(state);
+
+ std::memcpy(hostStateData->name, name.c_str(), name.length());
+}
+
+HostStatePacket& HostStatePacket::operator=(const Packet &p) {
+ Packet::operator=(p);
+
+ if(getLength() < sizeof(HostStateData))
+ setLength(sizeof(HostStateData));
+
+ hostStateData = (HostStateData*)&rawData->data;
+
+ return *this;
+}
+
+}
+}
+}
diff --git a/src/Net/Packets/HostStatePacket.h b/src/Net/Packets/HostStatePacket.h
new file mode 100644
index 0000000..5a34275
--- /dev/null
+++ b/src/Net/Packets/HostStatePacket.h
@@ -0,0 +1,74 @@
+/*
+ * HostStatePacket.h
+ *
+ * Copyright (C) 2008 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAD_NET_PACKETS_HOSTSTATEPACKET_H_
+#define MAD_NET_PACKETS_HOSTSTATEPACKET_H_
+
+#include "../Packet.h"
+#include <Common/HostInfo.h>
+
+#include <string>
+
+namespace Mad {
+namespace Net {
+namespace Packets {
+
+class HostStatePacket : public Packet {
+ protected:
+ struct HostStateData {
+ uint16_t state;
+ uint8_t name[0];
+ };
+
+ HostStateData *hostStateData;
+
+ public:
+ HostStatePacket(Type type, uint16_t requestId, const std::string &name, Common::HostInfo::State state);
+
+ HostStatePacket(const Packet &p) : Packet(p) {
+ if(getLength() < sizeof(HostStateData))
+ setLength(sizeof(HostStateData));
+
+ hostStateData = (HostStateData*)&rawData->data;
+ }
+
+ HostStatePacket(const HostStatePacket &p) : Packet(p) {
+ hostStateData = (HostStateData*)&rawData->data;
+ }
+
+ HostStatePacket& operator=(const Packet &p);
+
+ HostStatePacket& operator=(const HostStatePacket &p) {
+ return (*this = (Packet)p);
+ }
+
+ std::string getName() const {
+ return std::string((char*)hostStateData->name, getLength()-sizeof(HostStateData));
+ }
+
+ Common::HostInfo::State getState() const {
+ return (Common::HostInfo::State)ntohs(hostStateData->state);
+ }
+};
+
+}
+}
+}
+
+#endif /* MAD_NET_PACKETS_HOSTSTATEPACKET_H_ */
diff --git a/src/Net/Packets/Makefile.am b/src/Net/Packets/Makefile.am
index 0b44f6d..19dcc7c 100644
--- a/src/Net/Packets/Makefile.am
+++ b/src/Net/Packets/Makefile.am
@@ -1,4 +1,4 @@
noinst_LTLIBRARIES = libpackets.la
-libpackets_la_SOURCES = ErrorPacket.cpp HostListPacket.cpp HostStatusPacket.cpp LogPacket.cpp
+libpackets_la_SOURCES = ErrorPacket.cpp HostListPacket.cpp HostStatePacket.cpp HostStatusPacket.cpp LogPacket.cpp
-noinst_HEADERS = ErrorPacket.h HostListPacket.h HostStatusPacket.h LogPacket.h
+noinst_HEADERS = ErrorPacket.h HostListPacket.h HostStatePacket.h HostStatusPacket.h LogPacket.h
diff --git a/src/Net/Packets/Makefile.in b/src/Net/Packets/Makefile.in
index 9109103..b500da6 100644
--- a/src/Net/Packets/Makefile.in
+++ b/src/Net/Packets/Makefile.in
@@ -49,7 +49,7 @@ CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libpackets_la_LIBADD =
am_libpackets_la_OBJECTS = ErrorPacket.lo HostListPacket.lo \
- HostStatusPacket.lo LogPacket.lo
+ HostStatePacket.lo HostStatusPacket.lo LogPacket.lo
libpackets_la_OBJECTS = $(am_libpackets_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -188,8 +188,8 @@ target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
noinst_LTLIBRARIES = libpackets.la
-libpackets_la_SOURCES = ErrorPacket.cpp HostListPacket.cpp HostStatusPacket.cpp LogPacket.cpp
-noinst_HEADERS = ErrorPacket.h HostListPacket.h HostStatusPacket.h LogPacket.h
+libpackets_la_SOURCES = ErrorPacket.cpp HostListPacket.cpp HostStatePacket.cpp HostStatusPacket.cpp LogPacket.cpp
+noinst_HEADERS = ErrorPacket.h HostListPacket.h HostStatePacket.h HostStatusPacket.h LogPacket.h
all: all-am
.SUFFIXES:
@@ -243,6 +243,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ErrorPacket.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HostListPacket.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HostStatePacket.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HostStatusPacket.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogPacket.Plo@am__quote@
diff --git a/src/madc.cpp b/src/madc.cpp
index b109448..a2c7fda 100644
--- a/src/madc.cpp
+++ b/src/madc.cpp
@@ -24,6 +24,7 @@
#include "Common/RequestManager.h"
#include "Common/Util.h"
#include "Client/CommandParser.h"
+#include "Client/InformationManager.h"
#include <iostream>
#include <cstring>
@@ -94,10 +95,23 @@ int main(int argc, char *argv[]) {
connection->sendReceive(fd.revents);
}
- std::cerr << " connected." << std::endl << std::endl;
+ std::cerr << " connected." << std::endl;
Common::RequestManager::getRequestManager()->registerConnection(connection);
+ std::cerr << "Receiving host list..." << std::flush;
+
+ Client::InformationManager::init(connection);
+
+ while(!Client::InformationManager::getInformationManager()->isInitialised()) {
+ struct pollfd fd = connection->getPollfd();
+
+ if(poll(&fd, 1, 10000) > 0)
+ connection->sendReceive(fd.revents);
+ }
+
+ std::cerr << " done." << std::endl << std::endl;
+
parser = new Mad::Client::CommandParser(connection);
parser->signalFinished().connect(sigc::ptr_fun(activateReadline));