Exemplo n.º 1
0
void TlenIqResultRoster(TlenProtocol *proto, XmlNode *iqNode)
{
	XmlNode *queryNode;
	char *type;
	char *str;

	// RECVED: roster information
	// ACTION: populate LIST_ROSTER and create contact for any new rosters
	if ((type=TlenXmlGetAttrValue(iqNode, "type")) == NULL) return;
	if ((queryNode=TlenXmlGetChild(iqNode, "query")) == NULL) return;

	if (!strcmp(type, "result")) {
		str = TlenXmlGetAttrValue(queryNode, "xmlns");
		if (str != NULL && !strcmp(str, "jabber:iq:roster")) {
			DBVARIANT dbv;
			XmlNode *itemNode, *groupNode;
			TLEN_SUBSCRIPTION sub;
			TLEN_LIST_ITEM *item;
			char *jid, *name, *nick;
			int i, oldStatus;

			for (i=0; i<queryNode->numChild; i++) {
				itemNode = queryNode->child[i];
				if (!strcmp(itemNode->name, "item")) {
					str = TlenXmlGetAttrValue(itemNode, "subscription");
					if (str == NULL) sub = SUB_NONE;
					else if (!strcmp(str, "both")) sub = SUB_BOTH;
					else if (!strcmp(str, "to")) sub = SUB_TO;
					else if (!strcmp(str, "from")) sub = SUB_FROM;
					else sub = SUB_NONE;
					//if (str != NULL && (!strcmp(str, "to") || !strcmp(str, "both"))) {
					if ((jid=TlenXmlGetAttrValue(itemNode, "jid")) != NULL) {
						if ((name=TlenXmlGetAttrValue(itemNode, "name")) != NULL)
							nick = TlenTextDecode(name);
						else
							nick = TlenLocalNickFromJID(jid);
						
						if (nick != NULL) {
							MCONTACT hContact;
							item = TlenListAdd(proto, LIST_ROSTER, jid);
							if (item->nick) mir_free(item->nick);
							item->nick = nick;
							item->subscription = sub;
							if ((hContact=TlenHContactFromJID(proto, jid)) == NULL) {
								// Received roster has a new JID.
								// Add the jid (with empty resource) to Miranda contact list.
								hContact = TlenDBCreateContact(proto, jid, nick, FALSE);
							}
							db_set_s(hContact, "CList", "MyHandle", nick);
							if (item->group) mir_free(item->group);
							if ((groupNode=TlenXmlGetChild(itemNode, "group")) != NULL && groupNode->text != NULL) {
								item->group = TlenGroupDecode(groupNode->text);
								Clist_CreateGroup(0, _A2T(item->group));
								// Don't set group again if already correct, or Miranda may show wrong group count in some case
								if (!db_get(hContact, "CList", "Group", &dbv)) {
									if (strcmp(dbv.pszVal, item->group))
										db_set_s(hContact, "CList", "Group", item->group);
									db_free(&dbv);
								}
								else db_set_s(hContact, "CList", "Group", item->group);
							}
							else {
								item->group = NULL;
								db_unset(hContact, "CList", "Group");
							}
							if (!db_get(hContact, proto->m_szModuleName, "AvatarHash", &dbv)) {
								if (item->avatarHash) mir_free(item->avatarHash);
								item->avatarHash = mir_strdup(dbv.pszVal);
								proto->debugLogA("Setting hash [%s] = %s", nick, item->avatarHash);
								db_free(&dbv);
							}
							item->avatarFormat = db_get_dw(hContact, proto->m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN);
						}
					}
				}
			}
			
			// Delete orphaned contacts (if roster sync is enabled)
			if (db_get_b(NULL, proto->m_szModuleName, "RosterSync", FALSE) == TRUE) {
				for (MCONTACT hContact = db_find_first(proto->m_szModuleName); hContact; ) {
					MCONTACT hNext = hContact = db_find_next(hContact, proto->m_szModuleName);
					ptrA jid( db_get_sa(hContact, proto->m_szModuleName, "jid"));
					if (jid != NULL) {
						if (!TlenListExist(proto, LIST_ROSTER, jid)) {
							proto->debugLogA("Syncing roster: deleting 0x%x", hContact);
							CallService(MS_DB_CONTACT_DELETE, hContact, 0);
						}
					}
					hContact = hNext;
				}
			}

			CLISTMENUITEM mi = { sizeof(mi) };
			mi.flags = CMIM_FLAGS;
			Menu_ModifyItem(proto->hMenuMUC, &mi);
			if (proto->hMenuChats != NULL)
				Menu_ModifyItem(proto->hMenuChats, &mi);

			proto->isOnline = TRUE;
			proto->debugLogA("Status changed via THREADSTART");
			oldStatus = proto->m_iStatus;
			TlenSendPresence(proto, proto->m_iDesiredStatus);
			ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, proto->m_iStatus);
		}
	}
}
Exemplo n.º 2
0
void TlenResultSetRoster(TlenProtocol *proto, XmlNode *queryNode) {
	DBVARIANT dbv;
	XmlNode *itemNode, *groupNode;
	TLEN_LIST_ITEM *item;
	MCONTACT hContact;
	char *jid, *name, *nick;
	int i;
	char *str;

	for (i=0; i<queryNode->numChild; i++) {
		itemNode = queryNode->child[i];
		if (!strcmp(itemNode->name, "item")) {
			if ((jid=TlenXmlGetAttrValue(itemNode, "jid")) != NULL) {
				str = TlenXmlGetAttrValue(itemNode, "subscription");
				if (!strcmp(str, "remove")) {
					if ((hContact = TlenHContactFromJID(proto, jid)) != NULL) {
						if (db_get_w(hContact, proto->m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE)
							db_set_w(hContact, proto->m_szModuleName, "Status", ID_STATUS_OFFLINE);
					}
					TlenListRemove(proto, LIST_ROSTER, jid);
				} else {
					item = TlenListAdd(proto, LIST_ROSTER, jid);
					if (item != NULL) {
						if (str == NULL) item->subscription = SUB_NONE;
						else if (!strcmp(str, "both")) item->subscription = SUB_BOTH;
						else if (!strcmp(str, "to")) item->subscription = SUB_TO;
						else if (!strcmp(str, "from")) item->subscription = SUB_FROM;
						else item->subscription = SUB_NONE;
						if ((name=TlenXmlGetAttrValue(itemNode, "name")) != NULL) {
							nick = TlenTextDecode(name);
						} else {
							nick = TlenLocalNickFromJID(jid);
						}
						if (nick != NULL) {
							if (item->nick) mir_free(item->nick);
							item->nick = nick;

							if ((hContact=TlenHContactFromJID(proto, jid)) == NULL) {
								// Received roster has a new JID.
								// Add the jid (with empty resource) to Miranda contact list.
								hContact = TlenDBCreateContact(proto, jid, nick, FALSE);
							}
							db_set_s(hContact, "CList", "MyHandle", nick);
							if (item->group) mir_free(item->group);
							if ((groupNode=TlenXmlGetChild(itemNode, "group")) != NULL && groupNode->text != NULL) {
								item->group = TlenGroupDecode(groupNode->text);
								Clist_CreateGroup(0, _A2T(item->group));
								// Don't set group again if already correct, or Miranda may show wrong group count in some case
								if (!db_get(hContact, "CList", "Group", &dbv)) {
									if (strcmp(dbv.pszVal, item->group))
										db_set_s(hContact, "CList", "Group", item->group);
									db_free(&dbv);
								} else
									db_set_s(hContact, "CList", "Group", item->group);
							} else {
								item->group = NULL;
								db_unset(hContact, "CList", "Group");
							}
						}
					}
				}
			}
		}
	}
}
Exemplo n.º 3
0
void JabberIqResultGetRoster(XmlNode *iqNode, void *userdata)
{
	//struct ThreadData *info = (struct ThreadData *) userdata;
	XmlNode *queryNode;
	char *type;
	char *str;

	// RECVED: roster information
	// ACTION: populate LIST_ROSTER and create contact for any new rosters
	JabberLog("<iq/> iqIdGetRoster");
	if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return;
	if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return;

	if (!strcmp(type, "result")) {
		str = JabberXmlGetAttrValue(queryNode, "xmlns");
		if (str!=NULL && !strcmp(str, "jabber:iq:roster")) {
			DBVARIANT dbv;
			XmlNode *itemNode, *groupNode;
			JABBER_SUBSCRIPTION sub;
			JABBER_LIST_ITEM *item;
			HANDLE hContact;
			char *jid, *name, *nick;
			int i, oldStatus;

			for (i=0; i<queryNode->numChild; i++) {
				itemNode = queryNode->child[i];
				if (!strcmp(itemNode->name, "item")) {
					str = JabberXmlGetAttrValue(itemNode, "subscription");
					if (str==NULL) sub = SUB_NONE;
					else if (!strcmp(str, "both")) sub = SUB_BOTH;
					else if (!strcmp(str, "to")) sub = SUB_TO;
					else if (!strcmp(str, "from")) sub = SUB_FROM;
					else sub = SUB_NONE;
					//if (str!=NULL && (!strcmp(str, "to") || !strcmp(str, "both"))) {
					if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) {
						if ((name=JabberXmlGetAttrValue(itemNode, "name")) != NULL) {
							nick = JabberTextDecode(name);
						} else {
							nick = JabberLocalNickFromJID(jid);
						}
						if (nick != NULL) {
							item = JabberListAdd(LIST_ROSTER, jid);
							if (item->nick) mir_free(item->nick);
							item->nick = nick;
							item->subscription = sub;
							if ((hContact=JabberHContactFromJID(jid)) == NULL) {
								// Received roster has a new JID.
								// Add the jid (with empty resource) to Miranda contact list.
								hContact = JabberDBCreateContact(jid, nick, FALSE);
							}
							DBWriteContactSettingString(hContact, "CList", "MyHandle", nick);
							if (item->group) mir_free(item->group);
							if ((groupNode=JabberXmlGetChild(itemNode, "group"))!=NULL && groupNode->text!=NULL) {
								item->group = TlenGroupDecode(groupNode->text);
								JabberContactListCreateGroup(item->group);
								// Don't set group again if already correct, or Miranda may show wrong group count in some case
								if (!DBGetContactSetting(hContact, "CList", "Group", &dbv)) {
									if (strcmp(dbv.pszVal, item->group))
										DBWriteContactSettingString(hContact, "CList", "Group", item->group);
									DBFreeVariant(&dbv);
								}
								else
									DBWriteContactSettingString(hContact, "CList", "Group", item->group);
							}
							else {
								item->group = NULL;
								DBDeleteContactSetting(hContact, "CList", "Group");
							}
							if (!DBGetContactSetting(hContact, jabberProtoName, "AvatarHash", &dbv)) {
								if (item->newAvatarHash) mir_free(item->newAvatarHash);
								if (item->avatarHash) mir_free(item->avatarHash);
								item->avatarHash = mir_strdup(dbv.pszVal);
								item->newAvatarHash = mir_strdup(dbv.pszVal);
								DBFreeVariant(&dbv);
							}
							item->avatarFormat = DBGetContactSettingDword(hContact, jabberProtoName, "AvatarFormat", PA_FORMAT_UNKNOWN);
						}
					}
				}
			}
			// Delete orphaned contacts (if roster sync is enabled)
			if (DBGetContactSettingByte(NULL, jabberProtoName, "RosterSync", FALSE) == TRUE) {
				HANDLE *list;
				int listSize, listAllocSize;

				listSize = listAllocSize = 0;
				list = NULL;
				hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
				while (hContact != NULL) {
					str = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
					if(str!=NULL && !strcmp(str, jabberProtoName)) {
						if (!DBGetContactSetting(hContact, jabberProtoName, "jid", &dbv)) {
							if (!JabberListExist(LIST_ROSTER, dbv.pszVal)) {
								JabberLog("Syncing roster: preparing to delete %s (hContact=0x%x)", dbv.pszVal, hContact);
								if (listSize >= listAllocSize) {
									listAllocSize = listSize + 100;
									if ((list=(HANDLE *) mir_realloc(list, listAllocSize)) == NULL) {
										listSize = 0;
										break;
									}
								}
								list[listSize++] = hContact;
							}
							DBFreeVariant(&dbv);
						}
					}
					hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
				}
				for (i=0; i<listSize; i++) {
					JabberLog("Syncing roster: deleting 0x%x", list[i]);
					CallService(MS_DB_CONTACT_DELETE, (WPARAM) list[i], 0);
				}
				if (list != NULL)
					mir_free(list);
			}
			///////////////////////////////////////
			{
				CLISTMENUITEM clmi;
				memset(&clmi, 0, sizeof(CLISTMENUITEM));
				clmi.cbSize = sizeof(CLISTMENUITEM);
				clmi.flags = CMIM_FLAGS;
				CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) hMenuMUC, (LPARAM) &clmi);
				CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) hMenuChats, (LPARAM) &clmi);
			}

			jabberOnline = TRUE;
			JabberLog("Status changed via THREADSTART");
			oldStatus = jabberStatus;
			JabberSendPresence(jabberDesiredStatus);
			ProtoBroadcastAck(jabberProtoName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, jabberStatus);
			//////////////////////////////////
		}
	}
}