Changeset - ddbeef1ecccb
[Not reviewed]
Merge
0 2 0
vitalyster - 10 years ago 2015-10-03 11:36:46
vitalyster@gmail.com
Merge pull request #1 from Ri0n/swiften3

Swiften3 compilation fixes
2 files changed with 5 insertions and 1 deletions:
0 comments (0 inline, 0 general)
backends/libyahoo2/main.cpp
Show inline comments
 
// Transport includes
 
#include "transport/config.h"
 
#include "transport/networkplugin.h"
 
#include "transport/logging.h"
 

	
 
// Yahoo2
 
#include <yahoo2.h>
 
#include <yahoo2_callbacks.h>
 
#include <stdio.h>
 
#include <stdarg.h>
 
#include <stdlib.h>
 

	
 
#include "yahoohandler.h"
 
#include "yahoolocalaccount.h"
 
#include "httpfetch.h"
 

	
 
// Swiften
 
#include "Swiften/Swiften.h"
 
#include "Swiften/Network/TLSConnectionFactory.h"
 
#include "Swiften/TLS/OpenSSL/OpenSSLContextFactory.h"
 

	
 
#ifndef _WIN32
 
// for signal handler
 
#include "unistd.h"
 
#include "signal.h"
 
#include "sys/wait.h"
 
#include "sys/signal.h"
 
#endif
 

	
 
// Boost
 
#include <boost/algorithm/string.hpp>
 
using namespace boost::filesystem;
 
using namespace boost::program_options;
 
using namespace Transport;
 

	
 
class YahooHandler;
 
class YahooLocalAccount;
 

	
 
static std::string *currently_read_data;
 
static YahooLocalAccount *currently_writting_account;
 

	
 
YahooHandler::YahooHandler(YahooLocalAccount *account, int conn_tag, int handler_tag, void *data, yahoo_input_condition cond) :
 
	handler_tag(handler_tag), conn_tag(conn_tag), data(data), cond(cond), remove_later(false), account(account) {}
 

	
 
YahooHandler::~YahooHandler() {}
 

	
 
void YahooHandler::ready(std::string *buffer) {
 
	if (cond == YAHOO_INPUT_WRITE) {
 
		YahooLocalAccount *old = currently_writting_account;
 
		currently_writting_account = account;
 
		yahoo_write_ready(account->id, (void *) conn_tag, data);
 
		currently_writting_account = old;
 
	}
 
	else {
 
		if (!buffer) {
 
			return;
 
		}
 
		// yahoo_read_ready calls ext_yahoo_read(...) in a loop, so we just have to choose proper buffer from which will
 
		// that method read. We do that by static currently_read_data pointer.
 
		currently_read_data = buffer;
 
		// libyahoo2 reads data per 1024 bytes, so if we still have some data after the first ext_yahoo_read call,
 
		// we have to call yahoo_read_ready again...
 
		do {
 
			yahoo_read_ready(account->id, (void *) conn_tag, data);
 
		} while (currently_read_data->size() != 0);
 
	}
 
}
 

	
 

	
 
typedef struct {
 
	std::string yahoo_id;
 
	std::string name;
 
	int status;
 
	int away;
 
	std::string msg;
 
	std::string group;
 
} yahoo_account;
 

	
 
typedef struct {
 
	int id;
 
	char *label;
 
} yahoo_idlabel;
 

	
 
typedef struct {
 
	int id;
 
	char *who;
 
} yahoo_authorize_data;
 

	
 
DEFINE_LOGGER(logger, "Yahoo2");
 

	
 
// eventloop
 
Swift::SimpleEventLoop *loop_;
 

	
 
// Plugin
 
class YahooPlugin;
 
YahooPlugin * np = NULL;
 

	
 
class YahooPlugin : public NetworkPlugin {
 
	public:
 
		Swift::BoostNetworkFactories *m_factories;
 
		Swift::OpenSSLContextFactory *m_sslFactory;
 
		Swift::TLSConnectionFactory *m_tlsFactory;
 
		Swift::BoostIOServiceThread m_boostIOServiceThread;
 
		boost::shared_ptr<Swift::Connection> m_conn;
 

	
 
		YahooPlugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin() {
 
			this->config = config;
 
			m_factories = new Swift::BoostNetworkFactories(loop);
 
			m_sslFactory = new Swift::OpenSSLContextFactory();
 
#if HAVE_SWIFTEN3
 
			m_tlsFactory = new Swift::TLSConnectionFactory(m_sslFactory, m_factories->getConnectionFactory(), Swift::TLSOptions());
 
#else
 
			m_tlsFactory = new Swift::TLSConnectionFactory(m_sslFactory, m_factories->getConnectionFactory());
 
#endif
 
			m_conn = m_factories->getConnectionFactory()->createConnection();
 
			m_conn->onDataRead.connect(boost::bind(&YahooPlugin::_handleDataRead, this, _1));
 
			m_conn->connect(Swift::HostAddressPort(Swift::HostAddress(host), port));
 

	
 
			LOG4CXX_INFO(logger, "Starting the plugin.");
 
		}
 

	
 
		// NetworkPlugin uses this method to send the data to networkplugin server
 
		void sendData(const std::string &string) {
 
			m_conn->write(Swift::createSafeByteArray(string));
 
		}
 

	
 
		// This method has to call handleDataRead with all received data from network plugin server
 
		void _handleDataRead(boost::shared_ptr<Swift::SafeByteArray> data) {
 
			std::string d(data->begin(), data->end());
 
			handleDataRead(d);
 
		}
 

	
 
		void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
 
			YahooLocalAccount *account = new YahooLocalAccount(user, legacyName, password);
 
			m_users[user] = account;
 
			m_ids[account->id] = user;
 

	
 
			LOG4CXX_INFO(logger, user << ": Logging in the user as " << legacyName << " with id=" << account->id);
 
			account->login();
 
		}
 

	
 
		void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
 
			YahooLocalAccount *account = m_users[user];
 
			if (account) {
 
				yahoo_logoff(account->id);
 
				m_ids.erase(account->id);
 
				m_users.erase(user);
 
				delete account;
 
			}
 
		}
 

	
 
		void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml = "", const std::string &id = "") {
 
			YahooLocalAccount *account = m_users[user];
 
			if (account) {
 
				LOG4CXX_INFO(logger, "Sending message from " << user << " to " << legacyName << ": " << message << ".");
 
				yahoo_send_im(account->id, NULL, legacyName.c_str(), message.c_str(), 0, 0);
 
				_yahoo_write_ready(account);
 
			}
 
		}
 

	
 
		void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups) {
 
			LOG4CXX_INFO(logger, user << ": Added buddy " << buddyName << ".");
 
			handleBuddyChanged(user, buddyName, alias, groups, pbnetwork::STATUS_ONLINE);
 
		}
 

	
 
		void _avatar_fetched(HTTPFetch *fetch, int account_id, unsigned int id, const std::string &img) {
 
			handleVCard(m_ids[account_id], id, "", "", "", img);
 
			delete fetch;
 
		}
 

	
 
		void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) {
 
			YahooLocalAccount *account = m_users[user];
 
			if (!account) {
 
				return;
 
			}
 

	
 
			if (account->urls.find(legacyName) == account->urls.end()) {
 
				return;
 
			}
 

	
 
			HTTPFetch *fetch = new HTTPFetch(&m_boostIOServiceThread, m_factories->getConnectionFactory());
 
			fetch->onURLFetched.connect(boost::bind(&YahooPlugin::_avatar_fetched, this, fetch, account->id, id, _1));
 
			fetch->fetchURL(account->urls[legacyName]);
 
		}
 

	
 
		void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups) {
 

	
 
		}
 

	
 
		YahooLocalAccount *getAccount(int id) {
 
			return m_users[m_ids[id]];
 
		}
 

	
 
		void _yahoo_remove_account(YahooLocalAccount *account) {
 
			m_ids.erase(account->id);
 
			m_users.erase(account->user);
 
			delete account;
 
		}
 

	
 
		void _yahoo_connect_finished(YahooLocalAccount *account, yahoo_connect_callback callback, void *data, int conn_tag, bool error) {
 
			currently_writting_account = account;
 
			if (error) {
 
				LOG4CXX_ERROR(logger, account->user << ": Connection error!");
 
				callback(NULL, 0, data);
 
// 				np->handleDisconnected(user, 0, "Connection error.");
 
			}
 
			else {
 
				LOG4CXX_INFO(logger, account->user << ": Connected");
 
				// We will have dangling pointer here, but we can't pass boost::shared_ptr here...
 
				callback((void *) conn_tag, 0, data);
 
			}
 
		}
 

	
 
		void _yahoo_write_ready(YahooLocalAccount *account) {
 
			// Find all WRITE handlers and inform that they really can write.
 
			for (std::map<int, YahooHandler *>::iterator it = account->handlers.begin(); it != account->handlers.end(); it++) {
 
				if (it->second->cond == YAHOO_INPUT_WRITE && !it->second->remove_later) {
 
					it->second->ready();
 
				}
 
			}
 
		}
 

	
 
		void _yahoo_data_read(YahooLocalAccount *account, int conn_tag, boost::shared_ptr<Swift::SafeByteArray> data) {
 
			std::string d(data->begin(), data->end());
 

	
 
			// Find the handler that handles READing for this conn_tag
 
			for (std::map<int, YahooHandler *>::iterator it = account->handlers_per_conn[conn_tag].begin(); it != account->handlers_per_conn[conn_tag].end(); it++) {
 
				if (it->second->cond == YAHOO_INPUT_READ && !it->second->remove_later) {
 
					std::string cpy(d);
 
					it->second->ready(&cpy);
 

	
 
					// Look like libyahoo2 needs to be informed it can write to socket after the read
 
					// even we have informed it before...
 
					_yahoo_write_ready(account);
 
					break;
 
				}
 
			}
 

	
 
			account->removeOldHandlers();
 
		}
 

	
 
		void _yahoo_data_written(YahooLocalAccount *account, int conn_tag) {
 
			LOG4CXX_INFO(logger, "data written");
 
			for (std::map<int, YahooHandler *>::iterator it = account->handlers_per_conn[conn_tag].begin(); it != account->handlers_per_conn[conn_tag].end(); it++) {
 
				if (it->second->cond == YAHOO_INPUT_WRITE) {
 
					it->second->ready();
 
				}
 
			}
 

	
 
			account->removeOldHandlers();
 
		}
 

	
 
		void _yahoo_disconnected(YahooLocalAccount *account, int conn_tag, const boost::optional<Swift::Connection::Error> &error) {
 
			for (std::map<int, YahooHandler *>::iterator it = account->handlers_per_conn[conn_tag].begin(); it != account->handlers_per_conn[conn_tag].end(); it++) {
 
				if (it->second->cond == YAHOO_INPUT_READ && !it->second->remove_later) {
 
					std::string cpy;
 
					it->second->ready(&cpy);
 
					_yahoo_write_ready(account);
 
					break;
 
				}
 
			}
 

	
 
			account->removeConn(conn_tag);
 
		}
 

	
 
		int _yahoo_connect_async(int id, const char *host, int port, yahoo_connect_callback callback, void *data, int use_ssl) {
 
			YahooLocalAccount *account = getAccount(id);
 
			if (!account) {
 
				LOG4CXX_ERROR(logger, "Unknown account id=" << id);
 
				return -1;
 
			}
 

	
 
			boost::asio::ip::tcp::resolver resolver(*m_boostIOServiceThread.getIOService());
 
			boost::asio::ip::tcp::resolver::query query(host, "");
 
			boost::asio::ip::address address;
 
			for(boost::asio::ip::tcp::resolver::iterator i = resolver.resolve(query); i != boost::asio::ip::tcp::resolver::iterator(); ++i) {
 
				boost::asio::ip::tcp::endpoint end = *i;
 
				address = end.address();
 
				break;
 
			}
 

	
 
			LOG4CXX_INFO(logger, m_ids[id] << ": Connecting " << host << ":" << port);
 
			int tag = account->conn_tag++;
 
			if (use_ssl) {
 
				account->conns[tag] = m_tlsFactory->createConnection();
 
			}
 
			else {
 
				account->conns[tag] = m_factories->getConnectionFactory()->createConnection();
 
			}
 
			account->conns[tag]->onConnectFinished.connect(boost::bind(&YahooPlugin::_yahoo_connect_finished, this, account, callback, data, tag, _1));
 
			account->conns[tag]->onDisconnected.connect(boost::bind(&YahooPlugin::_yahoo_disconnected, this, account, tag, _1));
 
			account->conns[tag]->onDataRead.connect(boost::bind(&YahooPlugin::_yahoo_data_read, this, account, tag, _1));
 
			account->conns[tag]->onDataWritten.connect(boost::bind(&YahooPlugin::_yahoo_data_written, this, account, tag));
 
			account->conns[tag]->connect(Swift::HostAddressPort(Swift::HostAddress(address), port));
 
			return tag;
 
		}
 

	
 
	private:
 
		Config *config;
 
		std::map<std::string, YahooLocalAccount *> m_users;
 
		std::map<int, std::string> m_ids;
 
};
 

	
 
static void spectrum_sigchld_handler(int sig)
 
{
 
	int status;
backends/twitter/CMakeLists.txt
Show inline comments
 
include_directories (${libtransport_SOURCE_DIR}/backends/twitter/libtwitcurl) 
 
FILE(GLOB SRC *.cpp libtwitcurl/*.cpp Requests/*.cpp)
 
add_executable(spectrum2_twitter_backend ${SRC})
 

	
 
find_package(curl)
 
find_package(CURL)
 

	
 
if(CURL_FOUND)
 
message(STATUS "Using curl ${CURL_VERSION_STRING}: ${CURL_INCLUDE_DIRS} ${CURL_LIBRARIES}")
 
include_directories (${CURL_INCLUDE_DIRS}) 
 
target_link_libraries(spectrum2_twitter_backend transport ${CURL_LIBRARIES} ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
 
else()
 
message(FATAL_ERROR "curl not found")
 
endif()
 

	
 
INSTALL(TARGETS spectrum2_twitter_backend RUNTIME DESTINATION bin)
0 comments (0 inline, 0 general)