Changeset - 8e28ea2f10e9
[Not reviewed]
0 1 0
HanzZ - 13 years ago 2013-02-05 08:35:49
hanzz.k@gmail.com
fix previous commit
1 file changed with 4 insertions and 4 deletions:
0 comments (0 inline, 0 general)
backends/swiften/main.cpp
Show inline comments
 
@@ -126,336 +126,336 @@ class SwiftenPlugin : public NetworkPlugin {
 
			m_conn = m_factories->getConnectionFactory()->createConnection();
 
			m_conn->onDataRead.connect(boost::bind(&SwiftenPlugin::_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 handleSwiftDisconnected(const std::string &user, const boost::optional<Swift::ClientError> &error) {
 
			std::string message = "";
 
			bool reconnect = false;
 
			if (error) {
 
				switch(error->getType()) {
 
					case Swift::ClientError::UnknownError: message = ("Unknown Error"); reconnect = true; break;
 
					case Swift::ClientError::DomainNameResolveError: message = ("Unable to find server"); break;
 
					case Swift::ClientError::ConnectionError: message = ("Error connecting to server"); break;
 
					case Swift::ClientError::ConnectionReadError: message = ("Error while receiving server data"); reconnect = true; break;
 
					case Swift::ClientError::ConnectionWriteError: message = ("Error while sending data to the server"); reconnect = true; break;
 
					case Swift::ClientError::XMLError: message = ("Error parsing server data"); reconnect = true; break;
 
					case Swift::ClientError::AuthenticationFailedError: message = ("Login/password invalid"); break;
 
					case Swift::ClientError::CompressionFailedError: message = ("Error while compressing stream"); break;
 
					case Swift::ClientError::ServerVerificationFailedError: message = ("Server verification failed"); break;
 
					case Swift::ClientError::NoSupportedAuthMechanismsError: message = ("Authentication mechanisms not supported"); break;
 
					case Swift::ClientError::UnexpectedElementError: message = ("Unexpected response"); break;
 
					case Swift::ClientError::ResourceBindError: message = ("Error binding resource"); break;
 
					case Swift::ClientError::SessionStartError: message = ("Error starting session"); break;
 
					case Swift::ClientError::StreamError: message = ("Stream error"); break;
 
					case Swift::ClientError::TLSError: message = ("Encryption error"); break;
 
					case Swift::ClientError::ClientCertificateLoadError: message = ("Error loading certificate (Invalid password?)"); break;
 
					case Swift::ClientError::ClientCertificateError: message = ("Certificate not authorized"); break;
 

	
 
					case Swift::ClientError::UnknownCertificateError: message = ("Unknown certificate"); break;
 
					case Swift::ClientError::CertificateExpiredError: message = ("Certificate has expired"); break;
 
					case Swift::ClientError::CertificateNotYetValidError: message = ("Certificate is not yet valid"); break;
 
					case Swift::ClientError::CertificateSelfSignedError: message = ("Certificate is self-signed"); break;
 
					case Swift::ClientError::CertificateRejectedError: message = ("Certificate has been rejected"); break;
 
					case Swift::ClientError::CertificateUntrustedError: message = ("Certificate is not trusted"); break;
 
					case Swift::ClientError::InvalidCertificatePurposeError: message = ("Certificate cannot be used for encrypting your connection"); break;
 
					case Swift::ClientError::CertificatePathLengthExceededError: message = ("Certificate path length constraint exceeded"); break;
 
					case Swift::ClientError::InvalidCertificateSignatureError: message = ("Invalid certificate signature"); break;
 
					case Swift::ClientError::InvalidCAError: message = ("Invalid Certificate Authority"); break;
 
					case Swift::ClientError::InvalidServerIdentityError: message = ("Certificate does not match the host identity"); break;
 
				}
 
			}
 
			LOG4CXX_INFO(logger, user << ": Disconnected " << message);
 
			handleDisconnected(user, reconnect ? 0 : 3, message);
 

	
 
			boost::shared_ptr<Swift::Client> client = m_users[user];
 
			if (client) {
 
				client->onConnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
 
				client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
 
				client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
 
				m_users.erase(user);
 
				m_mucs.erase(user);
 
			}
 

	
 
#ifndef WIN32
 
#ifndef __FreeBSD__
 
#ifndef __MACH__
 
			// force returning of memory chunks allocated by libxml2 to kernel
 
			malloc_trim(0);
 
#endif
 
#endif
 
#endif
 
		}
 

	
 
		void handleSwiftConnected(const std::string &user) {
 
			LOG4CXX_INFO(logger, user << ": Connected to XMPP server.");
 
			handleConnected(user);
 
			m_users[user]->requestRoster();
 
			Swift::Presence::ref response = Swift::Presence::create();
 
			response->setFrom(m_users[user]->getJID());
 
			m_users[user]->sendPresence(response);
 
		}
 

	
 
		void handleSwiftRosterReceived(const std::string &user) {
 
			Swift::PresenceOracle *oracle = m_users[user]->getPresenceOracle();
 
			BOOST_FOREACH(const Swift::XMPPRosterItem &item, m_users[user]->getRoster()->getItems()) {
 
				Swift::Presence::ref lastPresence = oracle->getLastPresence(item.getJID());
 
				pbnetwork::StatusType status = lastPresence ? ((pbnetwork::StatusType) lastPresence->getShow()) : pbnetwork::STATUS_NONE;
 
				handleBuddyChanged(user, item.getJID().toBare().toString(),
 
								   item.getName(), item.getGroups(), status);
 
			}
 
		}
 

	
 
		void handleSwiftPresenceChanged(const std::string &user, Swift::Presence::ref presence) {
 
			boost::shared_ptr<Swift::Client> client = m_users[user];
 
			if (client->getMUCRegistry()->isMUC(presence->getFrom().toBare())) {
 
				return;
 
			}
 

	
 
			LOG4CXX_INFO(logger, user << ": " << presence->getFrom().toBare().toString() << " presence changed");
 

	
 
			std::string message = presence->getStatus();
 
			std::string photo = "";
 

	
 
			boost::shared_ptr<Swift::VCardUpdate> update = presence->getPayload<Swift::VCardUpdate>();
 
			if (update) {
 
				photo = update->getPhotoHash();
 
			}
 

	
 
			boost::optional<Swift::XMPPRosterItem> item = m_users[user]->getRoster()->getItem(presence->getFrom());
 
			if (item) {
 
				handleBuddyChanged(user, presence->getFrom().toBare().toString(), item->getName(), item->getGroups(), (pbnetwork::StatusType) presence->getShow(), message, photo);
 
			}
 
			else {
 
				std::vector<std::string> groups;
 
				handleBuddyChanged(user, presence->getFrom().toBare().toString(), presence->getFrom().toBare(), groups, (pbnetwork::StatusType) presence->getShow(), message, photo);
 
			}
 
		}
 

	
 
		void handleSwiftMessageReceived(const std::string &user, Swift::Message::ref message) {
 
			std::string body = message->getBody();
 
			boost::shared_ptr<Swift::Client> client = m_users[user];
 
			if (client) {
 
				if (message->getType() == Swift::Message::Groupchat) {
 
					boost::shared_ptr<Swift::Delay> delay = message->getPayload<Swift::Delay>();
 
					std::string timestamp = "";
 
					if (delay) {
 
						timestamp = boost::posix_time::to_iso_string(delay->getStamp());
 
					}
 
					handleMessage(user, message->getFrom().toBare().toString(), body, message->getFrom().getResource(), "", timestamp);
 
				}
 
				else {
 
					if (client->getMUCRegistry()->isMUC(message->getFrom().toBare())) {
 
						handleMessage(user, message->getFrom().toBare().toString(), body, message->getFrom().getResource(), "", "", false, true);
 
					}
 
					else {
 
						handleMessage(user, message->getFrom().toBare().toString(), body, "", "");
 
					}
 
				}
 
			}
 
		}
 

	
 
		void handleSwiftVCardReceived(const std::string &user, unsigned int id, Swift::VCard::ref vcard, Swift::ErrorPayload::ref error) {
 
			if (error || !vcard) {
 
				LOG4CXX_INFO(logger, user << ": error fetching VCard with id=" << id);
 
				handleVCard(user, id, "", "", "", "");
 
				return;
 
			}
 
			LOG4CXX_INFO(logger, user << ": VCard fetched - id=" << id);
 
			std::string photo((const char *)&vcard->getPhoto()[0], vcard->getPhoto().size());
 
			handleVCard(user, id, vcard->getFullName(), vcard->getFullName(), vcard->getNickname(), photo);
 
		}
 

	
 
		void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
 
			LOG4CXX_INFO(logger, user << ": connecting as " << legacyName);
 
			boost::shared_ptr<Swift::Client> client = boost::make_shared<Swift::Client>(Swift::JID(legacyName), password, m_factories);
 
			m_users[user] = client;
 
			client->setAlwaysTrustCertificates();
 
			client->onConnected.connect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
 
			client->onDisconnected.connect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
 
			client->onMessageReceived.connect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
 
			client->getRoster()->onInitialRosterPopulated.connect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user));
 
			client->getPresenceOracle()->onPresenceChange.connect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1));
 
			Swift::ClientOptions opt;
 
			opt.allowPLAINWithoutTLS = true;
 
			client->connect(opt);
 
		}
 

	
 
		void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
 
			boost::shared_ptr<Swift::Client> client = m_users[user];
 
			if (client) {
 
				client->onConnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
 
// 				client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
 
				client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
 
				client->getRoster()->onInitialRosterPopulated.disconnect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user));
 
				client->getPresenceOracle()->onPresenceChange.disconnect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1));
 
				client->disconnect();
 
				m_mucs.erase(user);
 
				m_users.erase(user);
 
			}
 
		}
 

	
 
		void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &msg, const std::string &xhtml = "", const std::string &id = "") {
 
			LOG4CXX_INFO(logger, "Sending message from " << user << " to " << legacyName << ".");
 
			boost::shared_ptr<Swift::Client> client = m_users[user];
 
			if (client) {
 
				boost::shared_ptr<Swift::Message> message(new Swift::Message());
 
				message->setTo(Swift::JID(legacyName));
 
				message->setFrom(client->getJID());
 
				message->setBody(msg);
 
// 				if (client->getMUCRegistry()->isMUC(legacyName)) {
 
// 					message->setType(Swift::Message::Groupchat);
 
// 					boost::shared_ptr<MUCController> muc = m_mucs[user][legacyName];
 
				if (client->getMUCRegistry()->isMUC(legacyName)) {
 
					message->setType(Swift::Message::Groupchat);
 
					boost::shared_ptr<MUCController> muc = m_mucs[user][legacyName];
 
// 					handleMessage(user, legacyName, msg, muc->getNickname(), xhtml);
 
// 				}
 
				}
 

	
 
				client->sendMessage(message);
 
			}
 
		}
 

	
 
		void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) {
 
			boost::shared_ptr<Swift::Client> client = m_users[user];
 
			if (client) {
 
				LOG4CXX_INFO(logger, user << ": fetching VCard of " << legacyName << " id=" << id);
 
				Swift::GetVCardRequest::ref request = Swift::GetVCardRequest::create(Swift::JID(legacyName), client->getIQRouter());
 
				request->onResponse.connect(boost::bind(&SwiftenPlugin::handleSwiftVCardReceived, this, user, id, _1, _2));
 
				request->send();
 
			}
 
		}
 

	
 
		void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups) {
 
			boost::shared_ptr<Swift::Client> client = m_users[user];
 
			if (client) {
 
				LOG4CXX_INFO(logger, user << ": Added/Updated buddy " << buddyName << ".");
 
				if (!client->getRoster()->containsJID(buddyName)) {
 
					Swift::RosterItemPayload item;
 
					item.setName(alias);
 
					item.setJID(buddyName);
 
					item.setGroups(groups);
 
					boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
 
					roster->addItem(item);
 
					Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
 
// 					request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
 
					request->send();
 
					client->getSubscriptionManager()->requestSubscription(buddyName);
 
				}
 
				else {
 
					Swift::JID contact(buddyName);
 
					Swift::RosterItemPayload item(contact, alias, client->getRoster()->getSubscriptionStateForJID(contact));
 
					item.setGroups(groups);
 
					boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
 
					roster->addItem(item);
 
					Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
 
// 					request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
 
					request->send();
 
				}
 

	
 
			}
 
		}
 

	
 
		void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups) {
 
			boost::shared_ptr<Swift::Client> client = m_users[user];
 
			if (client) {
 
				Swift::RosterItemPayload item(buddyName, "", Swift::RosterItemPayload::Remove);
 
				boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
 
				roster->addItem(item);
 
				Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
 
// 				request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
 
				request->send();
 
			}
 
		}
 

	
 
		void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) {
 
			boost::shared_ptr<Swift::Client> client = m_users[user];
 
			if (client) {
 
				if (client->getMUCRegistry()->isMUC(room)) {
 
					return;
 
				}
 

	
 
				boost::shared_ptr<MUCController> muc = boost::shared_ptr<MUCController>( new MUCController(user, client, room, nickname, password));
 
				m_mucs[user][room] = muc;
 
			}
 
		}
 

	
 
		void handleLeaveRoomRequest(const std::string &user, const std::string &room) {
 
			boost::shared_ptr<Swift::Client> client = m_users[user];
 
			if (client) {
 
				if (!client->getMUCRegistry()->isMUC(room)) {
 
					return;
 
				}
 

	
 
				boost::shared_ptr<MUCController> muc = m_mucs[user][room];
 
				if (!muc) {
 
					m_mucs[user].erase(room);
 
					return;
 
				}
 

	
 
				muc->part();
 
				m_mucs[user].erase(room);
 
			}
 
		}
 

	
 
	private:
 
		Config *config;
 
		std::map<std::string, boost::shared_ptr<Swift::Client> > m_users;
 
		std::map<std::string, std::map<std::string, boost::shared_ptr<MUCController> > > m_mucs;
 
};
 

	
 
#ifndef WIN32
 
static void spectrum_sigchld_handler(int sig)
 
{
 
	int status;
 
	pid_t pid;
 

	
 
	do {
 
		pid = waitpid(-1, &status, WNOHANG);
 
	} while (pid != 0 && pid != (pid_t)-1);
 

	
 
	if ((pid == (pid_t) - 1) && (errno != ECHILD)) {
 
		char errmsg[BUFSIZ];
 
		snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
 
		perror(errmsg);
 
	}
 
}
 
#endif
 

	
 

	
 
int main (int argc, char* argv[]) {
 
	std::string host;
 
	int port;
 

	
 
#ifndef WIN32
 
	if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) {
 
		std::cout << "SIGCHLD handler can't be set\n";
 
		return -1;
 
	}
 
#endif
 

	
 
	std::string error;
 
	Config *cfg = Config::createFromArgs(argc, argv, error, host, port);
 
	if (cfg == NULL) {
 
		std::cerr << error;
 
		return 1;
 
	}
 

	
 
	Logging::initBackendLogging(cfg);
 

	
 
	Swift::SimpleEventLoop eventLoop;
 
	loop_ = &eventLoop;
 
	np = new SwiftenPlugin(cfg, &eventLoop, host, port);
 
	loop_->run();
 

	
 
	return 0;
 
}
0 comments (0 inline, 0 general)