From 3b55a62fdcb1f8222de3c2c8fbed530792c419a0 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Fri, 12 Oct 2012 14:53:57 +0000 Subject: GTalkExt, ICQ, IRC, Jabber: folders restructurization git-svn-id: http://svn.miranda-ng.org/main/trunk@1890 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/JabberG/jabber_file.cpp | 552 -------------------------------------- 1 file changed, 552 deletions(-) delete mode 100644 protocols/JabberG/jabber_file.cpp (limited to 'protocols/JabberG/jabber_file.cpp') diff --git a/protocols/JabberG/jabber_file.cpp b/protocols/JabberG/jabber_file.cpp deleted file mode 100644 index 5db215d024..0000000000 --- a/protocols/JabberG/jabber_file.cpp +++ /dev/null @@ -1,552 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Copyright ( C ) 2002-04 Santithorn Bunchua -Copyright ( C ) 2005-12 George Hazan - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or ( at your option ) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include -#include -#include -#include -#include "jabber_caps.h" - -#define JABBER_NETWORK_BUFFER_SIZE 2048 - -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 ) CallService( 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; -} - -int CJabberProto::FileReceiveParse( filetransfer* ft, char* buffer, int datalen ) -{ - char* p, *q, *s, *eob; - char* str; - int num, code; - - eob = buffer + datalen; - p = buffer; - num = 0; - while ( true ) { - if ( ft->state==FT_CONNECTING || ft->state==FT_INITIALIZING ) { - for ( q=p; q+1state == FT_CONNECTING ) { - // looking for "HTTP/1.1 200 OK" - if ( sscanf( str, "HTTP/%*d.%*d %d %*s", &code )==1 && code==200 ) { - ft->state = FT_INITIALIZING; - ft->std.currentFileSize = -1; - Log( "Change to FT_INITIALIZING" ); - JSendBroadcast( ft->std.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ft, 0 ); - } - } - else { // FT_INITIALIZING - if ( str[0] == '\0' ) { - TCHAR* s; - if (( s = _tcsrchr( ft->httpPath, '/' )) != NULL ) - s++; - else - s = ft->httpPath; - ft->std.tszCurrentFile = mir_tstrdup( s ); - JabberHttpUrlDecode( ft->std.tszCurrentFile ); - if ( ft->create() == -1 ) { - ft->state = FT_ERROR; - break; - } - ft->state = FT_RECEIVING; - ft->std.currentFileProgress = 0; - Log( "Change to FT_RECEIVING" ); - } - else if (( s=strchr( str, ':' )) != NULL ) { - *s = '\0'; - if ( !strcmp( str, "Content-Length" )) - ft->std.totalBytes = ft->std.currentFileSize = _atoi64( s+1 ); - } } - - mir_free( str ); - q += 2; - num += ( q-p ); - p = q; - } - else { - ft->state = FT_ERROR; - break; - } - } - else { - break; - } - } - else if ( ft->state == FT_RECEIVING ) { - int bufferSize, writeSize; - __int64 remainingBytes; - - if ( ft->std.currentFileSize < 0 || ft->std.currentFileProgress < ft->std.currentFileSize ) { - bufferSize = eob - p; - remainingBytes = ft->std.currentFileSize - ft->std.currentFileProgress; - if ( remainingBytes < bufferSize ) - writeSize = remainingBytes; - else - writeSize = bufferSize; - if ( _write( ft->fileId, p, writeSize ) != writeSize ) { - Log( "_write() error" ); - ft->state = FT_ERROR; - } - else { - ft->std.currentFileProgress += writeSize; - ft->std.totalProgress += writeSize; - JSendBroadcast( ft->std.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, ( LPARAM )&ft->std ); - if ( ft->std.currentFileProgress == ft->std.currentFileSize ) - ft->state = FT_DONE; - } - } - num = datalen; - break; - } - else break; - } - - return num; -} - -void JabberFileServerConnection( JABBER_SOCKET hConnection, DWORD /*dwRemoteIP*/, void* extra ) -{ - CJabberProto* ppro = ( CJabberProto* )extra; - - NETLIBCONNINFO connInfo = { sizeof(connInfo) }; - CallService(MS_NETLIB_GETCONNECTIONINFO, (WPARAM)hConnection, (LPARAM)&connInfo); - - TCHAR szPort[10]; - mir_sntprintf( szPort, SIZEOF( szPort ), _T("%d"), connInfo.wPort ); - ppro->Log( "File server incoming connection accepted: %s", connInfo.szIpPort ); - - 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 __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 ) CallService( 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]; - - 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 = NULL; - DBVARIANT dbv; - if (m_options.BsDirect && m_options.BsDirectManual) { - if ( !DBGetContactSettingString( NULL, m_szModuleName, "BsDirectAddr", &dbv )) - myAddr = dbv.pszVal; - } - - if ( myAddr == NULL ) - myAddr = (char*)CallService( MS_NETLIB_ADDRESSTOSTRING, 1, nlb.dwExternalIP ); - - char szAddr[ 256 ]; - mir_snprintf( szAddr, sizeof(szAddr), "http://%s:%d/%s", myAddr, nlb.wPort, pFileName ); - - mir_free( pFileName ); - mir_free( myAddr ); - - 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 ); - } - 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; -} - -int CJabberProto::FileSendParse( JABBER_SOCKET s, filetransfer* ft, char* buffer, int datalen ) -{ - char* p, *q, *t, *eob; - char* str; - int num; - int currentFile; - int fileId; - int numRead; - - eob = buffer + datalen; - p = buffer; - num = 0; - while ( ft->state==FT_CONNECTING || ft->state==FT_INITIALIZING ) { - for ( q=p; q+1= eob ) - break; - if (( str=( char* )mir_alloc( q-p+1 )) == NULL ) { - ft->state = FT_ERROR; - break; - } - strncpy( str, p, q-p ); - str[q-p] = '\0'; - Log( "FT Got: %s", str ); - if ( ft->state == FT_CONNECTING ) { - // looking for "GET filename.ext HTTP/1.1" - if ( !strncmp( str, "GET ", 4 )) { - for ( t=str+4; *t!='\0' && *t!=' '; t++ ); - *t = '\0'; - for ( t=str+4; *t!='\0' && *t=='/'; t++ ); - ft->httpPath = mir_a2t( t ); - JabberHttpUrlDecode( ft->httpPath ); - ft->state = FT_INITIALIZING; - Log( "Change to FT_INITIALIZING" ); - } - } - else { // FT_INITIALIZING - if ( str[0] == '\0' ) { - struct _stati64 statbuf; - - mir_free( str ); - num += 2; - - currentFile = ft->std.currentFileNumber; - TCHAR* t = _tcsrchr( ft->std.ptszFiles[ currentFile ], '\\' ); - if ( t != NULL ) - t++; - else - t = ft->std.ptszFiles[currentFile]; - - if ( ft->httpPath==NULL || lstrcmp( ft->httpPath, t )) { - if ( ft->httpPath == NULL ) - Log( "Requested file name does not matched ( httpPath==NULL )" ); - else - Log( "Requested file name does not matched ( '%s' vs. '%s' )", ft->httpPath, t ); - ft->state = FT_ERROR; - break; - } - Log( "Sending [%s]", ft->std.ptszFiles[ currentFile ] ); - _tstati64( ft->std.ptszFiles[ currentFile ], &statbuf ); // file size in statbuf.st_size - if (( fileId = _topen( ft->std.ptszFiles[currentFile], _O_BINARY|_O_RDONLY )) < 0 ) { - Log( "File cannot be opened" ); - ft->state = FT_ERROR; - mir_free( ft->httpPath ); - ft->httpPath = NULL; - break; - } - - char fileBuffer[ 2048 ]; - int bytes = mir_snprintf( fileBuffer, sizeof(fileBuffer), "HTTP/1.1 200 OK\r\nContent-Length: %I64u\r\n\r\n", statbuf.st_size ); - WsSend( s, fileBuffer, bytes, MSG_DUMPASTEXT ); - - ft->std.flags |= PFTS_SENDING; - ft->std.currentFileProgress = 0; - Log( "Sending file data..." ); - - while (( numRead = _read( fileId, fileBuffer, 2048 )) > 0 ) { - if ( Netlib_Send( s, fileBuffer, numRead, 0 ) != numRead ) { - ft->state = FT_ERROR; - break; - } - ft->std.currentFileProgress += numRead; - ft->std.totalProgress += numRead; - JSendBroadcast( ft->std.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, ( LPARAM )&ft->std ); - } - _close( fileId ); - if ( ft->state != FT_ERROR ) - ft->state = FT_DONE; - Log( "Finishing this file..." ); - mir_free( ft->httpPath ); - ft->httpPath = NULL; - break; - } } - - mir_free( str ); - q += 2; - num += ( q-p ); - p = q; - } - - return num; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// filetransfer class members - -filetransfer::filetransfer( CJabberProto* proto ) -{ - memset( this, 0, sizeof( filetransfer )); - ppro = proto; - fileId = -1; - std.cbSize = sizeof( std ); - std.flags = PFTS_TCHAR; -} - -filetransfer::~filetransfer() -{ - ppro->Log( "Destroying file transfer session %08p", this ); - - if ( !bCompleted ) - ppro->JSendBroadcast( std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, this, 0 ); - - close(); - - if ( hWaitEvent != INVALID_HANDLE_VALUE ) - CloseHandle( hWaitEvent ); - - if ( jid ) mir_free( jid ); - if ( sid ) mir_free( sid ); - if ( iqId ) mir_free( iqId ); - if ( fileSize ) mir_free( fileSize ); - if ( httpHostName ) mir_free( httpHostName ); - if ( httpPath ) mir_free( httpPath ); - if ( szDescription ) mir_free( szDescription ); - - if ( std.tszWorkingDir ) mir_free( std.tszWorkingDir ); - if ( std.tszCurrentFile ) mir_free( std.tszCurrentFile ); - - if ( std.ptszFiles ) { - for ( int i=0; i < std.totalFiles; i++ ) - if ( std.ptszFiles[i] ) mir_free( std.ptszFiles[i] ); - - mir_free( std.ptszFiles ); -} } - -void filetransfer::close() -{ - if ( fileId != -1 ) { - _close( fileId ); - fileId = -1; -} } - -void filetransfer::complete() -{ - close(); - - bCompleted = true; - ppro->JSendBroadcast( std.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, this, 0); -} - -int filetransfer::create() -{ - if ( fileId != -1 ) - return fileId; - - TCHAR filefull[ MAX_PATH ]; - mir_sntprintf( filefull, SIZEOF(filefull), _T("%s\\%s"), std.tszWorkingDir, std.tszCurrentFile ); - replaceStrT( std.tszCurrentFile, filefull ); - - if ( hWaitEvent != INVALID_HANDLE_VALUE ) - CloseHandle( hWaitEvent ); - hWaitEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); - - if ( ppro->JSendBroadcast( std.hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, this, ( LPARAM )&std )) - WaitForSingleObject( hWaitEvent, INFINITE ); - - if ( fileId == -1 ) { - ppro->Log( "Saving to [%s]", std.tszCurrentFile ); - fileId = _topen( std.tszCurrentFile, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _S_IREAD | _S_IWRITE ); - } - - if ( fileId == -1 ) - ppro->Log( "Cannot create file '%s' during a file transfer", filefull ); - else if ( std.currentFileSize != 0 ) - _chsize( fileId, std.currentFileSize ); - - return fileId; -} -- cgit v1.2.3