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.
 
(4 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
 
'''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.
 
'''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.8.0'' ".
  
  
Riga 43: Riga 43:
 
                                      
 
                                      
 
   
 
   
  Library "libcurl"
+
  Library "libcurl:4.8.0"
 
   
 
   
 
  Private Const CURLOPT_USERNAME As Integer = 10173
 
  Private Const CURLOPT_USERNAME As Integer = 10173
Riga 49: Riga 49:
 
  Private Const CURLOPT_URL As Integer = 10002
 
  Private Const CURLOPT_URL As Integer = 10002
 
  Private Const CURLOPT_MAIL_FROM As Integer = 10186
 
  Private Const CURLOPT_MAIL_FROM As Integer = 10186
Private Const CURLOPT_MAIL_RCPT As Integer = 10187
 
 
  Private Const CURLOPT_READFUNCTION As Integer = 20012
 
  Private Const CURLOPT_READFUNCTION As Integer = 20012
 
  Private Const CURLOPT_READDATA As Integer = 10009
 
  Private Const CURLOPT_READDATA As Integer = 10009
Riga 84: Riga 83:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
 
   Dim cu As Pointer
 
   Dim cu As Pointer
Riga 93: Riga 92:
 
    
 
    
 
  <FONT Color=gray>' ''Va a generare l'apposita libreria dinamica condivisa esterna:''</font>
 
  <FONT Color=gray>' ''Va a generare l'apposita libreria dinamica condivisa esterna:''</font>
  CreaSo()
+
  CreaSo()
 
    
 
    
  destinazioni = [DESTINATARIO, CC, CCN]
+
  destinazioni = [DESTINATARIO, CC, CCN]
 
    
 
    
  cu = curl_easy_init()
+
  cu = curl_easy_init()
  If cu = 0 Then Error.Raise("Impossibile inizializzare la libreria 'curl' !")
+
  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>
 
  <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_USERNAME, "<FONT Color=gray>''nome_utente''</font>")
  curl_easy_setopt(cu, CURLOPT_PASSWORD, "<FONT Color=gray>''password_utente''</font>")
+
  curl_easy_setopt(cu, CURLOPT_PASSWORD, "<FONT Color=gray>''password_utente''</font>")
 
      
 
      
 
  <FONT Color=gray>' ''L'URL del mailserver dell'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>")
+
  curl_easy_setopt(cu, CURLOPT_URL, "smtps://<FONT Color=gray>''mainserver.esempio.it''</font>")
 
      
 
      
 
  <FONT Color=gray>' ''Imposta il mittente dell'email:''</font>
 
  <FONT Color=gray>' ''Imposta il mittente dell'email:''</font>
  curl_easy_setopt(cu, CURLOPT_MAIL_FROM, MITTENTE)
+
  curl_easy_setopt(cu, CURLOPT_MAIL_FROM, MITTENTE)
 
      
 
      
  Imposta_Destinatari(cu, destinazioni)
+
  Imposta_Destinatari(cu, destinazioni)
 
    
 
    
  curl_easy_setopt_callback(cu, CURLOPT_READFUNCTION, Dati)
+
  curl_easy_setopt_callback(cu, CURLOPT_READFUNCTION, Dati)
  curl_easy_setopt_upload_Status(cu, CURLOPT_READDATA, upload_ctx)
+
  curl_easy_setopt_upload_Status(cu, CURLOPT_READDATA, upload_ctx)
  l = CLong(Val("&" & "1"))
+
  l = CLong(Val("&" & "1"))
  curl_easy_setopt(cu, CURLOPT_UPLOAD, l)
+
  curl_easy_setopt(cu, CURLOPT_UPLOAD, l)
  curl_easy_setopt(cu, CURLOPT_VERBOSE, l)
+
  curl_easy_setopt(cu, CURLOPT_VERBOSE, l)
 
    
 
    
 
  <FONT Color=gray>' ''Invia la posta elettronica:''</font>
 
  <FONT Color=gray>' ''Invia la posta elettronica:''</font>
  ris = curl_easy_perform(cu)
+
  ris = curl_easy_perform(cu)
  If ris <> 0 Then Error.Raise("Invio dell'email non riuscito: " & curl_easy_strerror(ris))
+
  If ris <> 0 Then Error.Raise("Invio dell'email non riuscito: " & curl_easy_strerror(ris))
   
 
 
      
 
      
 
  <FONT Color=gray>' ''Va in chiusura:''</font>
 
  <FONT Color=gray>' ''Va in chiusura:''</font>
  curl_easy_cleanup(cu)
+
  curl_easy_cleanup(cu)
 
    
 
    
  '''End'''
+
  End  
 
   
 
   
 
   
 
   
  '''Private''' Function Dati(ptr As Pointer, size As Long, nmemb As Long, userdata As Pointer) As Long
+
  Private Function Dati(ptr As Pointer, size As Long, nmemb As Long, userdata As Pointer) As Long
 
    
 
    
 
   Dim upload_ctx As Upload_status
 
   Dim upload_ctx As Upload_status
Riga 136: Riga 134:
 
   Dim st As Stream
 
   Dim st As Stream
 
    
 
    
  upload_ctx = userdata
+
  upload_ctx = userdata
 
    
 
    
  If ((size = 0) Or (nmemb = 0) Or ((size * nmemb) < 1)) Then Return
+
  If ((size = 0) Or (nmemb = 0) Or ((size * nmemb) < 1)) Then Return
 
      
 
      
  data = costrutto[upload_ctx.lines_read]
+
  data = costrutto[upload_ctx.lines_read]
 
    
 
    
  If IsNull(data) = False
+
  If IsNull(data) = False
    lenl = Len(data)
+
    lenl = Len(data)
    st = Memory ptr For Write
+
    st = Memory ptr For Write
    Write #st, data, lenl
+
    Write #st, data, lenl
    st.Close
+
    st.Close
    Inc upload_ctx.lines_read
+
    Inc upload_ctx.lines_read
    Return lenl
+
    Return lenl
  Endif
+
  Endif
 
    
 
    
  Return 0
+
  Return 0
 
    
 
    
  '''End'''
+
  End  
 
   
 
   
 
   
 
   
  '''Private''' Procedure CreaSo()
+
  Private Procedure CreaSo()
 
    
 
    
 
   File.Save("/tmp/lib_cu.c", "#include <curl/curl.h>" &
 
   File.Save("/tmp/lib_cu.c", "#include <curl/curl.h>" &
Riga 178: Riga 176:
 
   Shell "gcc -o /tmp/lib_cu.so /tmp/lib_cu.c -lcurl -shared -fPIC" Wait
 
   Shell "gcc -o /tmp/lib_cu.so /tmp/lib_cu.c -lcurl -shared -fPIC" Wait
 
    
 
    
  '''End'''
+
  End
  
  
Riga 185: Riga 183:
 
* https://curl.haxx.se/libcurl/
 
* https://curl.haxx.se/libcurl/
 
* http://libcurl.org/
 
* 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

Versione attuale delle 17:15, 8 giu 2024

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.8.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.8.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