/* * This code implements communication based on Miranda netlib library * * (c) majvan 2002-2004 */ #include "..\yamn.h" #include "m_netlib.h" #include "netlib.h" //-------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- BOOL SSLLoaded=FALSE; HANDLE hNetlibUser=NULL; extern PVOID TLSCtx; extern PVOID SSLCtx; void __stdcall SSL_DebugLog(const char *fmt, ...) { char str[ 4096 ]; va_list vararg; va_start( vararg, fmt ); int tBytes = _vsnprintf( str, sizeof(str)-1, fmt, vararg ); if ( tBytes == 0 ) return; if ( tBytes > 0 ) str[ tBytes ] = 0; else str[ sizeof(str)-1 ] = 0; CallService(MS_NETLIB_LOG, (WPARAM)hNetlibUser, (LPARAM)str); va_end( vararg ); } HANDLE RegisterNLClient(const char *name) { static NETLIBUSER nlu={0}; char desc[128]; sprintf(desc, Translate("%s connection"),name); #ifdef DEBUG_COMM DebugLog(CommFile,""); #endif nlu.cbSize = sizeof(nlu); nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS; nlu.szDescriptiveName=desc; nlu.szSettingsModule=(char *)name; hNetlibUser=(HANDLE)CallService(MS_NETLIB_REGISTERUSER,0,(LPARAM)&nlu); #ifdef DEBUG_COMM if (NULL==hNetlibUser) DebugLog(CommFile,"\n"); else DebugLog(CommFile,"\n"); #endif return hNetlibUser; } //Move connection to SSL void CNLClient::SSLify() throw(DWORD) { #ifdef DEBUG_COMM SSL_DebugLog("Staring SSL..."); #endif int socket = CallService(MS_NETLIB_GETSOCKET, (WPARAM)hConnection, 0); if (socket != INVALID_SOCKET) { #ifdef DEBUG_COMM SSL_DebugLog("Staring netlib core SSL"); #endif if (CallService(MS_NETLIB_STARTSSL, (WPARAM)hConnection, 0)) { #ifdef DEBUG_COMM SSL_DebugLog("Netlib core SSL started"); #endif isTLSed = true; SSLLoaded = TRUE; return; } } //ssl could not be created throw NetworkError = (DWORD)ESSL_CREATESSL; } //Connects to the server through the sock //if not success, exception is throwed void CNLClient::Connect(const char* servername,const int port) throw(DWORD) { NETLIBOPENCONNECTION nloc; NetworkError=SystemError=0; isTLSed = false; #ifdef DEBUG_COMM DebugLog(CommFile,"\n"); #endif try { nloc.cbSize=sizeof(NETLIBOPENCONNECTION); nloc.szHost=servername; nloc.wPort=port; nloc.flags=0; if (NULL==(hConnection=(HANDLE)CallService(MS_NETLIB_OPENCONNECTION,(WPARAM)hNetlibUser,(LPARAM)&nloc))) { SystemError=WSAGetLastError(); throw NetworkError=(DWORD)ENL_CONNECT; } #ifdef DEBUG_COMM DebugLog(CommFile,"\n"); #endif return; } catch(...) { #ifdef DEBUG_COMM DebugLog(CommFile,"\n"); #endif throw; } } //Performs a simple query // query- command to send int CNLClient::LocalNetlib_Send(HANDLE hConn,const char *buf,int len,int flags) { if (isTLSed) { #ifdef DEBUG_COMM SSL_DebugLog("SSL send: %s", buf); #endif } NETLIBBUFFER nlb={(char*)buf,len,flags}; return CallService(MS_NETLIB_SEND,(WPARAM)hConn,(LPARAM)&nlb); } void CNLClient::Send(const char *query) throw(DWORD) { unsigned int Sent; if (NULL==query) return; if (hConnection==NULL) return; #ifdef DEBUG_COMM DebugLog(CommFile,"%s",query); #endif try { if ((SOCKET_ERROR==(Sent=LocalNetlib_Send(hConnection,query,(int)strlen(query),MSG_DUMPASTEXT))) || Sent!=(unsigned int)strlen(query)) { SystemError=WSAGetLastError(); throw NetworkError=(DWORD)ENL_SEND; } #ifdef DEBUG_COMM DebugLog(CommFile,"\n"); #endif } catch(...) { #ifdef DEBUG_COMM DebugLog(CommFile,"\n"); #endif throw; } } //Reads data from socket // buf- buffer where to store max. buflen of received characters // if buf is NULL, creates buffer of buflen size // buf is NULL by default //You need free() returned buffer, which can be allocated in this function //if not success, exception is throwed int CNLClient::LocalNetlib_Recv(HANDLE hConn,char *buf,int len,int flags) { NETLIBBUFFER nlb={buf,len,flags}; int iReturn = CallService(MS_NETLIB_RECV,(WPARAM)hConn,(LPARAM)&nlb); if (isTLSed) { #ifdef DEBUG_COMM SSL_DebugLog("SSL recv: %s", buf); #endif } return iReturn; } char* CNLClient::Recv(char *buf,int buflen) throw(DWORD) { #ifdef DEBUG_COMM DebugLog(CommFile,""); #endif try { if (buf==NULL) buf=(char *)malloc(sizeof(char)*(buflen+1)); if (buf==NULL) throw NetworkError=(DWORD)ENL_RECVALLOC; if (!isTLSed) { NETLIBSELECT nls; memset(&nls, 0, sizeof(NETLIBSELECT)); nls.cbSize = sizeof(NETLIBSELECT); nls.dwTimeout = 60000; nls.hReadConns[0] = hConnection; switch (CallService(MS_NETLIB_SELECT, 0, (LPARAM) &nls)) { case SOCKET_ERROR: free(buf); SystemError=WSAGetLastError(); throw NetworkError = (DWORD) ENL_RECV; case 0: // time out! free(buf); throw NetworkError = (DWORD) ENL_TIMEOUT; } } ZeroMemory(buf,buflen); if (SOCKET_ERROR==(Rcv=LocalNetlib_Recv(hConnection,buf,buflen,MSG_DUMPASTEXT))) { free(buf); SystemError=WSAGetLastError(); throw NetworkError=(DWORD)ENL_RECV; } if (!Rcv) { free(buf); SystemError=WSAGetLastError(); throw NetworkError=(DWORD)ENL_RECV; } #ifdef DEBUG_COMM *(buf+Rcv)=0; //end the buffer to write it to file DebugLog(CommFile,"%s",buf); DebugLog(CommFile,"\n"); #endif return(buf); } catch(...) { #ifdef DEBUG_COMM DebugLog(CommFile,"\n"); #endif throw; } } //Closes netlib connection void CNLClient::Disconnect() { Netlib_CloseHandle(hConnection); hConnection=(HANDLE)NULL; } //Uninitializes netlib library void UnregisterNLClient() { #ifdef DEBUG_COMM DebugLog(CommFile,""); #endif Netlib_CloseHandle(hNetlibUser); hNetlibUser=(HANDLE)NULL; #ifdef DEBUG_COMM DebugLog(CommFile,"\n"); #endif }