'/***************************************************************************
' *                                  _   _ ____  _
' *  Project                     ___| | | |  _ \| |
' *                             / __| | | | |_) | |
' *                            | (__| |_| |  _ <| |___
' *                             \___|\___/|_| \_\_____|
' *
' * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
' *
' * This software is licensed as described in the file COPYING, which
' * you should have received as part of this distribution. The terms
' * are also available at http://curl.haxx.se/docs/copyright.html.
' *
' * You may opt to use, copy, modify, merge, publish, distribute and/or sell
' * copies of the Software, and permit persons to whom the Software is
' * furnished to do so, under the terms of the COPYING file.
' *
' * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
' * KIND, either express or implied.
' *
' ***************************************************************************/

#Include ONCE "windows.bi"
#include ONCE "curl.bi"
#include ONCE "crt.bi"

'------------------------------------------------------------
'/////////////////////Функции из window9/////////////////////
'------------------------------------------------------------

Function Read_File (ByVal FileName As String,ByVal PAR As Integer=FILE_ATTRIBUTE_NORMAL) As HANDLE Export
  Var hFile = CreateFile(FileName,GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,0, OPEN_EXISTING, par,0)
  Return hFile
End Function

Function Size_File(ByVal H As HANDLE) As Integer Export
  Return GetFileSize(H,0)
End Function

Function Read_DataS (ByVal H As HANDLE, ByVal Lenght As Integer) As Byte Ptr Export
  Dim As Byte ptr pMemory = CAllocate(Lenght+1)
  Dim SizeReadWrite As integer
  ReadFile(H ,pMemory,Lenght,Cast(LPDWORD,@SizeReadWrite),0)
  Return pMemory
End Function

Function Close_File (ByVal H As HANDLE) As Integer Export
  Return CloseHandle(H)
End Function

Function Encode64(ByRef bs64 As String) As String export
      Dim as Integer j,k=0
      Dim as Integer l=len(bs64)
      if l=0 then return ""
      dim as string arr64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" & _
                            "abcdefghijklmnopqrstuvwxyz" & _
                            "0123456789+/"
      Dim as string  t64

      t64 = String(((l+2)\3)*4,"=")
      For j = 0 To l - ((l Mod 3)+1) Step 3
        t64[k+0] = arr64[(bs64[j+0] shr 2)]
        t64[k+1] = arr64[(((bs64[j+0] and 3) shl 4) + (bs64[j+1] shr 4))]
        t64[k+2] = arr64[(((bs64[j+1] and &H0F) shl 2) + (bs64[j+2] shr 6))]
        t64[k+3] = arr64[(bs64[j+2] and &H3F)]
        k += 4
      Next
      If (l mod 3) = 2 Then
        t64[k+0] = arr64[(bs64[j+0] shr 2)]
        t64[k+1] = arr64[(((bs64[j+0] and 3) shl 4) + (bs64[j+1] shr 4))]
        t64[k+2] = arr64[(((bs64[j+1] and &H0F) shl 2) + (bs64[j+2] shr 6))]
        t64[k+3]=61
      ElseIf (l mod 3) = 1 Then
        t64[k+0] = arr64[(bs64[j+0] shr 2)]
        t64[k+1] = arr64[((((bs64[j+0] and 3) shl 4) + (bs64[j+1] shr 4)))]
        t64[k+2]=61
        t64[k+3]=61
      End If
      return t64
End Function

Function PeekS(ByVal Memory As Any Ptr, iLen As Integer = 0) As String Export
	Dim sRetString As String
	Dim iCountBytes As Integer
	If iLen = 0 Then
		While TRUE
			If *Cast(Byte Ptr,(Memory+iCountBytes))<>0 Then
				iCountBytes+=1
			Else
				Exit While
			EndIf
		Wend
	Else
		iCountBytes = iLen
	EndIf
	If iCountBytes<>0 Then
		sRetString = Space(iCountBytes)
		CopyMemory(SAdd(sRetString),Cast(Byte Ptr,Memory),iCountBytes)
		Return sRetString
	EndIf
End Function

'------------------------------------------------------------
'////////////////////////////////////////////////////////////
'------------------------------------------------------------


#define FROM    "xxxxxxxxxxxx@yandex.ru" ' почтовый ящик откуда послать письмо
#define TO_      "xxxxxxxxxxx@yandex.ru" ' почтовый ящик куда послать письмо
#define PASSWORD "*********************" ' пароль для ящика FROM
#Define FILENAME "test.zip"

Type upload_status
	As integer lines_read
End Type

Dim As Byte Ptr data_
Dim As Integer file_size,iNSubt,itSize,ilenEnc
Dim As String Ptr szPointerData
Dim Shared As String szBuf 
Dim As CURL Ptr curl
Dim As CURLcode res = CURLE_OK
Dim As  curl_slist Ptr recipients = 0
Dim As  upload_status upload_ctx

ReDim Shared As string payload_text(16) 
payload_text(0) = "To: " &TO_&!"\r\n"
payload_text(1) = !"From: "& FROM&!"\r\n"
payload_text(2) = !"Subject: ТЕСТ\r\n"
payload_text(3) = !"Content-Type: multipart/mixed;\r\n boundary=""MyBoudary072015""\r\n"
payload_text(4) = !"MIME-Version: 1.0\r\n"
payload_text(5) = !"\r\n"
payload_text(6) = !"--MyBoudary072015\r\n"
payload_text(7) = !"Content-Type: text/plain; charset=windows-1251\r\n"
payload_text(8) = !"Content-Transfer-Encoding: quoted-printable\r\n"
payload_text(9) = !"\r\n"
payload_text(10) = !"Тестовое сообщение! \r\n\r\n"
payload_text(11) = !"--MyBoudary072015\r\n"
payload_text(12) = !"Content-Type: application/zip; name=\""&FILENAME&!"\"\r\n"
payload_text(13) = !"Content-Transfer-Encoding: base64\r\n"
payload_text(14) = !"Content-Disposition: attachment; filename=\""&FILENAME&!"\"\r\n"
payload_text(15) = !"\r\n"


Function payload_source Cdecl(ptr_ as Any Ptr, size As integer, nmemb As integer, userp As upload_status ptr) As Integer

	dim As upload_status Ptr  upload_ctx = userp
	Dim As String Ptr Data_

	if((size = 0) or (nmemb = 0) or ((size*nmemb) < 1)) Or upload_ctx->lines_read>UBound(payload_text) Then
		return 0
	EndIf

	data_ = @payload_text(upload_ctx->lines_read)

	if(Len(*data_)) Then
		Dim As integer len_ = len(*data_)
		memcpy(ptr_, SAdd(*data_), len_)
		upload_ctx->lines_read+=1
		Return len_
	EndIf

	return 0
End Function


Var handle=Read_File(FILENAME)
If handle<>-1 Then
	file_size = Size_File(handle)
   data_=Read_DataS(handle,file_size)
   szBuf = Encode64(PeekS(data_,file_size))
   ilenEnc = Len(szBuf)
	iNSubt = ilenEnc\72
   
	ReDim Preserve As string payload_text(17+iNSubt)
	
	For i As Integer = 0 To iNSubt
		itSize = IIf((ilenEnc-itSize)>72,72,(ilenEnc-itSize))
		payload_text(i+16) = Mid(szBuf,i*72+1,itSize) & !"\r\n"
	Next
   payload_text(17+iNSubt) = !"--MyBoudary072015--"
	Close_file(handle)
	DeAllocate (data_)
EndIf

upload_ctx.lines_read = 0

curl = curl_easy_init()

if(curl) Then

	curl_easy_setopt(curl, CURLOPT_USERNAME, FROM)
	curl_easy_setopt(curl, CURLOPT_PASSWORD, PASSWORD) 
	curl_easy_setopt(curl, CURLOPT_URL, "smtps://smtp.yandex.ru:465")
	curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL)
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L)
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L)
	curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM)
	recipients = curl_slist_append(recipients, TO_)
	curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients)
   curl_easy_setopt(curl, CURLOPT_INFILESIZE, file_size)
	curl_easy_setopt(curl, CURLOPT_READFUNCTION, @payload_source)
	curl_easy_setopt(curl, CURLOPT_READDATA, @upload_ctx)
	curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L)
	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L)
	res = curl_easy_perform(curl)
	
	if(res <> CURLE_OK) Then
		fprintf(stderr, !"curl_easy_perform() failed: %s\n",curl_easy_strerror(res))
	EndIf
	curl_slist_free_all(recipients)
	curl_easy_cleanup(curl)
EndIf
Sleep