Esempio n. 1
0
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;

}
Esempio n. 5
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 );
}
Esempio n. 6
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 );
}
Esempio n. 8
0
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;
}	}	}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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 );
}	}
Esempio n. 13
0
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 );
}
Esempio n. 14
0
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 );
}
Esempio n. 15
0
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 );
}	}
Esempio n. 17
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;
}	}
Esempio n. 20
0
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 );
}
Esempio n. 22
0
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
}
Esempio n. 24
0
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;
}
Esempio n. 25
0
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 );
}
Esempio n. 26
0
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" );
}
Esempio n. 27
0
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")));
}
Esempio n. 28
0
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" );
}
Esempio n. 29
0
char* __stdcall JGetContactName( HANDLE hContact )
{
	return ( char* )JCallService( MS_CLIST_GETCONTACTDISPLAYNAME, WPARAM( hContact ), 0 );
}
Esempio n. 30
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 )&pre;
				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 );
}