diff options
Diffstat (limited to 'Sluift')
-rw-r--r-- | Sluift/ClientHelpers.cpp | 50 | ||||
-rw-r--r-- | Sluift/ClientHelpers.h | 18 | ||||
-rw-r--r-- | Sluift/Lua/Value.cpp | 4 | ||||
-rw-r--r-- | Sluift/SConscript | 22 | ||||
-rw-r--r-- | Sluift/SluiftException.h | 70 | ||||
-rw-r--r-- | Sluift/sluift.cpp | 612 | ||||
-rw-r--r-- | Sluift/sluift.h | 11 |
7 files changed, 344 insertions, 443 deletions
diff --git a/Sluift/ClientHelpers.cpp b/Sluift/ClientHelpers.cpp new file mode 100644 index 0000000..8e07112 --- /dev/null +++ b/Sluift/ClientHelpers.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ + +#include <Sluift/ClientHelpers.h> + +#include <Swiften/Client/ClientError.h> + +using namespace Swift; + +std::string Swift::getClientErrorString(const ClientError& error) { + std::string reason = "Disconnected: "; + switch(error.getType()) { + case ClientError::UnknownError: reason += "Unknown Error"; break; + case ClientError::DomainNameResolveError: reason += "Unable to find server"; break; + case ClientError::ConnectionError: reason += "Error connecting to server"; break; + case ClientError::ConnectionReadError: reason += "Error while receiving server data"; break; + case ClientError::ConnectionWriteError: reason += "Error while sending data to the server"; break; + case ClientError::XMLError: reason += "Error parsing server data"; break; + case ClientError::AuthenticationFailedError: reason += "Login/password invalid"; break; + case ClientError::CompressionFailedError: reason += "Error while compressing stream"; break; + case ClientError::ServerVerificationFailedError: reason += "Server verification failed"; break; + case ClientError::NoSupportedAuthMechanismsError: reason += "Authentication mechanisms not supported"; break; + case ClientError::UnexpectedElementError: reason += "Unexpected response"; break; + case ClientError::ResourceBindError: reason += "Error binding resource"; break; + case ClientError::RevokedError: reason += "Certificate got revoked"; break; + case ClientError::RevocationCheckFailedError: reason += "Failed to do revokation check"; break; + case ClientError::SessionStartError: reason += "Error starting session"; break; + case ClientError::StreamError: reason += "Stream error"; break; + case ClientError::TLSError: reason += "Encryption error"; break; + case ClientError::ClientCertificateLoadError: reason += "Error loading certificate (Invalid password?)"; break; + case ClientError::ClientCertificateError: reason += "Certificate not authorized"; break; + case ClientError::UnknownCertificateError: reason += "Unknown certificate"; break; + case ClientError::CertificateCardRemoved: reason += "Certificate card removed"; break; + case ClientError::CertificateExpiredError: reason += "Certificate has expired"; break; + case ClientError::CertificateNotYetValidError: reason += "Certificate is not yet valid"; break; + case ClientError::CertificateSelfSignedError: reason += "Certificate is self-signed"; break; + case ClientError::CertificateRejectedError: reason += "Certificate has been rejected"; break; + case ClientError::CertificateUntrustedError: reason += "Certificate is not trusted"; break; + case ClientError::InvalidCertificatePurposeError: reason += "Certificate cannot be used for encrypting your connection"; break; + case ClientError::CertificatePathLengthExceededError: reason += "Certificate path length constraint exceeded"; break; + case ClientError::InvalidCertificateSignatureError: reason += "Invalid certificate signature"; break; + case ClientError::InvalidCAError: reason += "Invalid Certificate Authority"; break; + case ClientError::InvalidServerIdentityError: reason += "Certificate does not match the host identity"; break; + } + return reason; +} + diff --git a/Sluift/ClientHelpers.h b/Sluift/ClientHelpers.h new file mode 100644 index 0000000..eb78ba6 --- /dev/null +++ b/Sluift/ClientHelpers.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ + +#pragma once + +#include <Swiften/Base/Override.h> +#include <Swiften/Base/API.h> + +#include <string> + +namespace Swift { + class ClientError; + + std::string getClientErrorString(const ClientError& error); +} diff --git a/Sluift/Lua/Value.cpp b/Sluift/Lua/Value.cpp index 817cbf3..4f8078e 100644 --- a/Sluift/Lua/Value.cpp +++ b/Sluift/Lua/Value.cpp @@ -6,7 +6,9 @@ #include "Value.h" -#include <lualib.h> +extern "C" { + #include <lualib.h> +} #include <boost/variant/apply_visitor.hpp> #include <boost/numeric/conversion/cast.hpp> #include <Swiften/Base/foreach.h> diff --git a/Sluift/SConscript b/Sluift/SConscript index 2c247d8..af3cf8c 100644 --- a/Sluift/SConscript +++ b/Sluift/SConscript @@ -8,17 +8,13 @@ if env["SCONS_STAGE"] == "build" and not GetOption("help") and not env.get("HAVE env["PROJECTS"].remove("Sluift") elif env["SCONS_STAGE"] == "build" : - lib_env = env.Clone() - lib_env.UseFlags(env["LUA_FLAGS"]) - lib_env.UseFlags(env["SWIFTEN_FLAGS"]) - lib_env.UseFlags(env["SWIFTEN_DEP_FLAGS"]) - sluift_lib = lib_env.StaticLibrary("SluiftCore", [ - "Lua/Value.cpp", - "sluift.cpp" - ]); + sluift_sources = [ + "Lua/Value.cpp", + "ClientHelpers.cpp", + "sluift.cpp" + ] myenv = env.Clone() - myenv.Append(LIBS = sluift_lib) myenv.UseFlags(env.get("LUA_FLAGS", {})) myenv.UseFlags(env["SWIFTEN_FLAGS"]) myenv.UseFlags(env["SWIFTEN_DEP_FLAGS"]) @@ -27,10 +23,6 @@ elif env["SCONS_STAGE"] == "build" : myenv.Append(CPPDEFINES = ["SLUIFT_BUILD_DLL"]) elif myenv["PLATFORM"] == "darwin" : myenv["SHLIBSUFFIX"] = ".so" - if env["PLATFORM"] == "win32" : - myenv.Append(CFLAGS = ["/TP"]) - else : - myenv.Append(CFLAGS = ["-x", "c++"]) myenv["SLUIFT_VERSION"] = Version.getBuildVersion(env.Dir("#").abspath, "sluift") def patchLua(env, target, source) : @@ -51,13 +43,13 @@ elif env["SCONS_STAGE"] == "build" : if myenv.get("HAVE_READLINE", False) : myenv.Append(CPPDEFINES = ["LUA_USE_READLINE"]) myenv.MergeFlags(myenv["READLINE_FLAGS"]) - env["SLUIFT"] = myenv.Program("sluift", [ + env["SLUIFT"] = myenv.Program("sluift", sluift_sources + [ "lua.c", "linit.c", ]) myenv.WriteVal("dll.c", myenv.Value("")) - myenv.SharedLibrary("sluift", ["dll.c"]) + myenv.SharedLibrary("sluift", sluift_sources + ["dll.c"]) if env["PLATFORM"] == "win32" : ssl_libs = [] diff --git a/Sluift/SluiftException.h b/Sluift/SluiftException.h deleted file mode 100644 index 6964523..0000000 --- a/Sluift/SluiftException.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2011 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#pragma once - -#include <string> - -#include <Swiften/Client/ClientError.h> - -namespace Swift { - class SluiftException : public std::exception { - public: - virtual ~SluiftException() throw() {} - - SluiftException(const std::string& reason) : reason(reason) { - } - - SluiftException(const ClientError& error) { - reason = "Disconnected: "; - switch(error.getType()) { - case ClientError::UnknownError: reason += "Unknown Error"; break; - case ClientError::DomainNameResolveError: reason += "Unable to find server"; break; - case ClientError::ConnectionError: reason += "Error connecting to server"; break; - case ClientError::ConnectionReadError: reason += "Error while receiving server data"; break; - case ClientError::ConnectionWriteError: reason += "Error while sending data to the server"; break; - case ClientError::XMLError: reason += "Error parsing server data"; break; - case ClientError::AuthenticationFailedError: reason += "Login/password invalid"; break; - case ClientError::CompressionFailedError: reason += "Error while compressing stream"; break; - case ClientError::ServerVerificationFailedError: reason += "Server verification failed"; break; - case ClientError::NoSupportedAuthMechanismsError: reason += "Authentication mechanisms not supported"; break; - case ClientError::UnexpectedElementError: reason += "Unexpected response"; break; - case ClientError::ResourceBindError: reason += "Error binding resource"; break; - case ClientError::RevokedError: reason += "Certificate got revoked"; break; - case ClientError::RevocationCheckFailedError: reason += "Failed to do revokation check"; break; - case ClientError::SessionStartError: reason += "Error starting session"; break; - case ClientError::StreamError: reason += "Stream error"; break; - case ClientError::TLSError: reason += "Encryption error"; break; - case ClientError::ClientCertificateLoadError: reason += "Error loading certificate (Invalid password?)"; break; - case ClientError::ClientCertificateError: reason += "Certificate not authorized"; break; - case ClientError::UnknownCertificateError: reason += "Unknown certificate"; break; - case ClientError::CertificateCardRemoved: reason += "Certificate card removed"; break; - case ClientError::CertificateExpiredError: reason += "Certificate has expired"; break; - case ClientError::CertificateNotYetValidError: reason += "Certificate is not yet valid"; break; - case ClientError::CertificateSelfSignedError: reason += "Certificate is self-signed"; break; - case ClientError::CertificateRejectedError: reason += "Certificate has been rejected"; break; - case ClientError::CertificateUntrustedError: reason += "Certificate is not trusted"; break; - case ClientError::InvalidCertificatePurposeError: reason += "Certificate cannot be used for encrypting your connection"; break; - case ClientError::CertificatePathLengthExceededError: reason += "Certificate path length constraint exceeded"; break; - case ClientError::InvalidCertificateSignatureError: reason += "Invalid certificate signature"; break; - case ClientError::InvalidCAError: reason += "Invalid Certificate Authority"; break; - case ClientError::InvalidServerIdentityError: reason += "Certificate does not match the host identity"; break; - } - } - - const std::string& getReason() const { - return reason; - } - - virtual const char* what() const throw() { - return getReason().c_str(); - } - - - private: - std::string reason; - }; -} diff --git a/Sluift/sluift.cpp b/Sluift/sluift.cpp index 0a653bb..397d7f3 100644 --- a/Sluift/sluift.cpp +++ b/Sluift/sluift.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Remko Tronçon + * Copyright (c) 2011-2013 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -17,9 +17,9 @@ #include <Swiften/Swiften.h> #include "Watchdog.h" -#include "SluiftException.h" #include "ResponseSink.h" #include "Lua/Value.h" +#include "ClientHelpers.h" using namespace Swift; @@ -42,7 +42,7 @@ static BoostNetworkFactories networkFactories(&eventLoop); class SluiftClient { public: - SluiftClient(const JID& jid, const std::string& password) : tracer(NULL) { + SluiftClient(const JID& jid, const std::string& password, lua_State* L) : L(L), tracer(NULL) { client = new Client(jid, password, &networkFactories); client->setAlwaysTrustCertificates(); client->onDisconnected.connect(boost::bind(&SluiftClient::handleDisconnected, this, _1)); @@ -85,7 +85,7 @@ class SluiftClient { } if (watchdog.getTimedOut()) { client->disconnect(); - throw SluiftException("Timeout while connecting"); + luaL_error(L, "Timeout while connecting"); } } @@ -183,11 +183,12 @@ class SluiftClient { void handleDisconnected(const boost::optional<ClientError>& error) { if (error) { - throw SluiftException(*error); + luaL_error(L, getClientErrorString(*error).c_str()); } } private: + lua_State* L; Client* client; ClientOptions options; ClientXMLTracer* tracer; @@ -205,44 +206,29 @@ static inline SluiftClient* getClient(lua_State* L) { } static int sluift_client_connect(lua_State *L) { - try { - SluiftClient* client = getClient(L); - std::string host; - if (lua_type(L, 2) != LUA_TNONE) { - host = luaL_checkstring(L, 2); - } - if (host.empty()) { - client->connect(); - } - else { - client->connect(host); - } - client->waitConnected(); - return 1; + SluiftClient* client = getClient(L); + std::string host; + if (lua_type(L, 2) != LUA_TNONE) { + host = luaL_checkstring(L, 2); } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); + if (host.empty()) { + client->connect(); } + else { + client->connect(host); + } + client->waitConnected(); + return 1; } static int sluift_client_async_connect(lua_State *L) { - try { - getClient(L)->connect(); - return 1; - } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); - } + getClient(L)->connect(); + return 1; } static int sluift_client_wait_connected(lua_State *L) { - try { - getClient(L)->waitConnected(); - return 1; - } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); - } + getClient(L)->waitConnected(); + return 1; } static int sluift_client_is_connected(lua_State *L) { @@ -251,221 +237,176 @@ static int sluift_client_is_connected(lua_State *L) { } static int sluift_client_disconnect(lua_State *L) { - try { - getClient(L)->disconnect(); - return 1; - } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); - } + getClient(L)->disconnect(); + return 1; } static int sluift_client_set_version(lua_State *L) { - try { - eventLoop.runOnce(); + eventLoop.runOnce(); - SluiftClient* client = getClient(L); - luaL_checktype(L, 2, LUA_TTABLE); - lua_getfield(L, 2, "name"); - const char* rawName = lua_tostring(L, -1); - lua_getfield(L, 2, "version"); - const char* rawVersion = lua_tostring(L, -1); - lua_getfield(L, 2, "os"); - const char* rawOS = lua_tostring(L, -1); - client->setSoftwareVersion(rawName ? rawName : "", rawVersion ? rawVersion : "", rawOS ? rawOS : ""); - lua_pop(L, 3); - lua_pushvalue(L, 1); - return 1; - } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); - } + SluiftClient* client = getClient(L); + luaL_checktype(L, 2, LUA_TTABLE); + lua_getfield(L, 2, "name"); + const char* rawName = lua_tostring(L, -1); + lua_getfield(L, 2, "version"); + const char* rawVersion = lua_tostring(L, -1); + lua_getfield(L, 2, "os"); + const char* rawOS = lua_tostring(L, -1); + client->setSoftwareVersion(rawName ? rawName : "", rawVersion ? rawVersion : "", rawOS ? rawOS : ""); + lua_pop(L, 3); + lua_pushvalue(L, 1); + return 1; } static int sluift_client_get_contacts(lua_State *L) { - try { - eventLoop.runOnce(); + eventLoop.runOnce(); - SluiftClient* client = getClient(L); - Lua::Table contactsTable; - foreach(const XMPPRosterItem& item, client->getRoster()) { - std::string subscription; - switch(item.getSubscription()) { - case RosterItemPayload::None: subscription = "none"; break; - case RosterItemPayload::To: subscription = "to"; break; - case RosterItemPayload::From: subscription = "from"; break; - case RosterItemPayload::Both: subscription = "both"; break; - case RosterItemPayload::Remove: subscription = "remove"; break; - } - Lua::Value groups(std::vector<Lua::Value>(item.getGroups().begin(), item.getGroups().end())); - Lua::Table itemTable = boost::assign::map_list_of - ("jid", boost::make_shared<Lua::Value>(item.getJID().toString())) - ("name", boost::make_shared<Lua::Value>(item.getName())) - ("subscription", boost::make_shared<Lua::Value>(subscription)) - ("groups", boost::make_shared<Lua::Value>(std::vector<Lua::Value>(item.getGroups().begin(), item.getGroups().end()))); - contactsTable[item.getJID().toString()] = boost::make_shared<Lua::Value>(itemTable); - } - pushValue(L, contactsTable); - return 1; - } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); - } + SluiftClient* client = getClient(L); + Lua::Table contactsTable; + foreach(const XMPPRosterItem& item, client->getRoster()) { + std::string subscription; + switch(item.getSubscription()) { + case RosterItemPayload::None: subscription = "none"; break; + case RosterItemPayload::To: subscription = "to"; break; + case RosterItemPayload::From: subscription = "from"; break; + case RosterItemPayload::Both: subscription = "both"; break; + case RosterItemPayload::Remove: subscription = "remove"; break; + } + Lua::Value groups(std::vector<Lua::Value>(item.getGroups().begin(), item.getGroups().end())); + Lua::Table itemTable = boost::assign::map_list_of + ("jid", boost::make_shared<Lua::Value>(item.getJID().toString())) + ("name", boost::make_shared<Lua::Value>(item.getName())) + ("subscription", boost::make_shared<Lua::Value>(subscription)) + ("groups", boost::make_shared<Lua::Value>(std::vector<Lua::Value>(item.getGroups().begin(), item.getGroups().end()))); + contactsTable[item.getJID().toString()] = boost::make_shared<Lua::Value>(itemTable); + } + pushValue(L, contactsTable); + return 1; } static int sluift_client_get_version(lua_State *L) { - try { - SluiftClient* client = getClient(L); - int timeout = -1; - if (lua_type(L, 3) != LUA_TNONE) { - timeout = boost::numeric_cast<int>(luaL_checknumber(L, 3)); - } + SluiftClient* client = getClient(L); + int timeout = -1; + if (lua_type(L, 3) != LUA_TNONE) { + timeout = boost::numeric_cast<int>(luaL_checknumber(L, 3)); + } - ResponseSink<SoftwareVersion> sink; - GetSoftwareVersionRequest::ref request = GetSoftwareVersionRequest::create(std::string(luaL_checkstring(L, 2)), client->getClient()->getIQRouter()); - boost::signals::scoped_connection c = request->onResponse.connect(boost::ref(sink)); - request->send(); + ResponseSink<SoftwareVersion> sink; + GetSoftwareVersionRequest::ref request = GetSoftwareVersionRequest::create(std::string(luaL_checkstring(L, 2)), client->getClient()->getIQRouter()); + boost::signals::scoped_connection c = request->onResponse.connect(boost::ref(sink)); + request->send(); - Watchdog watchdog(timeout, networkFactories.getTimerFactory()); - while (!watchdog.getTimedOut() && !sink.hasResponse()) { - eventLoop.runUntilEvents(); - } + Watchdog watchdog(timeout, networkFactories.getTimerFactory()); + while (!watchdog.getTimedOut() && !sink.hasResponse()) { + eventLoop.runUntilEvents(); + } - ErrorPayload::ref error = sink.getResponseError(); - if (error || watchdog.getTimedOut()) { - lua_pushnil(L); - if (watchdog.getTimedOut()) { - lua_pushstring(L, "Timeout"); - } - else if (error->getCondition() == ErrorPayload::RemoteServerNotFound) { - lua_pushstring(L, "Remote server not found"); - } - // TODO - else { - lua_pushstring(L, "Error"); - } - return 2; + ErrorPayload::ref error = sink.getResponseError(); + if (error || watchdog.getTimedOut()) { + lua_pushnil(L); + if (watchdog.getTimedOut()) { + lua_pushstring(L, "Timeout"); } - else if (SoftwareVersion::ref version = sink.getResponsePayload()) { - Lua::Table result = boost::assign::map_list_of - ("name", boost::make_shared<Lua::Value>(version->getName())) - ("version", boost::make_shared<Lua::Value>(version->getVersion())) - ("os", boost::make_shared<Lua::Value>(version->getOS())); - Lua::pushValue(L, result); + else if (error->getCondition() == ErrorPayload::RemoteServerNotFound) { + lua_pushstring(L, "Remote server not found"); } + // TODO else { - lua_pushnil(L); + lua_pushstring(L, "Error"); } - return 1; + return 2; + } + else if (SoftwareVersion::ref version = sink.getResponsePayload()) { + Lua::Table result = boost::assign::map_list_of + ("name", boost::make_shared<Lua::Value>(version->getName())) + ("version", boost::make_shared<Lua::Value>(version->getVersion())) + ("os", boost::make_shared<Lua::Value>(version->getOS())); + Lua::pushValue(L, result); } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); + else { + lua_pushnil(L); } + return 1; } static int sluift_client_send_message(lua_State *L) { - try { - eventLoop.runOnce(); + eventLoop.runOnce(); - getClient(L)->sendMessage(std::string(luaL_checkstring(L, 2)), luaL_checkstring(L, 3)); - lua_pushvalue(L, 1); - return 1; - } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); - } + getClient(L)->sendMessage(std::string(luaL_checkstring(L, 2)), luaL_checkstring(L, 3)); + lua_pushvalue(L, 1); + return 1; } static int sluift_client_send_presence(lua_State *L) { - try { - eventLoop.runOnce(); + eventLoop.runOnce(); - getClient(L)->sendPresence(std::string(luaL_checkstring(L, 2))); - lua_pushvalue(L, 1); - return 0; - } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); - } + getClient(L)->sendPresence(std::string(luaL_checkstring(L, 2))); + lua_pushvalue(L, 1); + return 0; } static int sluift_client_get(lua_State *L) { - try { - SluiftClient* client = getClient(L); - JID jid; - std::string data; - int timeout = -1; - if (lua_type(L, 3) == LUA_TSTRING) { - jid = JID(std::string(luaL_checkstring(L, 2))); - data = std::string(luaL_checkstring(L, 3)); - if (lua_type(L, 4) != LUA_TNONE) { - timeout = boost::numeric_cast<int>(luaL_checknumber(L, 4)); - } - } - else { - data = std::string(luaL_checkstring(L, 2)); - if (lua_type(L, 3) != LUA_TNONE) { - timeout = boost::numeric_cast<int>(luaL_checknumber(L, 3)); - } - } - boost::optional<std::string> result = client->sendQuery(jid, IQ::Get, data, timeout); - if (result) { - lua_pushstring(L, result->c_str()); + SluiftClient* client = getClient(L); + JID jid; + std::string data; + int timeout = -1; + if (lua_type(L, 3) == LUA_TSTRING) { + jid = JID(std::string(luaL_checkstring(L, 2))); + data = std::string(luaL_checkstring(L, 3)); + if (lua_type(L, 4) != LUA_TNONE) { + timeout = boost::numeric_cast<int>(luaL_checknumber(L, 4)); } - else { - lua_pushnil(L); + } + else { + data = std::string(luaL_checkstring(L, 2)); + if (lua_type(L, 3) != LUA_TNONE) { + timeout = boost::numeric_cast<int>(luaL_checknumber(L, 3)); } - return 1; } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); + boost::optional<std::string> result = client->sendQuery(jid, IQ::Get, data, timeout); + if (result) { + lua_pushstring(L, result->c_str()); } + else { + lua_pushnil(L); + } + return 1; } static int sluift_client_set(lua_State *L) { - try { - SluiftClient* client = getClient(L); - JID jid; - std::string data; - int timeout = -1; - if (lua_type(L, 3) == LUA_TSTRING) { - jid = JID(std::string(luaL_checkstring(L, 2))); - data = std::string(luaL_checkstring(L, 3)); - if (lua_type(L, 4) != LUA_TNONE) { - timeout = boost::numeric_cast<int>(luaL_checknumber(L, 4)); - } - } - else { - data = std::string(luaL_checkstring(L, 2)); - if (lua_type(L, 3) != LUA_TNONE) { - timeout = boost::numeric_cast<int>(luaL_checknumber(L, 3)); - } - } - boost::optional<std::string> result = client->sendQuery(jid, IQ::Set, data, timeout); - if (result) { - lua_pushstring(L, result->c_str()); + SluiftClient* client = getClient(L); + JID jid; + std::string data; + int timeout = -1; + if (lua_type(L, 3) == LUA_TSTRING) { + jid = JID(std::string(luaL_checkstring(L, 2))); + data = std::string(luaL_checkstring(L, 3)); + if (lua_type(L, 4) != LUA_TNONE) { + timeout = boost::numeric_cast<int>(luaL_checknumber(L, 4)); } - else { - lua_pushnil(L); + } + else { + data = std::string(luaL_checkstring(L, 2)); + if (lua_type(L, 3) != LUA_TNONE) { + timeout = boost::numeric_cast<int>(luaL_checknumber(L, 3)); } - return 1; } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); + boost::optional<std::string> result = client->sendQuery(jid, IQ::Set, data, timeout); + if (result) { + lua_pushstring(L, result->c_str()); + } + else { + lua_pushnil(L); } + return 1; } static int sluift_client_send(lua_State *L) { - try { - eventLoop.runOnce(); + eventLoop.runOnce(); - getClient(L)->getClient()->sendData(std::string(luaL_checkstring(L, 2))); - lua_pushvalue(L, 1); - return 0; - } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); - } + getClient(L)->getClient()->sendData(std::string(luaL_checkstring(L, 2))); + lua_pushvalue(L, 1); + return 0; } static int sluift_client_set_options(lua_State* L) { @@ -509,131 +450,91 @@ static void pushEvent(lua_State* L, Stanza::ref event) { } static int sluift_client_for_event(lua_State *L) { - try { - eventLoop.runOnce(); + eventLoop.runOnce(); - SluiftClient* client = getClient(L); - luaL_checktype(L, 2, LUA_TFUNCTION); - int timeout = -1; - if (lua_type(L, 3) != LUA_TNONE) { - timeout = boost::numeric_cast<int>(lua_tonumber(L, 3)); - } + SluiftClient* client = getClient(L); + luaL_checktype(L, 2, LUA_TFUNCTION); + int timeout = -1; + if (lua_type(L, 3) != LUA_TNONE) { + timeout = boost::numeric_cast<int>(lua_tonumber(L, 3)); + } - while (true) { - Stanza::ref event = client->getNextEvent(timeout); - if (!event) { - // We got a timeout - lua_pushnil(L); - return 1; - } - else { - // Push the function and event on the stack - lua_pushvalue(L, 2); - pushEvent(L, event); - int oldTop = lua_gettop(L) - 2; - lua_call(L, 1, LUA_MULTRET); - int returnValues = lua_gettop(L) - oldTop; - if (returnValues > 0) { - lua_remove(L, -1 - returnValues); - return returnValues; - } + while (true) { + Stanza::ref event = client->getNextEvent(timeout); + if (!event) { + // We got a timeout + lua_pushnil(L); + return 1; + } + else { + // Push the function and event on the stack + lua_pushvalue(L, 2); + pushEvent(L, event); + int oldTop = lua_gettop(L) - 2; + lua_call(L, 1, LUA_MULTRET); + int returnValues = lua_gettop(L) - oldTop; + if (returnValues > 0) { + lua_remove(L, -1 - returnValues); + return returnValues; } } } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); - } } static int sluift_client_get_next_event(lua_State *L) { - try { - eventLoop.runOnce(); + eventLoop.runOnce(); - SluiftClient* client = getClient(L); - int timeout = -1; - if (lua_type(L, 2) != LUA_TNONE) { - timeout = boost::numeric_cast<int>(lua_tonumber(L, 2)); - } - pushEvent(L, client->getNextEvent(timeout)); - return 1; - } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); + SluiftClient* client = getClient(L); + int timeout = -1; + if (lua_type(L, 2) != LUA_TNONE) { + timeout = boost::numeric_cast<int>(lua_tonumber(L, 2)); } + pushEvent(L, client->getNextEvent(timeout)); + return 1; } static int sluift_client_add_contact(lua_State* L) { - try { - eventLoop.runOnce(); - SluiftClient* client = getClient(L); - RosterItemPayload item; - if (lua_type(L, 2) == LUA_TTABLE) { - lua_getfield(L, 2, "jid"); - const char* rawJID = lua_tostring(L, -1); - if (rawJID) { - item.setJID(std::string(rawJID)); - } - lua_getfield(L, 2, "name"); - const char* rawName = lua_tostring(L, -1); - if (rawName) { - item.setName(rawName); - } - lua_getfield(L, 2, "groups"); - if (!lua_isnil(L, -1)) { - if (lua_type(L, -1) == LUA_TTABLE) { - for (size_t i = 1; i <= lua_objlen(L, -1); ++i) { - lua_rawgeti(L, -1, boost::numeric_cast<int>(i)); - const char* rawGroup = lua_tostring(L, -1); - if (rawGroup) { - item.addGroup(rawGroup); - } - lua_pop(L, 1); + eventLoop.runOnce(); + SluiftClient* client = getClient(L); + RosterItemPayload item; + if (lua_type(L, 2) == LUA_TTABLE) { + lua_getfield(L, 2, "jid"); + const char* rawJID = lua_tostring(L, -1); + if (rawJID) { + item.setJID(std::string(rawJID)); + } + lua_getfield(L, 2, "name"); + const char* rawName = lua_tostring(L, -1); + if (rawName) { + item.setName(rawName); + } + lua_getfield(L, 2, "groups"); + if (!lua_isnil(L, -1)) { + if (lua_type(L, -1) == LUA_TTABLE) { + for (size_t i = 1; i <= lua_objlen(L, -1); ++i) { + lua_rawgeti(L, -1, boost::numeric_cast<int>(i)); + const char* rawGroup = lua_tostring(L, -1); + if (rawGroup) { + item.addGroup(rawGroup); } - } - else { - return luaL_error(L, "Groups should be a table"); + lua_pop(L, 1); } } - } - else { - item.setJID(luaL_checkstring(L, 2)); - } - - client->getRoster(); - if (!client->getClient()->getRoster()->containsJID(item.getJID())) { - RosterPayload::ref roster = boost::make_shared<RosterPayload>(); - roster->addItem(item); - - ResponseSink<RosterPayload> sink; - SetRosterRequest::ref request = SetRosterRequest::create(roster, client->getClient()->getIQRouter()); - boost::signals::scoped_connection c = request->onResponse.connect(boost::ref(sink)); - request->send(); - while (!sink.hasResponse()) { - eventLoop.runUntilEvents(); - } - if (sink.getResponseError()) { - lua_pushboolean(L, false); - return 1; + else { + return luaL_error(L, "Groups should be a table"); } } - client->getClient()->getSubscriptionManager()->requestSubscription(item.getJID()); - lua_pushboolean(L, true); - return 1; } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); + else { + item.setJID(luaL_checkstring(L, 2)); } -} - -static int sluift_client_remove_contact(lua_State* L) { - try { - eventLoop.runOnce(); - SluiftClient* client = getClient(L); - JID jid(luaL_checkstring(L, 2)); + client->getRoster(); + if (!client->getClient()->getRoster()->containsJID(item.getJID())) { RosterPayload::ref roster = boost::make_shared<RosterPayload>(); - roster->addItem(RosterItemPayload(JID(luaL_checkstring(L, 2)), "", RosterItemPayload::Remove)); + roster->addItem(item); + ResponseSink<RosterPayload> sink; SetRosterRequest::ref request = SetRosterRequest::create(roster, client->getClient()->getIQRouter()); boost::signals::scoped_connection c = request->onResponse.connect(boost::ref(sink)); @@ -641,38 +542,48 @@ static int sluift_client_remove_contact(lua_State* L) { while (!sink.hasResponse()) { eventLoop.runUntilEvents(); } - lua_pushboolean(L, !sink.getResponseError()); - return 1; - } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); + if (sink.getResponseError()) { + lua_pushboolean(L, false); + return 1; + } } + client->getClient()->getSubscriptionManager()->requestSubscription(item.getJID()); + lua_pushboolean(L, true); + return 1; +} + +static int sluift_client_remove_contact(lua_State* L) { + eventLoop.runOnce(); + SluiftClient* client = getClient(L); + JID jid(luaL_checkstring(L, 2)); + + RosterPayload::ref roster = boost::make_shared<RosterPayload>(); + roster->addItem(RosterItemPayload(JID(luaL_checkstring(L, 2)), "", RosterItemPayload::Remove)); + ResponseSink<RosterPayload> sink; + SetRosterRequest::ref request = SetRosterRequest::create(roster, client->getClient()->getIQRouter()); + boost::signals::scoped_connection c = request->onResponse.connect(boost::ref(sink)); + request->send(); + while (!sink.hasResponse()) { + eventLoop.runUntilEvents(); + } + lua_pushboolean(L, !sink.getResponseError()); + return 1; } static int sluift_client_confirm_subscription(lua_State* L) { - try { - eventLoop.runOnce(); - SluiftClient* client = getClient(L); - JID jid(luaL_checkstring(L, 2)); - client->getClient()->getSubscriptionManager()->confirmSubscription(jid); - return 0; - } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); - } + eventLoop.runOnce(); + SluiftClient* client = getClient(L); + JID jid(luaL_checkstring(L, 2)); + client->getClient()->getSubscriptionManager()->confirmSubscription(jid); + return 0; } static int sluift_client_cancel_subscription(lua_State* L) { - try { - eventLoop.runOnce(); - SluiftClient* client = getClient(L); - JID jid(luaL_checkstring(L, 2)); - client->getClient()->getSubscriptionManager()->cancelSubscription(jid); - return 0; - } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); - } + eventLoop.runOnce(); + SluiftClient* client = getClient(L); + JID jid(luaL_checkstring(L, 2)); + client->getClient()->getSubscriptionManager()->cancelSubscription(jid); + return 0; } static int sluift_client_gc (lua_State *L) { @@ -711,20 +622,16 @@ static const luaL_reg sluift_client_functions[] = { ******************************************************************************/ static int sluift_new_client(lua_State *L) { - try { - JID jid(std::string(luaL_checkstring(L, 1))); - std::string password(luaL_checkstring(L, 2)); + luaL_checkstring(L, 1); + JID jid(std::string(luaL_checkstring(L, 1))); + std::string password(luaL_checkstring(L, 2)); - SluiftClient** client = reinterpret_cast<SluiftClient**>(lua_newuserdata(L, sizeof(SluiftClient*))); - luaL_getmetatable(L, SLUIFT_CLIENT); - lua_setmetatable(L, -2); + SluiftClient** client = reinterpret_cast<SluiftClient**>(lua_newuserdata(L, sizeof(SluiftClient*))); + luaL_getmetatable(L, SLUIFT_CLIENT); + lua_setmetatable(L, -2); - *client = new SluiftClient(jid, password); - return 1; - } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); - } + *client = new SluiftClient(jid, password, L); + return 1; } static int sluift_jid_to_bare(lua_State *L) { @@ -752,20 +659,15 @@ static int sluift_jid_resource(lua_State *L) { } static int sluift_sleep(lua_State *L) { - try { - eventLoop.runOnce(); + eventLoop.runOnce(); - int timeout = boost::numeric_cast<int>(luaL_checknumber(L, 1)); - Watchdog watchdog(timeout, networkFactories.getTimerFactory()); - while (!watchdog.getTimedOut()) { - Swift::sleep(boost::numeric_cast<unsigned int>(std::min(100, timeout))); - eventLoop.runOnce(); - } - return 0; - } - catch (const SluiftException& e) { - return luaL_error(L, e.getReason().c_str()); + int timeout = boost::numeric_cast<int>(luaL_checknumber(L, 1)); + Watchdog watchdog(timeout, networkFactories.getTimerFactory()); + while (!watchdog.getTimedOut()) { + Swift::sleep(boost::numeric_cast<unsigned int>(std::min(100, timeout))); + eventLoop.runOnce(); } + return 0; } static int sluift_index(lua_State *L) { diff --git a/Sluift/sluift.h b/Sluift/sluift.h index 27b4eab..4e0f5ee 100644 --- a/Sluift/sluift.h +++ b/Sluift/sluift.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Remko Tronçon + * Copyright (c) 2011-2013 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -9,9 +9,16 @@ #if defined(SLUIFT_BUILD_DLL) #define SLUIFT_API __declspec(dllexport) #else -#define SLUIFT_API extern +#define SLUIFT_API #endif +#if defined(__cplusplus) +#include <lua.hpp> +#else #include <lua.h> +#endif +#if defined(__cplusplus) +extern "C" +#endif SLUIFT_API int (luaopen_sluift)(lua_State *L); |