void CJabberProto::IqResultProxyDiscovery( HXML iqNode, CJabberIqInfo* pInfo ) { JABBER_BYTE_TRANSFER *jbt = ( JABBER_BYTE_TRANSFER * )pInfo->GetUserData(); if ( pInfo->GetIqType() == JABBER_IQ_TYPE_RESULT ) { HXML queryNode = xmlGetChild( iqNode , "query" ); if ( queryNode ) { const TCHAR *queryXmlns = xmlGetAttrValue( queryNode, _T( "xmlns" )); if (queryXmlns && !_tcscmp( queryXmlns, _T(JABBER_FEAT_BYTESTREAMS))) { HXML streamHostNode = xmlGetChild( queryNode , "streamhost" ); if ( streamHostNode ) { const TCHAR *streamJid = xmlGetAttrValue( streamHostNode, _T( "jid" )); const TCHAR *streamHost = xmlGetAttrValue( streamHostNode, _T( "host" )); const TCHAR *streamPort = xmlGetAttrValue( streamHostNode, _T( "port" )); if ( streamJid && streamHost && streamPort ) { jbt->szProxyHost = mir_tstrdup( streamHost ); jbt->szProxyJid = mir_tstrdup( streamJid ); jbt->szProxyPort = mir_tstrdup( streamPort ); jbt->bProxyDiscovered = TRUE; } } } } } else if ( pInfo->GetIqType() == JABBER_IQ_TYPE_ERROR ) jbt->state = JBT_ERROR; if ( jbt->hProxyEvent ) SetEvent( jbt->hProxyEvent ); }
BOOL CJabberProto::OnIqHttpAuth(HXML node, CJabberIqInfo *pInfo) { if (!m_options.AcceptHttpAuth) return TRUE; if (!node || !pInfo->GetChildNode() || !pInfo->GetFrom() || !pInfo->GetIdStr()) return TRUE; HXML pConfirm = xmlGetChild(node , "confirm"); if (!pConfirm) return TRUE; const TCHAR *szId = xmlGetAttrValue(pConfirm, _T("id")); const TCHAR *szMethod = xmlGetAttrValue(pConfirm, _T("method")); const TCHAR *szUrl = xmlGetAttrValue(pConfirm, _T("url")); if (!szId || !szMethod || !szUrl) return TRUE; CJabberHttpAuthParams *pParams = (CJabberHttpAuthParams*)mir_calloc(sizeof(CJabberHttpAuthParams)); if (pParams) { pParams->m_nType = CJabberHttpAuthParams::IQ; pParams->m_szFrom = mir_tstrdup(pInfo->GetFrom()); pParams->m_szId = mir_tstrdup(szId); pParams->m_szMethod = mir_tstrdup(szMethod); pParams->m_szUrl = mir_tstrdup(szUrl); AddClistHttpAuthEvent(pParams); } return TRUE; }
BOOL CJabberIqManager::HandleIqPermanent(HXML pNode) { mir_cslock lck(m_cs); CJabberIqPermanentInfo *pInfo = m_pPermanentHandlers; while (pInfo) { // have to get all data here, in the loop, because there's always possibility that previous handler modified it const TCHAR *szType = xmlGetAttrValue(pNode, _T("type")); if (!szType) return FALSE; CJabberIqInfo iqInfo; iqInfo.m_nIqType = JABBER_IQ_TYPE_FAIL; if (!_tcsicmp(szType, _T("get"))) iqInfo.m_nIqType = JABBER_IQ_TYPE_GET; else if (!_tcsicmp(szType, _T("set"))) iqInfo.m_nIqType = JABBER_IQ_TYPE_SET; else return FALSE; if (pInfo->m_nIqTypes & iqInfo.m_nIqType) { HXML pFirstChild = xmlGetChild(pNode , 0); if (!pFirstChild || !xmlGetName(pFirstChild)) return FALSE; const TCHAR *szTagName = xmlGetName(pFirstChild); const TCHAR *szXmlns = xmlGetAttrValue(pFirstChild, _T("xmlns")); if ((!pInfo->m_szXmlns || (szXmlns && !_tcscmp(pInfo->m_szXmlns, szXmlns))) && (!pInfo->m_szTag || !_tcscmp(pInfo->m_szTag, szTagName))) { // node suits handler criteria, call the handler iqInfo.m_pChildNode = pFirstChild; iqInfo.m_szChildTagName = (TCHAR*)szTagName; iqInfo.m_szChildTagXmlns = (TCHAR*)szXmlns; iqInfo.m_szId = (TCHAR*)xmlGetAttrValue(pNode, _T("id")); iqInfo.m_pUserData = pInfo->m_pUserData; if (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_TO) iqInfo.m_szTo = (TCHAR*)xmlGetAttrValue(pNode, _T("to")); if (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_FROM) iqInfo.m_szFrom = (TCHAR*)xmlGetAttrValue(pNode, _T("from")); if ((pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_HCONTACT) && (iqInfo.m_szFrom)) iqInfo.m_hContact = ppro->HContactFromJID(iqInfo.m_szFrom, 3); ppro->debugLogA("Handling iq id %S, type %S, from %S", iqInfo.m_szId, szType, iqInfo.m_szFrom); if ((ppro->*(pInfo->m_pHandler))(pNode, &iqInfo)) return TRUE; } } pInfo = pInfo->m_pNext; } return FALSE; }
void CJabberProto::OnIqResultGetCollection(HXML iqNode, CJabberIqInfo*) { if ( mir_tstrcmp( xmlGetAttrValue(iqNode, _T("type")), _T("result"))) return; HXML chatNode = xmlGetChild(iqNode, "chat"); if (!chatNode || mir_tstrcmp( xmlGetAttrValue(chatNode, _T("xmlns")), JABBER_FEAT_ARCHIVE)) return; const TCHAR* start = xmlGetAttrValue(chatNode, _T("start")); const TCHAR* with = xmlGetAttrValue(chatNode, _T("with")); if (!start || !with) return; MCONTACT hContact = HContactFromJID(with); time_t tmStart = str2time(start); if (hContact == 0 || tmStart == 0) return; _tzset(); for (int nodeIdx = 0; ; nodeIdx++) { HXML itemNode = xmlGetChild(chatNode, nodeIdx); if (!itemNode) break; int from; const TCHAR *itemName = xmlGetName(itemNode); if (!mir_tstrcmp(itemName, _T("to"))) from = DBEF_SENT; else if (!mir_tstrcmp(itemName, _T("from"))) from = 0; else continue; HXML body = xmlGetChild(itemNode, "body"); if (!body) continue; const TCHAR *tszBody = xmlGetText(body); const TCHAR *tszSecs = xmlGetAttrValue(itemNode, _T("secs")); if (!tszBody || !tszSecs) continue; ptrA szEventText( mir_utf8encodeT(tszBody)); DBEVENTINFO dbei = { sizeof(DBEVENTINFO) }; dbei.eventType = EVENTTYPE_MESSAGE; dbei.szModule = m_szModuleName; dbei.cbBlob = (DWORD)strlen(szEventText); dbei.flags = DBEF_READ + DBEF_UTF + from; dbei.pBlob = (PBYTE)(char*)szEventText; dbei.timestamp = tmStart + _ttol(tszSecs) - timezone; if (!IsDuplicateEvent(hContact, dbei)) db_event_add(hContact, &dbei); } }
BOOL CJabberProto::OnMessageIbb(HXML, ThreadData*, CJabberMessageInfo* pInfo) { BOOL bOk = FALSE; const TCHAR *sid = xmlGetAttrValue(pInfo->GetChildNode(), _T("sid")); const TCHAR *seq = xmlGetAttrValue(pInfo->GetChildNode(), _T("seq")); if (sid && seq && xmlGetText(pInfo->GetChildNode())) bOk = OnIbbRecvdData(xmlGetText(pInfo->GetChildNode()), sid, seq); return TRUE; }
BOOL CJabberIqManager::HandleIq(int nIqId, HXML pNode ) { if (nIqId == -1 || pNode == NULL) return FALSE; const TCHAR *szType = xmlGetAttrValue( pNode, _T("type")); if ( !szType ) return FALSE; int nIqType = JABBER_IQ_TYPE_FAIL; if (!_tcsicmp(szType, _T("result"))) nIqType = JABBER_IQ_TYPE_RESULT; else if (!_tcsicmp(szType, _T("error"))) nIqType = JABBER_IQ_TYPE_ERROR; else return FALSE; Lock(); CJabberIqInfo* pInfo = DetachInfo(nIqId); Unlock(); if (pInfo) { pInfo->m_nIqType = nIqType; if (nIqType == JABBER_IQ_TYPE_RESULT) { if (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_CHILD_TAG_NODE) pInfo->m_pChildNode = xmlGetChild( pNode , 0 ); if (pInfo->m_pChildNode && (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_CHILD_TAG_NAME)) pInfo->m_szChildTagName = ( TCHAR* )xmlGetName( pInfo->m_pChildNode ); if (pInfo->m_pChildNode && (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_CHILD_TAG_XMLNS)) pInfo->m_szChildTagXmlns = ( TCHAR* )xmlGetAttrValue( pNode, _T("xmlns")); } if (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_TO) pInfo->m_szTo = ( TCHAR* )xmlGetAttrValue( pNode, _T("to")); if (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_FROM) pInfo->m_szFrom = ( TCHAR* )xmlGetAttrValue( pNode, _T("from")); if (pInfo->m_szFrom && (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_HCONTACT)) pInfo->m_hContact = ppro->HContactFromJID( pInfo->m_szFrom, 3 ); if (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_ID_STR) pInfo->m_szId = ( TCHAR* )xmlGetAttrValue( pNode, _T("id")); (ppro->*(pInfo->m_pHandler))(pNode, pInfo); delete pInfo; return TRUE; } return FALSE; }
void CJabberProto::ByteInitiateResult( HXML iqNode, CJabberIqInfo* pInfo ) { JABBER_BYTE_TRANSFER *jbt = ( JABBER_BYTE_TRANSFER * )pInfo->GetUserData(); if ( pInfo->GetIqType() == JABBER_IQ_TYPE_RESULT ) { HXML queryNode = xmlGetChild( iqNode , "query" ); if ( queryNode ) { const TCHAR* queryXmlns = xmlGetAttrValue( queryNode, _T("xmlns")); if ( queryXmlns && !_tcscmp( queryXmlns, _T( JABBER_FEAT_BYTESTREAMS ))) { HXML streamHostNode = xmlGetChild( queryNode , "streamhost-used" ); if ( streamHostNode ) { const TCHAR* streamJid = xmlGetAttrValue( streamHostNode, _T("jid")); if ( streamJid ) jbt->szStreamhostUsed = mir_tstrdup( streamJid ); } } } } if ( jbt->hProxyEvent ) SetEvent( jbt->hProxyEvent ); }
XmlNodeIq::XmlNodeIq(const TCHAR *type, HXML node, LPCTSTR to) : XmlNode(_T("iq")) { if (type != NULL) *this << XATTR(_T("type"), type ); if (to != NULL) *this << XATTR(_T("to"), to ); if (node != NULL) { const TCHAR *iqId = xmlGetAttrValue(*this, _T("id")); if (iqId != NULL) *this << XATTR(_T("id"), iqId); } }
void CJabberProto::OnIqResultGetCollectionList(HXML iqNode, CJabberIqInfo*) { const TCHAR *to = xmlGetAttrValue(iqNode, _T("to")); if (to == NULL || mir_tstrcmp( xmlGetAttrValue(iqNode, _T("type")), _T("result"))) return; HXML list = xmlGetChild(iqNode, "list"); if (!list || mir_tstrcmp( xmlGetAttrValue(list, _T("xmlns")), JABBER_FEAT_ARCHIVE)) return; MCONTACT hContact = NULL; time_t tmLast = 0; for (int nodeIdx = 1; ; nodeIdx++) { HXML itemNode = xmlGetNthChild(list, _T("chat"), nodeIdx); if (!itemNode) break; const TCHAR* start = xmlGetAttrValue(itemNode, _T("start")); const TCHAR* with = xmlGetAttrValue(itemNode, _T("with")); if (!start || !with) continue; if (hContact == NULL) { if ((hContact = HContactFromJID(with)) == NULL) continue; tmLast = getDword(hContact, "LastCollection", 0); } m_ThreadInfo->send( XmlNodeIq( AddIQ(&CJabberProto::OnIqResultGetCollection, JABBER_IQ_TYPE_GET)) << XCHILDNS( _T("retrieve"), JABBER_FEAT_ARCHIVE) << XATTR(_T("with"), with) << XATTR(_T("start"), start)); time_t tmThis = str2time(start); if ( tmThis > tmLast) { tmLast = tmThis; setDword(hContact, "LastCollection", tmLast+1); } } }
void CJabberProto::OnIqResultGetMuc( HXML iqNode ) { HXML queryNode, xNode; const TCHAR *type, *from, *str; // RECVED: room config form // ACTION: show the form Log( "<iq/> iqIdGetMuc" ); if (( type = xmlGetAttrValue( iqNode, _T("type"))) == NULL ) return; if (( from = xmlGetAttrValue( iqNode, _T("from"))) == NULL ) return; if ( !_tcscmp( type, _T("result"))) { if (( queryNode = xmlGetChild( iqNode , "query" )) != NULL ) { str = xmlGetAttrValue( queryNode, _T("xmlns")); if ( !lstrcmp( str, _T("http://jabber.org/protocol/muc#owner" ))) { if (( xNode = xmlGetChild( queryNode , "x" )) != NULL ) { str = xmlGetAttrValue( xNode, _T("xmlns")); if ( !lstrcmp( str, _T(JABBER_FEAT_DATA_FORMS))) //LaunchForm(xNode); FormCreateDialog( xNode, _T("Jabber Conference Room Configuration"), &CJabberProto::SetMucConfig, mir_tstrdup( from )); } } } } }
void OnSubmit(CCtrlButton*) { HXML queryNode, xNode; const TCHAR *from; if (m_agentRegIqNode == NULL) return; if ((from = xmlGetAttrValue(m_agentRegIqNode, _T("from"))) == NULL) return; if ((queryNode = xmlGetChild(m_agentRegIqNode , "query")) == NULL) return; HWND hFrame = GetDlgItem(m_hwnd, IDC_FRAME); TCHAR *str2 = (TCHAR*)alloca(sizeof(TCHAR) * 128); int id = 0; XmlNodeIq iq( m_proto->AddIQ(&CJabberProto::OnIqResultSetRegister, JABBER_IQ_TYPE_SET, from)); HXML query = iq << XQUERY(JABBER_FEAT_REGISTER); if ((xNode = xmlGetChild(queryNode , "x")) != NULL) { // use new jabber:x:data form HXML n = JabberFormGetData(hFrame, xNode); xmlAddChild(query, n); xi.destroyNode(n); } else { // use old registration information form for (int i=0; ; i++) { HXML n = xmlGetChild(queryNode ,i); if (!n) break; if (xmlGetName(n)) { if (!lstrcmp(xmlGetName(n), _T("key"))) { // field that must be passed along with the registration if (xmlGetText(n)) xmlAddChild(query, xmlGetName(n), xmlGetText(n)); else xmlAddChild(query, xmlGetName(n)); } else if (!lstrcmp(xmlGetName(n), _T("registered")) || !lstrcmp(xmlGetName(n), _T("instructions"))) { // do nothing, we will skip these } else { GetDlgItemText(hFrame, id, str2, 128); xmlAddChild(query, xmlGetName(n), str2); id++; } } } } m_proto->m_ThreadInfo->send(iq); CAgentRegProgressDlg(m_proto, m_hwnd).DoModal(); Close(); }
BOOL CJabberProto::OnFtHandleIbbIq( HXML iqNode, CJabberIqInfo* pInfo ) { if ( !_tcscmp( pInfo->GetChildNodeName(), _T("open"))) FtHandleIbbRequest( iqNode, TRUE ); else if ( !_tcscmp( pInfo->GetChildNodeName(), _T("close"))) FtHandleIbbRequest( iqNode, FALSE ); else if ( !_tcscmp( pInfo->GetChildNodeName(), _T("data"))) { BOOL bOk = FALSE; const TCHAR *sid = xmlGetAttrValue( pInfo->GetChildNode(), _T("sid")); const TCHAR *seq = xmlGetAttrValue( pInfo->GetChildNode(), _T("seq")); if ( sid && seq && xmlGetText( pInfo->GetChildNode())) bOk = OnIbbRecvdData( xmlGetText( pInfo->GetChildNode()), sid, seq ); if ( bOk ) m_ThreadInfo->send( XmlNodeIq( _T("result"), pInfo )); else m_ThreadInfo->send( XmlNodeIq( _T("error"), pInfo ) << XCHILD( _T("error")) << XATTRI( _T("code"), 404 ) << XATTR( _T("type"), _T("cancel")) << XCHILDNS( _T("item-not-found"), _T("urn:ietf:params:xml:ns:xmpp-stanzas"))); } return TRUE; }
BOOL CJabberProto::OnSiRequest(HXML node, CJabberIqInfo *pInfo) { const TCHAR *szProfile = xmlGetAttrValue(pInfo->GetChildNode(), _T("profile")); if (szProfile && !_tcscmp(szProfile, JABBER_FEAT_SI_FT)) FtHandleSiRequest(node); else { XmlNodeIq iq(_T("error"), pInfo); HXML error = iq << XCHILD(_T("error")) << XATTRI(_T("code"), 400) << XATTR(_T("type"), _T("cancel")); error << XCHILDNS(_T("bad-request"), _T("urn:ietf:params:xml:ns:xmpp-stanzas")); error << XCHILD(_T("bad-profile")); m_ThreadInfo->send(iq); } return TRUE; }
void CJabberProto::OnIqResultMucGetJidList( HXML iqNode, JABBER_MUC_JIDLIST_TYPE listType ) { const TCHAR* type; JABBER_MUC_JIDLIST_INFO *jidListInfo; if (( type = xmlGetAttrValue( iqNode, _T("type"))) == NULL ) return; if ( !lstrcmp( type, _T("result" ))) { if (( jidListInfo = new JABBER_MUC_JIDLIST_INFO ) != NULL ) { jidListInfo->type = listType; jidListInfo->ppro = this; jidListInfo->roomJid = NULL; // Set in the dialog procedure if (( jidListInfo->iqNode = xi.copyNode( iqNode )) != NULL ) CallFunctionAsync( JabberMucJidListCreateDialogApcProc, jidListInfo ); else mir_free( jidListInfo ); } } }
void CJabberProto::IqResultStreamActivate( HXML iqNode ) { int id = JabberGetPacketID( iqNode ); TCHAR listJid[JABBER_MAX_JID_LEN]; mir_sntprintf(listJid, SIZEOF( listJid ), _T("ftproxy_%d"), id); JABBER_LIST_ITEM *item = ListGetItemPtr( LIST_FTIQID, listJid ); if ( !item ) return; if ( !lstrcmp( xmlGetAttrValue( iqNode, _T("type")), _T( "result" ))) item->jbt->bStreamActivated = TRUE; if ( item->jbt->hProxyEvent ) SetEvent( item->jbt->hProxyEvent ); }
static void CALLBACK JabberMucJidListCreateDialogApcProc( void* param ) { HXML iqNode, queryNode; const TCHAR* from; HWND *pHwndJidList; JABBER_MUC_JIDLIST_INFO *jidListInfo = (JABBER_MUC_JIDLIST_INFO *)param; if ( jidListInfo == NULL ) return; if (( iqNode = jidListInfo->iqNode ) == NULL ) return; if (( from = xmlGetAttrValue( iqNode, _T("from"))) == NULL ) return; if (( queryNode = xmlGetChild( iqNode , "query" )) == NULL ) return; CJabberProto* ppro = jidListInfo->ppro; switch ( jidListInfo->type ) { case MUC_VOICELIST: pHwndJidList = &ppro->m_hwndMucVoiceList; break; case MUC_MEMBERLIST: pHwndJidList = &ppro->m_hwndMucMemberList; break; case MUC_MODERATORLIST: pHwndJidList = &ppro->m_hwndMucModeratorList; break; case MUC_BANLIST: pHwndJidList = &ppro->m_hwndMucBanList; break; case MUC_ADMINLIST: pHwndJidList = &ppro->m_hwndMucAdminList; break; case MUC_OWNERLIST: pHwndJidList = &ppro->m_hwndMucOwnerList; break; default: mir_free( jidListInfo ); return; } if ( *pHwndJidList!=NULL && IsWindow( *pHwndJidList )) { SetForegroundWindow( *pHwndJidList ); SendMessage( *pHwndJidList, WM_JABBER_REFRESH, 0, ( LPARAM )jidListInfo ); } else *pHwndJidList = CreateDialogParam( hInst, MAKEINTRESOURCE( IDD_JIDLIST ), GetForegroundWindow(), JabberMucJidListDlgProc, ( LPARAM )jidListInfo ); }
void CJabberProto::OnIqResultCapsDiscoInfo(HXML, CJabberIqInfo *pInfo) { pResourceStatus r(ResourceInfoFromJID(pInfo->GetFrom())); HXML query = pInfo->GetChildNode(); if (pInfo->GetIqType() == JABBER_IQ_TYPE_RESULT && query) { JabberCapsBits jcbCaps = 0; HXML feature; for (int i = 1; (feature = xmlGetNthChild(query, _T("feature"), i)) != NULL; i++) { const TCHAR *featureName = xmlGetAttrValue(feature, _T("var")); if (!featureName) continue; for (int j = 0; g_JabberFeatCapPairs[j].szFeature; j++) { if (!_tcscmp(g_JabberFeatCapPairs[j].szFeature, featureName)) { jcbCaps |= g_JabberFeatCapPairs[j].jcbCap; break; } } } // no version info support and no XEP-0115 support? if (r && r->m_dwVersionRequestTime == -1 && !r->m_tszSoftwareVersion && !r->m_tszSoftware && !r->m_tszCapsNode) { r->m_jcbCachedCaps = jcbCaps; r->m_dwDiscoInfoRequestTime = -1; return; } if (r && !m_clientCapsManager.SetClientCaps(pInfo->GetIqId(), jcbCaps)) r->m_jcbCachedCaps = jcbCaps; JabberUserInfoUpdate(pInfo->GetHContact()); } else { // no version info support and no XEP-0115 support? if (r && r->m_dwVersionRequestTime == -1 && !r->m_tszSoftwareVersion && !r->m_tszSoftware && !r->m_tszCapsNode) { r->m_jcbCachedCaps = JABBER_RESOURCE_CAPS_NONE; r->m_dwDiscoInfoRequestTime = -1; } else m_clientCapsManager.SetClientCaps(pInfo->GetIqId(), JABBER_RESOURCE_CAPS_ERROR); } }
BOOL CJabberProto::OnHandleDiscoInfoRequest(HXML iqNode, CJabberIqInfo *pInfo) { if (!pInfo->GetChildNode()) return TRUE; const TCHAR *szNode = xmlGetAttrValue(pInfo->GetChildNode(), _T("node")); // caps hack if (m_clientCapsManager.HandleInfoRequest(iqNode, pInfo, szNode)) return TRUE; // ad-hoc hack: if (szNode && m_adhocManager.HandleInfoRequest(iqNode, pInfo, szNode)) return TRUE; // another request, send empty result m_ThreadInfo->send( XmlNodeIq(_T("error"), pInfo) << XCHILD(_T("error")) << XATTRI(_T("code"), 404) << XATTR(_T("type"), _T("cancel")) << XCHILDNS(_T("item-not-found"), _T("urn:ietf:params:xml:ns:xmpp-stanzas"))); return TRUE; }
BOOL CJabberProto::OnHandleDiscoItemsRequest(HXML iqNode, CJabberIqInfo *pInfo) { if (!pInfo->GetChildNode()) return TRUE; // ad-hoc commands check: const TCHAR *szNode = xmlGetAttrValue(pInfo->GetChildNode(), _T("node")); if (szNode && m_adhocManager.HandleItemsRequest(iqNode, pInfo, szNode)) return TRUE; // another request, send empty result XmlNodeIq iq(_T("result"), pInfo); HXML resultQuery = iq << XQUERY(JABBER_FEAT_DISCO_ITEMS); if (szNode) xmlAddAttr(resultQuery, _T("node"), szNode); if (!szNode && m_options.EnableRemoteControl) resultQuery << XCHILD(_T("item")) << XATTR(_T("jid"), m_ThreadInfo->fullJID) << XATTR(_T("node"), JABBER_FEAT_COMMANDS) << XATTR(_T("name"), _T("Ad-hoc commands")); m_ThreadInfo->send(iq); return TRUE; }
INT_PTR CSkypeProto::GetCallEventText(WPARAM, LPARAM lParam) { DBEVENTGETTEXT *pEvent = (DBEVENTGETTEXT *)lParam; INT_PTR nRetVal = 0; ptrA pszText; switch (pEvent->dbei->eventType) { case SKYPE_DB_EVENT_TYPE_CALL_INFO: { CMStringA text; HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("partlist")); if (xml != NULL) { ptrA type(mir_t2a(xmlGetAttrValue(xml, _T("type")))); bool bType = (!mir_strcmpi(type, "started")) ? 1 : 0; for (int i = 0; i < xmlGetChildCount(xml); i++) { HXML xmlPart = xmlGetNthChild(xml, _T("part"), i); if (xmlPart != NULL) { HXML xmlName = xmlGetChildByPath(xmlPart, _T("name"), 0); if (xmlName != NULL) { text.AppendFormat(Translate("%s %s this call.\n"), _T2A(xmlGetText(xmlName)), bType ? Translate("enters") : Translate("leaves")); xmlDestroyNode(xmlName); } xmlDestroyNode(xmlPart); } } xmlDestroyNode(xml); } pszText = mir_strdup(text.GetBuffer()); break; } case SKYPE_DB_EVENT_TYPE_FILETRANSFER_INFO: { CMStringA text; HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("files")); if (xml != NULL) { for (int i = 0; i < xmlGetChildCount(xml); i++) { size_t fileSize = 0; HXML xmlNode = xmlGetNthChild(xml, _T("file"), i); if (xmlNode != NULL) { fileSize = _ttoi(ptrT((TCHAR*)xmlGetAttrValue(xmlNode, _T("size")))); ptrA fileName(mir_utf8encodeT(ptrT((TCHAR*)xmlGetText(xmlNode)))); if (fileName != NULL) { CMStringA msg(FORMAT, Translate("File transfer:\n\tFile name: %s\n\tSize: %d bytes"), fileName, fileSize); text.AppendFormat("%s\n", msg); } xmlDestroyNode(xmlNode); } } xmlDestroyNode(xml); } pszText = mir_strdup(text.GetBuffer()); break; } case SKYPE_DB_EVENT_TYPE_URIOBJ: { CMStringA text; HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("URIObject")); if (xml != NULL) { text.Append(_T2A(xmlGetText(xml))); xmlDestroyNode(xml); } pszText = mir_strdup(text.GetBuffer()); break; } case SKYPE_DB_EVENT_TYPE_INCOMING_CALL: { pszText = Translate("Incoming call."); break; } default: { pszText = mir_strdup((char*)pEvent->dbei->pBlob); } } if (pEvent->datatype == DBVT_TCHAR) { TCHAR *pwszText = _A2T(pszText); nRetVal = (INT_PTR)mir_tstrdup(pwszText); } else if (pEvent->datatype == DBVT_ASCIIZ) nRetVal = (INT_PTR)mir_strdup(pszText); return nRetVal; }
void CJabberProto::OnIqResultDiscovery(HXML iqNode, CJabberIqInfo *pInfo) { if (!iqNode || !pInfo) return; HWND hwndList = (HWND)pInfo->GetUserData(); SendMessage(hwndList, CB_SHOWDROPDOWN, FALSE, 0); SendMessage(hwndList, CB_RESETCONTENT, 0, 0); if ( pInfo->GetIqType() == JABBER_IQ_TYPE_RESULT ) { HXML query = xmlGetChild( iqNode , "query" ); if ( !query ) { sttRoomListAppend(hwndList, RoomInfo::ROOM_FAIL, TranslateT("Jabber Error"), TranslateT("Failed to retrieve room list from server."), _T("")); } else { bool found = false; HXML item; for ( int i = 1; item = xmlGetNthChild( query, _T("item"), i ); i++ ) { const TCHAR *jid = xmlGetAttrValue( item, _T("jid")); TCHAR *name = NEWTSTR_ALLOCA(jid); if (name) { if (TCHAR *p = _tcschr(name, _T('@'))) *p = 0; } else { name = _T(""); } sttRoomListAppend(hwndList, ListGetItemPtr(LIST_BOOKMARK, jid) ? RoomInfo::ROOM_BOOKMARK : RoomInfo::ROOM_DEFAULT, xmlGetAttrValue( item, _T("name")), jid, name); found = true; } if (!found) { sttRoomListAppend(hwndList, RoomInfo::ROOM_FAIL, TranslateT("Jabber Error"), TranslateT("No rooms available on server."), _T("")); } } } else if ( pInfo->GetIqType() == JABBER_IQ_TYPE_ERROR ) { HXML errorNode = xmlGetChild( iqNode , "error" ); TCHAR* str = JabberErrorMsg( errorNode ); sttRoomListAppend(hwndList, RoomInfo::ROOM_FAIL, TranslateT("Jabber Error"), str, _T("")); mir_free( str ); } else { sttRoomListAppend(hwndList, RoomInfo::ROOM_FAIL, TranslateT("Jabber Error"), TranslateT("Room list request timed out."), _T("")); } SendMessage(hwndList, CB_SHOWDROPDOWN, TRUE, 0); }
LPCTSTR __fastcall XmlGetAttrValue(HXML hXml, LPCTSTR key) { return xmlGetAttrValue(hXml, key); }
INT_PTR CSkypeProto::GetEventText(WPARAM, LPARAM lParam) { DBEVENTGETTEXT *pEvent = (DBEVENTGETTEXT *)lParam; CMStringA szText; BOOL bUseBB = db_get_b(NULL, pEvent->dbei->szModule, "UseBBCodes", 1); switch (pEvent->dbei->eventType) { case SKYPE_DB_EVENT_TYPE_EDITED_MESSAGE: { JSONNode jMsg = JSONNode::parse((char*)pEvent->dbei->pBlob); if (jMsg) { JSONNode &jOriginalMsg = jMsg["original_message"]; szText.AppendFormat(bUseBB ? Translate("[b]Original message:[/b]\n%s\n") : Translate("Original message:\n%s\n"), mir_utf8decodeA(jOriginalMsg["text"].as_string().c_str())); JSONNode &jEdits = jMsg["edits"]; for (auto it = jEdits.begin(); it != jEdits.end(); ++it) { const JSONNode &jEdit = *it; time_t time = jEdit["time"].as_int(); char szTime[MAX_PATH]; strftime(szTime, sizeof(szTime), "%X %x", localtime(&time)); szText.AppendFormat(bUseBB ? Translate("[b]Edited at %s:[/b]\n%s\n") : Translate("Edited at %s:\n%s\n"), szTime, mir_utf8decodeA(jEdit["text"].as_string().c_str())); } } else { szText = INVALID_DATA; } break; } case SKYPE_DB_EVENT_TYPE_CALL_INFO: { HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("partlist")); if (xml != NULL) { ptrA type(mir_t2a(xmlGetAttrValue(xml, _T("type")))); bool bType = (!mir_strcmpi(type, "started")) ? 1 : 0; time_t callDuration = 0; for (int i = 0; i < xmlGetChildCount(xml); i++) { HXML xmlPart = xmlGetNthChild(xml, _T("part"), i); if (xmlPart != NULL) { HXML xmlDuration = xmlGetChildByPath(xmlPart, _T("duration"), 0); if (xmlDuration != NULL) { callDuration = _ttol(xmlGetText(xmlDuration)); xmlDestroyNode(xmlDuration); xmlDestroyNode(xmlPart); break; } xmlDestroyNode(xmlPart); } } if (bType) { szText = Translate("Call"); } else { if (callDuration == 0) { szText = Translate("Call missed"); } else { char szTime[100]; strftime(szTime, sizeof(szTime), "%X", gmtime(&callDuration)); szText.Format(Translate("Call ended (%s)"), szTime); } } xmlDestroyNode(xml); } else { szText = INVALID_DATA; } break; } case SKYPE_DB_EVENT_TYPE_FILETRANSFER_INFO: { HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("files")); if (xml != NULL) { for (int i = 0; i < xmlGetChildCount(xml); i++) { LONGLONG fileSize = 0; HXML xmlNode = xmlGetNthChild(xml, _T("file"), i); if (xmlNode != NULL) { fileSize = _ttol(xmlGetAttrValue(xmlNode, _T("size"))); char *fileName = _T2A(xmlGetText(xmlNode)); if (fileName != NULL) { szText.AppendFormat(Translate("File transfer:\n\tFile name: %s \n\tSize: %lld bytes \n"), fileName, fileSize); } xmlDestroyNode(xmlNode); } } xmlDestroyNode(xml); } else { szText = INVALID_DATA; } break; } case SKYPE_DB_EVENT_TYPE_MOJI: case SKYPE_DB_EVENT_TYPE_URIOBJ: { HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("URIObject")); if (xml != NULL) { szText.Append(_T2A(xmlGetText(xml))); HXML xmlA = xmlGetChildByPath(xml, _T("a"), 0); if (xmlA != NULL) { szText += _T2A(xmlGetAttrValue(xmlA, _T("href"))); xmlDestroyNode(xmlA); } xmlDestroyNode(xml); } else { szText = INVALID_DATA; } break; } case SKYPE_DB_EVENT_TYPE_INCOMING_CALL: { szText = Translate("Incoming call"); break; } case SKYPE_DB_EVENT_TYPE_UNKNOWN: { szText.Format(Translate("Unknown event, please send this text for developer: \"%s\""), mir_utf8decodeA((char*)pEvent->dbei->pBlob)); break; } default: { szText = ptrA(mir_utf8decodeA((char*)pEvent->dbei->pBlob)); } } switch(pEvent->datatype) { case DBVT_TCHAR: { return (INT_PTR)mir_a2t(szText); } case DBVT_ASCIIZ: { return (INT_PTR)szText.Detach(); } case DBVT_UTF8: { return (INT_PTR)mir_utf8encode(szText); } default: { return NULL; } } }
BOOL CJabberMessageManager::HandleMessagePermanent(HXML node, ThreadData *pThreadData) { BOOL bStopHandling = FALSE; Lock(); CJabberMessagePermanentInfo *pInfo = m_pPermanentHandlers; while ( pInfo && !bStopHandling ) { // have to get all data here, in the loop, because there's always possibility that previous handler modified it CJabberMessageInfo messageInfo; LPCTSTR szType = xmlGetAttrValue(node, _T("type")); if ( szType ) { if ( !_tcsicmp( szType, _T("normal"))) messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_NORMAL; else if ( !_tcsicmp( szType, _T("error"))) messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_ERROR; else if ( !_tcsicmp( szType, _T("chat"))) messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_CHAT; else if ( !_tcsicmp( szType, _T("groupchat"))) messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_GROUPCHAT; else if ( !_tcsicmp( szType, _T("headline"))) messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_HEADLINE; else break; // m_nMessageType = JABBER_MESSAGE_TYPE_FAIL; } else { messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_NORMAL; } if ( (pInfo->m_nMessageTypes & messageInfo.m_nMessageType )) { int i; for ( i = xmlGetChildCount( node ) - 1; i >= 0; i-- ) { // enumerate all children and see whether this node suits handler criteria HXML child = xmlGetChild( node, i ); LPCTSTR szTagName = xmlGetName(child); LPCTSTR szXmlns = xmlGetAttrValue( child, _T("xmlns")); if ( (!pInfo->m_szXmlns || ( szXmlns && !_tcscmp( pInfo->m_szXmlns, szXmlns ))) && ( !pInfo->m_szTag || !_tcscmp( pInfo->m_szTag, szTagName ))) { // node suits handler criteria, call the handler messageInfo.m_hChildNode = child; messageInfo.m_szChildTagName = szTagName; messageInfo.m_szChildTagXmlns = szXmlns; messageInfo.m_pUserData = pInfo->m_pUserData; messageInfo.m_szFrom = xmlGetAttrValue( node, _T("from")); // is necessary for ppro->Log() below, that's why we must parse it even if JABBER_MESSAGE_PARSE_FROM flag is not set if (pInfo->m_dwParamsToParse & JABBER_MESSAGE_PARSE_ID_STR) messageInfo.m_szId = xmlGetAttrValue( node, _T("id")); if (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_TO) messageInfo.m_szTo = xmlGetAttrValue( node, _T("to")); if (pInfo->m_dwParamsToParse & JABBER_MESSAGE_PARSE_HCONTACT) messageInfo.m_hContact = ppro->HContactFromJID( messageInfo.m_szFrom, 3 ); if (messageInfo.m_szFrom) ppro->Log( "Handling message from " TCHAR_STR_PARAM, messageInfo.m_szFrom ); if ((ppro->*(pInfo->m_pHandler))(node, pThreadData, &messageInfo)) { bStopHandling = TRUE; break; } } } } pInfo = pInfo->m_pNext; } Unlock(); return bStopHandling; }
void CJabberProto::OnIqResultAdvancedSearch( HXML iqNode ) { const TCHAR* type; int id; U_TCHAR_MAP mColumnsNames(10); LIST<void> SearchResults(2); if ((( id = JabberGetPacketID( iqNode )) == -1 ) || (( type = xmlGetAttrValue( iqNode, _T("type"))) == NULL )) { JSendBroadcast( NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, ( HANDLE ) id, 0 ); return; } if ( !lstrcmp( type, _T("result"))) { HXML queryNode = xmlGetNthChild( iqNode, _T("query"), 1 ); HXML xNode = xmlGetChildByTag( queryNode, "x", "xmlns", _T(JABBER_FEAT_DATA_FORMS)); if (xNode) { //1. Form search results info HXML reportNode = xmlGetNthChild( xNode, _T("reported"), 1 ); if (reportNode) { int i = 1; while ( HXML fieldNode = xmlGetNthChild( reportNode, _T("field"), i++ )) { TCHAR* var = ( TCHAR* )xmlGetAttrValue( fieldNode, _T( "var" )); if ( var ) { TCHAR* Label = ( TCHAR* )xmlGetAttrValue( fieldNode, _T( "label" )); mColumnsNames.insert(var, (Label!=NULL) ? Label : var); } } } int i=1; HXML itemNode; while ( itemNode = xmlGetNthChild( xNode, _T("item"), i++ )) { U_TCHAR_MAP *pUserColumn = new U_TCHAR_MAP(10); int j = 1; while ( HXML fieldNode = xmlGetNthChild( itemNode, _T("field"), j++ )) { if ( TCHAR* var = (TCHAR*)xmlGetAttrValue( fieldNode, _T("var"))) { if ( TCHAR* Text = (TCHAR*)xmlGetText( xmlGetChild( fieldNode, _T("value")))) { if ( !mColumnsNames[var] ) mColumnsNames.insert(var,var); pUserColumn->insert(var,Text); } } } SearchResults.insert((void*)pUserColumn); } } else { //2. Field list search results info int i=1; while ( HXML itemNode = xmlGetNthChild( queryNode, _T("item"), i++ )) { U_TCHAR_MAP *pUserColumn=new U_TCHAR_MAP(10); TCHAR* jid = (TCHAR*)xmlGetAttrValue( itemNode, _T("jid")); TCHAR* keyReturned; mColumnsNames.insertCopyKey( _T("jid"),_T("jid"),&keyReturned, CopyKey, DestroyKey ); mColumnsNames.insert( _T("jid"), keyReturned ); pUserColumn->insertCopyKey( _T("jid"), jid, NULL, CopyKey, DestroyKey ); for ( int j=0; ; j++ ) { HXML child = xmlGetChild( itemNode, j ); if ( !child ) break; const TCHAR* szColumnName = xmlGetName( child ); if ( szColumnName ) { if ( xmlGetText( child ) && xmlGetText( child )[0] != _T('\0')) { mColumnsNames.insertCopyKey(( TCHAR* )szColumnName,_T(""),&keyReturned, CopyKey, DestroyKey); mColumnsNames.insert(( TCHAR* )szColumnName,keyReturned); pUserColumn->insertCopyKey(( TCHAR* )szColumnName, ( TCHAR* )xmlGetText( child ),NULL, CopyKey, DestroyKey); } } } SearchResults.insert((void*)pUserColumn); } } } else if (!lstrcmp( type, _T("error"))) { const TCHAR* code=NULL; const TCHAR* description=NULL; TCHAR buff[255]; HXML errorNode = xmlGetChild( iqNode , "error" ); if (errorNode) { code = xmlGetAttrValue( errorNode, _T("code")); description = xmlGetText( errorNode ); } _sntprintf(buff,SIZEOF(buff),TranslateT("Error %s %s\r\nTry to specify more detailed"),code ? code : _T(""),description?description:_T("")); JSendBroadcast( NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, ( HANDLE ) id, 0 ); if (searchHandleDlg ) SetDlgItemText(searchHandleDlg,IDC_INSTRUCTIONS,buff); else MessageBox(NULL, buff, TranslateT("Search error"), MB_OK|MB_ICONSTOP); return; } SearchReturnResults((HANDLE)id, (void*)&SearchResults, (U_TCHAR_MAP *)&mColumnsNames); for (int i=0; i < SearchResults.getCount(); i++ ) delete ((U_TCHAR_MAP *)SearchResults[i]); //send success to finish searching JSendBroadcast( NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, ( HANDLE ) id, 0 ); }
void CJabberProto::OnIqResultGetSearchFields( HXML iqNode ) { if ( !searchHandleDlg ) return; LPCTSTR type = xmlGetAttrValue( iqNode, _T("type")); if ( !type ) return; if ( !lstrcmp( type, _T("result"))) { HXML queryNode = xmlGetNthChild( iqNode, _T("query"), 1 ); HXML xNode = xmlGetChildByTag( queryNode, "x", "xmlns", _T(JABBER_FEAT_DATA_FORMS)); ShowWindow(searchHandleDlg,SW_HIDE); if ( xNode ) { //1. Form PostMessage( searchHandleDlg, WM_USER+11, ( WPARAM )xi.copyNode( xNode ), ( LPARAM )0 ); HXML xcNode = xmlGetNthChild( xNode, _T("instructions"), 1 ); if ( xcNode ) SetDlgItemText( searchHandleDlg, IDC_INSTRUCTIONS, xmlGetText( xcNode )); } else { int Order=0; for ( int i = 0; ; i++ ) { HXML chNode = xmlGetChild( queryNode, i ); if ( !chNode ) break; if ( !_tcsicmp( xmlGetName( chNode ), _T("instructions")) && xmlGetText( chNode )) SetDlgItemText(searchHandleDlg,IDC_INSTRUCTIONS,TranslateTS(xmlGetText( chNode ))); else if ( xmlGetName( chNode ) ) { Data *MyData=(Data*)malloc(sizeof(Data)); memset(MyData,0,sizeof(Data)); MyData->Label = mir_tstrdup( xmlGetName( chNode )); MyData->Var = mir_tstrdup( xmlGetName( chNode )); MyData->defValue = mir_tstrdup(xmlGetText( chNode )); MyData->Order = Order; if (MyData->defValue) MyData->bReadOnly = TRUE; PostMessage(searchHandleDlg,WM_USER+10,(WPARAM)FALSE,(LPARAM)MyData); Order++; } } } const TCHAR* szFrom = xmlGetAttrValue( iqNode, _T("from")); if (szFrom) SearchAddToRecent(szFrom,searchHandleDlg); PostMessage(searchHandleDlg,WM_USER+10,(WPARAM)0,(LPARAM)0); ShowWindow(searchHandleDlg,SW_SHOW); } else if ( !lstrcmp( type, _T("error"))) { const TCHAR* code=NULL; const TCHAR* description=NULL; TCHAR buff[255]; HXML errorNode = xmlGetChild( iqNode, "error"); if ( errorNode ) { code = xmlGetAttrValue( errorNode, _T("code")); description=xmlGetText( errorNode ); } _sntprintf(buff,SIZEOF(buff),TranslateT("Error %s %s\r\nPlease select other server"),code ? code : _T(""),description?description:_T("")); SetDlgItemText(searchHandleDlg,IDC_INSTRUCTIONS,buff); } else SetDlgItemText( searchHandleDlg, IDC_INSTRUCTIONS, TranslateT( "Error Unknown reply recieved\r\nPlease select other server" )); }
BOOL CJabberProto::OnRosterPushRequest(HXML, CJabberIqInfo *pInfo) { HXML queryNode = pInfo->GetChildNode(); // RFC 3921 #7.2 Business Rules if (pInfo->GetFrom()) { TCHAR *szFrom = JabberPrepareJid(pInfo->GetFrom()); if (!szFrom) return TRUE; TCHAR *szTo = JabberPrepareJid(m_ThreadInfo->fullJID); if (!szTo) { mir_free(szFrom); return TRUE; } TCHAR *pDelimiter = _tcschr(szFrom, _T('/')); if (pDelimiter) *pDelimiter = 0; pDelimiter = _tcschr(szTo, _T('/')); if (pDelimiter) *pDelimiter = 0; BOOL bRetVal = _tcscmp(szFrom, szTo) == 0; mir_free(szFrom); mir_free(szTo); // invalid JID if (!bRetVal) { debugLogA("<iq/> attempt to hack via roster push from %S", pInfo->GetFrom()); return TRUE; } } JABBER_LIST_ITEM *item; HANDLE hContact = NULL; const TCHAR *jid, *str, *name; TCHAR *nick; debugLogA("<iq/> Got roster push, query has %d children", xmlGetChildCount(queryNode)); for (int i=0; ; i++) { HXML itemNode = xmlGetChild(queryNode ,i); if (!itemNode) break; if (_tcscmp(xmlGetName(itemNode), _T("item")) != 0) continue; if ((jid = xmlGetAttrValue(itemNode, _T("jid"))) == NULL) continue; if ((str = xmlGetAttrValue(itemNode, _T("subscription"))) == NULL) continue; // we will not add new account when subscription=remove if (!_tcscmp(str, _T("to")) || !_tcscmp(str, _T("both")) || !_tcscmp(str, _T("from")) || !_tcscmp(str, _T("none"))) { if ((name = xmlGetAttrValue(itemNode, _T("name"))) != NULL) nick = mir_tstrdup(name); else nick = JabberNickFromJID(jid); if (nick != NULL) { if ((item=ListAdd(LIST_ROSTER, jid)) != NULL) { replaceStrT(item->nick, nick); HXML groupNode = xmlGetChild(itemNode , "group"); replaceStrT(item->group, xmlGetText(groupNode)); if ((hContact=HContactFromJID(jid, 0)) == NULL) { // Received roster has a new JID. // Add the jid (with empty resource) to Miranda contact list. hContact = DBCreateContact(jid, nick, FALSE, FALSE); } else setTString(hContact, "jid", jid); if (name != NULL) { ptrT tszNick( getTStringA(hContact, "Nick")); if (tszNick != NULL) { if (_tcscmp(nick, tszNick) != 0) db_set_ts(hContact, "CList", "MyHandle", nick); else db_unset(hContact, "CList", "MyHandle"); } else db_set_ts(hContact, "CList", "MyHandle", nick); } else db_unset(hContact, "CList", "MyHandle"); if (!m_options.IgnoreRosterGroups) { if (item->group != NULL) { Clist_CreateGroup(0, item->group); db_set_ts(hContact, "CList", "Group", item->group); } else db_unset(hContact, "CList", "Group"); } } mir_free(nick); } } if ((item=ListGetItemPtr(LIST_ROSTER, jid)) != NULL) { if (!_tcscmp(str, _T("both"))) item->subscription = SUB_BOTH; else if (!_tcscmp(str, _T("to"))) item->subscription = SUB_TO; else if (!_tcscmp(str, _T("from"))) item->subscription = SUB_FROM; else item->subscription = SUB_NONE; debugLogA("Roster push for jid=%S, set subscription to %S", jid, str); // subscription = remove is to remove from roster list // but we will just set the contact to offline and not actually // remove, so that history will be retained. if (!_tcscmp(str, _T("remove"))) { if ((hContact=HContactFromJID(jid)) != NULL) { SetContactOfflineStatus(hContact); ListRemove(LIST_ROSTER, jid); } } else if ( isChatRoom(hContact)) db_unset(hContact, "CList", "Hidden"); else UpdateSubscriptionInfo(hContact, item); } } UI_SAFE_NOTIFY(m_pDlgServiceDiscovery, WM_JABBER_TRANSPORT_REFRESH); RebuildInfoFrame(); return TRUE; }
void __cdecl CJabberProto::ByteReceiveThread( JABBER_BYTE_TRANSFER *jbt ) { HXML iqNode, queryNode = NULL, n; const TCHAR *sid = NULL, *from = NULL, *to = NULL, *szId = NULL, *szHost, *szPort, *str; int i; WORD port; HANDLE hConn; char data[3]; char* buffer; int datalen, bytesParsed, recvResult; BOOL validStreamhost = FALSE; if ( jbt == NULL ) return; jbt->state = JBT_INIT; if ( iqNode = jbt->iqNode ) { from = xmlGetAttrValue( iqNode, _T("from")); to = xmlGetAttrValue( iqNode, _T("to")); szId = xmlGetAttrValue( iqNode, _T("id")); queryNode = xmlGetChild( iqNode , "query" ); if ( queryNode ) sid = xmlGetAttrValue( queryNode, _T("sid")); } if ( szId && from && to && sid && ( n = xmlGetChild( queryNode , "streamhost" ))!=NULL ) { jbt->iqId = mir_tstrdup( szId ); jbt->srcJID = mir_tstrdup( from ); jbt->dstJID = mir_tstrdup( to ); jbt->sid = mir_tstrdup( sid ); if (( buffer=( char* )mir_alloc( JABBER_NETWORK_BUFFER_SIZE ))) { for ( i=1; ( n = xmlGetNthChild( queryNode, _T("streamhost"), i ))!=NULL; i++ ) { if (( szHost = xmlGetAttrValue( n, _T("host"))) != NULL && ( szPort = xmlGetAttrValue( n, _T("port"))) != NULL && ( str = xmlGetAttrValue( n, _T("jid"))) != NULL ) { port = ( WORD )_ttoi( szPort ); if ( jbt->streamhostJID ) mir_free( jbt->streamhostJID ); jbt->streamhostJID = mir_tstrdup( str ); Log( "bytestream_recv connecting to " TCHAR_STR_PARAM ":%d", szHost, port ); NETLIBOPENCONNECTION nloc = { 0 }; nloc.cbSize = sizeof( nloc ); nloc.szHost = mir_t2a(szHost); nloc.wPort = port; hConn = ( HANDLE ) JCallService( MS_NETLIB_OPENCONNECTION, ( WPARAM ) m_hNetlibUser, ( LPARAM )&nloc ); mir_free((void*)nloc.szHost); if ( hConn == NULL ) { Log( "bytestream_recv_connection connection failed ( %d ), try next streamhost", WSAGetLastError()); continue; } jbt->hConn = hConn; data[0] = 5; data[1] = 1; data[2] = 0; Netlib_Send( hConn, data, 3, 0 ); jbt->state = JBT_INIT; datalen = 0; while ( jbt->state!=JBT_DONE && jbt->state!=JBT_ERROR && jbt->state!=JBT_SOCKSERR ) { recvResult = Netlib_Recv( hConn, buffer+datalen, JABBER_NETWORK_BUFFER_SIZE-datalen, 0 ); if ( recvResult <= 0 ) break; datalen += recvResult; bytesParsed = ByteReceiveParse( hConn, jbt, buffer, datalen ); if ( bytesParsed < datalen ) memmove( buffer, buffer+bytesParsed, datalen-bytesParsed ); datalen -= bytesParsed; if ( jbt->state == JBT_RECVING ) validStreamhost = TRUE; } Netlib_CloseHandle( hConn ); Log( "bytestream_recv_connection closing connection" ); } if ( jbt->state==JBT_ERROR || validStreamhost==TRUE ) break; Log( "bytestream_recv_connection stream cannot be established, try next streamhost" ); } mir_free( buffer ); } } (this->*jbt->pfnFinal)(( jbt->state==JBT_DONE )?TRUE:FALSE, jbt->ft ); jbt->ft = NULL; if ( !validStreamhost && szId && from ) { Log( "bytestream_recv_connection session not completed" ); m_ThreadInfo->send( XmlNodeIq( _T("error"), szId, from ) << XCHILD( _T("error")) << XATTRI( _T("code"), 404 ) << XATTR( _T("type"), _T("cancel")) << XCHILDNS( _T("item-not-found"), _T("urn:ietf:params:xml:ns:xmpp-stanzas"))); } delete jbt; Log( "Thread ended: type=bytestream_recv" ); }
static void sttFillJidList(HWND hwndDlg) { JABBER_MUC_JIDLIST_INFO *jidListInfo; HXML iqNode, queryNode; const TCHAR* from, *jid, *reason, *nick; LVITEM lvi; HWND hwndList; int count, i; TCHAR *filter = NULL; if (GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_FILTER), GWLP_USERDATA)) { int filterLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_FILTER)) + 1; filter = (TCHAR *)_alloca(filterLength * sizeof(TCHAR)); GetDlgItemText(hwndDlg, IDC_FILTER, filter, filterLength); } jidListInfo = ( JABBER_MUC_JIDLIST_INFO * ) GetWindowLongPtr( hwndDlg, GWLP_USERDATA ); if ( !jidListInfo ) return; hwndList = GetDlgItem( hwndDlg, IDC_LIST ); SendMessage(hwndList, WM_SETREDRAW, FALSE, 0); count = ListView_GetItemCount( hwndList ); lvi.mask = LVIF_PARAM; lvi.iSubItem = 0; for ( i=0; i<count; i++ ) { lvi.iItem = i; if ( ListView_GetItem( hwndList, &lvi ) == TRUE ) { if ( lvi.lParam!=( LPARAM )( -1 ) && lvi.lParam!=( LPARAM )( NULL )) { mir_free(( void * ) lvi.lParam ); } } } ListView_DeleteAllItems( hwndList ); // Populate displayed list from iqNode if (( iqNode = jidListInfo->iqNode ) != NULL ) { if (( from = xmlGetAttrValue( iqNode, _T("from"))) != NULL ) { if (( queryNode = xmlGetChild( iqNode , "query" )) != NULL ) { lvi.mask = LVIF_TEXT | LVIF_PARAM; lvi.iSubItem = 0; lvi.iItem = 0; for ( i=0; ; i++ ) { HXML itemNode = xmlGetChild( queryNode ,i); if ( !itemNode ) break; if (( jid = xmlGetAttrValue( itemNode, _T("jid"))) != NULL ) { lvi.pszText = ( TCHAR* )jid; if ( jidListInfo->type == MUC_BANLIST ) { if (( reason = xmlGetText(xmlGetChild( itemNode , "reason" ))) != NULL ) { TCHAR jidreason[ JABBER_MAX_JID_LEN + 256 ]; mir_sntprintf( jidreason, SIZEOF( jidreason ), _T("%s (%s)") , jid, reason ); lvi.pszText = jidreason; } } if ( jidListInfo->type == MUC_VOICELIST || jidListInfo->type == MUC_MODERATORLIST ) { if (( nick = xmlGetAttrValue( itemNode, _T("nick"))) != NULL ) { TCHAR nickjid[ JABBER_MAX_JID_LEN + 256 ]; mir_sntprintf( nickjid, SIZEOF( nickjid ), _T("%s (%s)") , nick, jid ); lvi.pszText = nickjid; } } if (filter && *filter && !JabberStrIStr(lvi.pszText, filter)) continue; lvi.lParam = ( LPARAM )mir_tstrdup( jid ); ListView_InsertItem( hwndList, &lvi ); lvi.iItem++; } } } } } lvi.mask = LVIF_PARAM; lvi.lParam = ( LPARAM )( -1 ); ListView_InsertItem( hwndList, &lvi ); SendMessage(hwndList, WM_SETREDRAW, TRUE, 0); RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); }
static INT_PTR CALLBACK JabberMucJidListDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { JABBER_MUC_JIDLIST_INFO* dat = (JABBER_MUC_JIDLIST_INFO*)GetWindowLongPtr( hwndDlg, GWLP_USERDATA ); switch( msg ) { case WM_INITDIALOG: { LVCOLUMN lvc; RECT rc; HWND hwndList; TranslateDialogDefault( hwndDlg ); hwndList = GetDlgItem( hwndDlg, IDC_LIST ); ListView_SetExtendedListViewStyle(hwndList, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); GetClientRect( hwndList, &rc ); //rc.right -= GetSystemMetrics( SM_CXVSCROLL ); lvc.mask = LVCF_WIDTH; lvc.cx = rc.right - 20; ListView_InsertColumn( hwndList, 0, &lvc ); lvc.cx = 20; ListView_InsertColumn( hwndList, 1, &lvc ); SendMessage( hwndDlg, WM_JABBER_REFRESH, 0, lParam ); dat = (JABBER_MUC_JIDLIST_INFO*)lParam; static struct { int idc; char *title; char *icon; bool push; } buttons[] = { {IDC_BTN_FILTERAPPLY, "Apply filter", "sd_filter_apply", false}, {IDC_BTN_FILTERRESET, "Reset filter", "sd_filter_reset", false}, }; for (int i = 0; i < SIZEOF(buttons); ++i) { SendDlgItemMessage(hwndDlg, buttons[i].idc, BM_SETIMAGE, IMAGE_ICON, (LPARAM)dat->ppro->LoadIconEx(buttons[i].icon)); SendDlgItemMessage(hwndDlg, buttons[i].idc, BUTTONSETASFLATBTN, 0, 0); SendDlgItemMessage(hwndDlg, buttons[i].idc, BUTTONADDTOOLTIP, (WPARAM)buttons[i].title, 0); if (buttons[i].push) SendDlgItemMessage(hwndDlg, buttons[i].idc, BUTTONSETASPUSHBTN, 0, 0); } Utils_RestoreWindowPosition(hwndDlg, NULL, dat->ppro->m_szModuleName, "jidListWnd_"); } return TRUE; case WM_SIZE: { UTILRESIZEDIALOG urd = {0}; urd.cbSize = sizeof(urd); urd.hInstance = hInst; urd.hwndDlg = hwndDlg; urd.lpTemplate = MAKEINTRESOURCEA(IDD_JIDLIST); urd.pfnResizer = sttJidListResizer; CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); RECT listrc; LVCOLUMN lvc; HWND hwndList = GetDlgItem( hwndDlg, IDC_LIST ); GetClientRect( hwndList, &listrc ); lvc.mask = LVCF_WIDTH; //listrc.right -= GetSystemMetrics( SM_CXVSCROLL ); lvc.cx = listrc.right - 20; SendMessage(hwndList, LVM_SETCOLUMN, 0, (LPARAM)&lvc); break; } break; case WM_JABBER_REFRESH: { // lParam is ( JABBER_MUC_JIDLIST_INFO * ) HXML iqNode, queryNode; const TCHAR* from; TCHAR title[256]; // Clear current GWL_USERDATA, if any if ( dat != NULL ) delete dat; // Set new GWL_USERDATA dat = ( JABBER_MUC_JIDLIST_INFO * ) lParam; SetWindowLongPtr( hwndDlg, GWLP_USERDATA, ( LONG_PTR ) dat ); // Populate displayed list from iqNode lstrcpyn( title, TranslateT( "JID List" ), SIZEOF( title )); if (( dat=( JABBER_MUC_JIDLIST_INFO * ) lParam ) != NULL ) { if (( iqNode = dat->iqNode ) != NULL ) { if (( from = xmlGetAttrValue( iqNode, _T("from"))) != NULL ) { dat->roomJid = mir_tstrdup( from ); if (( queryNode = xmlGetChild( iqNode , "query" )) != NULL ) { TCHAR* localFrom = mir_tstrdup( from ); mir_sntprintf( title, SIZEOF( title ), TranslateT("%s, %d items (%s)"), ( dat->type == MUC_VOICELIST ) ? TranslateT( "Voice List" ) : ( dat->type == MUC_MEMBERLIST ) ? TranslateT( "Member List" ) : ( dat->type == MUC_MODERATORLIST ) ? TranslateT( "Moderator List" ) : ( dat->type == MUC_BANLIST ) ? TranslateT( "Ban List" ) : ( dat->type == MUC_ADMINLIST ) ? TranslateT( "Admin List" ) : ( dat->type == MUC_OWNERLIST ) ? TranslateT( "Owner List" ) : TranslateT( "JID List" ), xmlGetChildCount(queryNode), localFrom ); mir_free( localFrom ); } } } } SetWindowText( hwndDlg, title ); SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_FILTER), GWLP_USERDATA, 0); sttFillJidList(hwndDlg); } break; case WM_NOTIFY: if (( ( LPNMHDR )lParam )->idFrom == IDC_LIST ) { switch (( ( LPNMHDR )lParam )->code ) { case NM_CUSTOMDRAW: { NMLVCUSTOMDRAW *nm = ( NMLVCUSTOMDRAW * ) lParam; switch ( nm->nmcd.dwDrawStage ) { case CDDS_PREPAINT: case CDDS_ITEMPREPAINT: SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, CDRF_NOTIFYSUBITEMDRAW ); return TRUE; case CDDS_SUBITEM|CDDS_ITEMPREPAINT: { RECT rc; HICON hIcon; ListView_GetSubItemRect( nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec, nm->iSubItem, LVIR_LABEL, &rc ); if ( nm->iSubItem == 1 ) { if( nm->nmcd.lItemlParam == ( LPARAM )( -1 )) hIcon = ( HICON )LoadImage( hInst, MAKEINTRESOURCE( IDI_ADDCONTACT ), IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), 0 ); else hIcon = ( HICON )LoadImage( hInst, MAKEINTRESOURCE( IDI_DELETE ), IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), 0 ); DrawIconEx( nm->nmcd.hdc, ( rc.left+rc.right-GetSystemMetrics( SM_CXSMICON ))/2, ( rc.top+rc.bottom-GetSystemMetrics( SM_CYSMICON ))/2,hIcon, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), 0, GetSysColorBrush(COLOR_WINDOW), DI_NORMAL ); DestroyIcon( hIcon ); SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT ); return TRUE; } } } } break; case NM_CLICK: { NMLISTVIEW *nm = ( NMLISTVIEW * ) lParam; LVITEM lvi; LVHITTESTINFO hti; TCHAR text[128]; if ( nm->iSubItem < 1 ) break; hti.pt.x = ( short ) LOWORD( GetMessagePos()); hti.pt.y = ( short ) HIWORD( GetMessagePos()); ScreenToClient( nm->hdr.hwndFrom, &hti.pt ); if ( ListView_SubItemHitTest( nm->hdr.hwndFrom, &hti ) == -1 ) break; if ( hti.iSubItem != 1 ) break; lvi.mask = LVIF_PARAM | LVIF_TEXT; lvi.iItem = hti.iItem; lvi.iSubItem = 0; lvi.pszText = text; lvi.cchTextMax = sizeof( text ); ListView_GetItem( nm->hdr.hwndFrom, &lvi ); if ( lvi.lParam == ( LPARAM )( -1 )) { TCHAR szBuffer[ 1024 ]; _tcscpy( szBuffer, dat->type2str()); if ( !dat->ppro->EnterString(szBuffer, SIZEOF(szBuffer), NULL, JES_COMBO, "gcAddNick_")) break; // Trim leading and trailing whitespaces TCHAR *p = szBuffer, *q; for ( p = szBuffer; *p!='\0' && isspace( BYTE( *p )); p++); for ( q = p; *q!='\0' && !isspace( BYTE( *q )); q++); if (*q != '\0') *q = '\0'; if (*p == '\0') break; TCHAR rsn[ 1024 ]; _tcscpy( rsn, dat->type2str()); if ( dat->type == MUC_BANLIST ) { dat->ppro->EnterString(rsn, SIZEOF(rsn), TranslateT("Reason to ban") , JES_COMBO, "gcAddReason_"); if ( szBuffer ) dat->ppro->AddMucListItem( dat, p , rsn); else dat->ppro->AddMucListItem( dat, p ); } else dat->ppro->AddMucListItem( dat, p ); } else { //delete TCHAR msgText[128]; mir_sntprintf( msgText, SIZEOF( msgText ), _T("%s %s?"), TranslateT( "Removing" ), text ); if ( MessageBox( hwndDlg, msgText, dat->type2str(), MB_YESNO|MB_SETFOREGROUND ) == IDYES ) { dat->ppro->DeleteMucListItem( dat, ( TCHAR* )lvi.lParam ); mir_free(( void * )lvi.lParam ); ListView_DeleteItem( nm->hdr.hwndFrom, hti.iItem ); } } } break; } break; } break; case WM_COMMAND: if ((LOWORD(wParam) == IDC_BTN_FILTERAPPLY) || ((LOWORD(wParam) == IDOK) && (GetFocus() == GetDlgItem(hwndDlg, IDC_FILTER)))) { SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_FILTER), GWLP_USERDATA, 1); sttFillJidList(hwndDlg); } else if ((LOWORD(wParam) == IDC_BTN_FILTERRESET) || ((LOWORD(wParam) == IDCANCEL) && (GetFocus() == GetDlgItem(hwndDlg, IDC_FILTER)))) { SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_FILTER), GWLP_USERDATA, 0); sttFillJidList(hwndDlg); } break; /* case WM_SETCURSOR: if ( LOWORD( LPARAM )!= HTCLIENT ) break; if ( GetForegroundWindow() == GetParent( hwndDlg )) { POINT pt; GetCursorPos( &pt ); ScreenToClient( hwndDlg,&pt ); SetFocus( ChildWindowFromPoint( hwndDlg,pt )); //ugly hack because listviews ignore their first click } break; */ case WM_CLOSE: { HWND hwndList; int count, i; LVITEM lvi; // Free lParam of the displayed list items hwndList = GetDlgItem( hwndDlg, IDC_LIST ); count = ListView_GetItemCount( hwndList ); lvi.mask = LVIF_PARAM; lvi.iSubItem = 0; for ( i=0; i<count; i++ ) { lvi.iItem = i; if ( ListView_GetItem( hwndList, &lvi ) == TRUE ) { if ( lvi.lParam!=( LPARAM )( -1 ) && lvi.lParam!=( LPARAM )( NULL )) { mir_free(( void * ) lvi.lParam ); } } } ListView_DeleteAllItems( hwndList ); CJabberProto* ppro = dat->ppro; switch ( dat->type ) { case MUC_VOICELIST: ppro->m_hwndMucVoiceList = NULL; break; case MUC_MEMBERLIST: ppro->m_hwndMucMemberList = NULL; break; case MUC_MODERATORLIST: ppro->m_hwndMucModeratorList = NULL; break; case MUC_BANLIST: ppro->m_hwndMucBanList = NULL; break; case MUC_ADMINLIST: ppro->m_hwndMucAdminList = NULL; break; case MUC_OWNERLIST: ppro->m_hwndMucOwnerList = NULL; break; } DestroyWindow( hwndDlg ); } break; case WM_DESTROY: // Clear GWL_USERDATA if ( dat != NULL ) { Utils_SaveWindowPosition(hwndDlg, NULL, dat->ppro->m_szModuleName, "jidListWnd_"); delete dat; } break; } return FALSE; }