diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 389ce0041e..e5d9db7fb9 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,27 @@ past entries belonging to author(s): Viktor Szakats. */ +2009-07-24 09:40 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) + * contrib/hbtip/sendmail.prg + * contrib/hbtip/client.prg + * contrib/hbtip/smtpcln.prg + + Added TLS (SMTPS, SSL) support for SMTP class. It's experimental + yet, and there is still some protocol level error. + With this it'll possible to send e-mails through gmail for + example. + Some level of STARTTLS support (TLS on normal SMTP ports) + was also added, but I cannot test this. + Anyhow from this point it should be an easy task to + finish above details. + Since TLS was added to low level client class, it's now + possible to add SSL support also for POPS, HTTPS and FTPS. + ; NOTE: This code part is only active if hbtip is built with + -DHAVE_OPENSSL build-time flag, and it also requires + hbssl lib + OpenSSL libs. + + * contrib/hbtip/utils.c + ! Fixed timezone offset being always zero in TIP_TIMESTAMP() + 2009-07-23 21:44 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) * contrib/rddads/ads1.c ! Reverted prev change plus added error handling. Thx Przemek. @@ -65,6 +86,9 @@ * contrib/hbcurl/hbcurl.c * contrib/hbwin/win_prt.c ! Fixed similar to above allocation errors. + CURL_EASY_RECV() in hbcurl. + WINPORTREAD() in hbwin. + HB_FREADLINE() in xhb. * config/global.cf + Added HB_???_INSTALL initialization. Just a step, needs more diff --git a/harbour/contrib/hbtip/client.prg b/harbour/contrib/hbtip/client.prg index 1a4859cd91..9320aad060 100644 --- a/harbour/contrib/hbtip/client.prg +++ b/harbour/contrib/hbtip/client.prg @@ -73,6 +73,14 @@ #include "error.ch" #include "fileio.ch" +#if defined( _SSL_DEBUG_TEMP ) + #include "simpleio.ch" +#endif + +#if defined( HAVE_OPENSSL ) + #include "hbssl.ch" +#endif + #include "tip.ch" #define RCV_BUF_SIZE Int( ::InetRcvBufSize( ::SocketCon ) / 2 ) @@ -114,6 +122,13 @@ CREATE CLASS tIPClient VAR exGauge /* Gauge control; it can be a codeblock or a function pointer. */ + VAR lTLS INIT .F. +#if defined( HAVE_OPENSSL ) + VAR ssl_ctx + VAR ssl + VAR nSSLError INIT 0 +#endif + VAR Cargo /* Data for proxy connection */ @@ -125,6 +140,8 @@ CREATE CLASS tIPClient METHOD New( oUrl, lTrace, oCredentials ) METHOD Open() + METHOD EnableTLS( lEnable ) + METHOD Read( iLen ) METHOD ReadToFile( cFile, nMode, nSize ) METHOD Write( cData, iLen, bCommit ) @@ -138,7 +155,7 @@ CREATE CLASS tIPClient METHOD SetProxy( cProxyHost, nProxyPort, cProxyUser, cProxyPassword ) METHOD lastErrorCode() INLINE ::nLastError - METHOD lastErrorMessage(SocketCon) INLINE ::INetErrorDesc(SocketCon) + METHOD lastErrorMessage( SocketCon ) INLINE ::INetErrorDesc( SocketCon ) METHOD InetRcvBufSize( SocketCon, nSizeBuff ) METHOD InetSndBufSize( SocketCon, nSizeBuff ) @@ -147,8 +164,8 @@ CREATE CLASS tIPClient VAR nLastError INIT 0 - METHOD OpenProxy( cServer, nPort, cProxy, nProxyPort, cResp, cUserName, cPassWord, nTimeOut, cUserAgent ) - METHOD ReadHTTPProxyResponse() + METHOD OpenProxy( cServer, nPort, cProxy, nProxyPort, cResp, cUserName, cPassWord, cUserAgent ) + METHOD ReadHTTPProxyResponse( sResponse ) /* Methods to log data if needed */ METHOD InetRecv( SocketCon, cStr1, len) @@ -156,8 +173,8 @@ CREATE CLASS tIPClient METHOD InetRecvAll( SocketCon, cStr1, len ) METHOD InetCount( SocketCon ) METHOD InetSendAll( SocketCon, cData, nLen ) - METHOD InetErrorCode(SocketCon) - METHOD InetErrorDesc(SocketCon) + METHOD InetErrorCode( SocketCon ) + METHOD InetErrorDesc( SocketCon ) METHOD InetConnect( cServer, nPort, SocketCon ) METHOD Log() @@ -166,11 +183,16 @@ ENDCLASS METHOD New( oUrl, lTrace, oCredentials ) CLASS tIPClient LOCAL oErr + LOCAL cProtoAccepted := "ftp,http,pop,smtp" DEFAULT lTrace TO .F. IF ! ::bInitSocks hb_inetInit() +#if defined( HAVE_OPENSSL ) + SSL_init() + RAND_seed( Time() + hb_username() + DToS( Date() ) + hb_DirBase() + NetName() ) +#endif ::bInitSocks := .T. ENDIF @@ -178,7 +200,17 @@ METHOD New( oUrl, lTrace, oCredentials ) CLASS tIPClient oUrl := tUrl():New( oUrl ) ENDIF - IF ! oURL:cProto $ "ftp,http,pop,smtp" +#if defined( HAVE_OPENSSL ) + IF oURL:cProto == "ftps" .OR. ; + oURL:cProto == "https" .OR. ; + oURL:cProto == "pops" .OR. ; + oURL:cProto == "smtps" + ::EnableTLS( .T. ) + ENDIF + cProtoAccepted += "," + "ftps,https,pops,smtps" +#endif + + IF ! oURL:cProto $ cProtoAccepted oErr := ErrorNew() oErr:Args := { Self, oURL:cProto } oErr:CanDefault := .F. @@ -223,10 +255,13 @@ METHOD Open( cUrl ) CLASS tIPClient ::SocketCon := hb_inetCreate() - hb_inetTimeout( ::SocketCon, ::nConnTimeout ) + IF ISNUMBER( ::nConnTimeout ) + hb_inetTimeout( ::SocketCon, ::nConnTimeout ) + ENDIF + IF ! Empty( ::cProxyHost ) cResp := "" - IF ! ::OpenProxy( ::oUrl:cServer, nPort, ::cProxyHost, ::nProxyPort, @cResp, ::cProxyUser, ::cProxyPassword, ::nConnTimeout, "Mozilla/3.0 compatible" ) + IF ! ::OpenProxy( ::oUrl:cServer, nPort, ::cProxyHost, ::nProxyPort, @cResp, ::cProxyUser, ::cProxyPassword, "Mozilla/3.0 compatible" ) RETURN .F. ENDIF ELSE @@ -239,7 +274,34 @@ METHOD Open( cUrl ) CLASS tIPClient ::isOpen := .T. RETURN .T. -METHOD OpenProxy( cServer, nPort, cProxy, nProxyPort, cResp, cUserName, cPassWord, nTimeOut, cUserAgent ) CLASS tIPClient +METHOD EnableTLS( lEnable ) CLASS tIPClient + LOCAL lSuccess + + IF ::lTLS == lEnable + RETURN .T. + ENDIF + +#if defined( HAVE_OPENSSL ) + IF lEnable + ::ssl_ctx := SSL_CTX_new() + ::ssl := SSL_new( ::ssl_ctx ) + ::lTLS := .T. + lSuccess := .T. + ELSE + ::lTLS := .F. + lSuccess := .T. + ENDIF +#else + IF lEnable + lSuccess := .F. + ELSE + lSuccess := .T. + ENDIF +#endif + + RETURN lSuccess + +METHOD OpenProxy( cServer, nPort, cProxy, nProxyPort, cResp, cUserName, cPassWord, cUserAgent ) CLASS tIPClient LOCAL cRequest LOCAL lRet := .F. LOCAL tmp @@ -257,7 +319,7 @@ METHOD OpenProxy( cServer, nPort, cProxy, nProxyPort, cResp, cUserName, cPassWor cRequest += Chr( 13 ) + Chr( 10 ) ::InetSendAll( ::SocketCon, cRequest ) cResp := "" - IF ::ReadHTTPProxyResponse( nTimeOut, @cResp ) + IF ::ReadHTTPProxyResponse( @cResp ) tmp := At( " ", cResp ) IF tmp > 0 .AND. Val( SubStr( cResp, tmp + 1 ) ) == 200 lRet := .T. @@ -273,17 +335,15 @@ METHOD OpenProxy( cServer, nPort, cProxy, nProxyPort, cResp, cUserName, cPassWor RETURN lRet -METHOD ReadHTTPProxyResponse( dwTimeout, sResponse ) CLASS tIPClient +METHOD ReadHTTPProxyResponse( /* @ */ sResponse ) CLASS tIPClient LOCAL bMoreDataToRead := .T. LOCAL nLength, nData LOCAL szResponse - HB_SYMBOL_UNUSED( dwTimeout ) - DO WHILE bMoreDataToRead szResponse := Space( 1 ) - nData := hb_inetRecv( ::SocketCon, @szResponse, Len( szResponse ) ) + nData := ::InetRecv( ::SocketCon, @szResponse, Len( szResponse ) ) IF nData == 0 RETURN .F. ENDIF @@ -305,6 +365,14 @@ METHOD Close() CLASS tIPClient nRet := hb_inetClose( ::SocketCon ) +#if defined( HAVE_OPENSSL ) + IF ::lTLS + SSL_shutdown( ::ssl ) + ::ssl := NIL + ::ssl_ctx := NIL + ENDIF +#endif + ::SocketCon := NIL ::isOpen := .F. ENDIF @@ -346,11 +414,18 @@ METHOD Read( nLen ) CLASS tIPClient // read an amount of data cStr0 := Space( nLen ) - // S.R. if len of file is less than RCV_BUF_SIZE hb_inetRecvAll return 0 - // ::nLastRead := hb_inetRecvAll( ::SocketCon, @cStr0, nLen ) - - ::InetRecvAll( ::SocketCon, @cStr0, nLen ) - ::nLastRead := ::InetCount( ::SocketCon ) + IF ::lTLS +#if defined( HAVE_OPENSSL ) + /* Getting around implementing the hack used in non-SSL branch for now. + IMO the proper fix would have been done to hb_inetRecvAll(). [vszakats] */ + ::nLastRead := ::InetRecvAll( ::SocketCon, @cStr0, nLen ) +#endif + ELSE + // S.R. if len of file is less than RCV_BUF_SIZE hb_inetRecvAll return 0 + // ::nLastRead := ::InetRecvAll( ::SocketCon, @cStr0, nLen ) + ::InetRecvAll( ::SocketCon, @cStr0, nLen ) + ::nLastRead := ::InetCount( ::SocketCon ) + ENDIF ::nRead += ::nLastRead IF ::nLastRead != nLen @@ -459,7 +534,7 @@ METHOD WriteFromFile( cFile ) CLASS tIPClient nLen := FRead( nFin, @cData, nBufSize ) ENDDO - // it may happen that the file has lenght 0 + // it may happen that the file has length 0 IF nSent > 0 ::Commit() ENDIF @@ -503,7 +578,19 @@ METHOD InetSendAll( SocketCon, cData, nLen ) CLASS tIPClient nLen := Len( cData ) ENDIF - nRet := hb_inetSendAll( SocketCon, cData, nLen ) + IF ::lTLS +#if defined( HAVE_OPENSSL ) +#if defined( _SSL_DEBUG_TEMP ) + ? "SSL_WRITE()", cData +#endif + nRet := SSL_write( ::ssl, cData, nLen ) + ::nSSLError := iif( nRet < 0, nRet, 0 ) +#else + nRet := 0 +#endif + ELSE + nRet := hb_inetSendAll( SocketCon, cData, nLen ) + ENDIF IF ::lTrace ::Log( SocketCon, nlen, cData, nRet ) @@ -521,7 +608,21 @@ METHOD InetCount( SocketCon ) CLASS tIPClient RETURN nRet METHOD InetRecv( SocketCon, cStr1, len ) CLASS tIPClient - LOCAL nRet := hb_inetRecv( SocketCon, @cStr1, len ) + LOCAL nRet + + IF ::lTLS +#if defined( HAVE_OPENSSL ) +#if defined( _SSL_DEBUG_TEMP ) + ? "SSL_READ()" +#endif + nRet := SSL_read( ::ssl, @cStr1, len ) + ::nSSLError := iif( nRet < 0, nRet, 0 ) +#else + nRet := 0 +#endif + ELSE + nRet := hb_inetRecv( SocketCon, @cStr1, len ) + ENDIF IF ::lTrace ::Log( SocketCon, "", len, iif( nRet >= 0, cStr1, nRet ) ) @@ -529,8 +630,26 @@ METHOD InetRecv( SocketCon, cStr1, len ) CLASS tIPClient RETURN nRet -METHOD InetRecvLine( SocketCon, nLen, size ) CLASS tIPClient - LOCAL cRet := hb_inetRecvLine( SocketCon, @nLen, size ) +METHOD InetRecvLine( SocketCon, nRet, size ) CLASS tIPClient + LOCAL cRet + + IF ::lTLS +#if defined( HAVE_OPENSSL ) + nRet := hb_SSL_read_line( ::ssl, @cRet, size, ::nConnTimeout ) +#if defined( _SSL_DEBUG_TEMP ) + ? "HB_SSL_READ_LINE()", cRet +#endif + IF nRet == 0 .OR. Empty( cRet ) + cRet := NIL + ENDIF + ::nSSLError := iif( nRet < 0, nRet, 0 ) +#else + cRet := "" + nRet := 0 +#endif + ELSE + cRet := hb_inetRecvLine( SocketCon, @nRet, size ) + ENDIF IF ::lTrace ::Log( SocketCon, "", size, cRet ) @@ -538,17 +657,45 @@ METHOD InetRecvLine( SocketCon, nLen, size ) CLASS tIPClient RETURN cRet -METHOD InetRecvAll( SocketCon, cStr1, len ) CLASS tIPClient - LOCAL nRet := hb_inetRecvAll( SocketCon, @cStr1, len ) +METHOD InetRecvAll( SocketCon, cRet, size ) CLASS tIPClient + LOCAL nRet + + IF ::lTLS +#if defined( HAVE_OPENSSL ) + nRet := hb_SSL_read_all( ::ssl, @cRet, size, ::nConnTimeout ) +#if defined( _SSL_DEBUG_TEMP ) + ? "HB_SSL_READ_ALL()", cRet +#endif + IF nRet == 0 .OR. Empty( cRet ) + cRet := NIL + ENDIF + ::nSSLError := iif( nRet < 0, nRet, 0 ) +#else + cRet := "" + nRet := 0 +#endif + ELSE + nRet := hb_inetRecvAll( SocketCon, @cRet, size ) + ENDIF IF ::lTrace - ::Log( SocketCon, "", len, iif( nRet >= 0, cStr1, nRet ) ) + ::Log( SocketCon, "", size, iif( nRet >= 0, cRet, nRet ) ) ENDIF RETURN nRet METHOD InetErrorCode( SocketCon ) CLASS tIPClient - LOCAL nRet := hb_inetErrorCode( SocketCon ) + LOCAL nRet + + IF ::lTLS +#if defined( HAVE_OPENSSL ) + nRet := iif( ::nSSLError == 0, 0, SSL_get_error( ::ssl, ::nSSLError ) ) +#else + nRet := 0 +#endif + ELSE + nRet := hb_inetErrorCode( SocketCon ) + ENDIF ::nLastError := nRet @@ -564,14 +711,22 @@ METHOD InetErrorDesc( SocketCon ) CLASS tIPClient DEFAULT SocketCon TO ::SocketCon IF ! Empty( SocketCon ) - cMsg := hb_inetErrorDesc( SocketCon ) + IF ::lTLS +#if defined( HAVE_OPENSSL ) + IF ::nSSLError != 0 + cMsg := ERR_error_string( SSL_get_error( ::ssl, ::nSSLError ) ) + ENDIF +#endif + ELSE + cMsg := hb_inetErrorDesc( SocketCon ) + ENDIF ENDIF RETURN cMsg /* BROKEN, should test number of parameters and act accordingly, see doc\inet.txt */ METHOD InetConnect( cServer, nPort, SocketCon ) CLASS tIPClient - +LOCAL tmp hb_inetConnect( cServer, nPort, SocketCon ) IF ! Empty( ::nDefaultSndBuffSize ) @@ -582,6 +737,15 @@ METHOD InetConnect( cServer, nPort, SocketCon ) CLASS tIPClient ::InetRcvBufSize( SocketCon, ::nDefaultRcvBuffSize ) ENDIF +#if defined( HAVE_OPENSSL ) + IF ::lTLS + SSL_set_mode( ::ssl, HB_SSL_MODE_AUTO_RETRY ) + SSL_set_fd( ::ssl, hb_inetFD( SocketCon ) ) + SSL_connect( ::ssl ) + /* TODO: Add error handling */ + ENDIF +#endif + IF ::lTrace ::Log( cServer, nPort, SocketCon ) ENDIF diff --git a/harbour/contrib/hbtip/sendmail.prg b/harbour/contrib/hbtip/sendmail.prg index 9a0d42c780..a170a497db 100644 --- a/harbour/contrib/hbtip/sendmail.prg +++ b/harbour/contrib/hbtip/sendmail.prg @@ -54,7 +54,7 @@ #translate ( LIKE ) => ( hb_regexLike( (), () ) ) -FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aFiles, cUser, cPass, cPopServer, nPriority, lRead, lTrace, lPopAuth, lNoAuth, nTimeOut, cReplyTo ) +FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aFiles, cUser, cPass, cPopServer, nPriority, lRead, lTrace, lPopAuth, lNoAuth, nTimeOut, cReplyTo, lTLS, cSMTPPass ) /* cServer -> Required. IP or domain name of the mail server nPort -> Optional. Port used my email server @@ -127,6 +127,12 @@ FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aF IF ! ISCHARACTER( cReplyTo ) cReplyTo := "" ENDIF + IF ! ISLOGICAL( lTLS ) + lTLS := .F. + ENDIF + IF ! ISCHARACTER( cSMTPPass ) + cSMTPPass := cPass + ENDIF cUser := StrTran( cUser, "@", "&at;" ) @@ -207,7 +213,7 @@ FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aF ENDIF BEGIN SEQUENCE - oUrl := tUrl():New( "smtp://" + cUser + "@" + cServer + "/" + cTo ) + oUrl := tUrl():New( iif( lTLS, "smtps://", "smtp://" ) + cUser + iif( Empty( cSMTPPass ), "", ":" + cSMTPPass ) + "@" + cServer + "/" + cTo ) RECOVER lReturn := .F. END SEQUENCE @@ -278,19 +284,19 @@ FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aF ENDDO IF lAuthLogin - IF ! oInMail:Auth( cUser, cPass ) + IF ! oInMail:Auth( cUser, cSMTPPass ) lConnect := .F. ELSE - lConnectPlain := .T. + lConnectPlain := .T. ENDIF ENDIF IF lAuthPlain .AND. ! lConnect - IF !oInMail:AuthPlain( cUser, cPass ) + IF ! oInMail:AuthPlain( cUser, cSMTPPass ) lConnect := .F. ENDIF ELSE - IF !lConnectPlain + IF ! lConnectPlain oInmail:Getok() lConnect := .F. ENDIF @@ -309,7 +315,7 @@ FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aF ENDIF BEGIN SEQUENCE - oInmail := tIPClientsmtp():New( oUrl, lTrace ) + oInmail := tIPClientSMTP():New( oUrl, lTrace ) RECOVER lReturn := .F. END SEQUENCE @@ -332,14 +338,14 @@ FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aF oInMail:oUrl:cUserid := cFrom - oMail:hHeaders[ "To" ] := cTo + oMail:hHeaders[ "To" ] := cTo oMail:hHeaders[ "Subject" ] := cSubject FOR EACH aThisFile IN aFiles IF ISCHARACTER( aThisFile ) cFile := aThisFile - cData := Memoread( cFile ) + Chr( 13 ) + Chr( 10 ) + cData := MemoRead( cFile ) + Chr( 13 ) + Chr( 10 ) ELSEIF ISARRAY( aThisFile ) .AND. Len( aThisFile ) >= 2 cFile := aThisFile[ 1 ] cData := aThisFile[ 2 ] + Chr( 13 ) + Chr( 10 ) diff --git a/harbour/contrib/hbtip/smtpcln.prg b/harbour/contrib/hbtip/smtpcln.prg index 4685df95df..ca443530e4 100644 --- a/harbour/contrib/hbtip/smtpcln.prg +++ b/harbour/contrib/hbtip/smtpcln.prg @@ -55,6 +55,9 @@ */ #include "hbclass.ch" + +#include "common.ch" + #include "tip.ch" CREATE CLASS tIPClientSMTP FROM tIPClient @@ -92,7 +95,7 @@ METHOD New( oUrl, lTrace, oCredentials ) CLASS tIPClientSMTP ::nConnTimeout := 5000 ::nAccessMode := TIP_WO // a write only - IF ::ltrace + IF ::lTrace IF ! hb_FileExists( "sendmail.log" ) ::nHandle := FCreate( "sendmail.log" ) ELSE @@ -106,7 +109,7 @@ METHOD New( oUrl, lTrace, oCredentials ) CLASS tIPClientSMTP RETURN Self -METHOD Open( cUrl ) CLASS tIPClientSMTP +METHOD Open( cUrl, lTLS ) CLASS tIPClientSMTP IF ! ::super:Open( cUrl ) RETURN .F. @@ -114,11 +117,20 @@ METHOD Open( cUrl ) CLASS tIPClientSMTP hb_inetTimeout( ::SocketCon, ::nConnTimeout ) + DEFAULT lTLS TO .F. + + IF lTLS + ::InetSendall( ::SocketCon, "STARTTLS" + ::cCRLF ) + IF ::GetOk() + ::EnableTLS( .T. ) + ENDIF + ENDIF + ::InetSendall( ::SocketCon, "HELO " + iif( Empty( ::oUrl:cUserid ), "tipClientSMTP", ::oUrl:cUserid ) + ::cCRLF ) RETURN ::GetOk() -METHOD OpenSecure( cUrl ) CLASS tIPClientSMTP +METHOD OpenSecure( cUrl, lTLS ) CLASS tIPClientSMTP IF ! ::super:Open( cUrl ) RETURN .F. @@ -126,6 +138,15 @@ METHOD OpenSecure( cUrl ) CLASS tIPClientSMTP hb_inetTimeout( ::SocketCon, ::nConnTimeout ) + DEFAULT lTLS TO .F. + + IF lTLS + ::InetSendall( ::SocketCon, "STARTTLS" + ::cCRLF ) + IF ::GetOk() + ::EnableTLS( .T. ) + ENDIF + ENDIF + ::InetSendall( ::SocketCon, "EHLO " + iif( Empty( ::oUrl:cUserid ), "tipClientSMTP", ::oUrl:cUserid ) + ::cCRLF ) RETURN ::GetOk() @@ -133,7 +154,7 @@ METHOD OpenSecure( cUrl ) CLASS tIPClientSMTP METHOD GetOk() CLASS tIPClientSMTP ::cReply := ::InetRecvLine( ::SocketCon,, 512 ) - IF ::InetErrorCode( ::SocketCon ) != 0 .OR. Left( ::cReply, 1 ) == "5" + IF ::InetErrorCode( ::SocketCon ) != 0 .OR. ! ISCHARACTER( ::cReply ) .OR. Left( ::cReply, 1 ) == "5" RETURN .F. ENDIF @@ -141,7 +162,7 @@ METHOD GetOk() CLASS tIPClientSMTP METHOD Close() CLASS tIPClientSMTP hb_inetTimeOut( ::SocketCon, ::nConnTimeout ) - IF ::ltrace + IF ::lTrace FClose( ::nHandle ) ENDIF ::Quit() @@ -250,7 +271,7 @@ METHOD SendMail( oTIpMail ) CLASS TIpClientSmtp ENDIF IF ! ::isAuth - ::Auth( ::oUrl:cUserId, ::oUrl:cPassWord ) + ::Auth( ::oUrl:cUserId, ::oUrl:cPassword ) IF ! ::isAuth RETURN .F. ENDIF diff --git a/harbour/contrib/hbtip/utils.c b/harbour/contrib/hbtip/utils.c index 839602445e..bf037ed77f 100644 --- a/harbour/contrib/hbtip/utils.c +++ b/harbour/contrib/hbtip/utils.c @@ -97,8 +97,6 @@ HB_FUNC( TIP_TIMESTAMP ) if( GetTimeZoneInformation( &tzInfo ) == TIME_ZONE_ID_INVALID ) tzInfo.Bias = 0; - else - tzInfo.Bias -= tzInfo.Bias; if( ! pDate ) {