static HB_SIZE s_fileRead( PHB_FILE pFile, void * data, HB_SIZE nSize, HB_MAXINT timeout ) { HB_ERRCODE errcode = 0; long lRead = 0; if( ! pFile->fEof ) { lRead = nSize > LONG_MAX ? LONG_MAX : ( long ) nSize; if( timeout == -1 ) timeout = pFile->timeout; lRead = hb_sockexRead( pFile->sock, data, lRead, timeout ); errcode = hb_socketGetError(); if( lRead <= 0 ) { switch( errcode ) { case HB_SOCKET_ERR_TIMEOUT: case HB_SOCKET_ERR_AGAIN: case HB_SOCKET_ERR_TRYAGAIN: break; default: pFile->fEof = HB_TRUE; break; } lRead = 0; } } hb_fsSetError( errcode ); return lRead; }
static void s_fileClose( PHB_FILE pFile ) { hb_socketShutdown( pFile->sd, HB_SOCKET_SHUT_RDWR ); hb_socketClose( pFile->sd ); hb_fsSetError( hb_socketGetError() ); hb_xfree( pFile ); }
static HB_SIZE s_fileWrite( PHB_FILE pFile, const void * data, HB_SIZE nSize, HB_MAXINT timeout ) { long lSent = nSize > LONG_MAX ? LONG_MAX : ( long ) nSize; HB_ERRCODE errcode; if( timeout == -1 ) timeout = pFile->timeout; lSent = hb_sockexWrite( pFile->sock, data, lSent, timeout ); errcode = hb_socketGetError(); hb_fsSetError( errcode ); if( lSent < 0 ) { switch( errcode ) { case HB_SOCKET_ERR_TIMEOUT: case HB_SOCKET_ERR_AGAIN: case HB_SOCKET_ERR_TRYAGAIN: lSent = 0; break; } } return lSent; }
static long s_bf_send( PHB_SOCKEX_BF pBF, HB_MAXINT timeout ) { long lSent = 0, len = pBF->inbuffer; while( lSent < len ) { long l = hb_sockexWrite( pBF->sock, pBF->buffer + lSent, len - lSent, timeout ); if( l <= 0 ) { switch( hb_socketGetError() ) { case HB_SOCKET_ERR_TIMEOUT: case HB_SOCKET_ERR_AGAIN: case HB_SOCKET_ERR_TRYAGAIN: break; default: lSent = -1; break; } break; } lSent += l; if( timeout > 0 ) timeout = 0; } if( lSent > 0 ) { if( lSent < len ) memmove( pBF->buffer, pBF->buffer + lSent, len - lSent ); pBF->inbuffer -= lSent; } return lSent; }
static long s_srvRecvAll( PHB_CONSRV conn, void * buffer, long len ) { HB_BYTE * ptr = ( HB_BYTE * ) buffer; long lRead = 0, l; HB_MAXUINT end_timer; end_timer = conn->timeout > 0 ? hb_dateMilliSeconds() + conn->timeout : 0; while( lRead < len && ! conn->stop ) { if( conn->zstream ) l = hb_znetRead( conn->zstream, conn->sd, ptr + lRead, len - lRead, 1000 ); else l = hb_socketRecv( conn->sd, ptr + lRead, len - lRead, 0, 1000 ); if( l <= 0 ) { if( hb_socketGetError() != HB_SOCKET_ERR_TIMEOUT || hb_vmRequestQuery() != 0 || ( end_timer != 0 && end_timer <= hb_dateMilliSeconds() ) ) break; } else { lRead += l; conn->rd_count += l; } } return lRead; }
static int s_inetGetError( PHB_SOCKET_STRUCT socket ) { int iError; iError = socket->errorFunc ? socket->errorFunc( socket->stream ) : hb_socketGetError(); if( iError == HB_SOCKET_ERR_TIMEOUT ) iError = HB_INET_ERR_TIMEOUT; return iError; }
static HB_SIZE s_fileWrite( PHB_FILE pFile, const void * data, HB_SIZE nSize, HB_MAXINT timeout ) { long lSend = nSize > LONG_MAX ? LONG_MAX : ( long ) nSize; if( timeout == -1 ) timeout = pFile->timeout; lSend = hb_socketSend( pFile->sd, data, lSend, 0, timeout ); hb_fsSetError( hb_socketGetError() ); if( lSend < 0 ) lSend = 0; return lSend; }
HB_BOOL hb_lppSend( PHB_LPP pSocket, const void * data, HB_SIZE len, HB_MAXINT timeout ) { HB_MAXINT nTime = 0; long lSend; if( ! pSocket->pSendBuffer ) { pSocket->pSendBuffer = ( char * ) hb_xgrab( len + 4 ); HB_PUT_LE_UINT32( pSocket->pSendBuffer, len ); hb_xmemcpy( pSocket->pSendBuffer + 4, data, len ); pSocket->nSendLen = len + 4; pSocket->nSendPos = 0; } if( timeout > 0 ) nTime = ( HB_MAXINT ) hb_dateMilliSeconds() + timeout; for( ;; ) { if( pSocket->nSendLen - pSocket->nSendPos < ( HB_SIZE ) LONG_MAX ) lSend = ( long ) ( pSocket->nSendLen - pSocket->nSendPos ); else lSend = LONG_MAX; lSend = hb_socketSend( pSocket->sd, pSocket->pSendBuffer + pSocket->nSendPos, lSend, 0, timeout ); if( lSend == -1 ) { pSocket->iError = hb_socketGetError(); return HB_FALSE; } pSocket->nSendPos += lSend; if( pSocket->nSendPos == pSocket->nSendLen ) { hb_xfree( pSocket->pSendBuffer ); pSocket->pSendBuffer = NULL; pSocket->iError = 0; return HB_TRUE; } if( timeout == 0 || ( timeout > 0 && ( timeout = nTime - ( HB_MAXINT ) hb_dateMilliSeconds() ) <= 0 ) ) { pSocket->iError = HB_SOCKET_ERR_TIMEOUT; return HB_FALSE; } } }
static long s_srvSendAll( PHB_CONSRV conn, void * buffer, long len ) { HB_BYTE * ptr = ( HB_BYTE * ) buffer; long lSent = 0, lLast = 1, l; HB_MAXUINT end_timer; if( ! conn->mutex || hb_threadMutexLock( conn->mutex ) ) { end_timer = conn->timeout > 0 ? hb_dateMilliSeconds() + conn->timeout : 0; while( lSent < len && ! conn->stop ) { if( conn->zstream ) l = hb_znetWrite( conn->zstream, conn->sd, ptr + lSent, len - lSent, 1000, &lLast ); else l = lLast = hb_socketSend( conn->sd, ptr + lSent, len - lSent, 0, 1000 ); if( l > 0 ) { lSent += l; conn->wr_count += l; } if( lLast <= 0 ) { if( hb_socketGetError() != HB_SOCKET_ERR_TIMEOUT || hb_vmRequestQuery() != 0 || ( end_timer != 0 && end_timer <= hb_dateMilliSeconds() ) ) break; } } if( conn->zstream && lLast > 0 && ! conn->stop ) { if( hb_znetFlush( conn->zstream, conn->sd, conn->timeout > 0 ? conn->timeout : -1 ) != 0 ) lSent = -1; } if( conn->mutex ) hb_threadMutexUnlock( conn->mutex ); } return lSent; }
static long s_zsock_write( PHB_SOCKEX_Z pZ, HB_MAXINT timeout ) { long lSent = 0, len = HB_ZSOCK_WRBUFSIZE - pZ->z_write.avail_out; while( lSent < len ) { long l = hb_sockexWrite( pZ->sock, pZ->wrbuf + lSent, len - lSent, timeout ); if( l <= 0 ) { switch( hb_socketGetError() ) { case HB_SOCKET_ERR_TIMEOUT: case HB_SOCKET_ERR_AGAIN: case HB_SOCKET_ERR_TRYAGAIN: break; default: lSent = -1; break; } break; } lSent += l; if( timeout > 0 ) timeout = 0; } if( lSent > 0 ) { if( lSent < len ) memmove( pZ->wrbuf, pZ->wrbuf + lSent, len - lSent ); pZ->z_write.avail_out += lSent; pZ->z_write.next_out -= lSent; } return lSent; }
static void hb_inetGetError( PHB_SOCKET_STRUCT socket ) { socket->iError = hb_socketGetError(); if( socket->iError == HB_SOCKET_ERR_TIMEOUT ) socket->iError = HB_INET_ERR_TIMEOUT; }
static PHB_FILE s_fileOpen( PHB_FILE_FUNCS pFuncs, const char * pszName, const char * pszDefExt, HB_FATTR nExFlags, const char * pPaths, PHB_ITEM pError ) { const char * pszHost = pszName + FILE_PREFIX_LEN, * ptr; PHB_FILE pFile = NULL; HB_ERRCODE errcode = 0; HB_SIZE nLen = 0; int iPort = 0; HB_MAXINT timeout = -1; HB_SYMBOL_UNUSED( pFuncs ); HB_SYMBOL_UNUSED( pszDefExt ); HB_SYMBOL_UNUSED( pPaths ); if( ( ptr = strchr( pszHost, ':' ) ) != NULL && ptr != pszHost ) { nLen = ptr - pszHost; ++ptr; while( HB_ISDIGIT( * ptr ) ) iPort = iPort * 10 + ( * ptr++ - '0' ); if( * ptr == ':' ) { ++ptr; while( HB_ISDIGIT( * ptr ) ) timeout = HB_MAX( timeout, 0 ) * 10 + ( * ptr++ - '0' ); } if( * ptr != 0 && * ptr != ':' ) iPort = 0; } if( iPort > 0 ) { char * pszAddr, * pszIpAddr; hb_socketAutoInit(); pszAddr = hb_strndup( pszHost, nLen ); pszIpAddr = hb_socketResolveAddr( pszAddr, HB_SOCKET_AF_INET ); hb_xfree( pszAddr ); if( pszIpAddr ) { HB_SOCKET sd = hb_socketOpen( HB_SOCKET_PF_INET, HB_SOCKET_PT_STREAM, 0 ); if( sd != HB_NO_SOCKET ) { void * pSockAddr; unsigned uiLen; if( hb_socketInetAddr( &pSockAddr, &uiLen, pszIpAddr, iPort ) ) { hb_socketSetKeepAlive( sd, HB_TRUE ); if( hb_socketConnect( sd, pSockAddr, uiLen, timeout ) == 0 ) { PHB_SOCKEX sock; switch( nExFlags & ( FO_READ | FO_WRITE | FO_READWRITE ) ) { case FO_READ: hb_socketShutdown( sd, HB_SOCKET_SHUT_WR ); break; case FO_WRITE: hb_socketShutdown( sd, HB_SOCKET_SHUT_RD ); break; } sock = hb_sockexNew( sd, NULL, NULL ); if( sock ) { hb_sockexSetShutDown( sock, HB_TRUE ); hb_sockexSetAutoFlush( sock, HB_TRUE ); pFile = s_fileNew( sock, timeout ); sd = HB_NO_SOCKET; } } hb_xfree( pSockAddr ); } if( sd != HB_NO_SOCKET ) { errcode = hb_socketGetError(); hb_socketClose( sd ); } } hb_xfree( pszIpAddr ); } if( errcode == 0 && pFile == NULL ) errcode = hb_socketGetError(); } else errcode = HB_SOCKET_ERR_WRONGADDR; hb_fsSetError( errcode ); if( pError ) { hb_errPutFileName( pError, pszName ); if( pFile == NULL ) { hb_errPutOsCode( pError, errcode ); hb_errPutGenCode( pError, ( HB_ERRCODE ) EG_OPEN ); } } return pFile; }
static void s_inetRecvInternal( int iMode ) { PHB_SOCKET_STRUCT socket = HB_PARSOCKET( 1 ); PHB_ITEM pBuffer = hb_param( 2, HB_IT_STRING ); char * buffer; HB_SIZE nLen; int iLen, iMaxLen, iReceived; int iTimeElapsed; if( socket == NULL || pBuffer == NULL || ! HB_ISBYREF( 2 ) ) hb_inetErrRT(); else if( ! hb_inetIsOpen( socket ) ) hb_retni( -1 ); else { if( hb_itemGetWriteCL( pBuffer, &buffer, &nLen ) ) iLen = ( int ) nLen; else { iLen = 0; buffer = NULL; } if( HB_ISNUM( 3 ) ) { iMaxLen = hb_parni( 3 ); if( iMaxLen < 0 ) iMaxLen = 0; else if( iLen < iMaxLen ) iMaxLen = iLen; } else iMaxLen = iLen; iReceived = 0; iTimeElapsed = 0; socket->iError = HB_INET_ERR_OK; do { iLen = s_inetRecv( socket, buffer + iReceived, iMaxLen - iReceived, HB_FALSE ); if( iLen >= 0 ) { iReceived += iLen; if( iMode == 0 ) /* Called from hb_inetRecv()? */ break; } else if( iLen == -1 && hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT ) { /* timed out; let's see if we have to run a cb routine */ iTimeElapsed += socket->iTimeout; /* if we have a pPeriodicBlock, timeLimit is our REAL timeout */ if( socket->pPeriodicBlock ) { hb_execFromArray( socket->pPeriodicBlock ); /* do we continue? */ if( hb_parl( -1 ) && hb_vmRequestQuery() == 0 && ( socket->iTimeLimit == -1 || iTimeElapsed < socket->iTimeLimit ) ) iLen = 1; /* Declare success to continue loop */ } } } while( iReceived < iMaxLen && iLen > 0 ); socket->iCount = iReceived; if( iLen == 0 ) socket->iError = HB_INET_ERR_CLOSEDCONN; else if( iLen < 0 ) hb_inetGetError( socket ); hb_retni( iReceived > 0 ? iReceived : iLen ); } }
static void s_fileClose( PHB_FILE pFile ) { hb_sockexClose( pFile->sock, HB_TRUE ); hb_fsSetError( hb_socketGetError() ); hb_xfree( pFile ); }
static void s_inetRecvPattern( const char * const * patterns, int * patternsizes, int iPatternsCount, int iParam ) { PHB_SOCKET_STRUCT socket = HB_PARSOCKET( 1 ); PHB_ITEM pResult = hb_param( iParam, HB_IT_BYREF ); PHB_ITEM pMaxSize = hb_param( iParam + 1, HB_IT_NUMERIC ); PHB_ITEM pBufferSize = hb_param( iParam + 2, HB_IT_NUMERIC ); char cChar = '\0'; char * buffer; int iPaternFound = 0; int iTimeElapsed = 0; int iPos = 0; int iLen; int iAllocated, iBufferSize, iMax; int i; if( socket == NULL ) { hb_inetErrRT(); return; } else if( ! hb_inetIsOpen( socket ) ) { if( pResult ) hb_itemPutNI( pResult, -1 ); hb_retc_null(); return; } iBufferSize = pBufferSize ? hb_itemGetNI( pBufferSize ) : 80; iMax = pMaxSize ? hb_itemGetNI( pMaxSize ) : 0; socket->iError = HB_INET_ERR_OK; buffer = ( char * ) hb_xgrab( iBufferSize ); iAllocated = iBufferSize; do { if( iPos == iAllocated - 1 ) { iAllocated += iBufferSize; buffer = ( char * ) hb_xrealloc( buffer, iAllocated ); } iLen = s_inetRecv( socket, &cChar, 1, HB_TRUE ); if( iLen == -1 && hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT ) { iLen = -2; /* this signals timeout */ iTimeElapsed += socket->iTimeout; if( socket->pPeriodicBlock ) { HB_BOOL fResult; hb_execFromArray( socket->pPeriodicBlock ); fResult = hb_parl( -1 ) && hb_vmRequestQuery() == 0; if( fResult && ( socket->iTimeLimit == -1 || iTimeElapsed < socket->iTimeLimit ) ) iLen = 1; } } else if( iLen > 0 ) { buffer[ iPos++ ] = cChar; for( i = 0; i < iPatternsCount; ++i ) { if( patternsizes[ i ] <= iPos && cChar == patterns[ i ][ patternsizes[ i ] - 1 ] ) { if( memcmp( buffer + iPos - patternsizes[ i ], patterns[ i ], patternsizes[ i ] ) == 0 ) { iPaternFound = i + 1; break; } } } } } while( iLen > 0 && iPaternFound == 0 && ( iMax == 0 || iPos < iMax ) ); if( iPaternFound ) { socket->iCount = iPos; if( pResult ) hb_itemPutNI( pResult, iPos ); hb_retclen_buffer( buffer, iPos - patternsizes[ iPaternFound - 1 ] ); } else { if( iLen == 0 ) socket->iError = HB_INET_ERR_CLOSEDCONN; else if( iLen < 0 ) hb_inetGetError( socket ); else { socket->iError = HB_INET_ERR_BUFFOVERRUN; iLen = -1; } if( pResult ) hb_itemPutNI( pResult, iLen ); hb_xfree( buffer ); hb_retc_null(); } }
HB_BOOL hb_lppRecv( PHB_LPP pSocket, void ** data, HB_SIZE * len, HB_MAXINT timeout ) { HB_MAXINT nTime = 0; long lRecv; if( ! pSocket->pRecvBuffer ) { pSocket->pRecvBuffer = ( char * ) hb_xgrab( 4 ); pSocket->nRecvLen = 0; pSocket->fRecvHasSize = HB_FALSE; } if( timeout > 0 ) nTime = ( HB_MAXINT ) hb_dateMilliSeconds() + timeout; for( ;; ) { if( ! pSocket->fRecvHasSize ) { lRecv = ( long ) ( 4 - pSocket->nRecvLen ); lRecv = hb_socketRecv( pSocket->sd, pSocket->pRecvBuffer + pSocket->nRecvLen, lRecv, 0, timeout ); if( lRecv == -1 ) { pSocket->iError = hb_socketGetError(); return HB_FALSE; } else if( lRecv == 0 ) { /* peer closed connection */ pSocket->iError = 0; return HB_FALSE; } pSocket->nRecvLen += lRecv; if( pSocket->nRecvLen < 4 ) { pSocket->iError = HB_SOCKET_ERR_TIMEOUT; return HB_FALSE; } pSocket->nRecvSize = HB_GET_UINT32( pSocket->pRecvBuffer ); if( pSocket->nLimit && pSocket->nRecvSize > pSocket->nLimit ) { /* protection against remote memory exhaust attack */ pSocket->iError = HB_LPP_ERR_TOOLARGE; hb_xfree( pSocket->pRecvBuffer ); pSocket->pRecvBuffer = NULL; return HB_FALSE; } pSocket->nRecvLen = 0; pSocket->fRecvHasSize = HB_TRUE; if( pSocket->nRecvSize != 4 ) pSocket->pRecvBuffer = ( char * ) hb_xrealloc( pSocket->pRecvBuffer, pSocket->nRecvSize ); } if( pSocket->nRecvSize - pSocket->nRecvLen < ( HB_SIZE ) LONG_MAX ) lRecv = ( long ) ( pSocket->nRecvSize - pSocket->nRecvLen ); else lRecv = LONG_MAX; lRecv = hb_socketRecv( pSocket->sd, pSocket->pRecvBuffer + pSocket->nRecvLen, lRecv, 0, timeout ); if( lRecv == -1 ) { pSocket->iError = hb_socketGetError(); return HB_FALSE; } else if( lRecv == 0 ) { /* peer closed connection */ pSocket->iError = 0; return HB_FALSE; } pSocket->nRecvLen += lRecv; if( pSocket->nRecvSize == pSocket->nRecvLen ) { * data = pSocket->pRecvBuffer; * len = pSocket->nRecvLen; pSocket->pRecvBuffer = NULL; pSocket->iError = 0; return HB_TRUE; } if( timeout == 0 || ( timeout > 0 && ( timeout = nTime - ( HB_MAXINT ) hb_dateMilliSeconds() ) <= 0 ) ) { pSocket->iError = HB_SOCKET_ERR_TIMEOUT; return HB_FALSE; } } }
static void s_inetSendInternal( HB_BOOL lAll ) { PHB_SOCKET_STRUCT socket = HB_PARSOCKET( 1 ); PHB_ITEM pBuffer = hb_param( 2, HB_IT_STRING ); const char * buffer; int iLen, iSent, iSend; long lLastSnd = 1; if( socket == NULL || pBuffer == NULL ) hb_inetErrRT(); else if( ! hb_inetIsOpen( socket ) ) hb_retni( -1 ); else { buffer = hb_itemGetCPtr( pBuffer ); iSend = ( int ) hb_itemGetCLen( pBuffer ); if( HB_ISNUM( 3 ) ) { iLen = hb_parni( 3 ); if( iLen < iSend ) iSend = iLen; } socket->iError = HB_INET_ERR_OK; iSent = iLen = 0; while( iSent < iSend ) { if( socket->sendFunc ) { iLen = socket->sendFunc( socket->stream, socket->sd, buffer + iSent, iSend - iSent, socket->iTimeout, &lLastSnd ); if( lLastSnd <= 0 && iLen > 0 ) { iSent += iLen; iLen = ( int ) lLastSnd; } } else iLen = hb_socketSend( socket->sd, buffer + iSent, iSend - iSent, 0, socket->iTimeout ); if( iLen > 0 ) { iSent += iLen; if( ! lAll ) break; } else { hb_inetGetError( socket ); break; } } socket->iCount = iSent; if( socket->flushFunc && ( lLastSnd > 0 || ( lLastSnd == -1 && socket->iTimeout >= 0 && socket->iTimeout < 10000 && hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT ) ) ) { /* TODO: safe information about unflushed data and try to call flush before entering receive wait sate */ socket->flushFunc( socket->stream, socket->sd, socket->iTimeout < 0 ? socket->iTimeout : HB_MAX( socket->iTimeout, 10000 ) ); } hb_retni( iSent > 0 ? iSent : iLen ); } }