2009-10-16 13:54 UTC+0200 Viktor Szakats (harbour.01 syenar.hu)

* contrib/hbtip/sendmail.prg
  * contrib/hbtip/mail.prg
    ! Fixed encoding of subject, from, to, cc, bcc address lists, in some 
      places it was missing (cc, bcc, from), in some other places multiple 
      address support was missing (to, cc, bcc) from recent addition of 
      encoding support.
    + Added/Fixed support for human readable name component in e-mail addresses.
    + Using TIPMAIL:SETHEADER() in HB_SENDMAIL() to set above header components.
    ! Several minor cleanups in TIPMAIL:SETHEADER():
      - handling of empty values
      - using space instead of tab when passing multiple addresses in headers.
        Haven't checked the standard, but I used to see space there.
      - Minor formatting, optimizations.
    ! Minor tweaks to space and _ char in Q encoding. Now 
      they are both simply encoded.
    ; Overall probably a rewrite would be the best in case of hbtip mailing, 
      and maybe not just for mailing. Code is full of strange tweaks, 
      redundancy and the class layout/communication is rather strange, f.e. 
      SMTP protocol data is passed via TURL:cFile variable from HB_SENDMAIL 
      to SMTP client class. Also charset support is just an aftertought so 
      user code needs close syncronisation with HB_SENDMAIL() and replicating 
      the same parameter parsing logic on multiple layers of code.
      And I've probably just scratched the surface, f.e. I didn't test 
      attachments of HTML mails and probably several other options as well.
    ; Anyway please test.
This commit is contained in:
Viktor Szakats
2009-10-16 11:59:18 +00:00
parent 2025e58738
commit 825de608df
3 changed files with 123 additions and 86 deletions

View File

@@ -17,6 +17,33 @@
past entries belonging to author(s): Viktor Szakats.
*/
2009-10-16 13:54 UTC+0200 Viktor Szakats (harbour.01 syenar.hu)
* contrib/hbtip/sendmail.prg
* contrib/hbtip/mail.prg
! Fixed encoding of subject, from, to, cc, bcc address lists, in some
places it was missing (cc, bcc, from), in some other places multiple
address support was missing (to, cc, bcc) from recent addition of
encoding support.
+ Added/Fixed support for human readable name component in e-mail addresses.
+ Using TIPMAIL:SETHEADER() in HB_SENDMAIL() to set above header components.
! Several minor cleanups in TIPMAIL:SETHEADER():
- handling of empty values
- using space instead of tab when passing multiple addresses in headers.
Haven't checked the standard, but I used to see space there.
- Minor formatting, optimizations.
! Minor tweaks to space and _ char in Q encoding. Now
they are both simply encoded.
; Overall probably a rewrite would be the best in case of hbtip mailing,
and maybe not just for mailing. Code is full of strange tweaks,
redundancy and the class layout/communication is rather strange, f.e.
SMTP protocol data is passed via TURL:cFile variable from HB_SENDMAIL
to SMTP client class. Also charset support is just an aftertought so
user code needs close syncronisation with HB_SENDMAIL() and replicating
the same parameter parsing logic on multiple layers of code.
And I've probably just scratched the surface, f.e. I didn't test
attachments of HTML mails and probably several other options as well.
; Anyway please test.
2009-10-15 18:43 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com)
* contrib/hbqt/generator/hbqtgen.prg
! Changes to implemented GC pointers.

View File

@@ -313,13 +313,13 @@ METHOD ToString() CLASS TipMail
cRet += "Date: " + ::hHeaders[ "Date" ] + e"\r\n"
ENDIF
IF "From" $ ::hHeaders
cRet += "From: " + LTrim( WordEncodeQ( tip_GetNameEMail( ::hHeaders[ "From" ] ), ::cCharset ) + " <" + tip_GetRawEMail( ::hHeaders[ "From" ] ) + ">" ) + e"\r\n"
cRet += "From: " + ::hHeaders[ "From" ] + e"\r\n"
ENDIF
IF "To" $ ::hHeaders
cRet += "To: " + LTrim( WordEncodeQ( tip_GetNameEMail( ::hHeaders[ "To" ] ), ::cCharset ) + " <" + tip_GetRawEMail( ::hHeaders[ "To" ] ) + ">" ) + e"\r\n"
cRet += "To: " + ::hHeaders[ "To" ] + e"\r\n"
ENDIF
IF "Subject" $ ::hHeaders
cRet += "Subject: " + WordEncodeQ( ::hHeaders[ "Subject" ], ::cCharset ) + e"\r\n"
cRet += "Subject: " + ::hHeaders[ "Subject" ] + e"\r\n"
ENDIF
IF Len( ::aAttachments ) > 0
cRet += "Mime-Version:" + ::hHeaders[ "Mime-Version" ] + e"\r\n"
@@ -513,8 +513,9 @@ METHOD MakeBoundary() CLASS TipMail
RETURN cBound
METHOD setHeader( cSubject, cFrom, cTo, cCC, cBCC ) CLASS TipMail
METHOD setHeader( cSubject, cFrom, xTo, xCC, xBCC ) CLASS TipMail
LOCAL aTo, aCC, aBCC, i, imax
LOCAL cTo, cCC, cBCC
IF ! ISCHARACTER( cSubject )
cSubject := ""
@@ -524,66 +525,79 @@ METHOD setHeader( cSubject, cFrom, cTo, cCC, cBCC ) CLASS TipMail
RETURN .F.
ENDIF
IF ISCHARACTER( cTo )
aTo := { cTo }
ELSEIF ISARRAY( cTo )
aTo := cTo
IF ISCHARACTER( xTo )
aTo := { xTo }
ELSEIF ISARRAY( xTo )
aTo := xTo
ENDIF
IF ISCHARACTER( cCC )
aCC := { cCC }
ELSEIF ISARRAY( cCC )
aCC := cCC
ENDIF
IF ISCHARACTER( cBCC )
aBCC := { cBCC }
ELSEIF ISARRAY( cBCC )
aBCC := cBCC
ENDIF
IF aTO == NIL
IF Empty( aTO )
RETURN .F.
ENDIF
IF ! ::setFieldPart( "Subject", cSubject )
IF ISCHARACTER( xCC )
aCC := { xCC }
ELSEIF ISARRAY( xCC )
aCC := xCC
ENDIF
IF ISCHARACTER( xBCC )
aBCC := { xBCC }
ELSEIF ISARRAY( xBCC )
aBCC := xBCC
ENDIF
IF ! ::setFieldPart( "Subject", WordEncodeQ( cSubject, ::cCharset ) )
RETURN .F.
ENDIF
IF ! ::setFieldPart( "From", LTrim( WordEncodeQ( tip_GetNameEMail( AllTrim( cFrom ) ), ::cCharset ) + " <" + tip_GetRawEMail( AllTrim( cFrom ) ) + ">" ) )
RETURN .F.
ENDIF
IF ! ::setFieldPart( "From", cFrom )
RETURN .F.
ENDIF
cTo := aTO[ 1 ]
cTo := ""
imax := Len( aTO )
FOR i := 2 TO imax
cTo += "," + hb_inetCrlf() + Chr( 9 ) + aTo[ i ]
FOR i := 1 TO imax
IF i > 1
cTo += "," + hb_inetCrlf() + " "
ENDIF
cTo += LTrim( WordEncodeQ( tip_GetNameEMail( AllTrim( aTo[ i ] ) ), ::cCharset ) + " <" + tip_GetRawEMail( AllTrim( aTo[ i ] ) ) + ">" )
NEXT
IF Empty( cTo )
RETURN .F.
ENDIF
IF ! ::setFieldPart( "To", cTo )
RETURN .F.
ENDIF
IF aCC != NIL
cCC := aCC[ 1 ]
IF ! Empty( aCC )
cCC := ""
imax := Len( aCC )
FOR i := 2 TO imax
cCC += "," + hb_inetCrlf() + Chr( 9 ) + aCC[ i ]
IF i > 1
cCC += "," + hb_inetCrlf() + " "
ENDIF
cCC += LTrim( WordEncodeQ( tip_GetNameEMail( AllTrim( aCC[ i ] ) ), ::cCharset ) + " <" + tip_GetRawEMail( AllTrim( aCC[ i ] ) ) + ">" )
NEXT
IF ! ::setFieldPart( "Cc", cCC )
IF ! Empty( cCC ) .AND. ! ::setFieldPart( "Cc", cCC )
RETURN .F.
ENDIF
ENDIF
IF aBCC != NIL
cBCC := aBCC[ 1 ]
IF ! Empty( aBCC )
cBCC := ""
imax := Len( aBCC )
FOR i := 2 TO imax
cBCC += "," + hb_inetCrlf() + Chr( 9 ) + aBCC[ i ]
IF i > 1
cBCC += "," + hb_inetCrlf() + " "
ENDIF
cBCC += LTrim( WordEncodeQ( tip_GetNameEMail( AllTrim( aBCC[ i ] ) ), ::cCharset ) + " <" + tip_GetRawEMail( AllTrim( aBCC[ i ] ) ) + ">" )
NEXT
IF ! ::setFieldPart( "Bcc", cBCC )
IF ! Empty( cBCC ) .AND. ! ::setFieldPart( "Bcc", cBCC )
RETURN .F.
ENDIF
ENDIF
@@ -678,11 +692,8 @@ STATIC FUNCTION WordEncodeQ( cData, cCharset )
cString := "=?" + cCharset + "?" + "Q" + "?"
FOR EACH c IN cData
IF c == " "
cString += "_"
nLineLen += 1
ELSEIF Asc( c ) > 126 .OR. ;
c $ '=?!"#$@[\]^`{|}~' .OR. ;
IF Asc( c ) > 126 .OR. ;
c $ '=?!"#$@[\]^`{|}~_' .OR. ;
Asc( c ) <= 32
cString += "=" + hb_NumToHex( Asc( c ), 2 )
nLineLen += 3

View File

@@ -55,14 +55,14 @@
#translate ( <exp1> LIKE <exp2> ) => ( hb_regexLike( (<exp2>), (<exp1>) ) )
FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aFiles, cUser, cPass, cPopServer, nPriority, lRead, bTrace, lPopAuth, lNoAuth, nTimeOut, cReplyTo, lTLS, cSMTPPass, cCharset, cEncoding )
FUNCTION hb_SendMail( cServer, nPort, cFrom, xTo, xCC, xBCC, cBody, cSubject, aFiles, cUser, cPass, cPopServer, nPriority, lRead, bTrace, lPopAuth, lNoAuth, nTimeOut, cReplyTo, lTLS, cSMTPPass, cCharset, cEncoding )
/*
cServer -> Required. IP or domain name of the mail server
nPort -> Optional. Port used my email server
cFrom -> Required. Email address of the sender
aTo -> Required. Character string or array of email addresses to send the email to
aCC -> Optional. Character string or array of email adresses for CC (Carbon Copy)
aBCC -> Optional. Character string or array of email adresses for BCC (Blind Carbon Copy)
xTo -> Required. Character string or array of email addresses to send the email to
xCC -> Optional. Character string or array of email adresses for CC (Carbon Copy)
xBCC -> Optional. Character string or array of email adresses for BCC (Blind Carbon Copy)
cBody -> Optional. The body message of the email as text, or the filename of the HTML message to send.
cSubject -> Optional. Subject of the sending email
aFiles -> Optional. Array of attachments to the email to send
@@ -79,8 +79,18 @@ FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aF
cReplyTo -> Optional.
*/
LOCAL oInMail, cBodyTemp, oUrl, oMail, oAttach, aThisFile, cMimeText,;
cFile, cFname, cFext, cData, oUrl1
LOCAL oInMail
LOCAL cBodyTemp
LOCAL oUrl
LOCAL oMail
LOCAL oAttach
LOCAL aThisFile
LOCAL cMimeText
LOCAL cFile
LOCAL cFname
LOCAL cFext
LOCAL cData
LOCAL oUrl1
LOCAL cTmp := ""
LOCAL cTo := ""
@@ -154,53 +164,53 @@ FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aF
ENDIF
// cTo
IF ISARRAY( aTo )
IF Len( aTo ) > 1
FOR EACH cTo IN aTo
IF ISARRAY( xTo )
IF Len( xTo ) > 1
FOR EACH cTo IN xTo
IF cTo:__enumIndex() != 1
IF ! Empty( cTo )
cTmp += cTo + ","
cTmp += tip_GetRawEMail( AllTrim( cTo ) ) + ","
ENDIF
ENDIF
NEXT
cTmp := SubStr( cTmp, 1, Len( cTmp ) - 1 )
ENDIF
cTo := aTo[ 1 ]
cTo := tip_GetRawEMail( AllTrim( xTo[ 1 ] ) )
IF Len( cTmp ) > 0
cTo += "," + cTmp
ENDIF
ELSEIF ISCHARACTER( aTo )
cTo := AllTrim( aTo )
ELSEIF ISCHARACTER( xTo )
cTo := tip_GetRawEMail( AllTrim( xTo ) )
ENDIF
// CC (Carbon Copy)
IF ISARRAY( aCC )
IF Len( aCC ) > 0
FOR EACH cTmp IN aCC
IF ISARRAY( xCC )
IF Len( xCC ) > 0
FOR EACH cTmp IN xCC
IF ! Empty( cTmp )
cCC += cTmp + ","
cCC += tip_GetRawEMail( AllTrim( cTmp ) ) + ","
ENDIF
NEXT
cCC := SubStr( cCC, 1, Len( cCC ) - 1 )
ENDIF
ELSEIF ISCHARACTER( aCC )
cCC := AllTrim( aCC )
ELSEIF ISCHARACTER( xCC )
cCC := tip_GetRawEMail( AllTrim( xCC ) )
ENDIF
// BCC (Blind Carbon Copy)
IF ISARRAY( aBCC )
IF Len( aBCC ) > 0
FOR EACH cTmp IN aBCC
IF ISARRAY( xBCC )
IF Len( xBCC ) > 0
FOR EACH cTmp IN xBCC
IF ! Empty( cTmp )
cBCC += cTmp + ","
cBCC += tip_GetRawEMail( AllTrim( cTmp ) ) + ","
ENDIF
NEXT
cBCC := SubStr( cBCC, 1, Len( cBCC ) - 1 )
ENDIF
ELSEIF ISCHARACTER( aBCC )
cBCC := AllTrim( aBCC )
ELSEIF ISCHARACTER( xBCC )
cBCC := tip_GetRawEMail( AllTrim( xBCC ) )
ENDIF
IF cPopServer != NIL .AND. lPopAuth
@@ -214,7 +224,6 @@ FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aF
RECOVER
lReturn := .F.
END SEQUENCE
ENDIF
IF ! lReturn
@@ -222,7 +231,7 @@ FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aF
ENDIF
BEGIN SEQUENCE
oUrl := tUrl():New( iif( lTLS, "smtps://", "smtp://" ) + cUser + iif( Empty( cSMTPPass ), "", ":" + cSMTPPass ) + "@" + cServer + "/" + cTo )
oUrl := tUrl():New( iif( lTLS, "smtps://", "smtp://" ) + cUser + iif( Empty( cSMTPPass ), "", ":" + cSMTPPass ) + "@" + cServer )
RECOVER
lReturn := .F.
END SEQUENCE
@@ -237,6 +246,12 @@ FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aF
oMail := tipMail():new()
oMail:SetEncoder( cEncoding )
oMail:SetCharset( cCharset )
oMail:SetHeader( cSubject, cFrom, xTo, xCC, xBCC )
oMail:hHeaders[ "Date" ] := tip_Timestamp()
IF ! Empty( cReplyTo )
oMail:hHeaders[ "Reply-to" ] := cReplyTo
ENDIF
IF ! Empty( aFiles )
oAttach := tipMail():new()
oAttach:SetEncoder( cEncoding )
@@ -266,19 +281,6 @@ FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aF
oUrl:cFile := cTo + iif( Empty( cCC ), "", "," + cCC ) + iif( Empty( cBCC ), "", "," + cBCC )
oMail:hHeaders[ "Date" ] := tip_Timestamp()
oMail:hHeaders[ "From" ] := cFrom
IF ! Empty( cReplyTo )
oMail:hHeaders[ "Reply-to" ] := cReplyTo
ENDIF
IF ! Empty( cCC )
oMail:hHeaders[ "Cc" ] := cCC
ENDIF
IF ! Empty( cBCC )
oMail:hHeaders[ "Bcc" ] := cBCC
ENDIF
BEGIN SEQUENCE
oInmail := tIPClientSMTP():New( oUrl, bTrace )
RECOVER
@@ -369,9 +371,6 @@ FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aF
oInMail:oUrl:cUserid := cFromRaw
oMail:hHeaders[ "To" ] := cTo
oMail:hHeaders[ "Subject" ] := cSubject
FOR EACH aThisFile IN aFiles
IF ISCHARACTER( aThisFile )
@@ -456,7 +455,7 @@ FUNCTION hb_SendMail( cServer, nPort, cFrom, aTo, aCC, aBCC, cBody, cSubject, aF
oMail:hHeaders[ "X-Priority" ] := Str( nPriority, 1 )
ENDIF
oInmail:Write( oMail:ToString() )
oInMail:Write( oMail:ToString() )
oInMail:Commit()
oInMail:Close()