INT_PTR __cdecl CJabberProto::JabberGetAvatarInfo(WPARAM wParam, LPARAM lParam) { if (!m_options.EnableAvatars) return GAIR_NOAVATAR; PROTO_AVATAR_INFORMATIONT* AI = (PROTO_AVATAR_INFORMATIONT*)lParam; ptrA szHashValue( getStringA(AI->hContact, "AvatarHash")); if (szHashValue == NULL) { debugLogA("No avatar"); return GAIR_NOAVATAR; } TCHAR tszFileName[MAX_PATH]; GetAvatarFileName(AI->hContact, tszFileName, SIZEOF(tszFileName)); _tcsncpy(AI->filename, tszFileName, SIZEOF(AI->filename)); AI->format = (AI->hContact == NULL) ? PA_FORMAT_PNG : getByte(AI->hContact, "AvatarType", 0); if (::_taccess(AI->filename, 0) == 0) { ptrA szSavedHash( getStringA(AI->hContact, "AvatarSaved")); if (szSavedHash != NULL && !strcmp(szSavedHash, szHashValue)) { debugLogA("Avatar is Ok: %s == %s", szSavedHash, szHashValue); return GAIR_SUCCESS; } } if ((wParam & GAIF_FORCE) != 0 && AI->hContact != NULL && m_bJabberOnline) { ptrT tszJid( getTStringA(AI->hContact, "jid")); if (tszJid != NULL) { JABBER_LIST_ITEM *item = ListGetItemPtr(LIST_ROSTER, tszJid); if (item != NULL) { BOOL isXVcard = getByte(AI->hContact, "AvatarXVcard", 0); TCHAR szJid[JABBER_MAX_JID_LEN]; szJid[0] = 0; if (item->arResources.getCount() != NULL && !isXVcard) if (TCHAR *bestResName = ListGetBestClientResourceNamePtr(tszJid)) mir_sntprintf(szJid, SIZEOF(szJid), _T("%s/%s"), tszJid, bestResName); if (szJid[0] == 0) _tcsncpy_s(szJid, SIZEOF(szJid), tszJid, _TRUNCATE); debugLogA("Rereading %s for %S", isXVcard ? JABBER_FEAT_VCARD_TEMP : JABBER_FEAT_AVATAR, szJid); m_ThreadInfo->send((isXVcard) ? XmlNodeIq( AddIQ(&CJabberProto::OnIqResultGetVCardAvatar, JABBER_IQ_TYPE_GET, szJid)) << XCHILDNS(_T("vCard"), JABBER_FEAT_VCARD_TEMP) : XmlNodeIq( AddIQ(&CJabberProto::OnIqResultGetClientAvatar, JABBER_IQ_TYPE_GET, szJid)) << XQUERY(JABBER_FEAT_AVATAR)); return GAIR_WAITFOR; } } } debugLogA("No avatar"); return GAIR_NOAVATAR; }
LPTSTR CJabberProto::GetBestResourceName(LPCTSTR jid) { if (jid == NULL) return NULL; LPCTSTR p = _tcschr(jid, '/'); if (p == NULL) { mir_cslock lck(m_csLists); return mir_tstrdup(ListGetBestClientResourceNamePtr(jid)); } return mir_tstrdup(jid); }
// XEP-0224 support (Attention/Nudge) INT_PTR __cdecl CJabberProto::JabberSendNudge(WPARAM wParam, LPARAM) { if (!m_bJabberOnline) return 0; HANDLE hContact = (HANDLE)wParam; ptrT jid( getTStringA(hContact, "jid")); if (jid == NULL) return 0; TCHAR tszJid[JABBER_MAX_JID_LEN]; TCHAR *szResource = ListGetBestClientResourceNamePtr(jid); if (szResource) mir_sntprintf(tszJid, SIZEOF(tszJid), _T("%s/%s"), jid, szResource); else mir_sntprintf(tszJid, SIZEOF(tszJid), _T("%s"), jid); JabberCapsBits jcb = GetResourceCapabilites(tszJid, FALSE); m_ThreadInfo->send( XmlNode(_T("message")) << XATTR(_T("type"), _T("headline")) << XATTR(_T("to"), tszJid) << XCHILDNS(_T("attention"), JABBER_FEAT_ATTENTION)); return 0; }
void __cdecl CJabberProto::FileServerThread(filetransfer *ft) { debugLogA("Thread started: type=file_send"); ThreadData info(this, NULL); ft->type = FT_OOB; NETLIBBIND nlb = { 0 }; nlb.cbSize = sizeof(NETLIBBIND); nlb.pfnNewConnectionV2 = JabberFileServerConnection; nlb.pExtra = this; nlb.wPort = 0; // Use user-specified incoming port ranges, if available info.s = (HANDLE)CallService(MS_NETLIB_BINDPORT, (WPARAM)m_hNetlibUser, (LPARAM)&nlb); if (info.s == NULL) { debugLogA("Cannot allocate port to bind for file server thread, thread ended."); ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); delete ft; return; } ft->s = info.s; debugLogA("ft->s = %d", info.s); HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); ft->hFileEvent = hEvent; TCHAR szPort[20]; mir_sntprintf(szPort, _countof(szPort), _T("%d"), nlb.wPort); JABBER_LIST_ITEM *item = ListAdd(LIST_FILE, szPort); item->ft = ft; TCHAR *ptszResource = ListGetBestClientResourceNamePtr(ft->jid); if (ptszResource != NULL) { ft->state = FT_CONNECTING; for (int i = 0; i < ft->std.totalFiles && ft->state != FT_ERROR && ft->state != FT_DENIED; i++) { ft->std.currentFileNumber = i; ft->state = FT_CONNECTING; if (ft->httpPath) mir_free(ft->httpPath); ft->httpPath = NULL; TCHAR *p; if ((p = _tcschr(ft->std.ptszFiles[i], '\\')) != NULL) p++; else p = ft->std.ptszFiles[i]; ptrA pFileName(mir_urlEncode(T2Utf(p))); if (pFileName != NULL) { ft->szId = JabberId2string(SerialNext()); ptrA myAddr; if (m_options.BsDirect && m_options.BsDirectManual) myAddr = getStringA("BsDirectAddr"); if (myAddr == NULL) myAddr = (char*)CallService(MS_NETLIB_ADDRESSTOSTRING, 1, nlb.dwExternalIP); char szAddr[256]; mir_snprintf(szAddr, _countof(szAddr), "http://%s:%d/%s", myAddr, nlb.wPort, pFileName); size_t len = mir_tstrlen(ptszResource) + mir_tstrlen(ft->jid) + 2; TCHAR *fulljid = (TCHAR *)alloca(sizeof(TCHAR) * len); mir_sntprintf(fulljid, len, _T("%s/%s"), ft->jid, ptszResource); XmlNodeIq iq(_T("set"), ft->szId, fulljid); HXML query = iq << XQUERY(JABBER_FEAT_OOB); query << XCHILD(_T("url"), _A2T(szAddr)); query << XCHILD(_T("desc"), ft->szDescription); m_ThreadInfo->send(iq); debugLogA("Waiting for the file to be sent..."); WaitForSingleObject(hEvent, INFINITE); } debugLogA("File sent, advancing to the next file..."); ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0); } CloseHandle(hEvent); ft->hFileEvent = NULL; debugLogA("Finish all files"); } ft->s = NULL; debugLogA("ft->s is NULL"); ListRemove(LIST_FILE, szPort); switch (ft->state) { case FT_DONE: debugLogA("Finish successfully"); ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); break; case FT_DENIED: ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, ft, 0); break; default: // FT_ERROR: debugLogA("Finish with errors"); ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); break; } debugLogA("Thread ended: type=file_send"); delete ft; }
void __cdecl CJabberProto::FileServerThread( filetransfer* ft ) { Log( "Thread started: type=file_send" ); ThreadData info( this, JABBER_SESSION_NORMAL ); ft->type = FT_OOB; NETLIBBIND nlb = {0}; nlb.cbSize = sizeof( NETLIBBIND ); nlb.pfnNewConnectionV2 = JabberFileServerConnection; nlb.pExtra = this; nlb.wPort = 0; // Use user-specified incoming port ranges, if available info.s = ( HANDLE ) JCallService( MS_NETLIB_BINDPORT, ( WPARAM ) m_hNetlibUser, ( LPARAM )&nlb ); if ( info.s == NULL ) { Log( "Cannot allocate port to bind for file server thread, thread ended." ); JSendBroadcast( ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0 ); delete ft; return; } ft->s = info.s; Log( "ft->s = %d", info.s ); HANDLE hEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); ft->hFileEvent = hEvent; TCHAR szPort[20]; mir_sntprintf( szPort, SIZEOF( szPort ), _T("%d"), nlb.wPort ); JABBER_LIST_ITEM *item = ListAdd( LIST_FILE, szPort ); item->ft = ft; TCHAR* ptszResource = ListGetBestClientResourceNamePtr( ft->jid ); if ( ptszResource != NULL ) { ft->state = FT_CONNECTING; for ( int i=0; i < ft->std.totalFiles && ft->state != FT_ERROR && ft->state != FT_DENIED; i++ ) { ft->std.currentFileNumber = i; ft->state = FT_CONNECTING; if ( ft->httpPath ) mir_free( ft->httpPath ); ft->httpPath = NULL; TCHAR* p; if (( p = _tcschr( ft->std.ptszFiles[i], '\\' )) != NULL ) p++; else p = ft->std.ptszFiles[i]; in_addr in; in.S_un.S_addr = m_dwJabberLocalIP; TCHAR* pFileName = JabberHttpUrlEncode( p ); if ( pFileName != NULL ) { int id = SerialNext(); if ( ft->iqId ) mir_free( ft->iqId ); ft->iqId = ( TCHAR* )mir_alloc( sizeof(TCHAR)*( strlen( JABBER_IQID )+20 )); wsprintf( ft->iqId, _T(JABBER_IQID)_T("%d"), id ); char *myAddr; DBVARIANT dbv; if (m_options.BsDirect && m_options.BsDirectManual) { if ( !DBGetContactSettingString( NULL, m_szModuleName, "BsDirectAddr", &dbv )) { myAddr = NEWSTR_ALLOCA( dbv.pszVal ); JFreeVariant( &dbv ); } else myAddr = inet_ntoa( in ); } else myAddr = inet_ntoa( in ); char szAddr[ 256 ]; mir_snprintf( szAddr, sizeof(szAddr), "http://%s:%d/%s", myAddr, nlb.wPort, pFileName ); int len = lstrlen(ptszResource) + lstrlen(ft->jid) + 2; TCHAR* fulljid = ( TCHAR* )alloca( sizeof( TCHAR )*len ); wsprintf( fulljid, _T("%s/%s"), ft->jid, ptszResource ); XmlNodeIq iq( _T("set"), id, fulljid ); HXML query = iq << XQUERY( _T(JABBER_FEAT_OOB)); query << XCHILD( _T("url"), _A2T(szAddr)); query << XCHILD( _T("desc"), ft->szDescription); m_ThreadInfo->send( iq ); Log( "Waiting for the file to be sent..." ); WaitForSingleObject( hEvent, INFINITE ); mir_free( pFileName ); } Log( "File sent, advancing to the next file..." ); JSendBroadcast( ft->std.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0 ); } CloseHandle( hEvent ); ft->hFileEvent = NULL; Log( "Finish all files" ); } ft->s = NULL; Log( "ft->s is NULL" ); ListRemove( LIST_FILE, szPort ); switch ( ft->state ) { case FT_DONE: Log( "Finish successfully" ); JSendBroadcast( ft->std.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0 ); break; case FT_DENIED: JSendBroadcast( ft->std.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, ft, 0 ); break; default: // FT_ERROR: Log( "Finish with errors" ); JSendBroadcast( ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0 ); break; } Log( "Thread ended: type=file_send" ); delete ft; }