summaryrefslogtreecommitdiffstats
path: root/Sluift
diff options
context:
space:
mode:
Diffstat (limited to 'Sluift')
-rw-r--r--Sluift/ElementConvertors/DOMElementConvertor.cpp2
-rw-r--r--Sluift/ElementConvertors/DefaultElementConvertor.cpp4
-rw-r--r--Sluift/Examples/SendReference.lua74
-rw-r--r--Sluift/SConscript2
-rw-r--r--Sluift/SluiftClient.cpp20
-rw-r--r--Sluift/SluiftClient.h15
-rw-r--r--Sluift/SluiftComponent.cpp13
-rw-r--r--Sluift/SluiftComponent.h6
-rw-r--r--Sluift/client.cpp51
-rw-r--r--Sluift/component.cpp13
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);