bool CJabberIqManager::HandleIqPermanent(HXML pNode) { for (int i = 0; i < m_arHandlers.getCount(); i++) { CJabberIqPermanentInfo &pInfo = m_arHandlers[i]; // 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 (!mir_tstrcmpi(szType, _T("get"))) iqInfo.m_nIqType = JABBER_IQ_TYPE_GET; else if (!mir_tstrcmpi(szType, _T("set"))) iqInfo.m_nIqType = JABBER_IQ_TYPE_SET; else return FALSE; if (!(pInfo.m_nIqTypes & iqInfo.m_nIqType)) continue; 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 && !mir_tstrcmp(pInfo.m_szXmlns, szXmlns))) && (!pInfo.m_szTag || !mir_tstrcmp(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); ppro->debugLog(_T("Handling iq id %s, type %s, from %s"), iqInfo.m_szId, szType, iqInfo.m_szFrom); if ((ppro->*(pInfo.m_pHandler))(pNode, &iqInfo)) return true; } } 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; T2Utf szEventText(tszBody); DBEVENTINFO dbei = { sizeof(DBEVENTINFO) }; dbei.eventType = EVENTTYPE_MESSAGE; dbei.szModule = m_szModuleName; dbei.cbBlob = (DWORD)mir_strlen(szEventText); dbei.flags = DBEF_READ + DBEF_UTF + from; dbei.pBlob = szEventText; dbei.timestamp = tmStart + _ttol(tszSecs) - timezone; if (!IsDuplicateEvent(hContact, dbei)) db_event_add(hContact, &dbei); } }
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 (!mir_tstrcmpi(szType, _T("result"))) nIqType = JABBER_IQ_TYPE_RESULT; else if (!mir_tstrcmpi(szType, _T("error"))) nIqType = JABBER_IQ_TYPE_ERROR; else return false; CJabberIqInfo *pInfo = DetouchInfo(nIqId); if (pInfo == NULL) return false; do { 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); 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; } while ((pInfo = DetouchInfo(nIqId)) != NULL); return true; }
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); xmlDestroyNode(n); } else { // use old registration information form for (int i=0; ; i++) { HXML n = XmlGetChild(queryNode ,i); if (!n) break; if (XmlGetName(n)) { if (!mir_tstrcmp(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 (!mir_tstrcmp(XmlGetName(n), _T("registered")) || !mir_tstrcmp(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(); }
HXML __fastcall XmlGetNthChild(HXML hXml, LPCTSTR tag, int nth) { int i, num; if (!hXml || tag == NULL || mir_tstrlen(tag) <= 0 || nth < 1) return NULL; num = 1; for (i=0; ; i++) { HXML n = xmlGetChild(hXml, i); if (!n) break; if (!mir_tstrcmp(tag, XmlGetName(n))) { if (num == nth) return n; num++; } } return NULL; }
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 = mir_tstrcmp(szFrom, szTo) == 0; mir_free(szFrom); mir_free(szTo); // invalid JID if (!bRetVal) { debugLog(_T("<iq/> attempt to hack via roster push from %s"), pInfo->GetFrom()); return TRUE; } } JABBER_LIST_ITEM *item; MCONTACT hContact = NULL; const TCHAR *jid, *str; 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 (mir_tstrcmp(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 (!mir_tstrcmp(str, _T("to")) || !mir_tstrcmp(str, _T("both")) || !mir_tstrcmp(str, _T("from")) || !mir_tstrcmp(str, _T("none"))) { const TCHAR *name = XmlGetAttrValue(itemNode, _T("name")); ptrT nick((name != NULL) ? mir_tstrdup(name) : 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 (mir_tstrcmp(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"); } } } } if ((item = ListGetItemPtr(LIST_ROSTER, jid)) != NULL) { if (!mir_tstrcmp(str, _T("both"))) item->subscription = SUB_BOTH; else if (!mir_tstrcmp(str, _T("to"))) item->subscription = SUB_TO; else if (!mir_tstrcmp(str, _T("from"))) item->subscription = SUB_FROM; else item->subscription = SUB_NONE; debugLog(_T("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 (!mir_tstrcmp(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; }
virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CTLCOLORSTATIC: switch(GetDlgCtrlID((HWND)lParam)) { case IDC_WHITERECT: case IDC_INSTRUCTION: case IDC_TITLE: return (INT_PTR)GetStockObject(WHITE_BRUSH); default: return NULL; } case WM_JABBER_REGINPUT_ACTIVATE: if (wParam == 1) { // success // lParam = <iq/> node from agent JID as a result of "get jabber:iq:register" HWND hFrame = GetDlgItem(m_hwnd, IDC_FRAME); ShowWindow(GetDlgItem(m_hwnd, IDC_FRAME_TEXT), SW_HIDE); HXML queryNode, xNode; if ((m_agentRegIqNode = (HXML)lParam) == NULL) return TRUE; if ((queryNode = XmlGetChild(m_agentRegIqNode , "query")) == NULL) return TRUE; RECT rect; m_curPos = 0; GetClientRect(GetDlgItem(m_hwnd, IDC_FRAME), &(m_frameRect)); GetClientRect(GetDlgItem(m_hwnd, IDC_VSCROLL), &rect); m_frameRect.right -= (rect.right - rect.left); GetClientRect(GetDlgItem(m_hwnd, IDC_FRAME), &rect); m_frameHeight = rect.bottom - rect.top; if ((xNode=XmlGetChild(queryNode , "x")) != NULL) { // use new jabber:x:data form if (LPCTSTR ptszInstr = XmlGetText( XmlGetChild(xNode, "instructions"))) JabberFormSetInstruction(m_hwnd, ptszInstr); JabberFormCreateUI(hFrame, xNode, &m_formHeight /*dummy*/); } else { // use old registration information form HJFORMLAYOUT layout_info = JabberFormCreateLayout(hFrame); for (int i=0; ; i++) { HXML n = XmlGetChild(queryNode ,i); if (n == NULL) break; if (XmlGetName(n)) { if (!mir_tstrcmp(XmlGetName(n), _T("instructions"))) { JabberFormSetInstruction(m_hwnd, XmlGetText(n)); } else if (!mir_tstrcmp(XmlGetName(n), _T("key")) || !mir_tstrcmp(XmlGetName(n), _T("registered"))) { // do nothing } else if (!mir_tstrcmp(XmlGetName(n), _T("password"))) JabberFormAppendControl(hFrame, layout_info, JFORM_CTYPE_TEXT_PRIVATE, XmlGetName(n), XmlGetText(n)); else // everything else is a normal text field JabberFormAppendControl(hFrame, layout_info, JFORM_CTYPE_TEXT_SINGLE, XmlGetName(n), XmlGetText(n)); } } JabberFormLayoutControls(hFrame, layout_info, &m_formHeight); mir_free(layout_info); } if (m_formHeight > m_frameHeight) { HWND hwndScroll; hwndScroll = GetDlgItem(m_hwnd, IDC_VSCROLL); EnableWindow(hwndScroll, TRUE); SetScrollRange(hwndScroll, SB_CTL, 0, m_formHeight - m_frameHeight, FALSE); m_curPos = 0; } EnableWindow(GetDlgItem(m_hwnd, IDC_SUBMIT), TRUE); } else if (wParam == 0) { // lParam = error message SetDlgItemText(m_hwnd, IDC_FRAME_TEXT, (LPCTSTR) lParam); } return TRUE; case WM_VSCROLL: int pos = m_curPos; switch (LOWORD(wParam)) { case SB_LINEDOWN: pos += 10; break; case SB_LINEUP: pos -= 10; break; case SB_PAGEDOWN: pos += (m_frameHeight - 10); break; case SB_PAGEUP: pos -= (m_frameHeight - 10); break; case SB_THUMBTRACK: pos = HIWORD(wParam); break; } if (pos > (m_formHeight - m_frameHeight)) pos = m_formHeight - m_frameHeight; if (pos < 0) pos = 0; if (m_curPos != pos) { ScrollWindow(GetDlgItem(m_hwnd, IDC_FRAME), 0, m_curPos - pos, NULL, &(m_frameRect)); SetScrollPos(GetDlgItem(m_hwnd, IDC_VSCROLL), SB_CTL, pos, TRUE); m_curPos = pos; } } return CJabberDlgBase::DlgProc(msg, wParam, lParam); }