diff options
Diffstat (limited to 'Sluift')
-rw-r--r-- | Sluift/ElementConvertors/DOMElementConvertor.cpp | 2 | ||||
-rw-r--r-- | Sluift/ElementConvertors/DefaultElementConvertor.cpp | 4 | ||||
-rw-r--r-- | Sluift/Examples/SendReference.lua | 74 | ||||
-rw-r--r-- | Sluift/SConscript | 2 | ||||
-rw-r--r-- | Sluift/SluiftClient.cpp | 20 | ||||
-rw-r--r-- | Sluift/SluiftClient.h | 15 | ||||
-rw-r--r-- | Sluift/SluiftComponent.cpp | 13 | ||||
-rw-r--r-- | Sluift/SluiftComponent.h | 6 | ||||
-rw-r--r-- | Sluift/client.cpp | 51 | ||||
-rw-r--r-- | Sluift/component.cpp | 13 |
10 files changed, 169 insertions, 31 deletions
diff --git a/Sluift/ElementConvertors/DOMElementConvertor.cpp b/Sluift/ElementConvertors/DOMElementConvertor.cpp index 56b45aa..5e72cc8 100644 --- a/Sluift/ElementConvertors/DOMElementConvertor.cpp +++ b/Sluift/ElementConvertors/DOMElementConvertor.cpp @@ -185,7 +185,7 @@ boost::optional<std::string> DOMElementConvertor::convertToLua( // Parse the payload again ParserClient parserClient(L); - std::shared_ptr<XMLParser> parser(parsers.createXMLParser(&parserClient)); + std::shared_ptr<XMLParser> parser(parsers.createXMLParser(&parserClient, false)); bool result = parser->parse(serializedPayload); assert(result); diff --git a/Sluift/ElementConvertors/DefaultElementConvertor.cpp b/Sluift/ElementConvertors/DefaultElementConvertor.cpp index 75e6706..d3d60ff 100644 --- a/Sluift/ElementConvertors/DefaultElementConvertor.cpp +++ b/Sluift/ElementConvertors/DefaultElementConvertor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016 Isode Limited. + * Copyright (c) 2013-2019 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -20,7 +20,7 @@ DefaultElementConvertor::~DefaultElementConvertor() { } std::shared_ptr<Element> DefaultElementConvertor::convertFromLua(lua_State*, int, const std::string& type) { - SWIFT_LOG(warning) << "Unable to convert type '" << type << "'" << std::endl; + SWIFT_LOG(warning) << "Unable to convert type '" << type << "'"; return std::shared_ptr<Element>(); } diff --git a/Sluift/Examples/SendReference.lua b/Sluift/Examples/SendReference.lua new file mode 100644 index 0000000..2e60182 --- /dev/null +++ b/Sluift/Examples/SendReference.lua @@ -0,0 +1,74 @@ +#!/usr/bin/env sluift -- + +-- This is an example of sending a custom payload, a XEP-0372 reference in this +-- case. +-- +-- Running this requires a sluift binary somewhere in the PATH. Alternatively, +-- you can feed this to sluift, or to a Lua that has sluift.so in its library +-- path. + +require("sluift") + +DEFAULT_URI = "http://example.com/kitten.jpg" + +function usage(err) + print("Usage: SendReference.lua jid [tojid] [datauri]") + print() + print("This tool will log in as jid, and send a reference to tojid. If no tojid") + print("is provided, a message to itself is sent. The datauri defaults to") + print(DEFAULT_URI .. ", but can be overridden.") + + if err then + print("") + print("Error: " .. err) + end + os.exit(1) +end + +function get_password(prompt) + if prompt then + io.write(prompt) + end + local stty_ret = os.execute("stty -echo 2>/dev/null") + if stty_ret then + io.write("\027[8m") + end + local ok, pass = pcall(io.read, "*l") + if stty_ret then + io.write("\027[m") + else + os.execute("stty echo") + end + io.write("\n"); + if ok then + return pass + end +end + +if #arg < 1 then + usage("no jid specified") +end +jid = arg[1] +password = os.getenv("XMPP_PASSWORD") or get_password("Password: ") +tojid = #arg > 1 and arg[2] or jid +datauri = #arg > 2 and arg[3] or DEFAULT_URI + +sluift.debug = 1 +sluift.with(sluift.new_client(jid, password), function() + options = { host=os.getenv("XMPP_HOST"), port=os.getenv("XMPP_PORT") } + connect(options) + reference = { + ['_type'] = 'dom', + ['tag'] = 'reference', + ['ns'] = 'urn:xmpp:reference:0', + ['attributes'] = { + { ['name'] = 'type', ['value'] = 'data' }, + { ['name'] = 'uri', ['value'] = datauri }, + { ['name'] = 'mimeType', ['value'] = arg[4] }, + { ['name'] = 'begin', ['value'] = arg[5] }, + { ['name'] = 'end', ['value'] = arg[6] } + }, + } + send_message{to=tojid, body="Check out this data!", payloads={reference}} + disconnect() +end) diff --git a/Sluift/SConscript b/Sluift/SConscript index de9cab6..af54ece 100644 --- a/Sluift/SConscript +++ b/Sluift/SConscript @@ -3,7 +3,7 @@ import Version, os.path Import(["env"]) if env["SCONS_STAGE"] == "build" and not GetOption("help") and not env.get("HAVE_LUA", 0) : - print "Warning: Lua was not found. Sluift will not be built." + print("Warning: Lua was not found. Sluift will not be built.") if "Sluift" in env["PROJECTS"] : env["PROJECTS"].remove("Sluift") diff --git a/Sluift/SluiftClient.cpp b/Sluift/SluiftClient.cpp index e8c43c9..99892a9 100644 --- a/Sluift/SluiftClient.cpp +++ b/Sluift/SluiftClient.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 Isode Limited. + * Copyright (c) 2013-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -38,6 +38,9 @@ SluiftClient::SluiftClient( client->onPresenceReceived.connect(boost::bind(&SluiftClient::handleIncomingPresence, this, _1)); client->getPubSubManager()->onEvent.connect(boost::bind(&SluiftClient::handleIncomingPubSubEvent, this, _1, _2)); client->getRoster()->onInitialRosterPopulated.connect(boost::bind(&SluiftClient::handleInitialRosterPopulated, this)); + client->getRoster()->onJIDAdded.connect(boost::bind(&SluiftClient::handleIncomingRosterAdd, this, _1)); + client->getRoster()->onJIDRemoved.connect(boost::bind(&SluiftClient::handleIncomingRosterRemove, this, _1)); + client->getRoster()->onJIDUpdated.connect(boost::bind(&SluiftClient::handleIncomingRosterUpdate, this, _1)); client->getClientBlockListManager()->getBlockList()->onItemAdded.connect(boost::bind(&SluiftClient::handleIncomingBlockEvent, this, _1)); client->getClientBlockListManager()->getBlockList()->onItemRemoved.connect(boost::bind(&SluiftClient::handleIncomingUnblockEvent, this, _1)); } @@ -48,6 +51,9 @@ SluiftClient::~SluiftClient() { } void SluiftClient::connect() { + if (client->isActive()) { + throw Lua::Exception("Client is already connecting or connected"); + } rosterReceived = false; blockListReceived = false; disconnectedError = boost::optional<ClientError>(); @@ -189,6 +195,18 @@ void SluiftClient::handleInitialRosterPopulated() { rosterReceived = true; } +void SluiftClient::handleIncomingRosterAdd(const JID& item) { + pendingEvents.push_back(Event(item, Event::RosterAddType)); +} + +void SluiftClient::handleIncomingRosterRemove(const JID& item) { + pendingEvents.push_back(Event(item, Event::RosterRemoveType)); +} + +void SluiftClient::handleIncomingRosterUpdate(const JID& item) { + pendingEvents.push_back(Event(item, Event::RosterUpdateType)); +} + void SluiftClient::handleRequestResponse(std::shared_ptr<Payload> response, std::shared_ptr<ErrorPayload> error) { requestResponse = response; requestError = error; diff --git a/Sluift/SluiftClient.h b/Sluift/SluiftClient.h index a48c681..ac4c582 100644 --- a/Sluift/SluiftClient.h +++ b/Sluift/SluiftClient.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 Isode Limited. + * Copyright (c) 2013-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -45,7 +45,10 @@ namespace Swift { PresenceType, PubSubEventType, BlockEventType, - UnblockEventType + UnblockEventType, + RosterAddType, + RosterRemoveType, + RosterUpdateType }; Event(std::shared_ptr<Message> stanza) : type(MessageType), stanza(stanza) {} @@ -61,7 +64,7 @@ namespace Swift { JID from; std::shared_ptr<PubSubEventPayload> pubsubEvent; - // Blocklist + // Blocklist & Roster Push JID item; }; @@ -81,7 +84,6 @@ namespace Swift { } void connect(); - void connect(const std::string& host, int port); void waitConnected(int timeout); bool isConnected() const; void setTraceEnabled(bool b); @@ -110,7 +112,7 @@ namespace Swift { void disconnect(); void setSoftwareVersion(const std::string& name, const std::string& version, const std::string& os); boost::optional<SluiftClient::Event> getNextEvent(int timeout, - boost::function<bool (const Event&)> condition = 0); + boost::function<bool (const Event&)> condition = boost::function<bool (const Event&)>()); std::vector<XMPPRosterItem> getRoster(int timeout); std::vector<JID> getBlockList(int timeout); @@ -123,6 +125,9 @@ namespace Swift { void handleIncomingBlockEvent(const JID& item); void handleIncomingUnblockEvent(const JID& item); void handleInitialRosterPopulated(); + void handleIncomingRosterAdd(const JID& item); + void handleIncomingRosterRemove(const JID& item); + void handleIncomingRosterUpdate(const JID& item); void handleRequestResponse(std::shared_ptr<Payload> response, std::shared_ptr<ErrorPayload> error); void handleDisconnected(const boost::optional<ClientError>& error); diff --git a/Sluift/SluiftComponent.cpp b/Sluift/SluiftComponent.cpp index e1d1738..74728ee 100644 --- a/Sluift/SluiftComponent.cpp +++ b/Sluift/SluiftComponent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016 Isode Limited. + * Copyright (c) 2014-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -40,7 +40,10 @@ SluiftComponent::~SluiftComponent() { delete component; } -void SluiftComponent::connect(const std::string& host, int port) { +void SluiftComponent::connect(const std::string& host, unsigned short port) { + if (component->isActive()) { + throw Lua::Exception("Component is already connecting or connected"); + } disconnectedError = boost::optional<ComponentError>(); component->connect(host, port); } @@ -75,7 +78,7 @@ bool SluiftComponent::isConnected() const { void SluiftComponent::disconnect() { component->disconnect(); - while (component->isAvailable()) { + while (component->isActive()) { eventLoop->runUntilEvents(); } } @@ -102,12 +105,12 @@ boost::optional<SluiftComponent::Event> SluiftComponent::getNextEvent( } // Wait for new events - while (!watchdog.getTimedOut() && currentIndex >= pendingEvents.size() && component->isAvailable()) { + while (!watchdog.getTimedOut() && currentIndex >= pendingEvents.size() && component->isActive()) { eventLoop->runUntilEvents(); } // Finish if we're disconnected or timed out - if (watchdog.getTimedOut() || !component->isAvailable()) { + if (watchdog.getTimedOut() || !component->isActive()) { return boost::optional<Event>(); } } diff --git a/Sluift/SluiftComponent.h b/Sluift/SluiftComponent.h index d45c3b2..586a94e 100644 --- a/Sluift/SluiftComponent.h +++ b/Sluift/SluiftComponent.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016 Isode Limited. + * Copyright (c) 2014-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -63,7 +63,7 @@ namespace Swift { return component; } - void connect(const std::string& host, int port); + void connect(const std::string& host, unsigned short port); void waitConnected(int timeout); bool isConnected() const; void setTraceEnabled(bool b); @@ -85,7 +85,7 @@ namespace Swift { void disconnect(); void setSoftwareVersion(const std::string& name, const std::string& version, const std::string& os); boost::optional<SluiftComponent::Event> getNextEvent(int timeout, - boost::function<bool (const Event&)> condition = 0); + boost::function<bool (const Event&)> condition = boost::function<bool (const Event&)>()); private: Sluift::Response doSendRequest(std::shared_ptr<Request> request, int timeout); diff --git a/Sluift/client.cpp b/Sluift/client.cpp index ae2f610..814ad45 100644 --- a/Sluift/client.cpp +++ b/Sluift/client.cpp @@ -1,12 +1,10 @@ /* - * Copyright (c) 2013-2017 Isode Limited. + * Copyright (c) 2013-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <boost/assign/list_of.hpp> -#include <boost/lambda/bind.hpp> -#include <boost/lambda/lambda.hpp> #include <Swiften/Base/IDGenerator.h> #include <Swiften/Disco/ClientDiscoManager.h> @@ -42,7 +40,6 @@ #include <Sluift/globals.h> using namespace Swift; -namespace lambda = boost::lambda; static inline SluiftClient* getClient(lua_State* L) { return *Lua::checkUserData<SluiftClient>(L, 1); @@ -302,6 +299,7 @@ SLUIFT_LUA_FUNCTION_WITH_HELP( "body the body of the message. Can alternatively be specified using the `body` option\n", "to the JID to send the message to\n" + "id the id to set on the stanza\n" "body the body of the message\n" "subject the subject of the MUC room to set\n" "type the type of message to send (`normal`, `chat`, `error`, `groupchat`, `headline`)\n" @@ -310,6 +308,7 @@ SLUIFT_LUA_FUNCTION_WITH_HELP( Sluift::globals.eventLoop.runOnce(); JID to; boost::optional<std::string> body; + boost::optional<std::string> id; boost::optional<std::string> subject; std::vector<std::shared_ptr<Payload> > payloads; int index = 2; @@ -327,6 +326,10 @@ SLUIFT_LUA_FUNCTION_WITH_HELP( to = *value; } + if (boost::optional<std::string> value = Lua::getStringField(L, index, "id")) { + id = value; + } + if (boost::optional<std::string> value = Lua::getStringField(L, index, "body")) { body = value; } @@ -353,6 +356,9 @@ SLUIFT_LUA_FUNCTION_WITH_HELP( if (body && !body->empty()) { message->setBody(*body); } + if (id) { + message->setID(*id); + } if (subject) { message->setSubject(*subject); } @@ -372,7 +378,8 @@ SLUIFT_LUA_FUNCTION_WITH_HELP( "self\n" "body the text of the presence. Can alternatively be specified using the `status` option\n", - "to the JID to send the message to\n" + "to the JID to send the presence to\n" + "id the id to set on the stanza\n" "status the text of the presence\n" "show the availability of the presence (`online`, `ffc`, `away`, `xa`, `dnd`)\n" "priority the priority of the presence\n" @@ -391,6 +398,9 @@ SLUIFT_LUA_FUNCTION_WITH_HELP( if (boost::optional<std::string> value = Lua::getStringField(L, index, "to")) { presence->setTo(*value); } + if (boost::optional<std::string> id = Lua::getStringField(L, index, "id")) { + presence->setID(*id); + } if (boost::optional<std::string> value = Lua::getStringField(L, index, "status")) { presence->setStatus(*value); } @@ -602,6 +612,33 @@ static void pushEvent(lua_State* L, const SluiftClient::Event& event) { Lua::registerTableToString(L, -1); break; } + case SluiftClient::Event::RosterAddType: { + Lua::Table result = boost::assign::map_list_of + ("type", std::make_shared<Lua::Value>(std::string("rosterpush"))) + ("jid", std::make_shared<Lua::Value>(event.item.toString())) + ("action", std::make_shared<Lua::Value>(std::string("added"))); + Lua::pushValue(L, result); + Lua::registerTableToString(L, -1); + break; + } + case SluiftClient::Event::RosterRemoveType: { + Lua::Table result = boost::assign::map_list_of + ("type", std::make_shared<Lua::Value>(std::string("rosterpush"))) + ("jid", std::make_shared<Lua::Value>(event.item.toString())) + ("action", std::make_shared<Lua::Value>(std::string("removed"))); + Lua::pushValue(L, result); + Lua::registerTableToString(L, -1); + break; + } + case SluiftClient::Event::RosterUpdateType: { + Lua::Table result = boost::assign::map_list_of + ("type", std::make_shared<Lua::Value>(std::string("rosterpush"))) + ("jid", std::make_shared<Lua::Value>(event.item.toString())) + ("action", std::make_shared<Lua::Value>(std::string("updated"))); + Lua::pushValue(L, result); + Lua::registerTableToString(L, -1); + break; + } } } @@ -659,7 +696,9 @@ SLUIFT_LUA_FUNCTION(Client, get_next_event) { } else if (type) { event = client->getNextEvent( - timeout, lambda::bind(&SluiftClient::Event::type, lambda::_1) == *type); + timeout, [&](const SluiftClient::Event& event) { + return event.type == *type; + }); } else { event = client->getNextEvent(timeout); diff --git a/Sluift/component.cpp b/Sluift/component.cpp index df96d43..c1b1da4 100644 --- a/Sluift/component.cpp +++ b/Sluift/component.cpp @@ -1,12 +1,10 @@ /* - * Copyright (c) 2014-2016 Isode Limited. + * Copyright (c) 2014-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <boost/assign/list_of.hpp> -#include <boost/lambda/bind.hpp> -#include <boost/lambda/lambda.hpp> #include <Swiften/Base/IDGenerator.h> #include <Swiften/Elements/DiscoInfo.h> @@ -41,7 +39,6 @@ #include <Sluift/globals.h> using namespace Swift; -namespace lambda = boost::lambda; static inline SluiftComponent* getComponent(lua_State* L) { return *Lua::checkUserData<SluiftComponent>(L, 1); @@ -99,13 +96,13 @@ SLUIFT_LUA_FUNCTION(Component, async_connect) { SluiftComponent* component = getComponent(L); std::string host; - int port = 0; + unsigned short port = 0; if (lua_istable(L, 2)) { if (boost::optional<std::string> hostString = Lua::getStringField(L, 2, "host")) { host = *hostString; } if (boost::optional<int> portInt = Lua::getIntField(L, 2, "port")) { - port = *portInt; + port = boost::numeric_cast<unsigned short>(*portInt); } } component->connect(host, port); @@ -433,7 +430,9 @@ SLUIFT_LUA_FUNCTION(Component, get_next_event) { } else if (type) { event = component->getNextEvent( - timeout, lambda::bind(&SluiftComponent::Event::type, lambda::_1) == *type); + timeout, [&](const SluiftComponent::Event& event) { + return event.type == *type; + }); } else { event = component->getNextEvent(timeout); |