HANDLE JabberDBCreateContact( TCHAR* jid, TCHAR* nick, BOOL temporary, BOOL stripResource ) { TCHAR* s, *p, *q; int len; char* szProto; if ( jid==NULL || jid[0]=='\0' ) return NULL; s = mir_tstrdup( jid ); q = NULL; // strip resource if present if (( p = _tcschr( s, '@' )) != NULL ) if (( q = _tcschr( p, '/' )) != NULL ) *q = '\0'; if ( !stripResource && q!=NULL ) // so that resource is not stripped *q = '/'; len = _tcslen( s ); // We can't use JabberHContactFromJID() here because of the stripResource option HANDLE hContact = ( HANDLE ) JCallService( MS_DB_CONTACT_FINDFIRST, 0, 0 ); while ( hContact != NULL ) { szProto = ( char* )JCallService( MS_PROTO_GETCONTACTBASEPROTO, ( WPARAM ) hContact, 0 ); if ( szProto!=NULL && !strcmp( jabberProtoName, szProto )) { DBVARIANT dbv; if ( !JGetStringT( hContact, "jid", &dbv )) { p = dbv.ptszVal; if ( p && ( int )_tcslen( p )>=len && ( p[len]=='\0'||p[len]=='/' ) && !_tcsnicmp( p, s, len )) { JFreeVariant( &dbv ); break; } JFreeVariant( &dbv ); } } hContact = ( HANDLE ) JCallService( MS_DB_CONTACT_FINDNEXT, ( WPARAM ) hContact, 0 ); } if ( hContact == NULL ) { hContact = ( HANDLE ) JCallService( MS_DB_CONTACT_ADD, 0, 0 ); JCallService( MS_PROTO_ADDTOCONTACT, ( WPARAM ) hContact, ( LPARAM )jabberProtoName ); JSetStringT( hContact, "jid", s ); if ( nick != NULL && *nick != '\0' ) JSetStringT( hContact, "Nick", nick ); if ( temporary ) DBWriteContactSettingByte( hContact, "CList", "NotOnList", 1 ); else JabberSendGetVcard( s ); JabberLog( "Create Jabber contact jid=" TCHAR_STR_PARAM ", nick=" TCHAR_STR_PARAM, s, nick ); JabberDBCheckIsTransportedContact(s,hContact); } mir_free( s ); return hContact; }
void JabberCheckAllContactsAreTransported() { HANDLE hContact = ( HANDLE ) JCallService( MS_DB_CONTACT_FINDFIRST, 0, 0 ); while ( hContact != NULL ) { char* szProto = ( char* )JCallService( MS_PROTO_GETCONTACTBASEPROTO, ( WPARAM ) hContact, 0 ); if ( !lstrcmpA( jabberProtoName, szProto )) { DBVARIANT dbv; if ( !JGetStringT( hContact, "jid", &dbv )) { JabberDBCheckIsTransportedContact( dbv.ptszVal, hContact ); JFreeVariant( &dbv ); } } hContact = ( HANDLE )JCallService( MS_DB_CONTACT_FINDNEXT, ( WPARAM )hContact, 0 ); } }
int JabberGcInit( WPARAM wParam, LPARAM lParam ) { JABBER_LIST_ITEM* item = ( JABBER_LIST_ITEM* )wParam; GCSESSION gcw = {0}; GCEVENT gce = {0}; TCHAR* szNick = JabberNickFromJID( item->jid ); gcw.cbSize = sizeof(GCSESSION); gcw.iType = GCW_CHATROOM; gcw.pszModule = jabberProtoName; gcw.ptszName = szNick; gcw.ptszID = item->jid; gcw.dwFlags = GC_TCHAR; JCallService( MS_GC_NEWSESSION, NULL, (LPARAM)&gcw ); HANDLE hContact = JabberHContactFromJID( item->jid ); if ( hContact != NULL ) { DBVARIANT dbv; if ( !DBGetContactSettingTString( hContact, jabberProtoName, "MyNick", &dbv )) { if ( !lstrcmp( dbv.ptszVal, szNick )) JDeleteSetting( hContact, "MyNick" ); else JSetStringT( hContact, "MyNick", item->nick ); JFreeVariant( &dbv ); } else JSetStringT( hContact, "MyNick", item->nick ); } mir_free( szNick ); item->bChatActive = TRUE; GCDEST gcd = { jabberProtoName, NULL, GC_EVENT_ADDGROUP }; gcd.ptszID = item->jid; gce.cbSize = sizeof(GCEVENT); gce.pDest = &gcd; gce.dwFlags = GC_TCHAR; for ( int i = SIZEOF(sttRoles)-1; i >= 0; i-- ) { gce.ptszStatus = TranslateTS( sttRoles[i] ); JCallService(MS_GC_EVENT, NULL, ( LPARAM )&gce ); } gce.cbSize = sizeof(GCEVENT); gce.pDest = &gcd; gcd.iType = GC_EVENT_CONTROL; JCallService(MS_GC_EVENT, SESSION_INITDONE, (LPARAM)&gce); JCallService(MS_GC_EVENT, SESSION_ONLINE, (LPARAM)&gce); return 0; }
int JabberMenuBookmarkAdd( WPARAM wParam, LPARAM lParam ) { DBVARIANT dbv; if ( !wParam ) return 0; // we do not add ourself to the roster. (buggy situation - should not happen) if ( !JGetStringT( ( HANDLE ) wParam, "ChatRoomID", &dbv )) { TCHAR *roomID = mir_tstrdup(dbv.ptszVal); JFreeVariant( &dbv ); if ( JabberListGetItemPtr( LIST_BOOKMARK, roomID ) == NULL ) { TCHAR *nick = 0; if ( !JGetStringT( ( HANDLE ) wParam, "Nick", &dbv ) ) { nick = mir_tstrdup(dbv.ptszVal); JFreeVariant( &dbv ); } JABBER_LIST_ITEM* item = NULL; item = ( JABBER_LIST_ITEM* )mir_alloc( sizeof( JABBER_LIST_ITEM )); ZeroMemory( item, sizeof( JABBER_LIST_ITEM )); item->jid = mir_tstrdup(roomID); item->name = ( TCHAR* )JCallService( MS_CLIST_GETCONTACTDISPLAYNAME, wParam, GCDNF_TCHAR ); item->type = _T("conference"); if ( !JGetStringT(( HANDLE ) wParam, "MyNick", &dbv ) ) { item->nick = mir_tstrdup(dbv.ptszVal); JFreeVariant( &dbv ); } JabberAddEditBookmark(NULL, (LPARAM) item); mir_free(item); if (nick) mir_free(nick); } mir_free(roomID); } return 0; }
static void JabberContactListCreateClistGroup( TCHAR* groupName ) { char str[33]; int i; DBVARIANT dbv; for ( i=0;;i++ ) { itoa( i, str, 10 ); if ( DBGetContactSettingTString( NULL, "CListGroups", str, &dbv )) break; TCHAR* name = dbv.ptszVal; if ( name[0]!='\0' && !_tcscmp( name+1, groupName )) { // Already exists, no need to create JFreeVariant( &dbv ); return; } JFreeVariant( &dbv ); } // Create new group with id = i ( str is the text representation of i ) TCHAR newName[128]; newName[0] = 1 | GROUPF_EXPANDED; _tcsncpy( newName+1, groupName, SIZEOF( newName )-1 ); newName[ SIZEOF( newName )-1] = '\0'; DBWriteContactSettingTString( NULL, "CListGroups", str, newName ); JCallService( MS_CLUI_GROUPADDED, i+1, 0 ); }
void __cdecl CJabberProto::OnRenameContact( DBCONTACTWRITESETTING* cws, HANDLE hContact ) { DBVARIANT jid; if ( JGetStringT( hContact, "jid", &jid )) return; JABBER_LIST_ITEM* item = ListGetItemPtr( LIST_ROSTER, jid.ptszVal ); JFreeVariant( &jid ); if ( item == NULL ) return; if ( cws->value.type == DBVT_DELETED ) { TCHAR* nick = ( TCHAR* )JCallService( MS_CLIST_GETCONTACTDISPLAYNAME, ( WPARAM )hContact, GCDNF_NOMYHANDLE | GCDNF_TCHAR ); AddContactToRoster( item->jid, nick, item->group ); mir_free(nick); return; } TCHAR* newNick = sttSettingToTchar( cws ); if ( newNick ) { if ( lstrcmp( item->nick, newNick )) { Log( "Renaming contact " TCHAR_STR_PARAM ": " TCHAR_STR_PARAM " -> " TCHAR_STR_PARAM, item->jid, item->nick, newNick ); AddContactToRoster( item->jid, newNick, item->group ); } mir_free( newNick ); } }
static void sttEnableMenuItem( HANDLE hMenuItem, BOOL bEnable ) { CLISTMENUITEM clmi = {0}; clmi.cbSize = sizeof( CLISTMENUITEM ); clmi.flags = CMIM_FLAGS; if ( !bEnable ) clmi.flags |= CMIF_HIDDEN; JCallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hMenuItem, ( LPARAM )&clmi ); }
void JabberResolveTransportNicks( TCHAR* jid ) { // Set all contacts to offline HANDLE hContact = jabberThreadInfo->resolveContact; if ( hContact == NULL ) hContact = ( HANDLE ) JCallService( MS_DB_CONTACT_FINDFIRST, 0, 0 ); for ( ; hContact != NULL; hContact = ( HANDLE )JCallService( MS_DB_CONTACT_FINDNEXT, ( WPARAM ) hContact, 0 )) { char* szProto = ( char* )JCallService( MS_PROTO_GETCONTACTBASEPROTO, ( WPARAM ) hContact, 0 ); if ( lstrcmpA( szProto, jabberProtoName )) continue; if ( !JGetByte( hContact, "IsTransported", 0 )) continue; DBVARIANT dbv, nick; if ( JGetStringT( hContact, "jid", &dbv )) continue; if ( JGetStringT( hContact, "Nick", &nick )) { JFreeVariant( &dbv ); continue; } TCHAR* p = _tcschr( dbv.ptszVal, '@' ); if ( p ) { *p = 0; if ( !lstrcmp( jid, p+1 ) && !lstrcmp( dbv.ptszVal, nick.ptszVal )) { *p = '@'; jabberThreadInfo->resolveID = JabberSendGetVcard( dbv.ptszVal ); jabberThreadInfo->resolveContact = hContact; JFreeVariant( &dbv ); JFreeVariant( &nick ); return; } } JFreeVariant( &dbv ); JFreeVariant( &nick ); } jabberThreadInfo->resolveID = -1; jabberThreadInfo->resolveContact = NULL; }
void sttRenameParticipantNick( JABBER_LIST_ITEM* item, TCHAR* oldNick, XmlNode *itemNode ) { TCHAR* newNick = JabberXmlGetAttrValue( itemNode, "nick" ); TCHAR* jid = JabberXmlGetAttrValue( itemNode, "jid" ); if ( newNick == NULL ) return; for ( int i=0; i < item->resourceCount; i++ ) { JABBER_RESOURCE_STATUS& RS = item->resource[i]; if ( !lstrcmp( RS.resourceName, oldNick )) { replaceStr( RS.resourceName, newNick ); if ( !lstrcmp( item->nick, oldNick )) { replaceStr( item->nick, newNick ); HANDLE hContact = JabberHContactFromJID( item->jid ); if ( hContact != NULL ) JSetStringT( hContact, "MyNick", newNick ); } GCDEST gcd = { jabberProtoName, NULL, GC_EVENT_CHUID }; gcd.ptszID = item->jid; GCEVENT gce = {0}; gce.cbSize = sizeof(GCEVENT); gce.pDest = &gcd; gce.ptszNick = oldNick; gce.ptszText = newNick; if (jid != NULL) gce.ptszUserInfo = jid; gce.time = time(0); gce.dwFlags = GC_TCHAR; JCallService( MS_GC_EVENT, NULL, ( LPARAM )&gce ); gcd.iType = GC_EVENT_NICK; gce.ptszNick = oldNick; gce.ptszUID = newNick; gce.ptszText = newNick; JCallService( MS_GC_EVENT, NULL, ( LPARAM )&gce ); break; } } }
int JabberHttpGatewayInit( HANDLE /*hConn*/, NETLIBOPENCONNECTION* /*nloc*/, NETLIBHTTPREQUEST* /*nlhr*/ ) { #ifdef NNNN WORD wLen, wVersion, wType; WORD wIpLen; DWORD dwSid1, dwSid2, dwSid3, dwSid4; BYTE response[300], *buf; int responseBytes, recvResult; char szSid[33], szHttpServer[256], szHttpGetUrl[300], szHttpPostUrl[300]; NETLIBHTTPPROXYINFO nlhpi = {0}; for( responseBytes = 0; ; ) { recvResult = Netlib_Recv( hConn, response + responseBytes, sizeof( response ) - responseBytes, MSG_DUMPPROXY ); if( recvResult<=0 ) break; responseBytes += recvResult; if( responseBytes == sizeof( response )) break; } if( responseBytes < 31 ) { SetLastError( ERROR_INVALID_DATA ); return 0; } buf = response; unpackWord( &buf, &wLen ); unpackWord( &buf, &wVersion ); /* always 0x0443 */ unpackWord( &buf, &wType ); buf += 6; /* dunno */ unpackDWord( &buf, &dwSid1 ); unpackDWord( &buf, &dwSid2 ); unpackDWord( &buf, &dwSid3 ); unpackDWord( &buf, &dwSid4 ); sprintf( szSid, "%08x%08x%08x%08x", dwSid1, dwSid2, dwSid3, dwSid4 ); unpackWord( &buf, &wIpLen ); if( responseBytes < 30 + wIpLen || wIpLen == 0 || wIpLen > sizeof( szHttpServer ) - 1 ) { SetLastError( ERROR_INVALID_DATA ); return 0; } memcpy( szHttpServer, buf, wIpLen ); szHttpServer[wIpLen] = '\0'; nlhpi.cbSize = sizeof( nlhpi ); nlhpi.flags = NLHPIF_USEPOSTSEQUENCE; nlhpi.szHttpGetUrl = szHttpGetUrl; nlhpi.szHttpPostUrl = szHttpPostUrl; nlhpi.firstPostSequence = 1; sprintf( szHttpGetUrl, "http://%s/monitor?sid=%s", szHttpServer, szSid ); sprintf( szHttpPostUrl, "http://%s/data?sid=%s&seq=", szHttpServer, szSid ); return JCallService( MS_NETLIB_SETHTTPPROXYINFO, ( WPARAM )hConn, ( LPARAM )&nlhpi ); #endif return 1; }
void TreeList_Create(HWND hwnd) { TTreeList_Data *data = new TTreeList_Data; data->root = new TTreeList_ItemInfo; data->root->flags = TLIF_EXPANDED|TLIF_VISIBLE|TLIF_ROOT; data->root->indent = -1; data->hItemSelected = data->root; sttTreeList_SeWindowData(hwnd, data); ListView_SetExtendedListViewStyle(hwnd, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_GRIDLINES | LVS_EX_INFOTIP ); HIMAGELIST hIml; hIml = ImageList_Create(16, 16, ILC_MASK + ( IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16 ), 2, 1); ListView_SetImageList (hwnd, hIml, LVSIL_SMALL); hIml = ImageList_Create(16, 16, ILC_MASK + ( IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16 ), 2, 1); ImageList_AddIcon_Icolib(hIml, (HICON)JCallService( MS_SKIN_LOADICON, SKINICON_OTHER_GROUPOPEN, 0 )); ImageList_AddIcon_Icolib(hIml, (HICON)JCallService( MS_SKIN_LOADICON, SKINICON_OTHER_GROUPSHUT, 0 )); ImageList_AddIcon_Icolib(hIml, (HICON)JCallService( MS_SKIN_LOADICON, SKINICON_OTHER_DOWNARROW, 0 )); ListView_SetImageList (hwnd, hIml, LVSIL_STATE); }
void JabberGcQuit( JABBER_LIST_ITEM* item, int code, XmlNode* reason ) { TCHAR* szReason = NULL; if ( reason != NULL && reason->text != NULL ) szReason = reason->text; GCDEST gcd = { jabberProtoName, NULL, GC_EVENT_CONTROL }; gcd.ptszID = item->jid; GCEVENT gce = {0}; gce.cbSize = sizeof(GCEVENT); gce.ptszUID = item->jid; gce.ptszText = szReason; gce.dwFlags = GC_TCHAR; gce.pDest = &gcd; if ( code != 307 ) { JCallService( MS_GC_EVENT, SESSION_TERMINATE, ( LPARAM )&gce ); JCallService( MS_GC_EVENT, WINDOW_CLEARLOG, ( LPARAM )&gce ); } else { TCHAR* myNick = JabberNickFromJID( jabberJID ); JabberGcLogUpdateMemberStatus( item, myNick, NULL, GC_EVENT_KICK, reason ); mir_free( myNick ); JCallService( MS_GC_EVENT, SESSION_OFFLINE, ( LPARAM )&gce ); } DBDeleteContactSetting( JabberHContactFromJID( item->jid ), "CList", "Hidden" ); item->bChatActive = FALSE; if ( jabberOnline ) { TCHAR text[ 1024 ]; mir_sntprintf( text, SIZEOF( text ), _T("%s/%s"), item->jid, item->nick ); XmlNode p( "presence" ); p.addAttr( "to", text ); p.addAttr( "type", "unavailable" ); JabberSend( jabberThreadInfo->s, p ); JabberListRemove( LIST_CHATROOM, item->jid ); } }
int CJabberProto::JGetStaticString( const char* valueName, HANDLE hContact, char* dest, int dest_len ) { DBVARIANT dbv; dbv.pszVal = dest; dbv.cchVal = dest_len; dbv.type = DBVT_ASCIIZ; DBCONTACTGETSETTING sVal; sVal.pValue = &dbv; sVal.szModule = m_szModuleName; sVal.szSetting = valueName; if ( JCallService( MS_DB_CONTACT_GETSETTINGSTATIC, ( WPARAM )hContact, ( LPARAM )&sVal ) != 0 ) return 1; return ( dbv.type != DBVT_ASCIIZ ); }
int CJabberProto::JSendBroadcast( HANDLE hContact, int type, int result, HANDLE hProcess, LPARAM lParam ) { // clear saved passowrd on login error. ugly hack, but at least this is centralized if (type == ACKTYPE_LOGIN && (lParam == LOGINERR_WRONGPASSWORD || lParam == LOGINERR_BADUSERID)) *m_savedPassword = 0; ACKDATA ack = {0}; ack.cbSize = sizeof( ACKDATA ); ack.szModule = m_szModuleName; ack.hContact = hContact; ack.type = type; ack.result = result; ack.hProcess = hProcess; ack.lParam = lParam; return JCallService( MS_PROTO_BROADCASTACK, 0, ( LPARAM )&ack ); }
void JabberGetAvatarFileName( HANDLE hContact, char* pszDest, int cbLen ) { JCallService( MS_DB_GETPROFILEPATH, cbLen, LPARAM( pszDest )); int tPathLen = strlen( pszDest ); tPathLen += mir_snprintf( pszDest + tPathLen, MAX_PATH - tPathLen, "\\Jabber\\" ); CreateDirectoryA( pszDest, NULL ); char* szFileType; switch( JGetByte( hContact, "AvatarType", PA_FORMAT_PNG )) { case PA_FORMAT_JPEG: szFileType = "jpg"; break; case PA_FORMAT_GIF: szFileType = "gif"; break; case PA_FORMAT_BMP: szFileType = "bmp"; break; case PA_FORMAT_PNG: szFileType = "png"; break; default: szFileType = "bin"; } if ( hContact != NULL ) { char str[ 256 ]; DBVARIANT dbv; if ( !JGetStringUtf( hContact, "jid", &dbv )) { strncpy( str, dbv.pszVal, sizeof str ); str[ sizeof(str)-1 ] = 0; JFreeVariant( &dbv ); } else ltoa(( long )hContact, str, 10 ); char* hash = JabberSha1( str ); mir_snprintf( pszDest + tPathLen, MAX_PATH - tPathLen, "%s.%s", hash, szFileType ); mir_free( hash ); } else if ( jabberThreadInfo != NULL ) { mir_snprintf( pszDest + tPathLen, MAX_PATH - tPathLen, TCHAR_STR_PARAM"@%s avatar.%s", jabberThreadInfo->username, jabberThreadInfo->server, szFileType ); } else { DBVARIANT dbv1, dbv2; BOOL res1 = DBGetContactSetting( NULL, jabberProtoName, "LoginName", &dbv1 ); BOOL res2 = DBGetContactSetting( NULL, jabberProtoName, "LoginServer", &dbv2 ); mir_snprintf( pszDest + tPathLen, MAX_PATH - tPathLen, "%s@%s avatar.%s", res1 ? "noname" : dbv1.pszVal, res2 ? jabberProtoName : dbv2.pszVal, szFileType ); if (!res1) JFreeVariant( &dbv1 ); if (!res2) JFreeVariant( &dbv2 ); } }
static void sttSendPrivateMessage( JABBER_LIST_ITEM* item, const TCHAR* nick ) { TCHAR szFullJid[ 256 ]; mir_sntprintf( szFullJid, SIZEOF(szFullJid), _T("%s/%s"), item->jid, nick ); HANDLE hContact = JabberDBCreateContact( szFullJid, NULL, TRUE, FALSE ); if ( hContact != NULL ) { for ( int i=0; i < item->resourceCount; i++ ) { if ( _tcsicmp( item->resource[i].resourceName, nick ) == 0 ) { JSetWord( hContact, "Status", item->resource[i].status ); break; } } DBWriteContactSettingByte( hContact, "CList", "Hidden", 1 ); JSetStringT( hContact, "Nick", nick ); DBWriteContactSettingDword( hContact, "Ignore", "Mask1", 0 ); JCallService( MS_MSG_SENDMESSAGE, ( WPARAM )hContact, 0 ); } }
void JabberDBAddAuthRequest( TCHAR* jid, TCHAR* nick ) { HANDLE hContact = JabberDBCreateContact( jid, NULL, FALSE, TRUE ); JDeleteSetting( hContact, "Hidden" ); //JSetStringT( hContact, "Nick", nick ); #if defined( _UNICODE ) char* szJid = u2a( jid ); char* szNick = u2a( nick ); #else char* szJid = jid; char* szNick = nick; #endif //blob is: uin( DWORD ), hContact( HANDLE ), nick( ASCIIZ ), first( ASCIIZ ), last( ASCIIZ ), email( ASCIIZ ), reason( ASCIIZ ) //blob is: 0( DWORD ), hContact( HANDLE ), nick( ASCIIZ ), ""( ASCIIZ ), ""( ASCIIZ ), email( ASCIIZ ), ""( ASCIIZ ) DBEVENTINFO dbei = {0}; dbei.cbSize = sizeof( DBEVENTINFO ); dbei.szModule = jabberProtoName; dbei.timestamp = ( DWORD )time( NULL ); dbei.flags = 0; dbei.eventType = EVENTTYPE_AUTHREQUEST; dbei.cbBlob = sizeof( DWORD )+ sizeof( HANDLE ) + strlen( szNick ) + strlen( szJid ) + 5; PBYTE pCurBlob = dbei.pBlob = ( PBYTE ) mir_alloc( dbei.cbBlob ); *(( PDWORD ) pCurBlob ) = 0; pCurBlob += sizeof( DWORD ); *(( PHANDLE ) pCurBlob ) = hContact; pCurBlob += sizeof( HANDLE ); strcpy(( char* )pCurBlob, szNick ); pCurBlob += strlen( szNick )+1; *pCurBlob = '\0'; pCurBlob++; //firstName *pCurBlob = '\0'; pCurBlob++; //lastName strcpy(( char* )pCurBlob, szJid ); pCurBlob += strlen( szJid )+1; *pCurBlob = '\0'; //reason JCallService( MS_DB_EVENT_ADD, ( WPARAM ) ( HANDLE ) NULL, ( LPARAM )&dbei ); JabberLog( "Setup DBAUTHREQUEST with nick='" TCHAR_STR_PARAM "' jid='" TCHAR_STR_PARAM "'", szNick, szJid ); #if defined( _UNICODE ) mir_free( szJid ); mir_free( szNick ); #endif }
int JabberMenuPrebuildContactMenu( WPARAM wParam, LPARAM lParam ) { sttEnableMenuItem( hMenuRequestAuth, FALSE ); sttEnableMenuItem( hMenuGrantAuth, FALSE ); sttEnableMenuItem( hMenuRevokeAuth, FALSE ); sttEnableMenuItem( hMenuJoinLeave, FALSE ); sttEnableMenuItem( hMenuCommands, FALSE ); sttEnableMenuItem( hMenuConvert, FALSE ); sttEnableMenuItem( hMenuRosterAdd, FALSE ); sttEnableMenuItem( hMenuLogin, FALSE ); sttEnableMenuItem( hMenuVisitGMail, FALSE ); sttEnableMenuItem( hMenuRefresh, FALSE ); sttEnableMenuItem( hMenuAddBookmark, FALSE ); HANDLE hContact; if (( hContact=( HANDLE )wParam ) == NULL ) return 0; else { DBVARIANT dbv; if ( !JGetStringT( hContact, "FakeContact", &dbv )) { if (!_tcsicmp( dbv.ptszVal, _T("GMAIL"))){ sttEnableMenuItem( hMenuVisitGMail, TRUE ); return 0; } JFreeVariant( &dbv ); } } BYTE bIsChatRoom = (BYTE)JGetByte( hContact, "ChatRoom", 0 ); BYTE bIsTransport = (BYTE)JGetByte( hContact, "IsTransport", 0 ); if ((bIsChatRoom == GCW_CHATROOM) || bIsChatRoom == 0 ) { DBVARIANT dbv; if ( !JGetStringT( hContact, bIsChatRoom?(char*)"ChatRoomID":(char*)"jid", &dbv )) { JFreeVariant( &dbv ); CLISTMENUITEM clmi = { 0 }; sttEnableMenuItem( hMenuConvert, TRUE ); clmi.cbSize = sizeof( clmi ); clmi.pszName = (char *)(bIsChatRoom ? "&Convert to Contact" : "&Convert to Chat Room"); clmi.flags = CMIM_NAME | CMIM_FLAGS; JCallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hMenuConvert, ( LPARAM )&clmi ); } } if (!jabberOnline) return 0; if ( bIsChatRoom ) { DBVARIANT dbv; if ( !JGetStringT( hContact, "ChatRoomID", &dbv )) { if ( JabberListGetItemPtr( LIST_ROSTER, dbv.ptszVal ) == NULL ) sttEnableMenuItem( hMenuRosterAdd, TRUE ); if ( JabberListGetItemPtr( LIST_BOOKMARK, dbv.ptszVal ) == NULL ) if ( jabberThreadInfo && jabberThreadInfo->caps & CAPS_BOOKMARK ) sttEnableMenuItem( hMenuAddBookmark, TRUE ); JFreeVariant( &dbv ); } } if ( bIsChatRoom == GCW_CHATROOM ) { CLISTMENUITEM clmi = { 0 }; clmi.cbSize = sizeof( clmi ); clmi.pszName = (char *)(( JGetWord( hContact, "Status", 0 ) == ID_STATUS_ONLINE ) ? "&Leave" : "&Join"); clmi.flags = CMIM_NAME | CMIM_FLAGS; JCallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hMenuJoinLeave, ( LPARAM )&clmi ); return 0; } if ( bIsTransport ) { sttEnableMenuItem( hMenuLogin, TRUE ); sttEnableMenuItem( hMenuRefresh, TRUE ); } DBVARIANT dbv; if ( !JGetStringT( hContact, "jid", &dbv )) { JABBER_LIST_ITEM * item; item=JabberListGetItemPtr( LIST_ROSTER, dbv.ptszVal ); if ( !bIsTransport || (( item != NULL ) && (item->cap & AGENT_CAP_ADHOC) ) ) { sttEnableMenuItem( hMenuCommands, TRUE ); } else sttEnableMenuItem( hMenuCommands, FALSE ); JFreeVariant( &dbv ); } if ( !JGetStringT( hContact, "jid", &dbv )) { JABBER_LIST_ITEM* item = JabberListGetItemPtr( LIST_ROSTER, dbv.ptszVal ); JFreeVariant( &dbv ); if ( item != NULL ) { BOOL bCtrlPressed = ( GetKeyState( VK_CONTROL)&0x8000 ) != 0; sttEnableMenuItem( hMenuRequestAuth, item->subscription == SUB_FROM || item->subscription == SUB_NONE || bCtrlPressed ); sttEnableMenuItem( hMenuGrantAuth, item->subscription == SUB_TO || item->subscription == SUB_NONE || bCtrlPressed ); sttEnableMenuItem( hMenuRevokeAuth, item->subscription == SUB_FROM || item->subscription == SUB_BOTH || bCtrlPressed ); sttEnableMenuItem( hMenuCommands, (!bIsChatRoom && (!bIsTransport || (item->cap & AGENT_CAP_ADHOC))) ); return 0; } } return 0; }
static void sttLogListHook( JABBER_LIST_ITEM* item, GCHOOK* gch ) { TCHAR szBuffer[ 1024 ]; switch( gch->dwData ) { case IDM_VOICE: JabberAdminGet( gch->pDest->ptszID, xmlnsAdmin, "role", _T("participant"), JabberIqResultMucGetVoiceList ); break; case IDM_MEMBER: JabberAdminGet( gch->pDest->ptszID, xmlnsAdmin, "affiliation", _T("member"), JabberIqResultMucGetMemberList ); break; case IDM_MODERATOR: JabberAdminGet( gch->pDest->ptszID, xmlnsAdmin, "role", _T("moderator"), JabberIqResultMucGetModeratorList ); break; case IDM_BAN: JabberAdminGet( gch->pDest->ptszID, xmlnsAdmin, "affiliation", _T("outcast"), JabberIqResultMucGetBanList ); break; case IDM_ADMIN: JabberAdminGet( gch->pDest->ptszID, xmlnsOwner, "affiliation", _T("admin"), JabberIqResultMucGetAdminList ); break; case IDM_OWNER: JabberAdminGet( gch->pDest->ptszID, xmlnsOwner, "affiliation", _T("owner"), JabberIqResultMucGetOwnerList ); break; case IDM_TOPIC: mir_sntprintf( szBuffer, SIZEOF(szBuffer), _T("%s %s"), TranslateT( "Set topic for" ), gch->pDest->ptszID ); if ( JabberEnterString( szBuffer, SIZEOF(szBuffer))) { XmlNode msg( "message" ); msg.addAttr( "to", gch->pDest->ptszID ); msg.addAttr( "type", "groupchat" ); msg.addChild( "subject", szBuffer ); JabberSend( jabberThreadInfo->s, msg ); } break; case IDM_NICK: mir_sntprintf( szBuffer, SIZEOF(szBuffer), _T("%s %s"), TranslateT( "Change nickname in" ), gch->pDest->ptszID ); if ( JabberEnterString( szBuffer, SIZEOF(szBuffer))) { JABBER_LIST_ITEM* item = JabberListGetItemPtr( LIST_CHATROOM, gch->pDest->ptszID ); if ( item != NULL ) { TCHAR text[ 1024 ]; mir_sntprintf( text, SIZEOF( text ), _T("%s/%s"), gch->pDest->ptszID, szBuffer ); JabberSendPresenceTo( jabberStatus, text, NULL ); } } break; case IDM_INVITE: CreateDialogParam( hInst, MAKEINTRESOURCE( IDD_GROUPCHAT_INVITE ), NULL, JabberGcLogInviteDlgProc, ( LPARAM )gch->pDest->pszID ); break; case IDM_CONFIG: { int iqId = JabberSerialNext(); JabberIqAdd( iqId, IQ_PROC_NONE, JabberIqResultGetMuc ); XmlNodeIq iq( "get", iqId, gch->pDest->ptszID ); XmlNode* query = iq.addQuery( xmlnsOwner ); JabberSend( jabberThreadInfo->s, iq ); break; } case IDM_BOOKMARKS: { JABBER_LIST_ITEM* item = JabberListGetItemPtr( LIST_BOOKMARK, gch->pDest->ptszID ); if ( item == NULL ) { item = JabberListGetItemPtr( LIST_CHATROOM, gch->pDest->ptszID ); if (item != NULL) { item->type = _T("conference"); HANDLE hContact = JabberHContactFromJID( item->jid ); item->name = ( TCHAR* )JCallService( MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR ); JabberAddEditBookmark(NULL, (LPARAM) item); } } break; } case IDM_DESTROY: mir_sntprintf( szBuffer, SIZEOF(szBuffer), _T("%s %s"), TranslateT( "Reason to destroy" ), gch->pDest->ptszID ); if ( !JabberEnterString( szBuffer, SIZEOF(szBuffer))) break; { XmlNodeIq iq( "set", NOID, gch->pDest->ptszID ); XmlNode* query = iq.addQuery( xmlnsOwner ); query->addChild( "destroy" )->addChild( "reason", szBuffer ); JabberSend( jabberThreadInfo->s, iq ); } case IDM_LEAVE: JabberGcQuit( item, 0, 0 ); break; } }
void JabberFileServerConnection( JABBER_SOCKET hConnection, DWORD /*dwRemoteIP*/, void* extra ) { CJabberProto* ppro = ( CJabberProto* )extra; WORD localPort = 0; SOCKET s = JCallService( MS_NETLIB_GETSOCKET, ( WPARAM ) hConnection, 0 ); if ( s != INVALID_SOCKET ) { SOCKADDR_IN saddr; int len = sizeof( saddr ); if ( getsockname( s, ( SOCKADDR * ) &saddr, &len ) != SOCKET_ERROR ) { localPort = ntohs( saddr.sin_port ); } } if ( localPort == 0 ) { ppro->Log( "Unable to determine the local port, file server connection closed." ); Netlib_CloseHandle( hConnection ); return; } TCHAR szPort[20]; mir_sntprintf( szPort, SIZEOF( szPort ), _T("%d"), localPort ); ppro->Log( "File server incoming connection accepted: local_port=" TCHAR_STR_PARAM, szPort ); JABBER_LIST_ITEM *item = ppro->ListGetItemPtr( LIST_FILE, szPort ); if ( item == NULL ) { ppro->Log( "No file is currently served, file server connection closed." ); Netlib_CloseHandle( hConnection ); return; } filetransfer* ft = item->ft; JABBER_SOCKET slisten = ft->s; ft->s = hConnection; ppro->Log( "Set ft->s to %d ( saving %d )", hConnection, slisten ); char* buffer = ( char* )mir_alloc( JABBER_NETWORK_BUFFER_SIZE+1 ); if ( buffer == NULL ) { ppro->Log( "Cannot allocate network buffer, file server connection closed." ); Netlib_CloseHandle( hConnection ); ft->state = FT_ERROR; if ( ft->hFileEvent != NULL ) SetEvent( ft->hFileEvent ); return; } ppro->Log( "Entering recv loop for this file connection... ( ft->s is hConnection )" ); int datalen = 0; while ( ft->state!=FT_DONE && ft->state!=FT_ERROR ) { int recvResult, bytesParsed; recvResult = Netlib_Recv( hConnection, buffer+datalen, JABBER_NETWORK_BUFFER_SIZE-datalen, 0 ); if ( recvResult <= 0 ) break; datalen += recvResult; buffer[datalen] = '\0'; ppro->Log( "RECV:%s", buffer ); bytesParsed = ppro->FileSendParse( hConnection, ft, buffer, datalen ); if ( bytesParsed < datalen ) memmove( buffer, buffer+bytesParsed, datalen-bytesParsed ); datalen -= bytesParsed; } ppro->Log( "Closing connection for this file transfer... ( ft->s is now hBind )" ); Netlib_CloseHandle( hConnection ); ft->s = slisten; ppro->Log( "ft->s is restored to %d", ft->s ); if ( ft->hFileEvent != NULL ) SetEvent( ft->hFileEvent ); mir_free( buffer ); }
void JabberGcLogUpdateMemberStatus( JABBER_LIST_ITEM* item, TCHAR* nick, TCHAR* jid, int action, XmlNode* reason ) { int statusToSet = 0; TCHAR* szReason = NULL; if ( reason != NULL && reason->text != NULL ) szReason = reason->text; TCHAR* myNick = (item->nick == NULL) ? NULL : mir_tstrdup( item->nick ); if ( myNick == NULL ) myNick = JabberNickFromJID( jabberJID ); GCDEST gcd = { jabberProtoName, 0, 0 }; gcd.ptszID = item->jid; GCEVENT gce = {0}; gce.cbSize = sizeof(GCEVENT); gce.ptszNick = nick; gce.ptszUID = nick; if (jid != NULL) gce.ptszUserInfo = jid; gce.ptszText = szReason; gce.dwFlags = GC_TCHAR; gce.pDest = &gcd; if ( item->bChatActive == 2 ) { gce.dwFlags |= GCEF_ADDTOLOG; gce.time = time(0); } switch( gcd.iType = action ) { case GC_EVENT_PART: break; case GC_EVENT_KICK: gce.ptszStatus = TranslateT( "Moderator" ); break; default: for ( int i=0; i < item->resourceCount; i++ ) { JABBER_RESOURCE_STATUS& JS = item->resource[i]; if ( !lstrcmp( nick, JS.resourceName )) { if ( action != GC_EVENT_JOIN ) { switch( action ) { case 0: gcd.iType = GC_EVENT_ADDSTATUS; case GC_EVENT_REMOVESTATUS: gce.dwFlags &= ~GCEF_ADDTOLOG; } gce.ptszText = TranslateT( "Moderator" ); } gce.ptszStatus = TranslateTS( sttRoles[ JS.role ] ); gce.bIsMe = ( lstrcmp( nick, myNick ) == 0 ); statusToSet = JS.status; break; } } } JCallService( MS_GC_EVENT, NULL, ( LPARAM )&gce ); if ( statusToSet != 0 ) { gce.ptszText = nick; if ( statusToSet == ID_STATUS_AWAY || statusToSet == ID_STATUS_NA || statusToSet == ID_STATUS_DND ) gce.dwItemData = 3; else gce.dwItemData = 1; gcd.iType = GC_EVENT_SETSTATUSEX; JCallService( MS_GC_EVENT, NULL, ( LPARAM )&gce ); } mir_free( myNick ); }
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; }
void JabberGroupchatProcessMessage( XmlNode *node, void *userdata ) { ThreadData* info; XmlNode *n, *xNode; TCHAR* from, *type, *p, *nick, *msgText; JABBER_LIST_ITEM *item; if ( !node->name || strcmp( node->name, "message" )) return; if (( info=( ThreadData* ) userdata ) == NULL ) return; if (( from = JabberXmlGetAttrValue( node, "from" )) == NULL ) return; if (( item = JabberListGetItemPtr( LIST_CHATROOM, from )) == NULL ) return; if (( type = JabberXmlGetAttrValue( node, "type" )) == NULL ) return; if ( !lstrcmp( type, _T("error"))) return; GCDEST gcd = { jabberProtoName, NULL, 0 }; gcd.ptszID = item->jid; if (( n = JabberXmlGetChild( node, "subject" )) != NULL ) { if ( n->text == NULL || n->text[0] == '\0' ) return; msgText = n->text; gcd.iType = GC_EVENT_TOPIC; if ( from != NULL ) { nick = _tcschr( from, '/' ); if ( nick == NULL || nick[1] == '\0' ) nick = NULL; else nick++; } else nick = NULL; } else { if (( n = JabberXmlGetChild( node, "body" )) == NULL ) return; if ( n->text == NULL ) return; nick = _tcschr( from, '/' ); if ( nick == NULL || nick[1] == '\0' ) return; nick++; msgText = n->text; if ( _tcsncmp( msgText, _T("/me "), 4 ) == 0 && _tcslen( msgText ) > 4 ) { msgText += 4; gcd.iType = GC_EVENT_ACTION; } else gcd.iType = GC_EVENT_MESSAGE; } JabberGcLogCreate( item ); time_t msgTime = 0; BOOL delivered = FALSE; for ( int i = 1; ( xNode=JabberXmlGetNthChild( node, "x", i )) != NULL; i++ ) if (( p=JabberXmlGetAttrValue( xNode, "xmlns" )) != NULL ) if ( !_tcscmp( p, _T("jabber:x:delay")) && msgTime==0 ) if (( p=JabberXmlGetAttrValue( xNode, "stamp" )) != NULL ) msgTime = JabberIsoToUnixTime( p ); time_t now = time( NULL ); if ( msgTime == 0 || msgTime > now ) msgTime = now; GCEVENT gce = {0}; gce.cbSize = sizeof(GCEVENT); gce.pDest = &gcd; gce.ptszUID = nick; gce.ptszNick = nick; gce.time = msgTime; gce.ptszText = EscapeChatTags( msgText ); gce.bIsMe = lstrcmp( nick, item->nick ) == 0; gce.dwFlags = GC_TCHAR | GCEF_ADDTOLOG; JCallService(MS_GC_EVENT, NULL, (LPARAM)&gce); item->bChatActive = 2; if ( gcd.iType == GC_EVENT_TOPIC ) { gce.dwFlags &= ~GCEF_ADDTOLOG; gcd.iType = GC_EVENT_SETSBTEXT; JCallService(MS_GC_EVENT, NULL, (LPARAM)&gce); } mir_free( (void*)gce.pszText ); // Since we processed msgText and created a new string }
void __cdecl CJabberProto::FileReceiveThread( filetransfer* ft ) { char* buffer; int datalen; ThreadData info( this, JABBER_SESSION_NORMAL ); Log( "Thread started: type=file_receive server='%s' port='%d'", ft->httpHostName, ft->httpPort ); ft->type = FT_OOB; if (( buffer=( char* )mir_alloc( JABBER_NETWORK_BUFFER_SIZE )) == NULL ) { Log( "Cannot allocate network buffer, thread ended" ); JSendBroadcast( ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0 ); delete ft; return; } NETLIBOPENCONNECTION nloc = { 0 }; nloc.cbSize = sizeof( nloc ); nloc.cbSize = sizeof( NETLIBOPENCONNECTION ); nloc.szHost = ft->httpHostName; nloc.wPort = ft->httpPort; info.s = ( HANDLE ) JCallService( MS_NETLIB_OPENCONNECTION, ( WPARAM ) m_hNetlibUser, ( LPARAM )&nloc ); if ( info.s == NULL ) { Log( "Connection failed ( %d ), thread ended", WSAGetLastError()); JSendBroadcast( ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0 ); mir_free( buffer ); delete ft; return; } ft->s = info.s; info.send( "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", ft->httpPath, ft->httpHostName ); ft->state = FT_CONNECTING; Log( "Entering file_receive recv loop" ); datalen = 0; while ( ft->state != FT_DONE && ft->state != FT_ERROR ) { int recvResult, bytesParsed; Log( "Waiting for data..." ); recvResult = info.recv( buffer+datalen, JABBER_NETWORK_BUFFER_SIZE-datalen ); if ( recvResult <= 0 ) break; datalen += recvResult; bytesParsed = FileReceiveParse( ft, buffer, datalen ); if ( bytesParsed < datalen ) memmove( buffer, buffer+bytesParsed, datalen-bytesParsed ); datalen -= bytesParsed; } ft->s = NULL; if ( ft->state==FT_DONE || ( ft->state==FT_RECEIVING && ft->std.currentFileSize < 0 )) ft->complete(); Log( "Thread ended: type=file_receive server='%s'", ft->httpHostName ); mir_free( buffer ); delete ft; }
void JabberByteSendConnection( HANDLE hConn, DWORD /*dwRemoteIP*/, void* extra ) { CJabberProto* ppro = ( CJabberProto* )extra; SOCKET s; SOCKADDR_IN saddr; int len; WORD localPort; TCHAR szPort[8]; JABBER_BYTE_TRANSFER *jbt; int recvResult, bytesParsed; HANDLE hListen; JABBER_LIST_ITEM *item; char* buffer; int datalen; localPort = 0; if (( s = JCallService( MS_NETLIB_GETSOCKET, ( WPARAM ) hConn, 0 )) != INVALID_SOCKET ) { len = sizeof( saddr ); if ( getsockname( s, ( SOCKADDR * ) &saddr, &len ) != SOCKET_ERROR ) localPort = ntohs( saddr.sin_port ); } if ( localPort == 0 ) { ppro->Log( "bytestream_send_connection unable to determine the local port, connection closed." ); Netlib_CloseHandle( hConn ); return; } mir_sntprintf( szPort, SIZEOF( szPort ), _T("%d"), localPort ); ppro->Log( "bytestream_send_connection incoming connection accepted: local_port=" TCHAR_STR_PARAM, szPort ); if (( item = ppro->ListGetItemPtr( LIST_BYTE, szPort )) == NULL ) { ppro->Log( "No bytestream session is currently active, connection closed." ); Netlib_CloseHandle( hConn ); return; } jbt = item->jbt; if (( buffer = ( char* )mir_alloc( JABBER_NETWORK_BUFFER_SIZE )) == NULL ) { ppro->Log( "bytestream_send cannot allocate network buffer, connection closed." ); jbt->state = JBT_ERROR; Netlib_CloseHandle( hConn ); if ( jbt->hEvent != NULL ) SetEvent( jbt->hEvent ); return; } hListen = jbt->hConn; jbt->hConn = hConn; jbt->state = JBT_INIT; datalen = 0; while ( jbt->state!=JBT_DONE && jbt->state!=JBT_ERROR ) { recvResult = Netlib_Recv( hConn, buffer+datalen, JABBER_NETWORK_BUFFER_SIZE-datalen, 0 ); if ( recvResult <= 0 ) break; datalen += recvResult; bytesParsed = ppro->ByteSendParse( hConn, jbt, buffer, datalen ); if ( bytesParsed < datalen ) memmove( buffer, buffer+bytesParsed, datalen-bytesParsed ); datalen -= bytesParsed; } if ( jbt->hConn ) Netlib_CloseHandle( jbt->hConn ); ppro->Log( "bytestream_send_connection closing connection" ); jbt->hConn = hListen; mir_free( buffer ); if ( jbt->hEvent != NULL ) SetEvent( jbt->hEvent ); }
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" ); }
void CJabberProto::ByteSendViaProxy( JABBER_BYTE_TRANSFER *jbt ) { TCHAR *szHost, *szPort; WORD port; HANDLE hConn; char data[3]; char* buffer; int datalen, bytesParsed, recvResult; BOOL validStreamhost; if ( jbt == NULL ) return; if (( buffer=( char* )mir_alloc( JABBER_NETWORK_BUFFER_SIZE )) == NULL ) { m_ThreadInfo->send( XmlNodeIq( _T("error"), jbt->iqId, jbt->srcJID ) << XCHILD( _T("error")) << XATTRI( _T("code"), 406 ) << XATTR( _T("type"), _T("auth")) << XCHILDNS( _T("not-acceptable"), _T("urn:ietf:params:xml:ns:xmpp-stanzas"))); return; } jbt->state = JBT_INIT; validStreamhost = FALSE; szPort = jbt->szProxyPort; szHost = jbt->szProxyHost; port = ( WORD )_ttoi( szPort ); if ( jbt->streamhostJID ) mir_free( jbt->streamhostJID ); jbt->streamhostJID = mir_tstrdup( jbt->szProxyJid ); 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 ) { 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 = ByteSendProxyParse( hConn, jbt, buffer, datalen ); if ( bytesParsed < datalen ) memmove( buffer, buffer+bytesParsed, datalen-bytesParsed ); datalen -= bytesParsed; if ( jbt->state == JBT_DONE ) validStreamhost = TRUE; } Netlib_CloseHandle( hConn ); } mir_free( buffer ); (this->*jbt->pfnFinal)(( jbt->state == JBT_DONE ) ? TRUE : FALSE, jbt->ft ); jbt->ft = NULL; if ( !validStreamhost ) m_ThreadInfo->send( XmlNodeIq( _T("error"), jbt->iqId, jbt->srcJID ) << 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"))); }
void CJabberProto::ByteSendThread( JABBER_BYTE_TRANSFER *jbt ) { char* localAddr; char* localAddrInternal; struct in_addr in; DBVARIANT dbv; TCHAR szPort[8]; HANDLE hEvent = NULL; TCHAR* proxyJid; CJabberIqInfo* pInfo = NULL; int nIqId = 0; Log( "Thread started: type=bytestream_send" ); BOOL bDirect = m_options.BsDirect; if ( m_options.BsProxyManual ) { proxyJid = NULL; if ( !DBGetContactSettingString( NULL, m_szModuleName, "BsProxyServer", &dbv )) { proxyJid = mir_a2t( dbv.pszVal ); JFreeVariant( &dbv ); } if ( proxyJid ) { jbt->bProxyDiscovered = FALSE; jbt->szProxyHost = NULL; jbt->szProxyPort = NULL; jbt->szProxyJid = NULL; jbt->hProxyEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); pInfo = m_iqManager.AddHandler( &CJabberProto::IqResultProxyDiscovery, JABBER_IQ_TYPE_GET, proxyJid, 0, -1, jbt ); nIqId = pInfo->GetIqId(); XmlNodeIq iq( pInfo ); iq << XQUERY( _T(JABBER_FEAT_BYTESTREAMS)); m_ThreadInfo->send( iq ); WaitForSingleObject( jbt->hProxyEvent, INFINITE ); m_iqManager.ExpireIq ( nIqId ); CloseHandle( jbt->hProxyEvent ); jbt->hProxyEvent = NULL; mir_free( proxyJid ); if ( jbt->state == JBT_ERROR && !bDirect ) { Log( "Bytestream proxy failure" ); MsgPopup( pInfo->GetHContact(), TranslateT("Bytestream Proxy not available"), pInfo->GetReceiver()); jbt->ft->state = FT_DENIED; (this->*jbt->pfnFinal)( FALSE, jbt->ft ); jbt->ft = NULL; delete jbt; return; } } } pInfo = m_iqManager.AddHandler( &CJabberProto::ByteInitiateResult, JABBER_IQ_TYPE_SET, jbt->dstJID, 0, -1, jbt ); nIqId = pInfo->GetIqId(); { XmlNodeIq iq( pInfo ); HXML query = iq << XQUERY( _T(JABBER_FEAT_BYTESTREAMS)) << XATTR( _T("sid"), jbt->sid ); if ( bDirect ) { localAddr = NULL; if ( m_options.BsDirectManual == TRUE ) { if ( !DBGetContactSettingString( NULL, m_szModuleName, "BsDirectAddr", &dbv )) { localAddr = NEWSTR_ALLOCA( dbv.pszVal ); JFreeVariant( &dbv ); } } NETLIBBIND nlb = {0}; nlb.cbSize = sizeof( NETLIBBIND ); nlb.pfnNewConnectionV2 = JabberByteSendConnection; nlb.pExtra = this; nlb.wPort = 0; // Use user-specified incoming port ranges, if available jbt->hConn = ( HANDLE ) JCallService( MS_NETLIB_BINDPORT, ( WPARAM ) m_hNetlibUser, ( LPARAM )&nlb ); if ( jbt->hConn == NULL ) { Log( "Cannot allocate port for bytestream_send thread, thread ended." ); delete jbt; return; } if ( localAddr == NULL ) { in.S_un.S_addr = htonl(nlb.dwExternalIP); localAddr = NEWSTR_ALLOCA( inet_ntoa( in )); } in.S_un.S_addr = htonl(nlb.dwInternalIP); localAddrInternal = NEWSTR_ALLOCA( inet_ntoa( in )); mir_sntprintf( szPort, SIZEOF( szPort ), _T("%d"), nlb.wPort ); JABBER_LIST_ITEM *item = ListAdd( LIST_BYTE, szPort ); item->jbt = jbt; hEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); jbt->hEvent = hEvent; jbt->hSendEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); query << XCHILD( _T("streamhost")) << XATTR( _T("jid"), m_ThreadInfo->fullJID ) << XATTR( _T("host"), _A2T(localAddr)) << XATTRI( _T("port"), nlb.wPort ); if ( strcmp( localAddr, localAddrInternal )) query << XCHILD( _T("streamhost")) << XATTR( _T("jid"), m_ThreadInfo->fullJID ) << XATTR( _T("host"), _A2T(localAddrInternal)) << XATTRI( _T("port"), nlb.wPort ); } if ( jbt->bProxyDiscovered ) query << XCHILD( _T("streamhost")) << XATTR( _T("jid"), jbt->szProxyJid ) << XATTR( _T("host"), jbt->szProxyHost ) << XATTR( _T("port"), jbt->szProxyPort ); jbt->hProxyEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); jbt->szStreamhostUsed = NULL; m_ThreadInfo->send( iq ); } WaitForSingleObject( jbt->hProxyEvent, INFINITE ); m_iqManager.ExpireIq( nIqId ); CloseHandle( jbt->hProxyEvent ); jbt->hProxyEvent = NULL; if ( !jbt->szStreamhostUsed ) { if ( bDirect ) { SetEvent( jbt->hSendEvent ); CloseHandle( jbt->hSendEvent ); CloseHandle( hEvent ); jbt->hEvent = NULL; if ( jbt->hConn != NULL ) Netlib_CloseHandle( jbt->hConn ); jbt->hConn = NULL; ListRemove( LIST_BYTE, szPort ); } (this->*jbt->pfnFinal)(( jbt->state==JBT_DONE )?TRUE:FALSE, jbt->ft ); jbt->ft = NULL; // stupid fix: wait for listening thread exit Sleep( 100 ); delete jbt; return; } if ( jbt->bProxyDiscovered && !_tcscmp( jbt->szProxyJid, jbt->szStreamhostUsed )) { // jabber proxy used if ( bDirect ) { SetEvent( jbt->hSendEvent ); CloseHandle( jbt->hSendEvent ); CloseHandle( hEvent ); jbt->hEvent = NULL; if ( jbt->hConn != NULL ) Netlib_CloseHandle( jbt->hConn ); jbt->hConn = NULL; ListRemove( LIST_BYTE, szPort ); } ByteSendViaProxy( jbt ); } else { SetEvent( jbt->hSendEvent ); WaitForSingleObject( hEvent, INFINITE ); CloseHandle( hEvent ); CloseHandle( jbt->hSendEvent ); jbt->hEvent = NULL; (this->*jbt->pfnFinal)(( jbt->state == JBT_DONE ) ? TRUE : FALSE, jbt->ft ); jbt->ft = NULL; if ( jbt->hConn != NULL ) Netlib_CloseHandle( jbt->hConn ); jbt->hConn = NULL; ListRemove( LIST_BYTE, szPort ); } // stupid fix: wait for listening connection thread exit Sleep( 100 ); delete jbt; Log( "Thread ended: type=bytestream_send" ); }
char* __stdcall JGetContactName( HANDLE hContact ) { return ( char* )JCallService( MS_CLIST_GETCONTACTDISPLAYNAME, WPARAM( hContact ), 0 ); }
void JabberFtHandleSiRequest( XmlNode *iqNode ) { TCHAR* from, *sid, *str, *szId, *filename; XmlNode *siNode, *fileNode, *featureNode, *xNode, *fieldNode, *optionNode, *n; int filesize, i; JABBER_FT_TYPE ftType; if ( iqNode==NULL || ( from=JabberXmlGetAttrValue( iqNode, "from" ))==NULL || ( str=JabberXmlGetAttrValue( iqNode, "type" ))==NULL || _tcscmp( str, _T("set")) || ( siNode=JabberXmlGetChildWithGivenAttrValue( iqNode, "si", "xmlns", _T("http://jabber.org/protocol/si"))) == NULL ) return; szId = JabberXmlGetAttrValue( iqNode, "id" ); if (( sid=JabberXmlGetAttrValue( siNode, "id" ))!=NULL && ( fileNode=JabberXmlGetChildWithGivenAttrValue( siNode, "file", "xmlns", _T("http://jabber.org/protocol/si/profile/file-transfer")))!=NULL && ( filename=JabberXmlGetAttrValue( fileNode, "name" ))!=NULL && ( str=JabberXmlGetAttrValue( fileNode, "size" ))!=NULL ) { filesize = _ttoi( str ); if (( featureNode=JabberXmlGetChildWithGivenAttrValue( siNode, "feature", "xmlns", _T("http://jabber.org/protocol/feature-neg"))) != NULL && ( xNode=JabberXmlGetChildWithGivenAttrValue( featureNode, "x", "xmlns", _T("jabber:x:data")))!=NULL && ( fieldNode=JabberXmlGetChildWithGivenAttrValue( xNode, "field", "var", _T("stream-method")))!=NULL ) { for ( i=0; i<fieldNode->numChild; i++ ) { optionNode = fieldNode->child[i]; if ( optionNode->name && !strcmp( optionNode->name, "option" )) { if (( n=JabberXmlGetChild( optionNode, "value" ))!=NULL && n->text ) { if ( !_tcscmp( n->text, _T("http://jabber.org/protocol/bytestreams"))) { ftType = FT_BYTESTREAM; break; } } } } if ( i < fieldNode->numChild ) { // Found known stream mechanism CCSDATA ccs; PROTORECVEVENT pre; char *localFilename = t2a( filename ); char *desc = (( n=JabberXmlGetChild( fileNode, "desc" ))!=NULL && n->text!=NULL ) ? t2a( n->text ) : mir_strdup( "" ); filetransfer* ft = new filetransfer; ft->jid = mir_tstrdup( from ); ft->std.hContact = JabberHContactFromJID( from ); ft->sid = mir_tstrdup( sid ); ft->iqId = mir_tstrdup( szId ); ft->type = ftType; ft->std.totalFiles = 1; ft->std.currentFile = localFilename; ft->std.totalBytes = ft->std.currentFileSize = filesize; char* szBlob = ( char* )alloca( sizeof( DWORD )+ strlen( localFilename ) + strlen( desc ) + 2 ); *(( PDWORD ) szBlob ) = ( DWORD )ft; strcpy( szBlob + sizeof( DWORD ), localFilename ); strcpy( szBlob + sizeof( DWORD )+ strlen( localFilename ) + 1, desc ); pre.flags = 0; pre.timestamp = time( NULL ); pre.szMessage = szBlob; pre.lParam = 0; ccs.szProtoService = PSR_FILE; ccs.hContact = ft->std.hContact; ccs.wParam = 0; ccs.lParam = ( LPARAM )⪯ JCallService( MS_PROTO_CHAINRECV, 0, ( LPARAM )&ccs ); mir_free( desc ); return; } else { // Unknown stream mechanism XmlNodeIq iq( "error", szId, from ); XmlNode* e = iq.addChild( "error" ); e->addAttr( "code", 400 ); e->addAttr( "type", "cancel" ); XmlNode* br = e->addChild( "bad-request" ); br->addAttr( "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas" ); XmlNode* nvs = e->addChild( "no-valid-streams" ); nvs->addAttr( "xmlns", "http://jabber.org/protocol/si" ); JabberSend( jabberThreadInfo->s, iq ); return; } } } // Bad stream initiation, reply with bad-profile XmlNodeIq iq( "error", szId, from ); XmlNode* e = iq.addChild( "error" ); e->addAttr( "code", 400 ); e->addAttr( "type", "cancel" ); XmlNode* br = e->addChild( "bad-request" ); br->addAttr( "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas" ); XmlNode* nvs = e->addChild( "bad-profile" ); nvs->addAttr( "xmlns", "http://jabber.org/protocol/si" ); JabberSend( jabberThreadInfo->s, iq ); }