diff options
Diffstat (limited to 'src')
32 files changed, 285 insertions, 297 deletions
diff --git a/src/Client/CommandParser.cpp b/src/Client/CommandParser.cpp index 3cb5749..407b9c8 100644 --- a/src/Client/CommandParser.cpp +++ b/src/Client/CommandParser.cpp @@ -22,6 +22,7 @@ #include "Requests/DaemonListRequest.h" #include "Requests/DaemonStatusRequest.h" #include <Common/Exception.h> +#include <Common/RequestManager.h> #include <Common/Requests/DisconnectRequest.h> #include <Net/Packets/HostStatusPacket.h> #include <Net/Packets/NameListPacket.h> @@ -144,14 +145,14 @@ void CommandParser::helpCommand(const std::vector<std::string> &args) { void CommandParser::listHostsCommand(const std::vector<std::string>&) { activeRequests++; - Requests::DaemonListRequest::send(connection, sigc::mem_fun(this, &CommandParser::daemonListRequestFinished)); + Common::RequestManager::getRequestManager()->sendRequest(connection, std::auto_ptr<Common::RequestBase>(new Requests::DaemonListRequest(sigc::mem_fun(this, &CommandParser::daemonListRequestFinished)))); } void CommandParser::statusCommand(const std::vector<std::string> &args) { if(args.size() == 1) - Requests::CoreStatusRequest::send(connection, sigc::mem_fun(this, &CommandParser::coreStatusRequestFinished)); + Common::RequestManager::getRequestManager()->sendRequest(connection, std::auto_ptr<Common::RequestBase>(new Requests::CoreStatusRequest(sigc::mem_fun(this, &CommandParser::coreStatusRequestFinished)))); else if(args.size() == 2) - Requests::DaemonStatusRequest::send(connection, sigc::mem_fun(this, &CommandParser::daemonStatusRequestFinished), sigc::mem_fun(this, &CommandParser::errorCallback), args[1]); + Common::RequestManager::getRequestManager()->sendRequest(connection, std::auto_ptr<Common::RequestBase>(new Requests::DaemonStatusRequest(args[1], sigc::mem_fun(this, &CommandParser::daemonStatusRequestFinished)))); else { std::cerr << args[0] << ": Too many arguments." << std::endl; printUsage("status"); @@ -163,47 +164,67 @@ void CommandParser::statusCommand(const std::vector<std::string> &args) { void CommandParser::exitCommand(const std::vector<std::string>&) { activeRequests++; - disconnect = true; - Common::Requests::DisconnectRequest::send(connection, sigc::mem_fun(this, &CommandParser::requestFinished)); + Common::RequestManager::getRequestManager()->sendRequest(connection, std::auto_ptr<Common::RequestBase>(new Common::Requests::DisconnectRequest(sigc::mem_fun(this, &CommandParser::disconnectRequestFinished)))); } -void CommandParser::coreStatusRequestFinished(const Net::Packets::HostStatusPacket &packet) { - std::cout << "Server status:" << std::endl; - - printHostStatus(packet); +void CommandParser::coreStatusRequestFinished(const Common::Request<Net::Packets::HostStatusPacket> &request) { + try { + const Net::Packets::HostStatusPacket &packet = request.getResult(); + std::cout << "Server status:" << std::endl; + printHostStatus(packet); + } + catch(Common::Exception &exception) { + std::cerr << "An error occurred during your request: " << exception.strerror() << "." << std::endl << std::endl; + } requestFinished(); } -void CommandParser::daemonListRequestFinished(const Net::Packets::NameListPacket &packet) { - const std::vector<std::string>& hosts = packet.getNameList(); +void CommandParser::daemonListRequestFinished(const Common::Request<Net::Packets::NameListPacket> &request) { + try { + const std::vector<std::string>& hosts = request.getResult().getNameList(); - if(hosts.empty()) { - std::cout << "There aren't any active hosts." << std::endl << std::endl; - } - else { - std::cout << "Active hosts:" << std::endl; + if(hosts.empty()) { + std::cout << "There aren't any active hosts." << std::endl << std::endl; + } + else { + std::cout << "Active hosts:" << std::endl; - for(std::vector<std::string>::const_iterator host = hosts.begin(); host != hosts.end(); ++host) - std::cout << "\t" << *host << std::endl; + for(std::vector<std::string>::const_iterator host = hosts.begin(); host != hosts.end(); ++host) + std::cout << "\t" << *host << std::endl; - std::cout << std::endl; + std::cout << std::endl; + } + } + catch(Common::Exception &exception) { + std::cerr << "An error occurred during your request: " << exception.strerror() << "." << std::endl << std::endl; } requestFinished(); } -void CommandParser::daemonStatusRequestFinished(const Net::Packets::HostStatusPacket &packet) { - std::cout << "Host status:" << std::endl; - - printHostStatus(packet); +void CommandParser::daemonStatusRequestFinished(const Common::Request<Net::Packets::HostStatusPacket> &request) { + try { + const Net::Packets::HostStatusPacket &packet = request.getResult(); + std::cout << "Host status:" << std::endl; + printHostStatus(packet); + } + catch(Common::Exception &exception) { + std::cerr << "An error occurred during your request: " << exception.strerror() << "." << std::endl << std::endl; + } requestFinished(); } -void CommandParser::errorCallback(const Common::Exception &exception) { - std::cerr << "An error occurred during your request: " << exception.strerror() << "." << std::endl << std::endl; +void CommandParser::disconnectRequestFinished(const Common::Request<> &request) { + try { + request.getResult(); + disconnect = true; + } + catch(Common::Exception &exception) { + std::cerr << "An error occurred during your request: " << exception.strerror() << "." << std::endl << std::endl; + } requestFinished(); } diff --git a/src/Client/CommandParser.h b/src/Client/CommandParser.h index 08b21a1..4137cb3 100644 --- a/src/Client/CommandParser.h +++ b/src/Client/CommandParser.h @@ -20,7 +20,8 @@ #ifndef MAD_CLIENT_COMMANDPARSER_H_ #define MAD_CLIENT_COMMANDPARSER_H_ -#include <sigc++/signal.h> +#include <Common/Request.h> + #include <string> #include <vector> @@ -74,11 +75,10 @@ class CommandParser { void statusCommand(const std::vector<std::string> &args); void exitCommand(const std::vector<std::string>&); - void coreStatusRequestFinished(const Net::Packets::HostStatusPacket &packet); - void daemonListRequestFinished(const Net::Packets::NameListPacket &packet); - void daemonStatusRequestFinished(const Net::Packets::HostStatusPacket &packet); - - void errorCallback(const Common::Exception &exception); + void coreStatusRequestFinished(const Common::Request<Net::Packets::HostStatusPacket> &request); + void daemonListRequestFinished(const Common::Request<Net::Packets::NameListPacket> &request); + void daemonStatusRequestFinished(const Common::Request<Net::Packets::HostStatusPacket> &request); + void disconnectRequestFinished(const Common::Request<> &request); void requestFinished() { activeRequests--; diff --git a/src/Client/Requests/CoreStatusRequest.cpp b/src/Client/Requests/CoreStatusRequest.cpp index 93552f6..35a63e2 100644 --- a/src/Client/Requests/CoreStatusRequest.cpp +++ b/src/Client/Requests/CoreStatusRequest.cpp @@ -18,41 +18,24 @@ */ #include "CoreStatusRequest.h" -#include <Common/RequestManager.h> +#include <Net/Connection.h> #include <Net/Packets/HostStatusPacket.h> namespace Mad { namespace Client { namespace Requests { -bool CoreStatusRequest::send(Net::Connection *connection, const sigc::slot<void,const Net::Packets::HostStatusPacket&> &callback) { - CoreStatusRequest *request = new CoreStatusRequest(); - - request->finished.connect(callback); - - if(Mad::Common::RequestManager::getRequestManager()->sendRequest(connection, request)) - return true; - - delete request; - return false; -} - -bool CoreStatusRequest::sendRequest(Net::Connection *connection, uint16_t requestId) { - if(!connection->send(Net::Packet(Net::Packet::STATUS, requestId))) - return false; - - return true; +void CoreStatusRequest::sendRequest(Net::Connection *connection, uint16_t requestId) { + connection->send(Net::Packet(Net::Packet::STATUS, requestId)); } void CoreStatusRequest::handlePacket(Net::Connection*, const Net::Packet &packet) { if(packet.getType() != Net::Packet::OK) { - signalFinished().emit(); + finishWithError(Common::Exception(Common::Exception::UNEXPECTED_PACKET)); return; // TODO Logging } - finished(Net::Packets::HostStatusPacket(packet)); - - signalFinished().emit(); + finish(Net::Packets::HostStatusPacket(packet)); } } diff --git a/src/Client/Requests/CoreStatusRequest.h b/src/Client/Requests/CoreStatusRequest.h index ff9bdc1..94aff9c 100644 --- a/src/Client/Requests/CoreStatusRequest.h +++ b/src/Client/Requests/CoreStatusRequest.h @@ -22,8 +22,6 @@ #include <Common/Request.h> -#include <sigc++/signal.h> - namespace Mad { namespace Net { @@ -35,17 +33,13 @@ class HostStatusPacket; namespace Client { namespace Requests { -class CoreStatusRequest : public Common::Request { - private: - sigc::signal<void,const Net::Packets::HostStatusPacket&> finished; - - CoreStatusRequest() {} +class CoreStatusRequest : public Common::Request<Net::Packets::HostStatusPacket> { + protected: + virtual void sendRequest(Net::Connection *connection, uint16_t requestId); + virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); public: - static bool send(Net::Connection *connection, const sigc::slot<void,const Net::Packets::HostStatusPacket&> &callback); - - virtual bool sendRequest(Net::Connection *connection, uint16_t requestId); - virtual void handlePacket(Net::Connection*, const Net::Packet &packet); + CoreStatusRequest(slot_type slot) : Common::Request<Net::Packets::HostStatusPacket>(slot) {} }; } diff --git a/src/Client/Requests/DaemonListRequest.cpp b/src/Client/Requests/DaemonListRequest.cpp index cc6d353..2c2e195 100644 --- a/src/Client/Requests/DaemonListRequest.cpp +++ b/src/Client/Requests/DaemonListRequest.cpp @@ -18,41 +18,24 @@ */ #include "DaemonListRequest.h" -#include <Common/RequestManager.h> +#include <Net/Connection.h> #include <Net/Packets/NameListPacket.h> namespace Mad { namespace Client { namespace Requests { -bool DaemonListRequest::send(Net::Connection *connection, const sigc::slot<void,const Net::Packets::NameListPacket&> &callback) { - DaemonListRequest *request = new DaemonListRequest(); - - request->finished.connect(callback); - - if(Mad::Common::RequestManager::getRequestManager()->sendRequest(connection, request)) - return true; - - delete request; - return false; -} - -bool DaemonListRequest::sendRequest(Net::Connection *connection, uint16_t requestId) { - if(!connection->send(Net::Packet(Net::Packet::LIST_DAEMONS, requestId))) - return false; - - return true; +void DaemonListRequest::sendRequest(Net::Connection *connection, uint16_t requestId) { + connection->send(Net::Packet(Net::Packet::LIST_DAEMONS, requestId)); } void DaemonListRequest::handlePacket(Net::Connection*, const Net::Packet &packet) { if(packet.getType() != Net::Packet::OK) { - signalFinished().emit(); + finishWithError(Common::Exception(Common::Exception::UNEXPECTED_PACKET)); return; // TODO Logging } - finished(Net::Packets::NameListPacket(packet)); - - signalFinished().emit(); + finish(Net::Packets::NameListPacket(packet)); } } diff --git a/src/Client/Requests/DaemonListRequest.h b/src/Client/Requests/DaemonListRequest.h index 9a11d19..5c57502 100644 --- a/src/Client/Requests/DaemonListRequest.h +++ b/src/Client/Requests/DaemonListRequest.h @@ -22,8 +22,6 @@ #include <Common/Request.h> -#include <sigc++/signal.h> - namespace Mad { namespace Net { @@ -35,17 +33,13 @@ class NameListPacket; namespace Client { namespace Requests { -class DaemonListRequest : public Common::Request { - private: - sigc::signal<void,const Net::Packets::NameListPacket&> finished; - - DaemonListRequest() {} - - public: - static bool send(Net::Connection *connection, const sigc::slot<void,const Net::Packets::NameListPacket&> &callback); +class DaemonListRequest : public Common::Request<Net::Packets::NameListPacket> { + protected: + virtual void sendRequest(Net::Connection *connection, uint16_t requestId); + virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); - virtual bool sendRequest(Net::Connection *connection, uint16_t requestId); - virtual void handlePacket(Net::Connection*, const Net::Packet &packet); + public: + DaemonListRequest(slot_type slot) : Common::Request<Net::Packets::NameListPacket>(slot) {} }; } diff --git a/src/Client/Requests/DaemonStatusRequest.cpp b/src/Client/Requests/DaemonStatusRequest.cpp index 719ae5c..9238ed6 100644 --- a/src/Client/Requests/DaemonStatusRequest.cpp +++ b/src/Client/Requests/DaemonStatusRequest.cpp @@ -18,7 +18,7 @@ */ #include "DaemonStatusRequest.h" -#include <Common/RequestManager.h> +#include <Net/Connection.h> #include <Net/Packets/ErrorPacket.h> #include <Net/Packets/HostStatusPacket.h> @@ -26,42 +26,21 @@ namespace Mad { namespace Client { namespace Requests { -bool DaemonStatusRequest::send(Net::Connection *connection, const sigc::slot<void,const Net::Packets::HostStatusPacket&> &callback, - const sigc::slot<void,const Common::Exception&> &errorCallback, const std::string &daemon0) -{ - DaemonStatusRequest *request = new DaemonStatusRequest(daemon0); - - request->finished.connect(callback); - request->error.connect(errorCallback); - - if(Mad::Common::RequestManager::getRequestManager()->sendRequest(connection, request)) - return true; - - delete request; - return false; -} - -bool DaemonStatusRequest::sendRequest(Net::Connection *connection, uint16_t requestId) { - if(!connection->send(Net::Packet(Net::Packet::DAEMON_STATUS, requestId, daemon.c_str(), daemon.length()))) - return false; - - return true; +void DaemonStatusRequest::sendRequest(Net::Connection *connection, uint16_t requestId) { + connection->send(Net::Packet(Net::Packet::DAEMON_STATUS, requestId, daemon.c_str(), daemon.length())); } void DaemonStatusRequest::handlePacket(Net::Connection*, const Net::Packet &packet) { if(packet.getType() == Net::Packet::ERROR) { - error(Net::Packets::ErrorPacket(packet).getException()); - signalFinished().emit(); + finishWithError(Net::Packets::ErrorPacket(packet).getException()); return; } else if(packet.getType() != Net::Packet::OK) { - signalFinished().emit(); + finishWithError(Common::Exception(Common::Exception::UNEXPECTED_PACKET)); return; // TODO Logging } - finished(Net::Packets::HostStatusPacket(packet)); - - signalFinished().emit(); + finish(Net::Packets::HostStatusPacket(packet)); } } diff --git a/src/Client/Requests/DaemonStatusRequest.h b/src/Client/Requests/DaemonStatusRequest.h index f5c130d..8f74ca4 100644 --- a/src/Client/Requests/DaemonStatusRequest.h +++ b/src/Client/Requests/DaemonStatusRequest.h @@ -23,7 +23,6 @@ #include <Common/Request.h> #include <string> -#include <sigc++/signal.h> namespace Mad { @@ -40,21 +39,16 @@ class HostStatusPacket; namespace Client { namespace Requests { -class DaemonStatusRequest : public Common::Request { +class DaemonStatusRequest : public Common::Request<Net::Packets::HostStatusPacket> { private: - sigc::signal<void,const Net::Packets::HostStatusPacket&> finished; - sigc::signal<void,const Common::Exception&> error; - std::string daemon; - DaemonStatusRequest(const std::string &daemon0) : daemon(daemon0) {} + protected: + virtual void sendRequest(Net::Connection *connection, uint16_t requestId); + virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); public: - static bool send(Net::Connection *connection, const sigc::slot<void,const Net::Packets::HostStatusPacket&> &callback, - const sigc::slot<void,const Common::Exception&> &errorCallback, const std::string &daemon0); - - virtual bool sendRequest(Net::Connection *connection, uint16_t requestId); - virtual void handlePacket(Net::Connection*, const Net::Packet &packet); + DaemonStatusRequest(const std::string &daemon0, slot_type slot) : Common::Request<Net::Packets::HostStatusPacket>(slot), daemon(daemon0) {} }; } diff --git a/src/Common/Exception.h b/src/Common/Exception.h index d072db2..25bc56c 100644 --- a/src/Common/Exception.h +++ b/src/Common/Exception.h @@ -27,7 +27,8 @@ class Exception { public: enum ErrorCode { SUCCESS = 0x0000, UNEXPECTED_PACKET = 0x0001, INVALID_ACTION = 0x0002, - ALREADY_IDENTIFIED = 0x0010, UNKNOWN_DAEMON = 0x0011, DAEMON_INACTIVE = 0x0012 + NOT_FINISHED = 0x0010, + ALREADY_IDENTIFIED = 0x0020, UNKNOWN_DAEMON = 0x0021, DAEMON_INACTIVE = 0x0022 }; private: diff --git a/src/Common/Makefile.am b/src/Common/Makefile.am index d0c246c..80f01ba 100644 --- a/src/Common/Makefile.am +++ b/src/Common/Makefile.am @@ -4,4 +4,4 @@ noinst_LTLIBRARIES = libcommon.la libcommon_la_SOURCES = ConfigManager.cpp Exception.cpp RequestManager.cpp SystemBackend.cpp Util.cpp libcommon_la_LIBADD = Backends/libbackends.la Requests/librequests.la RequestHandlers/librequesthandlers.la -noinst_HEADERS = ConfigManager.h Exception.h Request.h RequestHandler.h RequestManager.h SystemBackend.h Util.h +noinst_HEADERS = ConfigManager.h Exception.h Request.h RequestBase.h RequestHandler.h RequestManager.h SystemBackend.h Util.h diff --git a/src/Common/Makefile.in b/src/Common/Makefile.in index 7c6eca2..7c2408e 100644 --- a/src/Common/Makefile.in +++ b/src/Common/Makefile.in @@ -201,7 +201,7 @@ SUBDIRS = Backends Requests RequestHandlers noinst_LTLIBRARIES = libcommon.la libcommon_la_SOURCES = ConfigManager.cpp Exception.cpp RequestManager.cpp SystemBackend.cpp Util.cpp libcommon_la_LIBADD = Backends/libbackends.la Requests/librequests.la RequestHandlers/librequesthandlers.la -noinst_HEADERS = ConfigManager.h Exception.h Request.h RequestHandler.h RequestManager.h SystemBackend.h Util.h +noinst_HEADERS = ConfigManager.h Exception.h Request.h RequestBase.h RequestHandler.h RequestManager.h SystemBackend.h Util.h all: all-recursive .SUFFIXES: diff --git a/src/Common/Request.h b/src/Common/Request.h index 3d4be63..fa6b619 100644 --- a/src/Common/Request.h +++ b/src/Common/Request.h @@ -20,15 +20,68 @@ #ifndef MAD_COMMON_REQUEST_H_ #define MAD_COMMON_REQUEST_H_ -#include "RequestHandler.h" -#include <stdint.h> +#include "RequestBase.h" +#include "Exception.h" + +#include <memory> +#include <sigc++/hide.h> namespace Mad { namespace Common { -class Request : public RequestHandler { +template<typename T = void> class Request : public RequestBase { + private: + sigc::signal<void,const Request<T>&> finished; + + std::auto_ptr<T> res; + Exception exp; + + protected: + typedef sigc::slot<void,const Request<T>&> slot_type; + + Request(slot_type slot) : exp(Exception::NOT_FINISHED) { + finished.connect(slot); + finished.connect(sigc::hide(signalFinished().make_slot())); + } + + void finish(std::auto_ptr<T> result) {res = result; finished(*this);} + void finish(const T& result) {res.reset(new T(result)); finished(*this);} + void finishWithError(const Exception &e) {exp = e; finished(*this);} + + public: + const T& getResult() const throw(Exception) { + if(res.get()) + return *res; + + throw exp; + } +}; + +template<> class Request<void> : public RequestBase { + private: + sigc::signal<void,const Request<void>&> finished; + + bool isFinished; + Exception exp; + + protected: + typedef sigc::slot<void,const Request<void>&> slot_type; + + Request(slot_type slot) : isFinished(false), exp(Exception::NOT_FINISHED) { + finished.connect(slot); + finished.connect(sigc::hide(signalFinished().make_slot())); + } + + void finish() {isFinished = true; finished(*this);} + void finishWithError(const Exception &e) {exp = e; finished(*this);} + public: - virtual bool sendRequest(Net::Connection *connection, uint16_t requestId) = 0; + void getResult() const throw(Exception) { + if(isFinished) + return; + + throw exp; + } }; } diff --git a/src/Common/RequestBase.h b/src/Common/RequestBase.h new file mode 100644 index 0000000..535f6d0 --- /dev/null +++ b/src/Common/RequestBase.h @@ -0,0 +1,39 @@ +/* + * RequestBase.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_COMMON_REQUESTBASE_H_ +#define MAD_COMMON_REQUESTBASE_H_ + +#include "RequestHandler.h" +#include <stdint.h> + +namespace Mad { +namespace Common { + +class RequestBase : public RequestHandler { + protected: + virtual void sendRequest(Net::Connection *connection, uint16_t requestId) = 0; + + friend class RequestManager; +}; + +} +} + +#endif /* MAD_COMMON_REQUESTBASE_H_ */ diff --git a/src/Common/RequestHandler.h b/src/Common/RequestHandler.h index 2bc2361..434f969 100644 --- a/src/Common/RequestHandler.h +++ b/src/Common/RequestHandler.h @@ -37,15 +37,21 @@ class RequestHandler { private: sigc::signal<void> finished; + // Prevent shallow copy + RequestHandler(const RequestHandler &o); + RequestHandler& operator=(const RequestHandler &o); + protected: RequestHandler() {} - public: - virtual ~RequestHandler() {} - sigc::signal<void> signalFinished() {return finished;} virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet) = 0; + + public: + virtual ~RequestHandler() {} + + friend class RequestManager; }; } diff --git a/src/Common/RequestHandlers/DisconnectRequestHandler.h b/src/Common/RequestHandlers/DisconnectRequestHandler.h index b4da634..f0ca85f 100644 --- a/src/Common/RequestHandlers/DisconnectRequestHandler.h +++ b/src/Common/RequestHandlers/DisconnectRequestHandler.h @@ -27,10 +27,11 @@ namespace Common { namespace RequestHandlers { class DisconnectRequestHandler : public RequestHandler { + protected: + virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); + public: DisconnectRequestHandler() {} - - virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); }; } diff --git a/src/Common/RequestHandlers/StatusRequestHandler.h b/src/Common/RequestHandlers/StatusRequestHandler.h index f98a9a4..c5dcbf7 100644 --- a/src/Common/RequestHandlers/StatusRequestHandler.h +++ b/src/Common/RequestHandlers/StatusRequestHandler.h @@ -27,10 +27,11 @@ namespace Common { namespace RequestHandlers { class StatusRequestHandler : public RequestHandler { + protected: + virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); + public: StatusRequestHandler() {} - - virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); }; } diff --git a/src/Common/RequestManager.cpp b/src/Common/RequestManager.cpp index 5d3fdcd..2bf82b0 100644 --- a/src/Common/RequestManager.cpp +++ b/src/Common/RequestManager.cpp @@ -33,6 +33,11 @@ namespace Common { std::auto_ptr<RequestManager> RequestManager::requestManager; +RequestManager::RequestMap::~RequestMap() { + for(iterator it = begin(); it != end(); ++it) + delete it->second; +} + bool RequestManager::RequestMap::addRequest(uint16_t id, RequestHandler *info) { if(!insert(std::make_pair(id, info)).second) return false; @@ -90,12 +95,11 @@ void RequestManager::receiveHandler(Net::Connection *connection, const Net::Pack return; } - std::cerr << "Received an unexpected packet." << std::endl; connection->send(Net::Packets::ErrorPacket(Net::Packet::ERROR, packet.getRequestId(), Exception(Exception::UNEXPECTED_PACKET))); } -bool RequestManager::sendRequest(Net::Connection *connection, Request *request) { +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()) @@ -108,10 +112,9 @@ bool RequestManager::sendRequest(Net::Connection *connection, Request *request) id = getRequestId(); } while(requestMap->findRequest(id)); - if(!request->sendRequest(connection, id)) - return false; + request->sendRequest(connection, id); - requestMap->addRequest(id, request); + requestMap->addRequest(id, request.release()); return true; } diff --git a/src/Common/RequestManager.h b/src/Common/RequestManager.h index c050d1d..2013860 100644 --- a/src/Common/RequestManager.h +++ b/src/Common/RequestManager.h @@ -20,7 +20,6 @@ #ifndef MAD_COMMON_REQUESTMANAGER_H_ #define MAD_COMMON_REQUESTMANAGER_H_ -#include "RequestHandler.h" #include <Net/Connection.h> #include <map> @@ -30,7 +29,8 @@ namespace Mad { namespace Common { -class Request; +class RequestBase; +class RequestHandler; class RequestManager { private: @@ -42,10 +42,7 @@ class RequestManager { public: RequestMap() {} - ~RequestMap() { - for(iterator it = begin(); it != end(); ++it) - delete it->second; - } + ~RequestMap(); bool addRequest(uint16_t id, RequestHandler *info); RequestHandler* findRequest(uint16_t id); @@ -105,7 +102,7 @@ class RequestManager { void unregisterPacketType(Net::Packet::Type type); - bool sendRequest(Net::Connection *connection, Request *request); + bool sendRequest(Net::Connection *connection, std::auto_ptr<RequestBase> request); virtual ~RequestManager(); }; diff --git a/src/Common/Requests/DisconnectRequest.cpp b/src/Common/Requests/DisconnectRequest.cpp index 81208f2..d8e7ee9 100644 --- a/src/Common/Requests/DisconnectRequest.cpp +++ b/src/Common/Requests/DisconnectRequest.cpp @@ -18,42 +18,25 @@ */ #include "DisconnectRequest.h" -#include "../RequestManager.h" +#include <Net/Connection.h> namespace Mad { namespace Common { namespace Requests { -bool DisconnectRequest::send(Net::Connection *connection, const sigc::slot<void> &callback) { - DisconnectRequest *request = new DisconnectRequest(); - - request->finished.connect(callback); - - if(Mad::Common::RequestManager::getRequestManager()->sendRequest(connection, request)) - return true; - - delete request; - return false; -} - -bool DisconnectRequest::sendRequest(Net::Connection *connection, uint16_t requestId) { - if(!connection->send(Net::Packet(Net::Packet::DISCONNECT, requestId))) - return false; - - return true; +void DisconnectRequest::sendRequest(Net::Connection *connection, uint16_t requestId) { + connection->send(Net::Packet(Net::Packet::DISCONNECT, requestId)); } void DisconnectRequest::handlePacket(Net::Connection *connection, const Net::Packet &packet) { if(packet.getType() != Net::Packet::OK) { - signalFinished().emit(); + finishWithError(Exception(Exception::UNEXPECTED_PACKET)); return; // TODO Logging } connection->disconnect(); - finished(); - - signalFinished().emit(); + finish(); } } diff --git a/src/Common/Requests/DisconnectRequest.h b/src/Common/Requests/DisconnectRequest.h index dcc2b9c..602505a 100644 --- a/src/Common/Requests/DisconnectRequest.h +++ b/src/Common/Requests/DisconnectRequest.h @@ -22,23 +22,17 @@ #include "../Request.h" -#include <sigc++/signal.h> - namespace Mad { namespace Common { namespace Requests { -class DisconnectRequest : public Request { - private: - sigc::signal<void> finished; - - DisconnectRequest() {} +class DisconnectRequest : public Request<> { + protected: + virtual void sendRequest(Net::Connection *connection, uint16_t requestId); + virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); public: - static bool send(Net::Connection *connection, const sigc::slot<void> &callback); - - virtual bool sendRequest(Net::Connection *connection, uint16_t requestId); - virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); + DisconnectRequest(slot_type slot) : Request<>(slot) {} }; } diff --git a/src/Common/Requests/GSSAPIAuthRequest.cpp b/src/Common/Requests/GSSAPIAuthRequest.cpp index 91488d0..53d969f 100644 --- a/src/Common/Requests/GSSAPIAuthRequest.cpp +++ b/src/Common/Requests/GSSAPIAuthRequest.cpp @@ -18,7 +18,7 @@ */ #include "GSSAPIAuthRequest.h" -#include "../RequestManager.h" +#include <Net/Connection.h> #include <cstring> @@ -37,17 +37,7 @@ GSSAPIAuthRequest::~GSSAPIAuthRequest() { gss_release_name(&minStat, &gssServiceName); } -bool GSSAPIAuthRequest::send(Net::Connection *connection, const std::string &serviceName0) { - GSSAPIAuthRequest *request = new GSSAPIAuthRequest(serviceName0); - - if(Mad::Common::RequestManager::getRequestManager()->sendRequest(connection, request)) - return true; - - delete request; - return false; -} - -bool GSSAPIAuthRequest::sendRequest(Net::Connection *connection, uint16_t requestId) { +void GSSAPIAuthRequest::sendRequest(Net::Connection *connection, uint16_t requestId) { OM_uint32 majStat, minStat; gss_buffer_desc buffer; @@ -61,7 +51,7 @@ bool GSSAPIAuthRequest::sendRequest(Net::Connection *connection, uint16_t reques if(majStat != GSS_S_COMPLETE) { gssServiceName = GSS_C_NO_NAME; - return false; + return; } majStat = gss_init_sec_context(&minStat, GSS_C_NO_CREDENTIAL, &gssContext, gssServiceName, GSS_C_NO_OID, GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, @@ -73,22 +63,20 @@ bool GSSAPIAuthRequest::sendRequest(Net::Connection *connection, uint16_t reques } else if(majStat != GSS_S_CONTINUE_NEEDED) { gss_release_buffer(&minStat, &buffer); - return false; + return; } if(!connection->send(Net::Packet(Net::Packet::GSSAPI_AUTH, requestId, buffer.value, buffer.length))) { gss_release_buffer(&minStat, &buffer); - return false; + return; } gss_release_buffer(&minStat, &buffer); - - return true; } void GSSAPIAuthRequest::handlePacket(Net::Connection *connection, const Net::Packet &packet) { if(packet.getType() != Net::Packet::GSSAPI_AUTH) { - signalFinished().emit(); + finishWithError(Exception(Exception::UNEXPECTED_PACKET)); return; // TODO Logging } @@ -157,7 +145,7 @@ void GSSAPIAuthRequest::handlePacket(Net::Connection *connection, const Net::Pac gss_release_buffer(&minStat, &sendBuffer); - signalFinished().emit(); + finish(); } } diff --git a/src/Common/Requests/GSSAPIAuthRequest.h b/src/Common/Requests/GSSAPIAuthRequest.h index 336e4f0..8f2328b 100644 --- a/src/Common/Requests/GSSAPIAuthRequest.h +++ b/src/Common/Requests/GSSAPIAuthRequest.h @@ -26,14 +26,11 @@ namespace Mad { namespace Common { - -class RequestManager; - namespace Requests { // TODO Logging & error handling! -class GSSAPIAuthRequest : public Request { +class GSSAPIAuthRequest : public Request<> { private: std::string serviceName; gss_name_t gssServiceName; @@ -41,15 +38,13 @@ class GSSAPIAuthRequest : public Request { bool gssContinue; - GSSAPIAuthRequest(const std::string &serviceName0) : serviceName(serviceName0), gssServiceName(GSS_C_NO_NAME), gssContext(GSS_C_NO_CONTEXT), gssContinue(true) {} + virtual void sendRequest(Net::Connection *connection, uint16_t requestId); + virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); public: + GSSAPIAuthRequest(const std::string &serviceName0, slot_type slot) + : Request<>(slot), serviceName(serviceName0), gssServiceName(GSS_C_NO_NAME), gssContext(GSS_C_NO_CONTEXT), gssContinue(true) {} virtual ~GSSAPIAuthRequest(); - - static bool send(Net::Connection *connection, const std::string &serviceName0); - - virtual bool sendRequest(Net::Connection *connection, uint16_t requestId); - virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); }; } diff --git a/src/Core/RequestHandlers/DaemonListRequestHandler.h b/src/Core/RequestHandlers/DaemonListRequestHandler.h index 1aabe5b..205ad02 100644 --- a/src/Core/RequestHandlers/DaemonListRequestHandler.h +++ b/src/Core/RequestHandlers/DaemonListRequestHandler.h @@ -27,10 +27,11 @@ namespace Core { namespace RequestHandlers { class DaemonListRequestHandler : public Common::RequestHandler { + protected: + virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); + public: DaemonListRequestHandler() {} - - virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); }; } diff --git a/src/Core/RequestHandlers/DaemonStatusRequestHandler.cpp b/src/Core/RequestHandlers/DaemonStatusRequestHandler.cpp index bb5d45f..efdf3ea 100644 --- a/src/Core/RequestHandlers/DaemonStatusRequestHandler.cpp +++ b/src/Core/RequestHandlers/DaemonStatusRequestHandler.cpp @@ -48,15 +48,21 @@ void DaemonStatusRequestHandler::handlePacket(Net::Connection *connection, const try { Net::Connection *daemonCon = ConnectionManager::getConnectionManager()->getDaemonConnection(daemonName); - Requests::DaemonStatusRequest::send(daemonCon, sigc::mem_fun(this, &DaemonStatusRequestHandler::requestFinished)); + Common::RequestManager::getRequestManager()->sendRequest(daemonCon, std::auto_ptr<Common::RequestBase>(new Requests::DaemonStatusRequest(sigc::mem_fun(this, &DaemonStatusRequestHandler::requestFinished)))); } catch(Common::Exception &e) { connection->send(Net::Packets::ErrorPacket(Net::Packet::ERROR, packet.getRequestId(), e)); } } -void DaemonStatusRequestHandler::requestFinished(const Net::Packets::HostStatusPacket &packet) { - con->send(Net::Packet(Net::Packet::OK, requestId, packet.getData(), packet.getLength())); +void DaemonStatusRequestHandler::requestFinished(const Common::Request<Net::Packets::HostStatusPacket> &request) { + try { + const Net::Packet &packet = request.getResult(); + con->send(Net::Packet(Net::Packet::OK, requestId, packet.getData(), packet.getLength())); + } + catch(Common::Exception &e) { + con->send(Net::Packets::ErrorPacket(Net::Packet::ERROR, requestId, e)); + } signalFinished().emit(); } diff --git a/src/Core/RequestHandlers/DaemonStatusRequestHandler.h b/src/Core/RequestHandlers/DaemonStatusRequestHandler.h index 916a3ec..d8edc41 100644 --- a/src/Core/RequestHandlers/DaemonStatusRequestHandler.h +++ b/src/Core/RequestHandlers/DaemonStatusRequestHandler.h @@ -21,6 +21,7 @@ #define MAD_CORE_REQUESTHANDLERS_DAEMONSTATUSREQUESTHANDLER_H_ #include <Common/RequestHandler.h> +#include <Common/Request.h> #include <stdint.h> namespace Mad { @@ -42,12 +43,13 @@ class DaemonStatusRequestHandler : public Common::RequestHandler { Net::Connection *con; uint16_t requestId; - void requestFinished(const Net::Packets::HostStatusPacket &packet); + void requestFinished(const Common::Request<Net::Packets::HostStatusPacket> &request); + + protected: + virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); public: DaemonStatusRequestHandler() {} - - virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); }; } diff --git a/src/Core/RequestHandlers/GSSAPIAuthRequestHandler.h b/src/Core/RequestHandlers/GSSAPIAuthRequestHandler.h index 2a7884b..e222fef 100644 --- a/src/Core/RequestHandlers/GSSAPIAuthRequestHandler.h +++ b/src/Core/RequestHandlers/GSSAPIAuthRequestHandler.h @@ -33,10 +33,11 @@ class GSSAPIAuthRequestHandler : public Common::RequestHandler { bool gssContinue, sentSignature; + protected: + virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); + public: GSSAPIAuthRequestHandler() : gssContext(GSS_C_NO_CONTEXT), gssContinue(true), sentSignature(false) {} - - virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); }; } diff --git a/src/Core/RequestHandlers/IdentifyRequestHandler.h b/src/Core/RequestHandlers/IdentifyRequestHandler.h index 74ffd54..58f10ba 100644 --- a/src/Core/RequestHandlers/IdentifyRequestHandler.h +++ b/src/Core/RequestHandlers/IdentifyRequestHandler.h @@ -27,10 +27,11 @@ namespace Core { namespace RequestHandlers { class IdentifyRequestHandler : public Common::RequestHandler { + protected: + virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); + public: IdentifyRequestHandler() {} - - virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); }; } diff --git a/src/Core/Requests/DaemonStatusRequest.cpp b/src/Core/Requests/DaemonStatusRequest.cpp index 86ef3c6..1741731 100644 --- a/src/Core/Requests/DaemonStatusRequest.cpp +++ b/src/Core/Requests/DaemonStatusRequest.cpp @@ -25,34 +25,17 @@ namespace Mad { namespace Core { namespace Requests { -bool DaemonStatusRequest::send(Net::Connection *connection, const sigc::slot<void,const Net::Packets::HostStatusPacket&> &callback) { - DaemonStatusRequest *request = new DaemonStatusRequest(); - - request->finished.connect(callback); - - if(Mad::Common::RequestManager::getRequestManager()->sendRequest(connection, request)) - return true; - - delete request; - return false; -} - -bool DaemonStatusRequest::sendRequest(Net::Connection *connection, uint16_t requestId) { - if(!connection->send(Net::Packet(Net::Packet::STATUS, requestId))) - return false; - - return true; +void DaemonStatusRequest::sendRequest(Net::Connection *connection, uint16_t requestId) { + connection->send(Net::Packet(Net::Packet::STATUS, requestId)); } void DaemonStatusRequest::handlePacket(Net::Connection*, const Net::Packet &packet) { if(packet.getType() != Net::Packet::OK) { - signalFinished().emit(); + finishWithError(Common::Exception(Common::Exception::UNEXPECTED_PACKET)); return; // TODO Logging } - finished(Net::Packets::HostStatusPacket(packet)); - - signalFinished().emit(); + finish(Net::Packets::HostStatusPacket(packet)); } } diff --git a/src/Core/Requests/DaemonStatusRequest.h b/src/Core/Requests/DaemonStatusRequest.h index ce6e4f7..baeb847 100644 --- a/src/Core/Requests/DaemonStatusRequest.h +++ b/src/Core/Requests/DaemonStatusRequest.h @@ -22,9 +22,6 @@ #include <Common/Request.h> -#include <string> -#include <sigc++/signal.h> - namespace Mad { namespace Net { @@ -36,17 +33,13 @@ class HostStatusPacket; namespace Core { namespace Requests { -class DaemonStatusRequest : public Common::Request { - private: - sigc::signal<void,const Net::Packets::HostStatusPacket&> finished; - - DaemonStatusRequest() {} +class DaemonStatusRequest : public Common::Request<Net::Packets::HostStatusPacket> { + protected: + virtual void sendRequest(Net::Connection *connection, uint16_t requestId); + virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); public: - static bool send(Net::Connection *connection, const sigc::slot<void,const Net::Packets::HostStatusPacket&> &callback); - - virtual bool sendRequest(Net::Connection *connection, uint16_t requestId); - virtual void handlePacket(Net::Connection*, const Net::Packet &packet); + DaemonStatusRequest(slot_type slot) : Common::Request<Net::Packets::HostStatusPacket>(slot) {} }; } diff --git a/src/Daemon/Requests/IdentifyRequest.cpp b/src/Daemon/Requests/IdentifyRequest.cpp index de3e359..e8b6082 100644 --- a/src/Daemon/Requests/IdentifyRequest.cpp +++ b/src/Daemon/Requests/IdentifyRequest.cpp @@ -18,35 +18,23 @@ */ #include "IdentifyRequest.h" -#include <Common/RequestManager.h> -#include <Net/Packet.h> +#include <Net/Connection.h> namespace Mad { namespace Daemon { namespace Requests { -bool IdentifyRequest::send(Net::Connection *connection, const std::string &hostname0) { - IdentifyRequest *request = new IdentifyRequest(hostname0); - - if(Common::RequestManager::getRequestManager()->sendRequest(connection, request)) - return true; - - delete request; - return false; -} - -bool IdentifyRequest::sendRequest(Net::Connection *connection, uint16_t requestId) { - if(!connection->send(Net::Packet(Net::Packet::IDENTIFY, requestId, hostname.c_str(), hostname.length()))) - return false; - - return true; +void IdentifyRequest::sendRequest(Net::Connection *connection, uint16_t requestId) { + connection->send(Net::Packet(Net::Packet::IDENTIFY, requestId, hostname.c_str(), hostname.length())); } void IdentifyRequest::handlePacket(Net::Connection*, const Net::Packet &packet) { - if(packet.getType() != Net::Packet::OK) + if(packet.getType() != Net::Packet::OK) { + finishWithError(Common::Exception(Common::Exception::UNEXPECTED_PACKET)); return; // TODO Logging + } - signalFinished().emit(); + finish(); } } diff --git a/src/Daemon/Requests/IdentifyRequest.h b/src/Daemon/Requests/IdentifyRequest.h index faec315..c728461 100644 --- a/src/Daemon/Requests/IdentifyRequest.h +++ b/src/Daemon/Requests/IdentifyRequest.h @@ -27,17 +27,16 @@ namespace Mad { namespace Daemon { namespace Requests { -class IdentifyRequest : public Common::Request { +class IdentifyRequest : public Common::Request<> { private: - IdentifyRequest(const std::string &hostname0) : hostname(hostname0) {} - std::string hostname; - public: - static bool send(Net::Connection *connection, const std::string &hostname0); - - virtual bool sendRequest(Net::Connection *connection, uint16_t requestId); + protected: + virtual void sendRequest(Net::Connection *connection, uint16_t requestId); virtual void handlePacket(Net::Connection*, const Net::Packet &packet); + + public: + IdentifyRequest(const std::string &hostname0, slot_type slot) : Common::Request<>(slot), hostname(hostname0) {} }; } diff --git a/src/mad.cpp b/src/mad.cpp index 0eda1f0..b2f8b61 100644 --- a/src/mad.cpp +++ b/src/mad.cpp @@ -20,6 +20,7 @@ #include "Net/ClientConnection.h" #include "Net/IPAddress.h" #include "Common/Backends/SystemBackendProc.h" +#include "Common/Request.h" #include "Common/RequestManager.h" #include "Common/RequestHandlers/StatusRequestHandler.h" #include "Daemon/Requests/IdentifyRequest.h" @@ -28,6 +29,10 @@ #include <unistd.h> +void requestFinished(const Mad::Common::Request<>&) { + std::cerr << "Identified." << std::endl; +} + int main() { Mad::Net::Connection::init(); @@ -52,8 +57,8 @@ int main() { //char hostname[256]; //gethostname(hostname, sizeof(hostname)); - //Mad::Daemon::Requests::IdentifyRequest::send(connection, hostname); - Mad::Daemon::Requests::IdentifyRequest::send(connection, "test"); + //Mad::Common::RequestManager::getRequestManager()->sendRequest(connection, std::auto_ptr<Mad::Common::RequestBase>(new Mad::Daemon::Requests::IdentifyRequest(hostname, sigc::ptr_fun(requestFinished)))); + Mad::Common::RequestManager::getRequestManager()->sendRequest(connection, std::auto_ptr<Mad::Common::RequestBase>(new Mad::Daemon::Requests::IdentifyRequest("test", sigc::ptr_fun(requestFinished)))); while(connection->isConnected()) { struct pollfd fd = connection->getPollfd(); |