Mail data is stored in the SMTP type...
Functions for mail date and base64 included...
Code:
'======================================================================================== ' Email functions '---------------------------------------------------------------------------------------- #COMPILE EXE "testmail.exe" #DIM ALL #INCLUDE "win32api.inc" Type SMTPType Server As Asciiz * 64 'Name of SMTP mail server From As Asciiz * 64 'Mail address sender IPAddress As Asciiz * 64 'IPv4 Address sender DisplayName As Asciiz * 64 'Name to be displayed at from To As Asciiz * 64 'Mail address receiver Cc As Asciiz * 256 'Carbon copy sent Caption As Asciiz * 64 'Title of mailmessage Bodytext As Asciiz * 64 'Body of mailmessage Files As Asciiz * 256 'Attached files if any Username As Asciiz * 64 'SMTP login username Password As Asciiz * 64 'SMTP login password Cmd As Asciiz * 256 'Last sent command (error tracking) Resp As Asciiz * 256 'Last received reply (error tracking) Date As Asciiz * 64 'Last send date End Type Global SMTP As SMTPTYPE '======================================================================================== ' Base64Encode(): - String to Base64 '======================================================================================== FUNCTION Base64Encode(pInStr AS STRING) AS STRING LOCAL lBase64, lOutStr, lPad AS STRING, lBlock, lInBlocks As Dword Local lByte1, lByte2, lByte3 As Byte, InPtr, OutPtr, BasePtr As Byte Ptr '-------------------------------------------------------------------------------------- lBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" lPad = String$(2- (Len(pInstr) -1) Mod 3, "=") 'Calc paddinglength lInBlocks = (Len(pInStr) +2) \3 'Blockcount rounded If lInBlocks * 3 > Len(pInStr) Then 'Ir input too short pInStr = LSet$(pInStr, lInBlocks * 3 Using $Nul) 'add zeroes tp fill End If ' lOutStr = Space$(lInBlocks * 4) 'Prepare out buffer InPtr = StrPtr(pInStr) 'Setup string ptrs OutPtr = StrPtr(lOutStr) ' BasePtr = StrPtr(lBase64) ' For lBlock = 1 To lInBlocks lByte1 = @InPtr : Incr InPtr lByte2 = @InPtr : Incr InPtr lByte3 = @InPtr : Incr InPtr @OutPtr = @BasePtr[lByte1 \ 4] : Incr OutPtr @OutPtr = @BasePtr[(lByte1 And &h03) * 16 + lByte2 \ 16] : Incr OutPtr @OutPtr = @BasePtr[(lByte2 And &h0F) * 4 + lByte3 \ 64] : Incr OutPtr @OutPtr = @BasePtr[lByte3 And &h3F] : Incr OutPtr Next RSet Abs lOutStr = lPad Function = lOutStr END FUNCTION '======================================================================================== ' Base64Decode(): - Base64 to string '======================================================================================== FUNCTION Base64Decode(pInStr AS STRING) AS STRING LOCAL lBase64, lOutstr AS STRING, lInBlocks, lBlock, lInMod, lCut As Dword Local lByte1, lByte2, lByte3, lByte4 As Byte, InPtr, OutPtr As Byte Ptr '-------------------------------------------------------------------------------------- lBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" lInMod = Len(pInstr) Mod 4 'Broken blocks? If lInMod Then ' pInstr = pInstr+String$(4-lInMod,Chr$(&h3D)) 'Yes, add padding End If lInBlocks = Len(pInStr) \ 4 ' lCut = Tally(pInStr, Chr$(&h3D)) '/ 3) * 4 ' lOutStr = Space$(lInBlocks * 3 + lInMod) InPtr = StrPtr(pInStr) OutPtr = StrPtr(lOutStr) For lBlock = 1 To lInBlocks lByte1 = InStr(lBase64, Chr$(@inPtr)) -1 : Incr InPtr lByte2 = InStr(lBase64, Chr$(@inPtr)) -1 : Incr InPtr lByte3 = InStr(lBase64, Chr$(@inPtr)) -1 : Incr InPtr lByte4 = InStr(lBase64, Chr$(@inPtr)) -1 : Incr InPtr @OutPtr = lByte1 * 4 + lByte2 \ 16 : Incr OutPtr @OutPtr = lByte2 * 16 + lByte3 \ 4 : Incr OutPtr @OutPtr = lByte3 * 64 + lByte4 :Incr OutPtr Next Function = Left$(lOutStr, lInBlocks * 3 - lCut) END FUNCTION '======================================================================================== ' MailDate() - Get date stamp '======================================================================================== Function MailDate () As String Local lszFormat As Asciiz * 40, lszStr As Asciiz * 40, lsRet As String Local lST As SYSTEMTIME, lsOffset As String, tzi As TIME_ZONE_INFORMATION '-------------------------------------------------------------------------------------- GetLocalTime lST 'Get time and format it to the local settings lszFormat = "ddd',' dd MMM yyyy" GetDateFormat %LOCALE_USER_DEFAULT, 0, lST, lszFormat, lszStr, SizeOf(lszStr) lsRet = lszStr lszFormat = "HH':'mm':'ss" GetTimeFormat %LOCALE_USER_DEFAULT, 0, lST, lszFormat, lszStr, SizeOf(lszStr) Select Case GetTimeZoneInformation(tzi) 'Create string needed in mail header Case %TIME_ZONE_ID_DAYLIGHT lsOffset = IIf$((tzi.bias + tzi.DaylightBias) <= 0, "+", "-") _ + Format$(Abs(tzi.bias + tzi.DaylightBias) \ 60, "00") _ + Format$(Abs(tzi.bias + tzi.DaylightBias) Mod 60, "00") Case %TIME_ZONE_ID_STANDARD lsOffset = IIf$((tzi.bias + tzi.StandardBias) <= 0, "+", "-") _ + Format$(Abs(tzi.bias + tzi.StandardBias) \ 60, "00") _ + Format$(Abs(tzi.bias + tzi.StandardBias) Mod 60, "00") Case Else lsOffset = "-0000" End Select Function = lsRet + " " + lszStr + " " + lsOffset End Function '======================================================================================== ' Send_Email() - Send an email through SMTP '======================================================================================== Function Send_Email (ByRef SMTP As SMTPTYPE) As Long Local lhTCP, lCnt, lCnt2 As Long, lhFile As Dword Local lsHost, lsBound, lFName, lBuffIn, lBuffOut As String '-------------------------------------------------------------------------------------- lsBound = "Boundary." +Remove$(GuidTxt$(Guid$),Any "{-}") 'Unique boundary- Function = 0 'marker lhTCP = FreeFile 'Open connection to Tcp Open Port 587 At SMTP.Server As lhTCP TimeOut 2000 'the smps server If Err Then Function = ErrClear : Exit Function 'Error opening,exit Tcp Recv lhTcp, SizeOf(SMTP.Resp), SMTP.Resp 'Get result If Instr(SMTP.Resp, "220") = 0 Then Exit Function 'Server not ready '---------------------------------------------------------------------------- SMTP.Cmd = "EHLO [" & SMTP.IPAddress & "]" ' Tcp Print lhTcp, SMTP.Cmd ' Tcp Recv lhTcp, SizeOf(SMTP.Resp), SMTP.Resp '250: OK/capability If Instr(SMTP.Resp, "250") = 0 Then Exit Function 'Exit '---------------------------------------------------------------------------- If Instr(Ucase$(SMTP.Resp),"AUTH") And Instr(Ucase$(SMTP.Resp),"LOGIN") Then SMTP.Cmd = "AUTH LOGIN" : Tcp Print lhTcp, SMTP.Cmd 'Login required? Tcp Recv lhTcp, SizeOf(SMTP.Resp), SMTP.Resp If Instr(SMTP.Resp, "334") Then '334: Auth method SMTP.Cmd = Base64encode(ByCopy SMTP.Username) 'accepted. Send TCP Print lhTcp, SMTP.Cmd 'username (base64) Tcp Recv lhTcp, SizeOf(SMTP.Resp), SMTP.Resp ' If Instr(SMTP.Resp, "334") Then '334: Auth method SMTP.Cmd = Base64encode(ByCopy SMTP.Password) 'accepted. Send TCP Print lhTcp, SMTP.Cmd 'password (base64) Tcp Recv lhTcp, SizeOf(SMTP.Resp), SMTP.Resp ' End If ' End If ' End If ' '---------------------------------------------------------------------------- SMTP.Cmd = "MAIL FROM:<" & SMTP.From & ">" 'Mail from: Tcp Print lhTCP, SMTP.Cmd ' Tcp Recv lhTCP, SizeOf(SMTP.Resp), SMTP.Resp ' If Instr(SMTP.Resp, "250") = 0 Then Exit Function ' '---------------------------------------------------------------------------- SMTP.Cmd = "RCPT TO:<" & SMTP.To & ">" 'Send mail to Tcp Print lhTCP, SMTP.Cmd ' Tcp Recv lhTCP, SizeOf(SMTP.Resp), SMTP.Resp ' If Instr(SMTP.Resp, "250") = 0 Then Exit Function 'Exit '---------------------------------------------------------------------------- If SMTP.Cc <> "" Then 'Send mail to cc: For lCnt = 1 To ParseCount (SMTP.Cc) '(can be multiple SMTP.Cmd = "RCPT TO:<" & Trim$(Parse$(SMTP.Cc, lCnt)) & ">" Tcp Print lhTCP, SMTP.Cmd Tcp Recv lhTCP, SizeOf(SMTP.Resp), SMTP.Resp If Instr(SMTP.Resp, "250") = 0 Then Exit Function 'Exit Next End If '---------------------------------------------------------------------------- SMTP.Cmd = "DATA" 'Start datatransfer Tcp Print lhTCP, SMTP.Cmd Tcp Recv lhTCP, SizeOf(SMTP.Resp), SMTP.Resp '354: response If Instr(SMTP.Resp, "354") = 0 Then Exit Function '---------------------------------------------------------------------------- SMTP.Date = MailDate() 'Send date info SMTP.Cmd = "Date: " & SMTP.Date Tcp Print lhTCP, SMTP.Cmd If SMTP.Displayname = "" Then SMTP.Cmd = "From: " & SMTP.From Tcp Print lhTCP, SMTP.Cmd Else If SMTP.From <> "" Then SMTP.Cmd = "From: " & SMTP.Displayname & "<" & SMTP.From & ">" Tcp Print lhTCP, SMTP.Cmd Else SMTP.Cmd = "From: " & SMTP.Displayname Tcp Print lhTCP, SMTP.Cmd End If End If '---------------------------------------------------------------------------- SMTP.Cmd = "To: " & SMTP.To : Tcp Print lhTCP, SMTP.Cmd If SMTP.Cc <> "" Then SMTP.Cmd = "Cc: " & SMTP.Cc : Tcp Print lhTCP, SMTP.Cmd End If '---------------------------------------------------------------------------- Tcp Print lhTCP, "Subject: " + SMTP.Caption Tcp Print lhTCP, "X-Mailer: Arcovox MIME/Base64 E-mailer 1.0" Tcp Print lhTCP, "MIME-Version: 1.0" SMTP.Cmd = "Content-Type: multipart/mixed; boundary=" + $Dq + lsBound + $Dq Tcp Print lhTCP, SMTP.Cmd Tcp Print lhTCP, "" Tcp Print lhTCP, "--" & lsBound SMTP.Cmd = "Content-Type: text/plain; charset=" + $Dq + "us-ascii" + $Dq Tcp Print lhTCP, SMTP.Cmd Tcp Print lhTCP, "Content-Transfer-Encoding: 7bit" Tcp Print lhTCP, "" '---------------------------------------------------------------------------- For lCnt = 1 To ParseCount(SMTP.BodyText, $Cr) 'Write message Tcp Print lhTcp, Parse$(SMTP.BodyText, lCnt) Next '---------------------------------------------------------------------------- If (SMTP.Files <> "") Then 'Are there files? For lCnt = 1 To ParseCount(SMTP.Files) 'Yes, get 1st name lFName = PathName$(NAMEX, Parse$(SMTP.Files,lCnt)) 'and strip it If IsFile (lFName) Then 'Does file exist? lhFile = FreeFile Open lFName For Binary Access Read Lock Shared As #lhFile Get$ #lhFile, Lof(lhFile), lBuffIn Close #lhFile If Len(lBuffIn) Then lBuffOut = Base64Encode(lBuffIn) Tcp Print lhTCP, "--" & lsBound 'Boundary separator Tcp Print lhTCP, "Content-Type: application/octet-stream; name=" & _ $Dq & lFName & $Dq Tcp Print lhTCP, "Content-Transfer-Encoding: base64" Tcp Print lhTCP, "" For lCnt2 = 1 To Len(lBuffOut) Step 76 'Write date in 76 If Len(lBuffOut) - lCnt2 >= 76 Then 'char lines.If less Tcp Print lhTCP, Mid$(lBuffOut, lCnt2, 76) 'then add a "=" Else Tcp Print lhTCP, Mid$(lBuffOut, lCnt2) & "=" End If Next End If End If Next End If '---------------------------------------------------------------------------- Tcp Print lhTCP, "--" & lsBound & "--" 'Close mail Tcp Print lhTCP, "." 'Line with only "." Tcp Recv lhTCP, SizeOf(SMTP.Resp), SMTP.Resp Tcp Print lhTCP, "QUIT" Tcp Recv lhTCP, SizeOf(SMTP.Resp), SMTP.Resp Tcp Close lhTCP 'Close socket Function = 1 End Function '======================================================================================== ' Main '======================================================================================== FUNCTION PBMAIN () AS LONG SMTP.Server = "smtp.provider.com" 'Name of SMTP mail server SMTP.From = "[email protected]" 'Mail address sender SMTP.IPAddress = "192.168.2.2" 'IPv4 Address sender SMTP.DisplayName = "My test email" 'Name to be displayed at from SMTP.To = "[email protected]" 'Mail address receiver SMTP.Caption = "Test with attachment" 'Title of mailmessage SMTP.Bodytext = "An attachment test..."'Body of mailmessage SMTP.Files = "testmail.bas" 'Attached files if any Send_Email(SMTP) END FUNCTION '========================================================================================
Leave a comment: