summaryrefslogtreecommitdiffstats
path: root/src/Common
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common')
-rw-r--r--src/Common/Exception.h3
-rw-r--r--src/Common/Makefile.am2
-rw-r--r--src/Common/Makefile.in2
-rw-r--r--src/Common/Request.h61
-rw-r--r--src/Common/RequestBase.h39
-rw-r--r--src/Common/RequestHandler.h12
-rw-r--r--src/Common/RequestHandlers/DisconnectRequestHandler.h5
-rw-r--r--src/Common/RequestHandlers/StatusRequestHandler.h5
-rw-r--r--src/Common/RequestManager.cpp13
-rw-r--r--src/Common/RequestManager.h11
-rw-r--r--src/Common/Requests/DisconnectRequest.cpp27
-rw-r--r--src/Common/Requests/DisconnectRequest.h16
-rw-r--r--src/Common/Requests/GSSAPIAuthRequest.cpp26
-rw-r--r--src/Common/Requests/GSSAPIAuthRequest.h15
14 files changed, 149 insertions, 88 deletions
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);
};
}