Changeset - 90aacd41d9df
[Not reviewed]
0 10 0
Jan Kaluza - 14 years ago 2011-09-14 15:09:21
hanzz.k@gmail.com
Use JID escaping by default + keep compatibility with spectrum1 database when using JID escaping
10 files changed with 35 insertions and 34 deletions:
0 comments (0 inline, 0 general)
include/transport/buddy.h
Show inline comments
 
@@ -141,36 +141,37 @@ class Buddy {
 
		virtual std::string getAlias() = 0;
 

	
 
		/// Returns list of groups this buddy is in.
 

	
 
		/// \return groups
 
		virtual std::vector<std::string> getGroups() = 0;
 

	
 
		/// Returns current legacy network status and statuMessage of this buddy.
 

	
 
		/// \param status current status/show is stored here
 
		/// \param statusMessage current status message is stored here
 
		/// \return true if status was stored successfully
 
		virtual bool getStatus(Swift::StatusShow &status, std::string &statusMessage) = 0;
 

	
 
		/// Returns SHA-1 hash of buddy icon (avatar) or empty string if there is no avatar for this buddy.
 

	
 
		/// \return avatar hash or empty string.
 
		virtual std::string getIconHash() = 0;
 

	
 
		/// Returns legacy name of buddy from JID.
 

	
 
		/// \param jid Jabber ID.
 
		/// \return legacy name of buddy from JID.
 
		static std::string JIDToLegacyName(const Swift::JID &jid);
 
		static BuddyFlag buddFlagsFromJID(const Swift::JID &jid);
 

	
 
	private:
 
		void generateJID();
 

	
 
		long m_id;
 
// 		Swift::Presence::ref m_lastPresence;
 
		Swift::JID m_jid;
 
		BuddyFlag m_flags;
 
		RosterManager *m_rosterManager;
 
};
 

	
 
}
spectrum/src/sample.cfg
Show inline comments
 
@@ -7,27 +7,27 @@ server_mode = 1
 
backend_host=localhost # < this option doesn't work yet
 
backend_port=10001
 
admin_username=admin
 
admin_password=test
 
#idle_reconnect_time=10
 
#cert=server.pfx #patch to PKCS#12 certificate
 
#cert_password=test #password to that certificate if any
 
users_per_backend=10
 
backend=/home/hanzz/code/libtransport/backends/libpurple/spectrum_libpurple_backend
 
#backend=../../backends/libircclient-qt/spectrum_libircclient-qt_backend
 
#protocol=prpl-msn
 
protocol=any
 
#protocol=prpl-icq
 
#idle_reconnect_time=10
 

	
 
[backend]
 
#default_avatar=catmelonhead.jpg
 
#no_vcard_fetch=true
 

	
 
[logging]
 
#config=logging.cfg # log4cxx/log4j logging configuration file
 
#backend_config=backend_logging.cfg # log4cxx/log4j logging configuration file for backends
 

	
 
[database]
 
#type = mysql # or "none" without database backend
 
type = none # or "none" without database backend
 
database = test.sql
 
prefix=icq
src/buddy.cpp
Show inline comments
 
@@ -29,49 +29,49 @@ namespace Transport {
 
Buddy::Buddy(RosterManager *rosterManager, long id) : m_id(id), m_flags(BUDDY_NO_FLAG), m_rosterManager(rosterManager){
 
// 	m_rosterManager->setBuddy(this);
 
}
 

	
 
Buddy::~Buddy() {
 
// 	m_rosterManager->unsetBuddy(this);
 
}
 

	
 
void Buddy::generateJID() {
 
	m_jid = Swift::JID();
 
	m_jid = Swift::JID(getSafeName(), m_rosterManager->getUser()->getComponent()->getJID().toString(), "bot");
 
}
 

	
 
void Buddy::setID(long id) {
 
	m_id = id;
 
}
 

	
 
long Buddy::getID() {
 
	return m_id;
 
}
 

	
 
void Buddy::setFlags(BuddyFlag flags) {
 
	m_flags = flags;
 

	
 
	generateJID();
 
// 	generateJID();
 
}
 

	
 
BuddyFlag Buddy::getFlags() {
 
	return m_flags;
 
}
 

	
 
const Swift::JID &Buddy::getJID() {
 
	if (!m_jid.isValid()) {
 
		generateJID();
 
	}
 
	return m_jid;
 
}
 

	
 
void Buddy::setSubscription(const std::string &subscription) {
 
// 	m_subscription = subscription;
 
}
 

	
 
const std::string Buddy::getSubscription() {
 
	return "ask";
 
}
 

	
 
Swift::Presence::ref Buddy::generatePresenceStanza(int features, bool only_new) {
 
	std::string alias = getAlias();
 
	std::string name = getSafeName();
 
@@ -104,68 +104,76 @@ Swift::Presence::ref Buddy::generatePresenceStanza(int features, bool only_new)
 
			presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::BlockPayload ()));
 
		}
 
	}
 

	
 
// 	if (only_new) {
 
// 		if (m_lastPresence)
 
// 			m_lastPresence->setTo(Swift::JID(""));
 
// 		if (m_lastPresence == presence) {
 
// 			return Swift::Presence::ref();
 
// 		}
 
// 		m_lastPresence = presence;
 
// 	}
 

	
 
	return presence;
 
}
 

	
 
std::string Buddy::getSafeName() {
 
	if (m_jid.isValid()) {
 
		return m_jid.getNode();
 
	}
 
	std::string name = getName();
 
// 	Transport::instance()->protocol()->prepareUsername(name, purple_buddy_get_account(m_buddy));
 
	if (getFlags() & BUDDY_JID_ESCAPING) {
 
		name = Swift::JID::getEscapedNode(name);
 
		std::cout << "OUT '" << getName() << "' '" << name << "'\n";
 
	}
 
	else {
 
		if (name.find_last_of("@") != std::string::npos) {
 
			name.replace(name.find_last_of("@"), 1, "%");
 
			name.replace(name.find_last_of("@"), 1, "%"); // OK
 
		}
 
	}
 
// 	if (name.empty()) {
 
// 		Log("SpectrumBuddy::getSafeName", "Name is EMPTY! Previous was " << getName() << ".");
 
// 	}
 
	return name;
 
}
 

	
 
void Buddy::handleBuddyChanged() {
 
	Swift::Presence::ref presence = generatePresenceStanza(255);
 
	if (presence) {
 
		m_rosterManager->getUser()->getComponent()->getStanzaChannel()->sendPresence(presence);
 
	}
 
	m_rosterManager->handleBuddyChanged(this);
 
}
 

	
 
void Buddy::handleVCardReceived(const std::string &id, Swift::VCard::ref vcard) {
 
	boost::shared_ptr<Swift::GenericRequest<Swift::VCard> > request(new Swift::GenericRequest<Swift::VCard>(Swift::IQ::Result, m_rosterManager->getUser()->getJID(), vcard, m_rosterManager->getUser()->getComponent()->getIQRouter()));
 
	request->send();
 
}
 

	
 
std::string Buddy::JIDToLegacyName(const Swift::JID &jid) {
 
	std::string name;
 
	if (jid.getUnescapedNode() == jid.getNode()) {
 
		name = jid.getNode();
 
		if (name.find_last_of("%") != std::string::npos) {
 
			name.replace(name.find_last_of("%"), 1, "@");
 
			name.replace(name.find_last_of("%"), 1, "@"); // OK
 
		}
 
	}
 
	else {
 
		name = jid.getUnescapedNode();
 
		// Psi sucks...
 
		if (name.find_last_of("\\40") != std::string::npos) {
 
			name.replace(name.find_last_of("\\40"), 1, "@");
 
			name.replace(name.find_last_of("\\40"), 1, "@"); // OK
 
		}
 
	}
 
	return name;
 
}
 

	
 
BuddyFlag Buddy::buddFlagsFromJID(const Swift::JID &jid) {
 
	if (jid.getUnescapedNode() == jid.getNode()) {
 
		return BUDDY_NO_FLAG;
 
	}
 
	return BUDDY_JID_ESCAPING;
 
}
 

	
 
}
src/conversation.cpp
Show inline comments
 
@@ -38,53 +38,49 @@ Conversation::Conversation(ConversationManager *conversationManager, const std::
 
	m_conversationManager->addConversation(this);
 
	m_muc = isMUC;
 
}
 

	
 
Conversation::~Conversation() {
 
}
 

	
 
void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, const std::string &nickname) {
 
	if (m_muc) {
 
		message->setType(Swift::Message::Groupchat);
 
	}
 
	else {
 
		message->setType(Swift::Message::Chat);
 
	}
 
	if (message->getType() != Swift::Message::Groupchat) {
 
		
 
		message->setTo(m_conversationManager->getUser()->getJID().toBare());
 
		// normal message
 
		if (nickname.empty()) {
 
			Buddy *buddy = m_conversationManager->getUser()->getRosterManager()->getBuddy(m_legacyName);
 
			if (buddy) {
 
				message->setFrom(buddy->getJID());
 
			}
 
			else {
 
				std::string name = nickname;
 
				if (name.find_last_of("@") != std::string::npos) {
 
					name.replace(name.find_last_of("@"), 1, "%");
 
				}
 
				message->setFrom(name);
 
				message->setFrom(Swift::JID(Swift::JID::getEscapedNode(nickname), m_conversationManager->getComponent()->getJID().toBare()));
 
			}
 
		}
 
		// PM message
 
		else {
 
			if (m_room.empty()) {
 
				message->setFrom(Swift::JID(nickname, m_conversationManager->getComponent()->getJID().toBare(), "user"));
 
			}
 
			else {
 
				message->setFrom(Swift::JID(m_room, m_conversationManager->getComponent()->getJID().toBare(), nickname));
 
			}
 
		}
 
		m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
 
	}
 
	else {
 
		message->setTo(m_conversationManager->getUser()->getJID().toString());
 
		message->setFrom(Swift::JID(m_legacyName, m_conversationManager->getComponent()->getJID().toBare(), nickname));
 
		m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
 
	}
 
}
 

	
 
void Conversation::handleParticipantChanged(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname) {
 
	std::string nickname = nick;
 
	Swift::Presence::ref presence = Swift::Presence::create();
 
 	presence->setFrom(Swift::JID(m_legacyName, m_conversationManager->getComponent()->getJID().toBare(), nickname));
src/conversationmanager.cpp
Show inline comments
 
@@ -42,47 +42,48 @@ ConversationManager::ConversationManager(User *user, Component *component){
 

	
 
ConversationManager::~ConversationManager() {
 
	while(!m_convs.empty()) {
 
		LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Removing conversation " << (*m_convs.begin()).first);
 
		delete (*m_convs.begin()).second;
 
		m_convs.erase(m_convs.begin());
 
	}
 
}
 

	
 
void ConversationManager::addConversation(Conversation *conv) {
 
	m_convs[conv->getLegacyName()] = conv;
 
	LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Adding conversation " << conv->getLegacyName());
 
}
 

	
 
void ConversationManager::removeConversation(Conversation *conv) {
 
	for (std::map<std::string, Conversation *>::const_iterator it = m_convs.begin(); it != m_convs.end(); it++) {
 
		if ((*it).second->getRoom() == conv->getLegacyName()) {
 
			(*it).second->setRoom("");
 
		}
 
	}
 
	m_convs.erase(conv->getLegacyName());
 
}
 

	
 
void ConversationManager::handleMessageReceived(Swift::Message::ref message) {
 
	std::string name = message->getTo().getUnescapedNode();
 
	if (name.find_last_of("%") != std::string::npos) {
 
		name.replace(name.find_last_of("%"), 1, "@");
 
	}
 
// 	std::string name = message->getTo().getUnescapedNode();
 
// 	if (name.find_last_of("%") != std::string::npos) { // OK when commented
 
// 		name.replace(name.find_last_of("%"), 1, "@"); // OK when commented
 
// 	}
 
	std::string name = Buddy::JIDToLegacyName(message->getTo());
 

	
 
	// create conversation if it does not exist.
 
	if (!m_convs[name]) {
 
		m_convs[name] = m_component->getFactory()->createConversation(this, name);
 
	}
 
	// if it exists and it's MUC, but this message is PM, get PM conversation or create new one.
 
	else if (m_convs[name]->isMUC() && message->getType() != Swift::Message::Groupchat) {
 
		std::string room_name = name;
 
		name = message->getTo().getResource();
 
		if (!m_convs[name]) {
 
			m_convs[name] = m_component->getFactory()->createConversation(this, name);
 
			m_convs[name]->setRoom(room_name);
 
		}
 
	}
 

	
 
	m_convs[name]->sendMessage(message);
 
}
 

	
 
}
 
\ No newline at end of file
src/networkpluginserver.cpp
Show inline comments
 
@@ -69,49 +69,49 @@ class NetworkConversation : public Conversation {
 

	
 
		boost::signal<void (NetworkConversation *, boost::shared_ptr<Swift::Message> &)> onMessageToSend;
 
};
 

	
 
class NetworkFactory : public Factory {
 
	public:
 
		NetworkFactory(NetworkPluginServer *nps) {
 
			m_nps = nps;
 
		}
 

	
 
		// Creates new conversation (NetworkConversation in this case)
 
		Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName) {
 
			NetworkConversation *nc = new NetworkConversation(conversationManager, legacyName);
 
			nc->onMessageToSend.connect(boost::bind(&NetworkPluginServer::handleMessageReceived, m_nps, _1, _2));
 
			return nc;
 
		}
 

	
 
		// Creates new LocalBuddy
 
		Buddy *createBuddy(RosterManager *rosterManager, const BuddyInfo &buddyInfo) {
 
			LocalBuddy *buddy = new LocalBuddy(rosterManager, buddyInfo.id);
 
			buddy->setAlias(buddyInfo.alias);
 
			buddy->setName(buddyInfo.legacyName);
 
			buddy->setSubscription(buddyInfo.subscription);
 
			buddy->setGroups(buddyInfo.groups);
 
			buddy->setFlags((BuddyFlag) buddyInfo.flags);
 
			buddy->setFlags((BuddyFlag) (buddyInfo.flags));
 
			if (buddyInfo.settings.find("icon_hash") != buddyInfo.settings.end())
 
				buddy->setIconHash(buddyInfo.settings.find("icon_hash")->second.s);
 
			return buddy;
 
		}
 

	
 
	private:
 
		NetworkPluginServer *m_nps;
 
};
 

	
 
// Wraps google protobuf payload into WrapperMessage and serialize it to string
 
#define WRAP(MESSAGE, TYPE) 	pbnetwork::WrapperMessage wrap; \
 
	wrap.set_type(TYPE); \
 
	wrap.set_payload(MESSAGE); \
 
	wrap.SerializeToString(&MESSAGE);
 

	
 
// Executes new backend
 
static unsigned long exec_(std::string path, const char *host, const char *port, const char *config) {
 
	std::string original_path = path;
 
	// BACKEND_ID is replaced with unique ID. The ID is increasing for every backend.
 
	boost::replace_all(path, "BACKEND_ID", boost::lexical_cast<std::string>(backend_id++));
 

	
 
	// Add host and port.
 
	path += std::string(" --host ") + host + " --port " + port + " " + config;
 
	LOG4CXX_INFO(logger, "Starting new backend " << path);
 
@@ -375,54 +375,53 @@ void NetworkPluginServer::handleVCardPayload(const std::string &data) {
 
	boost::shared_ptr<Swift::VCard> vcard(new Swift::VCard());
 
	vcard->setFullName(payload.fullname());
 
	vcard->setPhoto(Swift::createByteArray(payload.photo()));
 
	vcard->setNickname(payload.nickname());
 

	
 
	m_vcardResponder->sendVCard(payload.id(), vcard);
 
}
 

	
 
void NetworkPluginServer::handleAuthorizationPayload(const std::string &data) {
 
	pbnetwork::Buddy payload;
 
	if (payload.ParseFromString(data) == false) {
 
		// TODO: ERROR
 
		return;
 
	}
 

	
 
	User *user = m_userManager->getUser(payload.username());
 
	if (!user)
 
		return;
 

	
 
	// Create subscribe presence and forward it to XMPP side
 
	Swift::Presence::ref response = Swift::Presence::create();
 
	response->setTo(user->getJID());
 
	std::string name = payload.buddyname();
 

	
 
	// TODO:
 
// 	name = Swift::JID::getEscapedNode(name)
 
	name = Swift::JID::getEscapedNode(name);
 

	
 
	if (name.find_last_of("@") != std::string::npos) {
 
		name.replace(name.find_last_of("@"), 1, "%");
 
	}
 
// 	if (name.find_last_of("@") != std::string::npos) { // OK when commented
 
// 		name.replace(name.find_last_of("@"), 1, "%"); // OK when commented
 
// 	}
 

	
 
	response->setFrom(Swift::JID(name, m_component->getJID().toString()));
 
	response->setType(Swift::Presence::Subscribe);
 
	m_component->getStanzaChannel()->sendPresence(response);
 
}
 

	
 
void NetworkPluginServer::handleChatStatePayload(const std::string &data, Swift::ChatState::ChatStateType type) {
 
	pbnetwork::Buddy payload;
 
	if (payload.ParseFromString(data) == false) {
 
		// TODO: ERROR
 
		return;
 
	}
 

	
 
	User *user = m_userManager->getUser(payload.username());
 
	if (!user)
 
		return;
 

	
 
	// We're not creating new Conversation just because of chatstates.
 
	// Some networks/clients spams with chatstates a lot and it leads to bigger memory usage.
 
	NetworkConversation *conv = (NetworkConversation *) user->getConversationManager()->getConversation(payload.buddyname());
 
	if (!conv) {
 
		return;
 
	}
 

	
 
@@ -430,48 +429,49 @@ void NetworkPluginServer::handleChatStatePayload(const std::string &data, Swift:
 
	boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 
	msg->addPayload(boost::make_shared<Swift::ChatState>(type));
 

	
 
	conv->handleMessage(msg);
 
}
 

	
 
void NetworkPluginServer::handleBuddyChangedPayload(const std::string &data) {
 
	pbnetwork::Buddy payload;
 
	if (payload.ParseFromString(data) == false) {
 
		// TODO: ERROR
 
		return;
 
	}
 

	
 
	User *user = m_userManager->getUser(payload.username());
 
	if (!user)
 
		return;
 

	
 
	LocalBuddy *buddy = (LocalBuddy *) user->getRosterManager()->getBuddy(payload.buddyname());
 
	if (buddy) {
 
		handleBuddyPayload(buddy, payload);
 
		buddy->handleBuddyChanged();
 
	}
 
	else {
 
		buddy = new LocalBuddy(user->getRosterManager(), -1);
 
		buddy->setFlags(BUDDY_JID_ESCAPING);
 
		handleBuddyPayload(buddy, payload);
 
		user->getRosterManager()->setBuddy(buddy);
 
	}
 
}
 

	
 
void NetworkPluginServer::handleParticipantChangedPayload(const std::string &data) {
 
	pbnetwork::Participant payload;
 
	if (payload.ParseFromString(data) == false) {
 
		// TODO: ERROR
 
		return;
 
	}
 

	
 
	User *user = m_userManager->getUser(payload.username());
 
	if (!user)
 
		return;
 

	
 
	NetworkConversation *conv = (NetworkConversation *) user->getConversationManager()->getConversation(payload.room());
 
	if (!conv) {
 
		return;
 
	}
 

	
 
	conv->handleParticipantChanged(payload.nickname(), payload.flag(), payload.status(), payload.statusmessage(), payload.newname());
 
}
 

	
 
@@ -648,74 +648,72 @@ void NetworkPluginServer::handleDataRead(Backend *c, const Swift::SafeByteArray
 
				break;
 
			case pbnetwork::WrapperMessage_Type_TYPE_STATS:
 
				handleStatsPayload(c, wrapper.payload());
 
				break;
 
			default:
 
				return;
 
		}
 
	}
 
}
 

	
 
void NetworkPluginServer::send(boost::shared_ptr<Swift::Connection> &c, const std::string &data) {
 
	// generate header - size of wrapper message
 
	char header[4];
 
	*((int*)(header)) = htonl(data.size());
 

	
 
	// send header together with wrapper message
 
	c->write(Swift::createSafeByteArray(std::string(header, 4) + data));
 
}
 

	
 
void NetworkPluginServer::pingTimeout() {
 
	// TODO: move to separate timer, those 2 loops could be expensive
 
	// Some users are connected for weeks and they are blocking backend to be destroyed and its memory
 
	// to be freed. We are finding users who are inactive for more than "idle_reconnect_time" seconds and
 
	// reconnect them to long-running backend, where they can idle hapilly till the end of ages.
 
	unsigned long diff = CONFIG_INT(m_config, "service.idle_reconnect_time");
 
	if (diff != 0) {
 
	time_t now = time(NULL);
 
	std::vector<User *> usersToMove;
 
		></i>
 
	unsigned long diff = CONFIG_INT(m_config, "service.idle_reconnect_time");
 
	for (std::list<Backend *>::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) {
 
		// Users from long-running backends can't be moved
 
		if ((*it)->longRun) {
 
			continue;
 
		}
 

	
 
		// Find users which are inactive for more than 'diff'
 
		BOOST_FOREACH(User *u, (*it)->users) {
 
			if (now - u->getLastActivity() > diff) {
 
				usersToMove.push_back(u);
 
			}
 
		}
 
	}
 

	
 
	// Move inactive users to long-running backend.
 
	BOOST_FOREACH(User *u, usersToMove) {
 
		LOG4CXX_INFO(logger, "Moving user " << u->getJID().toString() << " to long-running backend");
 
		if (!moveToLongRunBackend(u))
 
			break;
 
	}
 
	}
 
	>
 

	
 

	
 
	// check ping responses
 
	std::vector<Backend *> toRemove;
 
	for (std::list<Backend *>::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) {
 
		// pong has been received OR backend just connected and did not have time to answer the ping
 
		// request.
 
		if ((*it)->pongReceived || (*it)->pongReceived == -1) {
 
			sendPing((*it));
 
		}
 
		else {
 
			LOG4CXX_INFO(logger, "Disconnecting backend " << (*it) << ". PING response not received.");
 
			toRemove.push_back(*it);
 
		}
 

	
 
		if ((*it)->users.size() == 0) {
 
			LOG4CXX_INFO(logger, "Disconnecting backend " << (*it) << ". There are no users.");
 
			toRemove.push_back(*it);
 
		}
 
	}
 

	
 
	BOOST_FOREACH(Backend *b, toRemove) {
 
		handleSessionFinished(b);
 
	}
src/rostermanager.cpp
Show inline comments
 
@@ -190,49 +190,49 @@ void RosterManager::handleBuddyRosterPushResponse(Swift::ErrorPayload::ref error
 
	request->onResponse.disconnect_all_slots();
 
}
 

	
 
void RosterManager::handleRemoteRosterResponse(boost::shared_ptr<Swift::RosterPayload> payload, Swift::ErrorPayload::ref error) {
 
	if (error) {
 
		m_supportRemoteRoster = false;
 
		LOG4CXX_INFO(logger, m_user->getJID().toString() << ": This server does not support remote roster protoXEP");
 
		return;
 
	}
 

	
 
	LOG4CXX_INFO(logger, m_user->getJID().toString() << ": This server supports remote roster protoXEP");
 
	m_supportRemoteRoster = true;
 

	
 
	BOOST_FOREACH(const Swift::RosterItemPayload &item, payload->getItems()) {
 
		std::string legacyName = Buddy::JIDToLegacyName(item.getJID());
 
		if (m_buddies.find(legacyName) != m_buddies.end()) {
 
			continue;
 
		}
 

	
 
		BuddyInfo buddyInfo;
 
		buddyInfo.id = -1;
 
		buddyInfo.alias = item.getName();
 
		buddyInfo.legacyName = legacyName;
 
		buddyInfo.subscription = "both";
 
		buddyInfo.flags = 0;
 
		buddyInfo.flags = Buddy::buddFlagsFromJID(item.getJID());
 

	
 
		Buddy *buddy = m_component->getFactory()->createBuddy(this, buddyInfo);
 
		setBuddy(buddy);
 
	}
 
}
 

	
 
Buddy *RosterManager::getBuddy(const std::string &name) {
 
	return m_buddies[name];
 
}
 

	
 
void RosterManager::sendRIE() {
 
	m_RIETimer->stop();
 

	
 
	// Check the feature, because proper resource could logout during RIETimer.
 
	Swift::JID jidWithRIE = m_user->getJIDWithFeature("http://jabber.org/protocol/rosterx");
 

	
 
	// fallback to normal subscribe
 
	if (!jidWithRIE.isValid()) {
 
		for (std::map<std::string, Buddy *, std::less<std::string>, boost::pool_allocator< std::pair<std::string, Buddy *> > >::iterator it = m_buddies.begin(); it != m_buddies.end(); it++) {
 
			Buddy *buddy = (*it).second;
 
			if (!buddy) {
 
				continue;
 
			}
 
			sendBuddySubscribePresence(buddy);
 
@@ -278,49 +278,49 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) {
 
					response->setType(Swift::Presence::Subscribed);
 
					break;
 
				case Swift::Presence::Unsubscribe:
 
					onBuddyRemoved(buddy);
 
					response->setType(Swift::Presence::Unsubscribed);
 
					break;
 
				case Swift::Presence::Subscribed:
 
					onBuddyAdded(buddy);
 
					break;
 
				default:
 
					return;
 
			}
 
			m_component->getStanzaChannel()->sendPresence(response);
 
			
 
		}
 
		else {
 
			BuddyInfo buddyInfo;
 
			switch (presence->getType()) {
 
				// buddy is not in roster, so add him
 
				case Swift::Presence::Subscribe:
 
					buddyInfo.id = -1;
 
					buddyInfo.alias = "";
 
					buddyInfo.legacyName = Buddy::JIDToLegacyName(presence->getTo());
 
					buddyInfo.subscription = "both";
 
					buddyInfo.flags = 0;
 
					buddyInfo.flags = Buddy::buddFlagsFromJID(presence->getTo());
 
					LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Subscription received for new buddy " << buddyInfo.legacyName << " => adding to legacy network");
 

	
 
					buddy = m_component->getFactory()->createBuddy(this, buddyInfo);
 
					setBuddy(buddy);
 
					onBuddyAdded(buddy);
 
					response->setType(Swift::Presence::Subscribed);
 
					break;
 
				case Swift::Presence::Subscribed:
 
					onBuddyAdded(buddy);
 
					break;
 
				// buddy is already there, so nothing to do, just answer
 
				case Swift::Presence::Unsubscribe:
 
					response->setType(Swift::Presence::Unsubscribed);
 
					break;
 
				default:
 
					return;
 
			}
 
			m_component->getStanzaChannel()->sendPresence(response);
 
		}
 
	}
 
	else {
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		Swift::Presence::ref currentPresence;
 
		response->setTo(presence->getFrom());
 
@@ -340,49 +340,49 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) {
 
					}
 
					break;
 
				// remove buddy
 
				case Swift::Presence::Unsubscribe:
 
					response->setType(Swift::Presence::Unsubscribed);
 
					onBuddyRemoved(buddy);
 
					break;
 
				// just send response
 
				case Swift::Presence::Unsubscribed:
 
// 					response->setType(Swift::Presence::Unsubscribe);
 
					break;
 
				default:
 
					return;
 
			}
 
		}
 
		else {
 
			BuddyInfo buddyInfo;
 
			switch (presence->getType()) {
 
				// buddy is not in roster, so add him
 
				case Swift::Presence::Subscribe:
 
					buddyInfo.id = -1;
 
					buddyInfo.alias = "";
 
					buddyInfo.legacyName = Buddy::JIDToLegacyName(presence->getTo());
 
					buddyInfo.subscription = "both";
 
					buddyInfo.flags = 0;
 
					buddyInfo.flags = Buddy::buddFlagsFromJID(presence->getTo());
 

	
 
					buddy = m_component->getFactory()->createBuddy(this, buddyInfo);
 
					setBuddy(buddy);
 
					onBuddyAdded(buddy);
 
					response->setType(Swift::Presence::Subscribed);
 
					break;
 
				// buddy is already there, so nothing to do, just answer
 
				case Swift::Presence::Unsubscribe:
 
					response->setType(Swift::Presence::Unsubscribed);
 
					onBuddyRemoved(buddy);
 
					break;
 
				// just send response
 
				case Swift::Presence::Unsubscribed:
 
					response->setType(Swift::Presence::Unsubscribe);
 
					break;
 
				// just send response
 
				default:
 
					return;
 
			}
 
		}
 

	
 
		m_component->getStanzaChannel()->sendPresence(response);
 

	
 
		// We have to act as buddy and send its subscribe/unsubscribe just to be sure...
src/rosterresponder.cpp
Show inline comments
 
@@ -73,36 +73,36 @@ bool RosterResponder::handleSetRequest(const Swift::JID& from, const Swift::JID&
 
		LOG4CXX_WARN(logger, from.toBare().toString() << ": Roster push with no item");
 
		return true;
 
	}
 

	
 
	Swift::RosterItemPayload item = payload->getItems()[0];
 

	
 
	Buddy *buddy = user->getRosterManager()->getBuddy(Buddy::JIDToLegacyName(item.getJID()));
 
	if (buddy) {
 
		if (item.getSubscription() == Swift::RosterItemPayload::Remove) {
 
			LOG4CXX_INFO(logger, from.toBare().toString() << ": Removing buddy " << buddy->getName());
 
			onBuddyRemoved(buddy);
 
		}
 
		else {
 
			LOG4CXX_INFO(logger, from.toBare().toString() << ": Updating buddy " << buddy->getName());
 
			onBuddyUpdated(buddy, item);
 
		}
 
	}
 
	else if (item.getSubscription() != Swift::RosterItemPayload::Remove) {
 
		// Roster push for this new buddy is sent by RosterManager
 
		BuddyInfo buddyInfo;
 
		buddyInfo.id = -1;
 
		buddyInfo.alias = item.getName();
 
		buddyInfo.legacyName = Buddy::JIDToLegacyName(item.getJID());
 
		buddyInfo.subscription = "both";
 
		buddyInfo.flags = 0;
 
		buddyInfo.flags = Buddy::buddFlagsFromJID(item.getJID());
 
		LOG4CXX_INFO(logger, from.toBare().toString() << ": Adding buddy " << buddyInfo.legacyName);
 

	
 
		buddy = user->getComponent()->getFactory()->createBuddy(user->getRosterManager(), buddyInfo);
 
		user->getRosterManager()->setBuddy(buddy);
 
		onBuddyAdded(buddy, item);
 
	}
 

	
 
	return true;
 
}
 

	
 
}
src/usermanager.cpp
Show inline comments
 
@@ -143,50 +143,50 @@ void UserManager::handlePresence(Swift::Presence::ref presence) {
 
			m_component->getStanzaChannel()->sendPresence(response);
 

	
 
			// Set user offline in database
 
			if (m_storageBackend) {
 
				UserInfo res;
 
				bool registered = m_storageBackend->getUser(userkey, res);
 
				if (registered) {
 
					m_storageBackend->setUserOnline(res.id, false);
 
				}
 
			}
 
			return;
 
		}
 

	
 
		UserInfo res;
 
		bool registered = m_storageBackend ? m_storageBackend->getUser(userkey, res) : false;
 

	
 
		// In server mode, there's no registration, but we store users into database
 
		// (if storagebackend is available) because of caching. Passwords are not stored
 
		// in server mode.
 
		if (m_component->inServerMode()) {
 
			if (!registered) {
 
				res.password = "";
 
				res.uin = presence->getFrom().getNode();
 
				res.jid = userkey;
 
				if (res.uin.find_last_of("%") != std::string::npos) {
 
					res.uin.replace(res.uin.find_last_of("%"), 1, "@");
 
				if (res.uin.find_last_of("%") != std::string::npos) { // OK
 
					res.uin.replace(res.uin.find_last_of("%"), 1, "@"); // OK
 
				}
 
				if (m_storageBackend) {
 
					// store user and getUser again to get user ID.
 
					m_storageBackend->setUser(res);
 
					registered = m_storageBackend->getUser(userkey, res);
 
				}
 
				else {
 
					registered = true;
 
				}
 
			}
 
			res.password = m_userRegistry->getUserPassword(userkey);
 
		}
 

	
 
		// Unregistered users are not able to login
 
		if (!registered) {
 
			LOG4CXX_WARN(logger, "Unregistered user " << userkey << " tried to login");
 
			return;
 
		}
 

	
 
		// Create new user class and set storagebackend
 
		user = new User(presence->getFrom(), res, m_component, this);
 
		user->getRosterManager()->setStorageBackend(m_storageBackend);
 
		addUser(user);
 
	}
src/vcardresponder.cpp
Show inline comments
 
@@ -75,54 +75,51 @@ void VCardResponder::collectTimeouted() {
 
	if (candidates.size() != 0) {
 
		LOG4CXX_INFO(logger, "Removing " << candidates.size() << " timeouted VCard requests");
 
	}
 

	
 
	BOOST_FOREACH(unsigned int id, candidates) {
 
		sendVCard(id, boost::shared_ptr<Swift::VCard>(new Swift::VCard()));
 
	}
 
	m_collectTimer->start();
 
}
 

	
 
bool VCardResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::VCard> payload) {
 
	// Get means we're in server mode and user wants to fetch his roster.
 
	// For now we send empty reponse, but TODO: Get buddies from database and send proper stored roster.
 
	User *user = m_userManager->getUser(from.toBare().toString());
 
	if (!user) {
 
		LOG4CXX_WARN(logger, from.toBare().toString() << ": User is not logged in");
 
		return false;
 
	}
 

	
 
	Swift::JID to_ = to;
 

	
 
	std::string name = to_.getUnescapedNode();
 
	if (name.empty()) {
 
		to_ = user->getJID();
 
		name = to_.getUnescapedNode();
 
	}
 

	
 
	if (name.find_last_of("%") != std::string::npos) {
 
		name.replace(name.find_last_of("%"), 1, "@");
 
	}
 
	name = Buddy::JIDToLegacyName(to_);
 

	
 
	LOG4CXX_INFO(logger, from.toBare().toString() << ": Requested VCard of " << name);
 

	
 
	m_queries[m_id].from = from;
 
	m_queries[m_id].to = to_;
 
	m_queries[m_id].id = id; 
 
	m_queries[m_id].received = time(NULL);
 
	onVCardRequired(user, name, m_id++);
 
	return true;
 
}
 

	
 
bool VCardResponder::handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::VCard> payload) {
 
	if (!to.getNode().empty()) {
 
		LOG4CXX_WARN(logger, from.toBare().toString() << ": Tried to set VCard of somebody else");
 
		return false;
 
	}
 

	
 
	User *user = m_userManager->getUser(from.toBare().toString());
 
	if (!user) {
 
		LOG4CXX_WARN(logger, from.toBare().toString() << ": User is not logged in");
 
		return false;
 
	}
 

	
 
	LOG4CXX_INFO(logger, from.toBare().toString() << ": Setting VCard");
0 comments (0 inline, 0 general)