diff options
34 files changed, 1198 insertions, 50 deletions
diff --git a/Makefile.in b/Makefile.in index 4118e69..f2e0977 100644 --- a/Makefile.in +++ b/Makefile.in @@ -196,6 +196,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ @@ -808,6 +808,8 @@ sigc_LIBS sigc_CFLAGS GnuTLS_LIBS GnuTLS_CFLAGS +libxml2_LIBS +libxml2_CFLAGS PKG_CONFIG INCLUDED_LTDL_FALSE INCLUDED_LTDL_TRUE @@ -977,6 +979,8 @@ CFLAGS CPP CXXCPP PKG_CONFIG +libxml2_CFLAGS +libxml2_LIBS GnuTLS_CFLAGS GnuTLS_LIBS sigc_CFLAGS @@ -1653,6 +1657,10 @@ Some influential environment variables: CPP C preprocessor CXXCPP C++ preprocessor PKG_CONFIG path to pkg-config utility + libxml2_CFLAGS + C compiler flags for libxml2, overriding pkg-config + libxml2_LIBS + linker flags for libxml2, overriding pkg-config GnuTLS_CFLAGS C compiler flags for GnuTLS, overriding pkg-config GnuTLS_LIBS linker flags for GnuTLS, overriding pkg-config @@ -5330,13 +5338,13 @@ if test "${lt_cv_nm_interface+set}" = set; then else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:5333: $ac_compile\"" >&5) + (eval echo "\"\$as_me:5341: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:5336: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:5344: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:5339: output\"" >&5) + (eval echo "\"\$as_me:5347: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -6424,7 +6432,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 6427 "configure"' > conftest.$ac_ext + echo '#line 6435 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -8763,11 +8771,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8766: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8774: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:8770: \$? = $ac_status" >&5 + echo "$as_me:8778: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -9087,11 +9095,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9090: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9098: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:9094: \$? = $ac_status" >&5 + echo "$as_me:9102: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -9192,11 +9200,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9195: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9203: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:9199: \$? = $ac_status" >&5 + echo "$as_me:9207: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9247,11 +9255,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9250: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9258: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:9254: \$? = $ac_status" >&5 + echo "$as_me:9262: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -12052,7 +12060,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12055 "configure" +#line 12063 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12152,7 +12160,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12155 "configure" +#line 12163 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -14163,11 +14171,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14166: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14174: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14170: \$? = $ac_status" >&5 + echo "$as_me:14178: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14262,11 +14270,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14265: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14273: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14269: \$? = $ac_status" >&5 + echo "$as_me:14277: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14314,11 +14322,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14317: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14325: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14321: \$? = $ac_status" >&5 + echo "$as_me:14329: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -16237,7 +16245,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 16240 "configure" +#line 16248 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -17610,6 +17618,81 @@ $as_echo "no" >&6; } fi pkg_failed=no +{ $as_echo "$as_me:$LINENO: checking for libxml2" >&5 +$as_echo_n "checking for libxml2... " >&6; } + +if test -n "$PKG_CONFIG"; then + if test -n "$libxml2_CFLAGS"; then + pkg_cv_libxml2_CFLAGS="$libxml2_CFLAGS" + else + if test -n "$PKG_CONFIG" && \ + { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libxml-2.0\"") >&5 + ($PKG_CONFIG --exists --print-errors "libxml-2.0") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + pkg_cv_libxml2_CFLAGS=`$PKG_CONFIG --cflags "libxml-2.0" 2>/dev/null` +else + pkg_failed=yes +fi + fi +else + pkg_failed=untried +fi +if test -n "$PKG_CONFIG"; then + if test -n "$libxml2_LIBS"; then + pkg_cv_libxml2_LIBS="$libxml2_LIBS" + else + if test -n "$PKG_CONFIG" && \ + { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libxml-2.0\"") >&5 + ($PKG_CONFIG --exists --print-errors "libxml-2.0") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + pkg_cv_libxml2_LIBS=`$PKG_CONFIG --libs "libxml-2.0" 2>/dev/null` +else + pkg_failed=yes +fi + fi +else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + libxml2_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "libxml-2.0"` + else + libxml2_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libxml-2.0"` + fi + # Put the nasty error message in config.log where it belongs + echo "$libxml2_PKG_ERRORS" >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:$LINENO: error: Test for libxml 2.0 failed." >&5 +$as_echo "$as_me: error: Test for libxml 2.0 failed." >&2;} + { (exit 1); exit 1; }; } +elif test $pkg_failed = untried; then + { { $as_echo "$as_me:$LINENO: error: Test for libxml 2.0 failed." >&5 +$as_echo "$as_me: error: Test for libxml 2.0 failed." >&2;} + { (exit 1); exit 1; }; } +else + libxml2_CFLAGS=$pkg_cv_libxml2_CFLAGS + libxml2_LIBS=$pkg_cv_libxml2_LIBS + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + : +fi + +pkg_failed=no { $as_echo "$as_me:$LINENO: checking for GnuTLS" >&5 $as_echo_n "checking for GnuTLS... " >&6; } @@ -17834,7 +17917,7 @@ fi $as_echo_n "checking for MySQL libraries... " >&6; } if test "$MYSQL_CONFIG" != "no"; then - MYSQL_CFLAGS="`$MYSQL_CONFIG --cflags`" + MYSQL_CFLAGS="`$MYSQL_CONFIG --include`" MYSQL_LDFLAGS="`$MYSQL_CONFIG --libs`" MYSQL_VERSION=`$MYSQL_CONFIG --version` @@ -17901,7 +17984,7 @@ $as_echo "no" >&6; } -CPPFLAGS='-I${top_srcdir}'"/src $GnuTLS_CFLAGS $sigc_CFLAGS $MYSQL_CFLAGS $INCLTDL $CPPFLAGS" +CPPFLAGS='-I${top_srcdir}'"/src $libxml2_CFLAGS $GnuTLS_CFLAGS $sigc_CFLAGS $MYSQL_CFLAGS $INCLTDL $CPPFLAGS" { $as_echo "$as_me:$LINENO: checking for gss_init_sec_context in -lgssapi_krb5" >&5 $as_echo_n "checking for gss_init_sec_context in -lgssapi_krb5... " >&6; } diff --git a/configure.ac b/configure.ac index 026669b..c49f46c 100644 --- a/configure.ac +++ b/configure.ac @@ -29,12 +29,13 @@ AC_SUBST(LIBLTDL) AM_CONDITIONAL(INCLUDED_LTDL, test "x$with_included_ltdl" = xyes) # Checks for libraries. +PKG_CHECK_MODULES(libxml2, libxml-2.0, , AC_MSG_ERROR(Test for libxml 2.0 failed.)) PKG_CHECK_MODULES(GnuTLS, gnutls, , AC_MSG_ERROR(Test for GnuTLS failed.)) PKG_CHECK_MODULES(sigc, sigc++-2.0, , AC_MSG_ERROR(Test for SigC++ 2.0 failed.)) AX_LIB_MYSQL -CPPFLAGS='-I${top_srcdir}'"/src $GnuTLS_CFLAGS $sigc_CFLAGS $MYSQL_CFLAGS $INCLTDL $CPPFLAGS" +CPPFLAGS='-I${top_srcdir}'"/src $libxml2_CFLAGS $GnuTLS_CFLAGS $sigc_CFLAGS $MYSQL_CFLAGS $INCLTDL $CPPFLAGS" AC_CHECK_LIB(gssapi_krb5, gss_init_sec_context, AC_SUBST(GSSAPI_LIBS, -lgssapi_krb5), AC_CHECK_LIB(gssapi, gss_init_sec_context, GSSAPI_LIBS=-lgssapi, AC_MSG_ERROR(Test for GSSAPI library failed.))) AC_CHECK_LIB(readline, readline, AC_SUBST(READLINE_LIBS, -lreadline), AC_MSG_ERROR(Test for GNU readline library failed.)) diff --git a/libltdl/Makefile.in b/libltdl/Makefile.in index e0fe3ff..d122409 100644 --- a/libltdl/Makefile.in +++ b/libltdl/Makefile.in @@ -268,6 +268,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ diff --git a/m4/ax_lib_mysql.m4 b/m4/ax_lib_mysql.m4 index a8ca178..f6e2552 100644 --- a/m4/ax_lib_mysql.m4 +++ b/m4/ax_lib_mysql.m4 @@ -81,7 +81,7 @@ AC_DEFUN([AX_LIB_MYSQL], AC_MSG_CHECKING([for MySQL libraries]) if test "$MYSQL_CONFIG" != "no"; then - MYSQL_CFLAGS="`$MYSQL_CONFIG --cflags`" + MYSQL_CFLAGS="`$MYSQL_CONFIG --include`" MYSQL_LDFLAGS="`$MYSQL_CONFIG --libs`" MYSQL_VERSION=`$MYSQL_CONFIG --version` diff --git a/src/Client/Makefile.in b/src/Client/Makefile.in index 20f85ee..2b3547f 100644 --- a/src/Client/Makefile.in +++ b/src/Client/Makefile.in @@ -201,6 +201,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ diff --git a/src/Client/Requests/Makefile.in b/src/Client/Requests/Makefile.in index 842713e..7f2d111 100644 --- a/src/Client/Requests/Makefile.in +++ b/src/Client/Requests/Makefile.in @@ -192,6 +192,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ diff --git a/src/Common/Makefile.am b/src/Common/Makefile.am index 665c21a..2fd4edb 100644 --- a/src/Common/Makefile.am +++ b/src/Common/Makefile.am @@ -3,10 +3,10 @@ SUBDIRS = Requests RequestHandlers noinst_LTLIBRARIES = libcommon.la libcommon_la_SOURCES = ActionManager.cpp ConfigEntry.cpp ConfigManager.cpp Exception.cpp Initializable.cpp \ Logger.cpp LogManager.cpp ModuleManager.cpp RequestManager.cpp \ - SystemBackend.cpp Tokenizer.cpp + SystemBackend.cpp Tokenizer.cpp XmlPacket.cpp libcommon_la_LIBADD = Requests/librequests.la RequestHandlers/librequesthandlers.la noinst_HEADERS = ActionManager.h ConfigEntry.h ConfigManager.h Configurable.h Exception.h HostInfo.h \ Initializable.h Logger.h LoggerBase.h LogManager.h ModuleManager.h \ RemoteLogger.h Request.h RequestBase.h RequestHandler.h RequestManager.h \ - SystemBackend.h Tokenizer.h UserInfo.h + SystemBackend.h Tokenizer.h UserInfo.h XmlPacket.h XmlRequestHandler.h diff --git a/src/Common/Makefile.in b/src/Common/Makefile.in index 2fb869f..3638371 100644 --- a/src/Common/Makefile.in +++ b/src/Common/Makefile.in @@ -54,7 +54,7 @@ libcommon_la_DEPENDENCIES = Requests/librequests.la \ am_libcommon_la_OBJECTS = ActionManager.lo ConfigEntry.lo \ ConfigManager.lo Exception.lo Initializable.lo Logger.lo \ LogManager.lo ModuleManager.lo RequestManager.lo \ - SystemBackend.lo Tokenizer.lo + SystemBackend.lo Tokenizer.lo XmlPacket.lo libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/config/depcomp @@ -204,6 +204,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ @@ -231,13 +233,13 @@ SUBDIRS = Requests RequestHandlers noinst_LTLIBRARIES = libcommon.la libcommon_la_SOURCES = ActionManager.cpp ConfigEntry.cpp ConfigManager.cpp Exception.cpp Initializable.cpp \ Logger.cpp LogManager.cpp ModuleManager.cpp RequestManager.cpp \ - SystemBackend.cpp Tokenizer.cpp + SystemBackend.cpp Tokenizer.cpp XmlPacket.cpp libcommon_la_LIBADD = Requests/librequests.la RequestHandlers/librequesthandlers.la noinst_HEADERS = ActionManager.h ConfigEntry.h ConfigManager.h Configurable.h Exception.h HostInfo.h \ Initializable.h Logger.h LoggerBase.h LogManager.h ModuleManager.h \ RemoteLogger.h Request.h RequestBase.h RequestHandler.h RequestManager.h \ - SystemBackend.h Tokenizer.h UserInfo.h + SystemBackend.h Tokenizer.h UserInfo.h XmlPacket.h XmlRequestHandler.h all: all-recursive @@ -301,6 +303,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestManager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SystemBackend.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Tokenizer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XmlPacket.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/src/Common/RequestHandlers/Makefile.in b/src/Common/RequestHandlers/Makefile.in index dc292e3..ccf87b4 100644 --- a/src/Common/RequestHandlers/Makefile.in +++ b/src/Common/RequestHandlers/Makefile.in @@ -191,6 +191,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ diff --git a/src/Common/RequestManager.cpp b/src/Common/RequestManager.cpp index d852f5d..94b3da9 100644 --- a/src/Common/RequestManager.cpp +++ b/src/Common/RequestManager.cpp @@ -19,6 +19,8 @@ #include "RequestManager.h" #include "Request.h" +#include "XmlRequest.h" +#include "XmlPacket.h" #include "RequestHandlers/DisconnectRequestHandler.h" #include "Logger.h" @@ -67,6 +69,40 @@ bool RequestManager::RequestMap::deleteRequest(uint16_t id) { } +RequestManager::XmlRequestMap::~XmlRequestMap() { + for(iterator it = begin(); it != end(); ++it) + delete it->second; +} + +bool RequestManager::XmlRequestMap::addRequest(uint16_t id, XmlRequestHandler *info) { + if(!insert(std::make_pair(id, info)).second) + return false; + + info->signalFinished().connect(sigc::hide_return(sigc::bind(sigc::mem_fun(this, &RequestManager::XmlRequestMap::deleteRequest), id))); + + return true; +} + +XmlRequestHandler* RequestManager::XmlRequestMap::findRequest(uint16_t id) { + iterator it = find(id); + if(it == end()) + return 0; + + return it->second; +} + +bool RequestManager::XmlRequestMap::deleteRequest(uint16_t id) { + iterator it = find(id); + if(it == end()) + return false; + + delete it->second; + + erase(it); + return true; +} + + void RequestManager::receiveHandler(Net::Connection *connection, const Net::Packet &packet) { std::map<Net::Connection*,RequestMap*>::iterator it = requestMaps.find(connection); @@ -86,6 +122,37 @@ void RequestManager::receiveHandler(Net::Connection *connection, const Net::Pack return; } + std::map<Net::Connection*,XmlRequestMap*>::iterator it2 = xmlRequestMaps.find(connection); + if(it2 == xmlRequestMaps.end()) { + // TODO: Error + Logger::log(Logger::ERROR, "Received a packet from an unregistered connection."); + + return; + } + + XmlRequestMap *xmlRequestMap = it2->second; + XmlRequestHandler *xmlRequest = xmlRequestMap->findRequest(packet.getRequestId()); + + if(xmlRequest) { + XmlPacket xmlPacket(packet); + xmlRequest->handlePacket(connection, xmlPacket); + + return; + } + + if(packet.getType() == Net::Packet::XML) { + XmlPacket xmlPacket(packet); + + std::map<std::string,XmlRequestHandlerFactory*>::iterator factoryIt = xmlRequestHandlerFactories.find(xmlPacket.getType()); + if(factoryIt != xmlRequestHandlerFactories.end()) { + xmlRequest = factoryIt->second->createRequestHandler(); + xmlRequestMap->addRequest(packet.getRequestId(), xmlRequest); + xmlRequest->handlePacket(connection, xmlPacket); + + return; + } + } + std::map<Net::Packet::Type,RequestHandlerFactory*>::iterator factoryIt = requestHandlerFactories.find(packet.getType()); if(factoryIt != requestHandlerFactories.end()) { request = factoryIt->second->createRequestHandler(); @@ -121,8 +188,31 @@ bool RequestManager::sendRequest(Net::Connection *connection, std::auto_ptr<Requ return true; } +bool RequestManager::sendRequest(Net::Connection *connection, std::auto_ptr<XmlRequestBase> request) { + std::map<Net::Connection*,XmlRequestMap*>::iterator it = xmlRequestMaps.find(connection); + + if(it == xmlRequestMaps.end()) { + Logger::log(Logger::CRITICAL, "Trying to send a request over an unregistered connecion."); + return false; + } + + XmlRequestMap *requestMap = it->second; + + uint16_t id; + do { + id = getRequestId(); + } while(requestMap->findRequest(id)); + + request->sendRequest(connection, id); + + requestMap->addRequest(id, request.release()); + + return true; +} + void RequestManager::registerConnection(Net::Connection *connection) { requestMaps.insert(std::make_pair(connection, new RequestMap())); + xmlRequestMaps.insert(std::make_pair(connection, new XmlRequestMap())); connection->signalReceive().connect(sigc::mem_fun(this, &RequestManager::receiveHandler)); } @@ -130,12 +220,17 @@ void RequestManager::registerConnection(Net::Connection *connection) { void RequestManager::unregisterConnection(Net::Connection *connection) { std::map<Net::Connection*,RequestMap*>::iterator it = requestMaps.find(connection); - if(it == requestMaps.end()) - return; + if(it != requestMaps.end()) { + delete it->second; + requestMaps.erase(it); + } - delete it->second; + std::map<Net::Connection*,XmlRequestMap*>::iterator it2 = xmlRequestMaps.find(connection); - requestMaps.erase(it); + if(it2 != xmlRequestMaps.end()) { + delete it2->second; + xmlRequestMaps.erase(it2); + } } void RequestManager::unregisterPacketType(Net::Packet::Type type) { @@ -149,6 +244,17 @@ void RequestManager::unregisterPacketType(Net::Packet::Type type) { requestHandlerFactories.erase(it); } +void RequestManager::unregisterPacketType(const std::string &type) { + std::map<std::string,XmlRequestHandlerFactory*>::iterator it = xmlRequestHandlerFactories.find(type); + + if(it == xmlRequestHandlerFactories.end()) + return; + + delete it->second; + + xmlRequestHandlerFactories.erase(it); +} + RequestManager::RequestManager() : core(false), requestId(-1) { registerPacketType<RequestHandlers::DisconnectRequestHandler>(Net::Packet::DISCONNECT); } @@ -159,8 +265,14 @@ RequestManager::~RequestManager() { for(std::map<Net::Connection*,RequestMap*>::iterator it = requestMaps.begin(); it != requestMaps.end(); ++it) delete it->second; + for(std::map<Net::Connection*,XmlRequestMap*>::iterator it = xmlRequestMaps.begin(); it != xmlRequestMaps.end(); ++it) + delete it->second; + for(std::map<Net::Packet::Type,RequestHandlerFactory*>::iterator it = requestHandlerFactories.begin(); it != requestHandlerFactories.end(); ++it) delete it->second; + + for(std::map<std::string,XmlRequestHandlerFactory*>::iterator it = xmlRequestHandlerFactories.begin(); it != xmlRequestHandlerFactories.end(); ++it) + delete it->second; } } diff --git a/src/Common/RequestManager.h b/src/Common/RequestManager.h index c2f58d2..00d940d 100644 --- a/src/Common/RequestManager.h +++ b/src/Common/RequestManager.h @@ -30,6 +30,8 @@ namespace Common { class RequestBase; class RequestHandler; +class XmlRequestBase; +class XmlRequestHandler; class RequestManager { private: @@ -48,6 +50,21 @@ class RequestManager { bool deleteRequest(uint16_t id); }; + class XmlRequestMap : private std::map<uint16_t,XmlRequestHandler*> { + private: + // Prevent shallow copy + XmlRequestMap(const XmlRequestMap &o); + XmlRequestMap& operator=(const XmlRequestMap &o); + + public: + XmlRequestMap() {} + ~XmlRequestMap(); + + bool addRequest(uint16_t id, XmlRequestHandler *info); + XmlRequestHandler* findRequest(uint16_t id); + bool deleteRequest(uint16_t id); + }; + class RequestHandlerFactory { protected: RequestHandlerFactory() {} @@ -64,13 +81,31 @@ class RequestManager { } }; + class XmlRequestHandlerFactory { + protected: + XmlRequestHandlerFactory() {} + + public: + virtual XmlRequestHandler* createRequestHandler() = 0; + virtual ~XmlRequestHandlerFactory() {} + }; + + template<class T> class SpecificXmlRequestHandlerFactory : public XmlRequestHandlerFactory { + public: + virtual XmlRequestHandler* createRequestHandler() { + return new T(); + } + }; + static RequestManager requestManager; std::map<Net::Connection*,RequestMap*> requestMaps; + std::map<Net::Connection*,XmlRequestMap*> xmlRequestMaps; bool core; uint16_t requestId; std::map<Net::Packet::Type,RequestHandlerFactory*> requestHandlerFactories; + std::map<std::string,XmlRequestHandlerFactory*> xmlRequestHandlerFactories; uint16_t getRequestId() { return requestId+=2; @@ -108,7 +143,14 @@ class RequestManager { void unregisterPacketType(Net::Packet::Type type); + template <class T> void registerPacketType(const std::string &type) { + xmlRequestHandlerFactories.insert(std::make_pair(type, new SpecificXmlRequestHandlerFactory<T>())); + } + + void unregisterPacketType(const std::string &type); + bool sendRequest(Net::Connection *connection, std::auto_ptr<RequestBase> request); + bool sendRequest(Net::Connection *connection, std::auto_ptr<XmlRequestBase> request); virtual ~RequestManager(); }; diff --git a/src/Common/Requests/Makefile.in b/src/Common/Requests/Makefile.in index 2c363eb..768a8a6 100644 --- a/src/Common/Requests/Makefile.in +++ b/src/Common/Requests/Makefile.in @@ -191,6 +191,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ diff --git a/src/Common/XmlPacket.cpp b/src/Common/XmlPacket.cpp new file mode 100644 index 0000000..8da861c --- /dev/null +++ b/src/Common/XmlPacket.cpp @@ -0,0 +1,239 @@ +/* + * XmlProcessor.cpp + * + * Copyright (C) 2009 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 "XmlPacket.h" +#include <cstdlib> + +namespace Mad { +namespace Common { + +XmlPacket::Entry XmlPacket::Element::nilEntry(0); +XmlPacket::Element XmlPacket::Entry::nilElement(0); + +void XmlPacket::Element::updateStr() { + if(type == NONE || type == LIST) + return; + + if(type != STRING) { + std::ostringstream buf; + + switch(type) { + case INT: + buf << value.var_int; + break; + case UINT: + buf << value.var_uint; + break; + case INT64: + buf << value.var_int64; + break; + case UINT64: + buf << value.var_uint64; + break; + case FLOAT: + buf << value.var_float; + break; + case DOUBLE: + buf << value.var_double; + break; + case LONGDOUBLE: + buf << value.var_ldouble; + default: + break; + + } + + str = buf.str(); + } + + xmlNodePtr newNode = xmlNewText((xmlChar*)str.c_str()); + xmlNodePtr oldNode = elementNode->children; + + xmlReplaceNode(oldNode, newNode); + xmlFreeNode(oldNode); +} + +XmlPacket::Element::Element(xmlNodePtr node) : elementNode(node), type(NONE) { + if(!node) + return; + + xmlChar *typestr = xmlGetProp(node, (xmlChar*)"type"); + if(!typestr) + return; + + xmlChar *content = xmlNodeGetContent(node->children); + if(!content) { + xmlFree(typestr); + return; + } + + str = (char*)content; + + if(!xmlStrcmp(typestr, (xmlChar*)"int")) { + type = INT; + value.var_int = std::strtol((char*)content, 0, 10); + } + else if(!xmlStrcmp(typestr, (xmlChar*)"uint")) { + type = UINT; + value.var_uint = std::strtoul((char*)content, 0, 10); + } + else if(!xmlStrcmp(typestr, (xmlChar*)"int64")) { + type = INT64; + value.var_int64 = std::strtoll((char*)content, 0, 10); + } + else if(!xmlStrcmp(typestr, (xmlChar*)"uint64")) { + type = UINT64; + value.var_uint64 = std::strtoull((char*)content, 0, 10); + } + else if(!xmlStrcmp(typestr, (xmlChar*)"float")) { + type = FLOAT; + value.var_float = std::strtof((char*)content, 0); + } + else if(!xmlStrcmp(typestr, (xmlChar*)"double")) { + type = DOUBLE; + value.var_double = std::strtod((char*)content, 0); + } + else if(!xmlStrcmp(typestr, (xmlChar*)"longdouble")) { + type = LONGDOUBLE; + value.var_ldouble = std::strtold((char*)content, 0); + } + else if(!xmlStrcmp(typestr, (xmlChar*)"string")) { + type = STRING; + } + + xmlFree(typestr); + xmlFree(content); + + updateStr(); +} + +XmlPacket::Entry::Entry(xmlNodePtr node) : entryNode(node) { + if(!node) + return; + + for(xmlNodePtr element = node->children; element != 0; element = element->next) { + if(element->type != XML_ELEMENT_NODE) + continue; + + xmlChar *name = xmlGetProp(element, (xmlChar*)"name"); + + if(!xmlStrcmp(element->name, (xmlChar*)"list")) + lists.insert(std::make_pair(std::string((char*)name), List(element))); + else if(!xmlStrcmp(element->name, (xmlChar*)"value")) + elements.insert(std::make_pair(std::string((char*)name), Element(element))); + + xmlFree(name); + } +} + +XmlPacket::Element& XmlPacket::Entry::operator[](const std::string &name) { + std::map<std::string, Element>::iterator it = elements.find(name); + if(it != elements.end()) + return it->second; + + std::map<std::string, List>::iterator it2 = lists.find(name); + if(it2 != lists.end()) + return it2->second; + + return nilElement; +} + +const XmlPacket::Element& XmlPacket::Entry::operator[](const std::string &name) const { + std::map<std::string, Element>::const_iterator it = elements.find(name); + if(it != elements.end()) + return it->second; + + std::map<std::string, List>::const_iterator it2 = lists.find(name); + if(it2 != lists.end()) + return it2->second; + + return nilElement; +} + +XmlPacket::List::List(xmlNodePtr node) : Element(node, LIST) { + for(xmlNodePtr entry = node->children; entry != 0; entry = entry->next) { + if(entry->type != XML_ELEMENT_NODE || xmlStrcmp(entry->name, (xmlChar*)"entry")) + continue; + + entries.push_back(Entry(entry)); + } +} + + +XmlPacket::XmlPacket() { + doc = xmlNewDoc((xmlChar*)"1.0"); + + packetNode = xmlNewNode(0, (xmlChar*)"packet"); + xmlDocSetRootElement(doc, packetNode); + + entry = new Entry(packetNode); +} + +XmlPacket::XmlPacket(const XmlPacket &o) { + doc = xmlCopyDoc(o.doc, 1); + packetNode = xmlDocGetRootElement(doc); + entry = new Entry(packetNode); +} + +XmlPacket::XmlPacket(const Net::Packet &packet) { + doc = xmlParseMemory((const char*)packet.getData(), packet.getLength()); + packetNode = xmlDocGetRootElement(doc); + entry = new Entry(packetNode); +} + +XmlPacket& XmlPacket::operator=(const XmlPacket &o) { + delete entry; + xmlFreeDoc(doc); + + doc = xmlCopyDoc(o.doc, 1); + packetNode = xmlDocGetRootElement(doc); + entry = new Entry(packetNode); + + return *this; +} + +std::string XmlPacket::getType() const { + xmlChar *type = xmlGetProp(packetNode, (xmlChar*)"type"); + + std::string ret(type ? (char*)type : ""); + + xmlFree(type); + + return ret; +} + +void XmlPacket::setType(const std::string &type) { + xmlSetProp(packetNode, (xmlChar*)"type", (xmlChar*)type.c_str()); +} + +Net::Packet XmlPacket::encode(uint16_t requestId) { + xmlChar *buf; + int length; + + xmlDocDumpMemory(doc, &buf, &length); + + Net::Packet packet(Net::Packet::XML, requestId, buf, length); + + xmlFree(buf); + + return packet; +} + +} +} diff --git a/src/Common/XmlPacket.h b/src/Common/XmlPacket.h new file mode 100644 index 0000000..007404a --- /dev/null +++ b/src/Common/XmlPacket.h @@ -0,0 +1,437 @@ +/* + * XmlProcessor.h + * + * Copyright (C) 2009 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_XMLPACKET_H_ +#define MAD_COMMON_XMLPACKET_H_ + +#include <Net/Packet.h> + +#include <map> +#include <string> +#include <sstream> +#include <vector> + +#include <libxml/parser.h> + +namespace Mad { +namespace Common { + +class XmlPacket { + public: + class Entry; + class List; + + private: + xmlDocPtr doc; + xmlNodePtr packetNode; + Entry *entry; + + public: + + class Element { + public: + enum Type { + NONE, LIST, + INT, UINT, INT64, UINT64, + FLOAT, DOUBLE, LONGDOUBLE, STRING + }; + + protected: + friend class Entry; + + xmlNodePtr elementNode; + + private: + std::string str; + + Type type; + union Variant { + int var_int; + unsigned int var_uint; + + long long var_int64; + unsigned long long var_uint64; + + float var_float; + double var_double; + long double var_ldouble; + } value; + + static Entry nilEntry; + + template<typename T> + void set(T val) { + switch(type) { + case INT: + value.var_int = static_cast<int>(val); + break; + case UINT: + value.var_uint = static_cast<unsigned int>(val); + break; + case INT64: + value.var_int64 = static_cast<long long>(val); + break; + case UINT64: + value.var_uint64 = static_cast<unsigned long long>(val); + break; + case FLOAT: + value.var_float = static_cast<float>(val); + break; + case DOUBLE: + value.var_double = static_cast<double>(val); + break; + case LONGDOUBLE: + value.var_ldouble = static_cast<long double>(val); + break; + default: + break; + } + + updateStr(); + } + + void updateStr(); + + protected: + Element(xmlNodePtr node, Type type0) : elementNode(node), type(type0) {} + + public: + Element(xmlNodePtr node); + + Type getType() const { + return type; + } + + virtual size_t getSize() const { + return 0; + } + + virtual Entry& operator[](size_t) { + return nilEntry; + } + + virtual const Entry& operator[](size_t) const { + return nilEntry; + } + + virtual bool insertEntry(size_t) {return false;} + virtual bool addEntry() {return false;} + virtual bool removeEntry(size_t) {return false;} + + template<typename T> + operator T() { + switch(type) { + case INT: + return static_cast<T>(value.var_int); + case UINT: + return static_cast<T>(value.var_uint); + case INT64: + return static_cast<T>(value.var_int64); + case UINT64: + return static_cast<T>(value.var_uint64); + case FLOAT: + return static_cast<T>(value.var_float); + case DOUBLE: + return static_cast<T>(value.var_double); + case LONGDOUBLE: + return static_cast<T>(value.var_ldouble); + default: + return static_cast<T>(0); + } + } + + operator std::string() { + return str; + } + + const Element& operator=(int val) { + set(val); + return *this; + } + + const Element& operator=(unsigned int val) { + set(val); + return *this; + } + + const Element& operator=(long long val) { + set(val); + return *this; + } + + const Element& operator=(unsigned long long val) { + set(val); + return *this; + } + + const Element& operator=(float val) { + set(val); + return *this; + } + + const Element& operator=(double val) { + set(val); + return *this; + } + + const Element& operator=(long double val) { + set(val); + return *this; + } + + const Element& operator=(const std::string &val) { + if(type == STRING) { + str = val; + updateStr(); + } + + return *this; + } + }; + + class Entry { + private: + friend class List; + + xmlNodePtr entryNode; + + std::map<std::string, Element> elements; + std::map<std::string, List> lists; + + static Element nilElement; + + private: + bool add(const std::string &name, const std::string &value, const char *type) { + if(!entryNode) + return false; + + if(lists.find(name) != lists.end() || elements.find(name) != elements.end()) + return false; + + xmlNodePtr newNode = xmlNewTextChild(entryNode, 0, (xmlChar*)"value", (xmlChar*)value.c_str()); + xmlSetProp(newNode, (xmlChar*)"name", (xmlChar*)name.c_str()); + xmlSetProp(newNode, (xmlChar*)"type", (xmlChar*)type); + + if(!elements.insert(std::make_pair(name, Element(newNode))).second) { + xmlUnlinkNode(newNode); + xmlFreeNode(newNode); + + return false; + } + + return true; + } + + public: + Entry(xmlNodePtr node); + + Element& operator[](const std::string &name); + const Element& operator[](const std::string &name) const; + + bool add(const std::string &name, int val) { + std::ostringstream buf; + buf << val; + + return add(name, buf.str(), "int"); + } + + bool add(const std::string &name, unsigned int val) { + std::ostringstream buf; + buf << val; + + return add(name, buf.str(), "uint"); + } + + bool add(const std::string &name, long long val) { + std::ostringstream buf; + buf << val; + + return add(name, buf.str(), "int64"); + } + + bool add(const std::string &name, unsigned long long val) { + std::ostringstream buf; + buf << val; + + return add(name, buf.str(), "uint64"); + } + + bool add(const std::string &name, float val) { + std::ostringstream buf; + buf << val; + + return add(name, buf.str(), "float"); + } + + bool add(const std::string &name, double val) { + std::ostringstream buf; + buf << val; + + return add(name, buf.str(), "double"); + } + + bool add(const std::string &name, long double val) { + std::ostringstream buf; + buf << val; + + return add(name, buf.str(), "longdouble"); + } + + bool add(const std::string &name, const std::string &val) { + return add(name, val, "string"); + } + + bool addList(const std::string &name) { + if(!entryNode) + return false; + + if(elements.find(name) != elements.end() || lists.find(name) != lists.end()) + return false; + + xmlNodePtr newNode = xmlNewChild(entryNode, 0, (xmlChar*)"list", 0); + xmlSetProp(newNode, (xmlChar*)"name", (xmlChar*)name.c_str()); + + if(!lists.insert(std::make_pair(name, List(newNode))).second) { + xmlUnlinkNode(newNode); + xmlFreeNode(newNode); + + return false; + } + + return true; + } + + bool remove(const std::string &name) { + std::map<std::string, Element>::iterator element = elements.find(name); + + if(element != elements.end()) { + xmlUnlinkNode(element->second.elementNode); + xmlFreeNode(element->second.elementNode); + + elements.erase(element); + + return true; + } + + std::map<std::string, List>::iterator list = lists.find(name); + + if(list != lists.end()) { + xmlUnlinkNode(list->second.elementNode); + xmlFreeNode(list->second.elementNode); + + lists.erase(list); + + return true; + } + + return false; + } + }; + + class List : public Element { + private: + std::vector<Entry> entries; + + public: + List(xmlNodePtr node); + + virtual size_t getSize() const { + return entries.size(); + } + + virtual Entry& operator[](size_t i) { + return entries[i]; + } + + virtual const Entry& operator[](size_t i) const { + return entries[i]; + } + + virtual bool insertEntry(size_t i) { + if(i > getSize()) + return false; + + xmlNodePtr newNode = xmlNewNode(0, (xmlChar*)"entry"); + xmlAddChild(elementNode, newNode); + + entries.insert(entries.begin()+i, Entry(newNode)); + + return true; + } + + virtual bool addEntry() { + return insertEntry(getSize()); + } + + virtual bool removeEntry(size_t i) { + if(i >= getSize()) + return false; + + xmlUnlinkNode(entries[i].entryNode); + xmlFreeNode(entries[i].entryNode); + + entries.erase(entries.begin()+i); + + return true; + } + }; + + XmlPacket(); + XmlPacket(const XmlPacket &o); + XmlPacket(const Net::Packet &packet); + + XmlPacket& operator=(const XmlPacket &o); + + virtual ~XmlPacket() { + delete entry; + + xmlFreeDoc(doc); + } + + std::string getType() const; + void setType(const std::string &type); + + Element& operator[](const std::string &name) { + return entry->operator[](name); + } + + const Element& operator[](const std::string &name) const { + return entry->operator[](name); + } + + template <typename T> + bool add(const std::string &name, T val) { + return entry->add(name, val); + } + + bool addList(const std::string &name) { + return entry->addList(name); + } + + bool remove(const std::string &name) { + return entry->remove(name); + } + + Net::Packet encode(uint16_t requestId); +}; + +} +} + +#endif /* MAD_COMMON_XMLPACKET_H_ */ diff --git a/src/Common/XmlRequest.h b/src/Common/XmlRequest.h new file mode 100644 index 0000000..0de0291 --- /dev/null +++ b/src/Common/XmlRequest.h @@ -0,0 +1,92 @@ +/* + * Request.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_XMLREQUEST_H_ +#define MAD_COMMON_XMLREQUEST_H_ + +#include "XmlRequestBase.h" +#include "Exception.h" + +#include <memory> +#include <sigc++/adaptors/hide.h> + +namespace Mad { +namespace Common { + +template<typename T = void> class XmlRequest : public XmlRequestBase { + private: + sigc::signal<void,const XmlRequest<T>&> finished; + + std::auto_ptr<T> res; + Exception exp; + + public: + typedef sigc::slot<void,const XmlRequest<T>&> slot_type; + + protected: + XmlRequest(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 XmlRequest<void> : public XmlRequestBase { + private: + sigc::signal<void,const XmlRequest<void>&> finished; + + bool isFinished; + Exception exp; + + public: + typedef sigc::slot<void,const XmlRequest<void>&> slot_type; + + protected: + XmlRequest(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: + void getResult() const throw(Exception) { + if(isFinished) + return; + + throw exp; + } +}; + +} +} + +#endif /* MAD_COMMON_XMLREQUEST_H_ */ diff --git a/src/Common/XmlRequestBase.h b/src/Common/XmlRequestBase.h new file mode 100644 index 0000000..fbecc71 --- /dev/null +++ b/src/Common/XmlRequestBase.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_XMLREQUESTBASE_H_ +#define MAD_COMMON_XMLREQUESTBASE_H_ + +#include "XmlRequestHandler.h" +#include <stdint.h> + +namespace Mad { +namespace Common { + +class XmlRequestBase : public XmlRequestHandler { + protected: + virtual void sendRequest(Net::Connection *connection, uint16_t requestId) = 0; + + friend class RequestManager; +}; + +} +} + +#endif /* MAD_COMMON_XMLREQUESTBASE_H_ */ diff --git a/src/Common/XmlRequestHandler.h b/src/Common/XmlRequestHandler.h new file mode 100644 index 0000000..e04e5b9 --- /dev/null +++ b/src/Common/XmlRequestHandler.h @@ -0,0 +1,60 @@ +/* + * RequestHandler.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_XMLREQUESTHANDLER_H_ +#define MAD_COMMON_XMLREQUESTHANDLER_H_ + +#include <sigc++/signal.h> + +namespace Mad { + +namespace Net { +class Connection; +} + +namespace Common { + +class RequestManager; +class XmlPacket; + +class XmlRequestHandler { + private: + sigc::signal<void> finished; + + // Prevent shallow copy + XmlRequestHandler(const XmlRequestHandler &o); + XmlRequestHandler& operator=(const XmlRequestHandler &o); + + protected: + XmlRequestHandler() {} + + sigc::signal<void> signalFinished() {return finished;} + + virtual void handlePacket(Net::Connection *connection, const XmlPacket &packet) = 0; + + public: + virtual ~XmlRequestHandler() {} + + friend class RequestManager; +}; + +} +} + +#endif /* MAD_COMMON_XMLREQUESTHANDLER_H_ */ diff --git a/src/Core/Backends/Makefile.in b/src/Core/Backends/Makefile.in index 0f181f4..d905185 100644 --- a/src/Core/Backends/Makefile.in +++ b/src/Core/Backends/Makefile.in @@ -186,6 +186,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ diff --git a/src/Core/Makefile.am b/src/Core/Makefile.am index f7d6289..adc4d29 100644 --- a/src/Core/Makefile.am +++ b/src/Core/Makefile.am @@ -1,8 +1,8 @@ -SUBDIRS = Backends Requests RequestHandlers +SUBDIRS = Requests RequestHandlers noinst_LTLIBRARIES = libcore.la libcore_la_SOURCES = ConnectionManager.cpp UserBackend.cpp -libcore_la_LIBADD = Backends/libbackends.la Requests/librequests.la RequestHandlers/librequesthandlers.la +libcore_la_LIBADD = Requests/librequests.la RequestHandlers/librequesthandlers.la noinst_HEADERS = ConnectionManager.h UserBackend.h diff --git a/src/Core/Makefile.in b/src/Core/Makefile.in index 4745e1b..06b5e8b 100644 --- a/src/Core/Makefile.in +++ b/src/Core/Makefile.in @@ -49,8 +49,8 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) -libcore_la_DEPENDENCIES = Backends/libbackends.la \ - Requests/librequests.la RequestHandlers/librequesthandlers.la +libcore_la_DEPENDENCIES = Requests/librequests.la \ + RequestHandlers/librequesthandlers.la am_libcore_la_OBJECTS = ConnectionManager.lo UserBackend.lo libcore_la_OBJECTS = $(am_libcore_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) @@ -201,6 +201,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ @@ -224,10 +226,10 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -SUBDIRS = Backends Requests RequestHandlers +SUBDIRS = Requests RequestHandlers noinst_LTLIBRARIES = libcore.la libcore_la_SOURCES = ConnectionManager.cpp UserBackend.cpp -libcore_la_LIBADD = Backends/libbackends.la Requests/librequests.la RequestHandlers/librequesthandlers.la +libcore_la_LIBADD = Requests/librequests.la RequestHandlers/librequesthandlers.la noinst_HEADERS = ConnectionManager.h UserBackend.h all: all-recursive diff --git a/src/Core/RequestHandlers/Makefile.in b/src/Core/RequestHandlers/Makefile.in index 18076c0..3b071a9 100644 --- a/src/Core/RequestHandlers/Makefile.in +++ b/src/Core/RequestHandlers/Makefile.in @@ -194,6 +194,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ diff --git a/src/Core/Requests/Makefile.in b/src/Core/Requests/Makefile.in index 8b2ad77..0a98adb 100644 --- a/src/Core/Requests/Makefile.in +++ b/src/Core/Requests/Makefile.in @@ -191,6 +191,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ diff --git a/src/Daemon/Backends/Makefile.in b/src/Daemon/Backends/Makefile.in index 6f3c136..b09e948 100644 --- a/src/Daemon/Backends/Makefile.in +++ b/src/Daemon/Backends/Makefile.in @@ -173,6 +173,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ diff --git a/src/Daemon/Makefile.in b/src/Daemon/Makefile.in index fbaa98c..e4d9fd3 100644 --- a/src/Daemon/Makefile.in +++ b/src/Daemon/Makefile.in @@ -199,6 +199,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ diff --git a/src/Daemon/RequestHandlers/Makefile.in b/src/Daemon/RequestHandlers/Makefile.in index e4b4282..e44899b 100644 --- a/src/Daemon/RequestHandlers/Makefile.in +++ b/src/Daemon/RequestHandlers/Makefile.in @@ -190,6 +190,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ diff --git a/src/Daemon/Requests/Makefile.in b/src/Daemon/Requests/Makefile.in index 4cd6fe1..63c4d6f 100644 --- a/src/Daemon/Requests/Makefile.in +++ b/src/Daemon/Requests/Makefile.in @@ -190,6 +190,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ diff --git a/src/Makefile.am b/src/Makefile.am index a9027b5..9b1a9a2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,14 +21,14 @@ bin_PROGRAMS = mad madc mad-core mad_SOURCES = mad.cpp mad_LDADD = Daemon/libdaemon.la Common/libcommon.la Net/libnet.la \ - $(sigc_LIBS) $(GnuTLS_LIBS) @LIBLTDL@ $(daemon_modules) + $(libxml2_LIBS) $(sigc_LIBS) $(GnuTLS_LIBS) @LIBLTDL@ $(daemon_modules) mad_LDFLAGS = -export-dynamic madc_SOURCES = madc.cpp madc_LDADD = Client/libclient.la Common/libcommon.la Net/libnet.la \ - $(sigc_LIBS) $(GnuTLS_LIBS) $(READLINE_LIBS) + $(libxml2_LIBS) $(sigc_LIBS) $(GnuTLS_LIBS) $(READLINE_LIBS) mad_core_SOURCES = mad-core.cpp mad_core_LDADD = Core/libcore.la Common/libcommon.la Net/libnet.la \ - $(sigc_LIBS) $(GnuTLS_LIBS) $(GSSAPI_LIBS) @LIBLTDL@ $(core_modules) + $(libxml2_LIBS) $(sigc_LIBS) $(GnuTLS_LIBS) $(GSSAPI_LIBS) @LIBLTDL@ $(core_modules) mad_core_LDFLAGS = -export-dynamic diff --git a/src/Makefile.in b/src/Makefile.in index db34b93..a0347a1 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -66,7 +66,7 @@ am__DEPENDENCIES_4 = modules/FileLogger.la $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_3) mad_DEPENDENCIES = Daemon/libdaemon.la Common/libcommon.la \ Net/libnet.la $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_4) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4) mad_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(mad_LDFLAGS) \ $(LDFLAGS) -o $@ @@ -78,7 +78,8 @@ am__DEPENDENCIES_6 = modules/FileLogger.la $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_5) mad_core_DEPENDENCIES = Core/libcore.la Common/libcommon.la \ Net/libnet.la $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_6) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_6) mad_core_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(mad_core_LDFLAGS) $(LDFLAGS) -o $@ @@ -86,7 +87,7 @@ am_madc_OBJECTS = madc.$(OBJEXT) madc_OBJECTS = $(am_madc_OBJECTS) madc_DEPENDENCIES = Client/libclient.la Common/libcommon.la \ Net/libnet.la $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles @@ -234,6 +235,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ @@ -264,16 +267,16 @@ core_modules = -dlpreopen modules/FileLogger.la $(am__append_2) \ $(am__append_4) $(am__append_5) mad_SOURCES = mad.cpp mad_LDADD = Daemon/libdaemon.la Common/libcommon.la Net/libnet.la \ - $(sigc_LIBS) $(GnuTLS_LIBS) @LIBLTDL@ $(daemon_modules) + $(libxml2_LIBS) $(sigc_LIBS) $(GnuTLS_LIBS) @LIBLTDL@ $(daemon_modules) mad_LDFLAGS = -export-dynamic madc_SOURCES = madc.cpp madc_LDADD = Client/libclient.la Common/libcommon.la Net/libnet.la \ - $(sigc_LIBS) $(GnuTLS_LIBS) $(READLINE_LIBS) + $(libxml2_LIBS) $(sigc_LIBS) $(GnuTLS_LIBS) $(READLINE_LIBS) mad_core_SOURCES = mad-core.cpp mad_core_LDADD = Core/libcore.la Common/libcommon.la Net/libnet.la \ - $(sigc_LIBS) $(GnuTLS_LIBS) $(GSSAPI_LIBS) @LIBLTDL@ $(core_modules) + $(libxml2_LIBS) $(sigc_LIBS) $(GnuTLS_LIBS) $(GSSAPI_LIBS) @LIBLTDL@ $(core_modules) mad_core_LDFLAGS = -export-dynamic all: all-recursive diff --git a/src/Net/Makefile.in b/src/Net/Makefile.in index 1fad631..e7aa6b6 100644 --- a/src/Net/Makefile.in +++ b/src/Net/Makefile.in @@ -201,6 +201,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ diff --git a/src/Net/Packet.h b/src/Net/Packet.h index daab921..7baa454 100644 --- a/src/Net/Packet.h +++ b/src/Net/Packet.h @@ -38,7 +38,8 @@ class Packet { COMMAND_SHUTDOWN = 0x0040, COMMAND_REBOOT = 0x0041, DAEMON_COMMAND_SHUTDOWN = 0x0050, DAEMON_COMMAND_REBOOT = 0x0051, DAEMON_STATE_UPDATE = 0x0060, - USERS_LIST = 0x0070 + USERS_LIST = 0x0070, + XML = 0xFFFF }; struct Data { diff --git a/src/Net/Packets/Makefile.in b/src/Net/Packets/Makefile.in index be59444..47641fb 100644 --- a/src/Net/Packets/Makefile.in +++ b/src/Net/Packets/Makefile.in @@ -192,6 +192,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ diff --git a/src/mad-core.cpp b/src/mad-core.cpp index d5693ea..b5f6999 100644 --- a/src/mad-core.cpp +++ b/src/mad-core.cpp @@ -23,6 +23,8 @@ #include "Common/ModuleManager.h" #include "Core/ConnectionManager.h" +#include "Common/XmlPacket.h" + #include <signal.h> using namespace Mad; diff --git a/src/modules/Makefile.in b/src/modules/Makefile.in index 294f1d3..7c733dd 100644 --- a/src/modules/Makefile.in +++ b/src/modules/Makefile.in @@ -230,6 +230,8 @@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ |