Differenze tra le versioni di "Invio di posta elettronica con SMTP e SSL mediante le funzioni esterne del API di Libcurl"

Da Gambas-it.org - Wikipedia.
(Creata pagina con "'''Liburl''' è una libreria di trasferimento URL lato-client gratuita, capace di supportare diversi protocolli per il trasferimento di dati. Essa consente - fra l'altro - di...")
 
 
(7 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
'''Liburl''' è una libreria di trasferimento URL lato-client gratuita, capace di supportare diversi protocolli per il trasferimento di dati. Essa consente - fra l'altro - di inviare posta elettronica.
+
'''Libcurl''' è una libreria gratuita lato-client di trasferimento dati con la sintassi URL, capace di supportare diversi protocolli. Essa consente - fra l'altro - di inviare posta elettronica.
  
Per poter fruire in Gambas delle risorse della libreria ''Libcurl'', è necessario avere installata nel sistema e richiamare la libreria dinamica condivisa: "''libcurl.so''"
+
Per poter fruire in Gambas delle risorse della libreria ''Libcurl'', è necessario avere installata nel sistema e richiamare la libreria dinamica condivisa: "''libcurl.so.4.7.0'' ".
  
  
Riga 9: Riga 9:
 
* Ccn
 
* Ccn
 
Gli indirizzi di posta elettronica del mittente e dei destinatari devono essere compresi fra i segni di maggiore > e minore <
 
Gli indirizzi di posta elettronica del mittente e dei destinatari devono essere compresi fra i segni di maggiore > e minore <
  <B><</b>indirizzo@servermail.xx<B>></b>
+
  <B><</b>nome_utente@dominio.xx<B>></b>
  
 
Va impostato ''almeno'' un indirizzo di posta elettronica di un destinatario. Qualora non si intenda imposare uno o due indirizzi dei destinatari, bisognerà porre nella rispettiva stringa dell'indirizzo uno spazio:
 
Va impostato ''almeno'' un indirizzo di posta elettronica di un destinatario. Qualora non si intenda imposare uno o due indirizzi dei destinatari, bisognerà porre nella rispettiva stringa dell'indirizzo uno spazio:
 
  " "
 
  " "
  
 +
Nell'esempio - per la gestione corretta di una prevista ''linked list'' - si farà uso di alcune righe di codice, scritto in C, mediante la generazione di apposita libreria dinamica .so esterna.
 +
 +
<FONT Color=gray>' ''Imposta l'indirizzo di posta elettronica del mittente:''</font>
 +
Private Const MITTENTE As String = "<<FONT Color=gray>''nome_utente@dominio''</font>>"
 +
 +
<FONT Color=gray>' ''Imposta l'indirizzo di posta elettronica dei destinatari:''</font>
 +
Private Const DESTINATARIO As String = "<<FONT Color=gray>''nome_utente@dominio''</font>>"
 +
Private Const CC As String = "<<FONT Color=gray>''nome_utente@dominio''</font>>"
 +
<FONT Color=gray>' ''Se non si vuole impostare un "qualunque" destinatario, è necessario porre un semplice spazio fra le doppie-virgolette:''</font>
 +
Private Const CCN As String = " "
 +
 +
Public Struct upload_status
 +
  lines_read As Integer
 +
End Struct
 +
 +
Private costrutto As String[] = ["From: " & MITTENTE & "\r\n",
 +
                                  "To: " & DESTINATARIO & "\r\n",
 +
                                  "Cc: " & CC & "\r\n",
 +
                                  "Ccn: " & CCN & "\r\n",
 +
                                  "Subject: Esempio di messaggio con SMTP SSL\r\n",
 +
                                  "\r\n",  <FONT Color=gray>' ''Linea vuota per dividere l'intestazione dal corpo del testo, vedere RFC5322''</font>
 +
                                  "Prima riga del testo del messaggio.\r\n",
 +
                                  "Seconda riga del testo del messaggio.\r\n",
 +
                                  "\r\n",
 +
                                  "Terza riga del testo del messaggio.\r\n",
 +
                                  "\nQuarta riga del testo del messaggio.\r\n",
 +
                                  Null]
 +
                                   
 +
 +
Library "libcurl:4.7.0"
 +
 +
Private Const CURLOPT_USERNAME As Integer = 10173
 +
Private Const CURLOPT_PASSWORD As Integer = 10174
 +
Private Const CURLOPT_URL As Integer = 10002
 +
Private Const CURLOPT_MAIL_FROM As Integer = 10186
 +
Private Const CURLOPT_READFUNCTION As Integer = 20012
 +
Private Const CURLOPT_READDATA As Integer = 10009
 +
Private Const CURLOPT_UPLOAD As Integer = 46
 +
Private Const CURLOPT_VERBOSE As Integer = 41
 +
 +
<FONT Color=gray>' ''CURL *curl_easy_init(void)''
 +
' ''Start a libcurl easy session.''</font>
 +
Private Extern curl_easy_init() As Pointer
 +
 +
<FONT Color=gray>' ''CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...)''
 +
' ''Set options for a curl easy handle''</font>
 +
Private Extern curl_easy_setopt(curl As Pointer, option As Integer, opts As String) As Integer
 +
Private Extern curl_easy_setopt_callback(curl As Pointer, option As Integer, callback As Pointer) As Integer Exec "curl_easy_setopt"
 +
Private Extern curl_easy_setopt_upload_Status(curl As Pointer, option As Integer, us As Upload_status) As Integer Exec "curl_easy_setopt"
 +
 +
<FONT Color=gray>' ''CURLcode curl_easy_perform(CURL *curl)''
 +
' ''Perform a blocking file transfer.''</font>
 +
Private Extern curl_easy_perform(curl As Pointer) As Pointer
 +
 +
<FONT Color=gray>' ''const char *curl_easy_strerror(CURLcode)''
 +
' ''Turn a CURLcode value into the equivalent human readable error string.''</font>
 +
Private Extern curl_easy_strerror(CURLcode As Integer) As String
 +
 +
<FONT Color=gray>' ''void curl_easy_cleanup(CURL *curl)''
 +
' ''End a libcurl easy handle.''</font>
 +
Private Extern curl_easy_cleanup(curl As Pointer)
 +
 +
 +
Library "/tmp/lib_cu"
 +
 +
<FONT Color=gray>' ''void Imposta_Destinatari(CURL *curl, char * dest[])''</font>
 +
Private Extern Imposta_Destinatari(curl As Pointer, dest As String[])
 +
 +
 +
'''Public''' Sub Main()
 +
 +
  Dim cu As Pointer
 +
  Dim upload_ctx As New Upload_status
 +
  Dim ris As Integer
 +
  Dim destinazioni As String[]
 +
  Dim l As Long
 +
 
 +
<FONT Color=gray>' ''Va a generare l'apposita libreria dinamica condivisa esterna:''</font>
 +
  CreaSo()
 +
 
 +
  destinazioni = [DESTINATARIO, CC, CCN]
 +
 
 +
  cu = curl_easy_init()
 +
  If cu = 0 Then Error.Raise("Impossibile inizializzare la libreria 'curl' !")
 +
   
 +
<FONT Color=gray>' ''Imposta il nome dell'utente dell'account email e la sua password:''</font>
 +
  curl_easy_setopt(cu, CURLOPT_USERNAME, "<FONT Color=gray>''nome_utente''</font>")
 +
  curl_easy_setopt(cu, CURLOPT_PASSWORD, "<FONT Color=gray>''password_utente''</font>")
 +
   
 +
<FONT Color=gray>' ''L'URL del mailserver dell'utente:''</font>
 +
  curl_easy_setopt(cu, CURLOPT_URL, "smtps://<FONT Color=gray>''mainserver.esempio.it''</font>")
 +
   
 +
<FONT Color=gray>' ''Imposta il mittente dell'email:''</font>
 +
  curl_easy_setopt(cu, CURLOPT_MAIL_FROM, MITTENTE)
 +
   
 +
  Imposta_Destinatari(cu, destinazioni)
 +
 
 +
  curl_easy_setopt_callback(cu, CURLOPT_READFUNCTION, Dati)
 +
  curl_easy_setopt_upload_Status(cu, CURLOPT_READDATA, upload_ctx)
 +
  l = CLong(Val("&" & "1"))
 +
  curl_easy_setopt(cu, CURLOPT_UPLOAD, l)
 +
  curl_easy_setopt(cu, CURLOPT_VERBOSE, l)
 +
 
 +
<FONT Color=gray>' ''Invia la posta elettronica:''</font>
 +
  ris = curl_easy_perform(cu)
 +
  If ris <> 0 Then Error.Raise("Invio dell'email non riuscito: " & curl_easy_strerror(ris))
 +
   
 +
   
 +
<FONT Color=gray>' ''Va in chiusura:''</font>
 +
  curl_easy_cleanup(cu)
 +
 
 +
'''End'''
 +
 +
'''Private''' Function Dati(ptr As Pointer, size As Long, nmemb As Long, userdata As Pointer) As Long
 +
 
 +
  Dim upload_ctx As Upload_status
 +
  Dim data As String
 +
  Dim lenl As Long
 +
  Dim st As Stream
 +
 
 +
  upload_ctx = userdata
 +
 
 +
  If ((size = 0) Or (nmemb = 0) Or ((size * nmemb) < 1)) Then Return
 +
   
 +
  data = costrutto[upload_ctx.lines_read]
 +
 
 +
  If IsNull(data) = False
 +
    lenl = Len(data)
 +
    st = Memory ptr For Write
 +
    Write #st, data, lenl
 +
    st.Close
 +
    Inc upload_ctx.lines_read
 +
    Return lenl
 +
  Endif
 +
 
 +
  Return 0
 +
 
 +
'''End'''
 +
 +
'''Private''' Procedure CreaSo()
 +
 
 +
  File.Save("/tmp/lib_cu.c", "#include <curl/curl.h>" &
 +
  "\n\n" &
 +
  "void Imposta_Destinatari(CURL *curl, char * dest[]) {" &
 +
  "\n\n" &
 +
  "  struct curl_slist *recipients = NULL;" &
 +
  "\n\n" &
 +
  "/* Aggiunge tre 'recipients', che in questo caso corrispondono agli indirizzi:\n" &
 +
  "*  To:\n" &
 +
  "*  Cc:\n" &
 +
  "*  Ccn:\n*/\n" &
 +
  "  if (*dest[0] != 0x20)\n" &
 +
  "      recipients = curl_slist_append(recipients, dest[0]);\n" &
 +
  "  if (*dest[1] != 0x20)\n" &
 +
  "      recipients = curl_slist_append(recipients, dest[1]);\n" &
 +
  "  if (*dest[2] != 0x20)\n" &
 +
  "      recipients = curl_slist_append(recipients, dest[2]);\n\n" &
 +
  "  curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);\n\n}")
 +
 
 +
  Shell "gcc -o /tmp/lib_cu.so /tmp/lib_cu.c -lcurl -shared -fPIC" Wait
 +
 
 +
'''End'''
  
  
Riga 19: Riga 181:
 
=Riferimenti=
 
=Riferimenti=
 
* https://curl.haxx.se/libcurl/
 
* https://curl.haxx.se/libcurl/
 
+
* http://libcurl.org/
 
+
* http://www.brescianet.com/manuali/specifiche/TCPIP/SMTP_rfc5321.pdf
 
+
* http://www.brescianet.com/manuali/specifiche/TCPIP/SMTP_Serv_Ext_rfc4954.pdf
<FONT Color=red size=4><B>Pagina in costruzione !</b></font>
 

Versione attuale delle 15:43, 8 mag 2023

Libcurl è una libreria gratuita lato-client di trasferimento dati con la sintassi URL, capace di supportare diversi protocolli. Essa consente - fra l'altro - di inviare posta elettronica.

Per poter fruire in Gambas delle risorse della libreria Libcurl, è necessario avere installata nel sistema e richiamare la libreria dinamica condivisa: "libcurl.so.4.7.0 ".


L'esempio pratico, che di seguito mostriamo, consente di inviare una e-mail ad uno o più destinatari corrispondenti agli indirizzi:

  • To:
  • Cc:
  • Ccn

Gli indirizzi di posta elettronica del mittente e dei destinatari devono essere compresi fra i segni di maggiore > e minore <

<nome_utente@dominio.xx>

Va impostato almeno un indirizzo di posta elettronica di un destinatario. Qualora non si intenda imposare uno o due indirizzi dei destinatari, bisognerà porre nella rispettiva stringa dell'indirizzo uno spazio:

" "

Nell'esempio - per la gestione corretta di una prevista linked list - si farà uso di alcune righe di codice, scritto in C, mediante la generazione di apposita libreria dinamica .so esterna.

' Imposta l'indirizzo di posta elettronica del mittente:
Private Const MITTENTE As String = "<nome_utente@dominio>"

' Imposta l'indirizzo di posta elettronica dei destinatari:
Private Const DESTINATARIO As String = "<nome_utente@dominio>"
Private Const CC As String = "<nome_utente@dominio>"
' Se non si vuole impostare un "qualunque" destinatario, è necessario porre un semplice spazio fra le doppie-virgolette:
Private Const CCN As String = " "

Public Struct upload_status
  lines_read As Integer
End Struct

Private costrutto As String[] = ["From: " & MITTENTE & "\r\n",
                                 "To: " & DESTINATARIO & "\r\n",
                                 "Cc: " & CC & "\r\n",
                                 "Ccn: " & CCN & "\r\n",
                                 "Subject: Esempio di messaggio con SMTP SSL\r\n",
                                 "\r\n",   ' Linea vuota per dividere l'intestazione dal corpo del testo, vedere RFC5322
                                 "Prima riga del testo del messaggio.\r\n",
                                 "Seconda riga del testo del messaggio.\r\n",
                                 "\r\n",
                                 "Terza riga del testo del messaggio.\r\n",
                                 "\nQuarta riga del testo del messaggio.\r\n",
                                 Null]
                                   

Library "libcurl:4.7.0"

Private Const CURLOPT_USERNAME As Integer = 10173
Private Const CURLOPT_PASSWORD As Integer = 10174
Private Const CURLOPT_URL As Integer = 10002
Private Const CURLOPT_MAIL_FROM As Integer = 10186
Private Const CURLOPT_READFUNCTION As Integer = 20012
Private Const CURLOPT_READDATA As Integer = 10009
Private Const CURLOPT_UPLOAD As Integer = 46
Private Const CURLOPT_VERBOSE As Integer = 41

' CURL *curl_easy_init(void)
' Start a libcurl easy session.
Private Extern curl_easy_init() As Pointer

' CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...)
' Set options for a curl easy handle
Private Extern curl_easy_setopt(curl As Pointer, option As Integer, opts As String) As Integer
Private Extern curl_easy_setopt_callback(curl As Pointer, option As Integer, callback As Pointer) As Integer Exec "curl_easy_setopt"
Private Extern curl_easy_setopt_upload_Status(curl As Pointer, option As Integer, us As Upload_status) As Integer Exec "curl_easy_setopt"

' CURLcode curl_easy_perform(CURL *curl)
' Perform a blocking file transfer.
Private Extern curl_easy_perform(curl As Pointer) As Pointer

' const char *curl_easy_strerror(CURLcode)
' Turn a CURLcode value into the equivalent human readable error string.
Private Extern curl_easy_strerror(CURLcode As Integer) As String

' void curl_easy_cleanup(CURL *curl)
' End a libcurl easy handle.
Private Extern curl_easy_cleanup(curl As Pointer)


Library "/tmp/lib_cu"

' void Imposta_Destinatari(CURL *curl, char * dest[])
Private Extern Imposta_Destinatari(curl As Pointer, dest As String[])


Public Sub Main()

 Dim cu As Pointer
 Dim upload_ctx As New Upload_status
 Dim ris As Integer
 Dim destinazioni As String[]
 Dim l As Long
 
' Va a generare l'apposita libreria dinamica condivisa esterna:
  CreaSo()
  
  destinazioni = [DESTINATARIO, CC, CCN]
  
  cu = curl_easy_init()
  If cu = 0 Then Error.Raise("Impossibile inizializzare la libreria 'curl' !")
   
' Imposta il nome dell'utente dell'account email e la sua password:
  curl_easy_setopt(cu, CURLOPT_USERNAME, "nome_utente")
  curl_easy_setopt(cu, CURLOPT_PASSWORD, "password_utente")
   
' L'URL del mailserver dell'utente:
  curl_easy_setopt(cu, CURLOPT_URL, "smtps://mainserver.esempio.it")
   
' Imposta il mittente dell'email:
  curl_easy_setopt(cu, CURLOPT_MAIL_FROM, MITTENTE)
   
  Imposta_Destinatari(cu, destinazioni)
  
  curl_easy_setopt_callback(cu, CURLOPT_READFUNCTION, Dati)
  curl_easy_setopt_upload_Status(cu, CURLOPT_READDATA, upload_ctx)
  l = CLong(Val("&" & "1"))
  curl_easy_setopt(cu, CURLOPT_UPLOAD, l)
  curl_easy_setopt(cu, CURLOPT_VERBOSE, l)
  
' Invia la posta elettronica:
  ris = curl_easy_perform(cu)
  If ris <> 0 Then Error.Raise("Invio dell'email non riuscito: " & curl_easy_strerror(ris))
   
   
' Va in chiusura:
  curl_easy_cleanup(cu)
  
End 

Private Function Dati(ptr As Pointer, size As Long, nmemb As Long, userdata As Pointer) As Long
 
 Dim upload_ctx As Upload_status
 Dim data As String
 Dim lenl As Long
 Dim st As Stream
 
  upload_ctx = userdata
  
  If ((size = 0) Or (nmemb = 0) Or ((size * nmemb) < 1)) Then Return
   
  data = costrutto[upload_ctx.lines_read]
  
  If IsNull(data) = False
    lenl = Len(data)
    st = Memory ptr For Write
    Write #st, data, lenl
    st.Close
    Inc upload_ctx.lines_read
    Return lenl
  Endif
  
  Return 0
  
End 

Private Procedure CreaSo()
 
 File.Save("/tmp/lib_cu.c", "#include <curl/curl.h>" &
 "\n\n" &
 "void Imposta_Destinatari(CURL *curl, char * dest[]) {" &
 "\n\n" &
 "   struct curl_slist *recipients = NULL;" &
 "\n\n" &
 "/* Aggiunge tre 'recipients', che in questo caso corrispondono agli indirizzi:\n" &
 "*  To:\n" &
 "*  Cc:\n" &
 "*  Ccn:\n*/\n" &
 "   if (*dest[0] != 0x20)\n" &
 "      recipients = curl_slist_append(recipients, dest[0]);\n" &
 "   if (*dest[1] != 0x20)\n" &
 "      recipients = curl_slist_append(recipients, dest[1]);\n" &
 "   if (*dest[2] != 0x20)\n" &
 "      recipients = curl_slist_append(recipients, dest[2]);\n\n" &
 "   curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);\n\n}")
 
 Shell "gcc -o /tmp/lib_cu.so /tmp/lib_cu.c -lcurl -shared -fPIC" Wait
 
End


Riferimenti