Leggere la posta elettronica con POP3 e SSL mediante le funzioni esterne del API di Libcurl

Da Gambas-it.org - Wikipedia.

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

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

Va sottolineato che nel 3° argomento della funzione esterna "curl_easy_setopt()" - immediatamente dopo l'impostazione della url del Server della posta elettronica e separato da uno slash - va definito il numero d'indice della e-mail ricevuta che si intende leggere. Tale indice inizia da 1 ed il suo ordine crescente corrisponde alle e-mail più recenti (pertanto impostando il numero 1 si otterrà la lettura della e-mail più vecchia presente nella propria casella di posta elettronica).

Eventuali allegati all'email saranno mostrati in formato ASCII secondo la codifica Base64.

Mostriamo un esempio pratico di lettura della posta elettronica con POP3 e SSL:

Library "libcurl:4.7.0"

Private Const CURLOPT_VERBOSE As Integer = 41
Private Const CURLOPT_URL As Integer = 10002
Private Const CURLOPT_USERNAME As Integer = 10173
Private Const CURLOPT_PASSWORD As Integer = 10174
  
' 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
 
' 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)


Public Sub Main()

 Dim cu As Pointer
 Dim ris As Integer
      
 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")
   
' Imposta l'URL del mailserver dell'utente, nonché l'e-mail ricevuta: in questo caso sarà mostrato il testo della "seconda" email più antica presente nella casella di posta elettronica.
 curl_easy_setopt(cu, CURLOPT_URL, "pop3s://pop.server.it/2")
  
' Procede alla lettura della e-mail prescelta, mostrandola nella console:
 ris = curl_easy_perform(cu)
 If ris <> 0 Then Error.Raise("Impossibile leggere la posta elettronica: " & curl_easy_strerror(ris))
   
   
' Va in chiusura:
 curl_easy_cleanup(cu)
  
End

Il codice sopra mostrato permette semplicemente e solo di vedere in console/Terminale il contenuto delle e-mail, presenti nella casella postale dell'utente, nonché i dati in rappresentazione testuale degli eventuali file allegati.

Se si intende raccogliere i predetti contenuti delle email in una variabile, che consente così all'utente di poterli gestire liberamente, bisognerà utilizzare nel codice una funzione di Callback, inserita all'interno di un'apposita libreria dinamica condivisa esterna scritta in C.

Mostriamo un esempio pratico:

Public Struct AreaMemoria
  memoria As Pointer
  size As Long
End Struct


Library "libcurl:4.7.0"

Private Const CURLOPT_WRITEDATA As Integer = 10001
Private Const CURLOPT_URL As Integer = 10002
Private Const CURLOPT_USERNAME As Integer = 10173
Private Const CURLOPT_PASSWORD As Integer = 10174
Private Const CURLOPT_WRITEFUNCTION As Integer = 20011

' 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, option As String) As Integer
Private Extern curl_easy_setopt_Pointer(curl As Pointer, option As Integer, option As Pointer) As Integer Exec "curl_easy_setopt"
Private Extern curl_easy_setopt_Struct(curl As Pointer, option As Integer, option As AreaMemoria) 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 Integer

' 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_mem"

' size_t ScriveMemoria(void *contents, size_t size, size_t nmemb, void *userp)
' Invoca una funzione di Callback per memorizzare i dati del'email in un'area di memoria.
Private Extern ScriveMemoria(con As Pointer, sz As Long, nm As Long, us As Pointer) As Long


Public Sub Main()
 
 Dim cu As Pointer
 Dim i As Integer
 Dim am As New AreaMemoria
 
' Va a creare la libreria condivisa .so esterna per l'invocazione della funzione di Callback:
 CreaSo()
   
 cu = curl_easy_init()
   
' Imposta l'identificativo dell'utente della casella di posta elettronica:
 curl_easy_setopt(cu, CURLOPT_USERNAME, "identificativo_utente")
   
' Imposta la password dell'utente della casella di posta elettronica:
 curl_easy_setopt(cu, CURLOPT_PASSWORD, "password")
   
' Imposta il Server della casella di posta elettronica ed il numero d'ordine della e-mail da leggere (esempio: "pop3s://pop.tiscali.it/7":
 curl_easy_setopt(cu, CURLOPT_URL, "pop3s://pop.server.xx/num")
   
' Invia tutti i dati alla funzione di CallBack 'ScriveMemoria()':
 curl_easy_setopt_Pointer(cu, CURLOPT_WRITEFUNCTION, ScriveMemoria)
   
' Memorizza i dati della e-mail nella Struttura:
 curl_easy_setopt_Struct(cu, CURLOPT_WRITEDATA, am)
   
 i = curl_easy_perform(cu)
 If i <> 0 Then Error.Raise("Errore: " & curl_easy_strerror(i))
   
' Per mera verifica mostra in console/terminale i dati della e-mail memorizzati nella Struttura:
 Print ">>>>>>>>>>>>\n"; String@(am.memoria); "\n<<<<<<<<<<<<"
   
 curl_easy_cleanup(cu)
   
End 


Private Procedure CreaSo()
 
' Salva il codice sorgente, scritto in C, della libreria dinamica condivisa esterna:
 File.Save("/tmp/lib_mem.c", "#include <stdlib.h>\n" &
           "#include <string.h>\n" &
           "#include <curl/curl.h>" &
           "\n\n" &
           "struct MemoryStruct {\n" &
           "   char *memory;\n" &
           "   size_t size;};" &
           "\n\n" &
           "struct MemoryStruct chunk;" &
           "\n\n" &
           "size_t ScriveMemoria(void *contents, size_t size, size_t nmemb, void *userp) {" &
           "\n\n" &
           "size_t realsize = size * nmemb;" &
           "\n\n" &
           "   struct MemoryStruct *mem = (struct MemoryStruct *)userp;" &
           "\n\n" &
           "   mem->memory = realloc(mem->memory, mem->size + realsize + 1);\n" &
           "   memcpy(&(mem->memory[mem->size]), contents, realsize);\n" &
           "   mem->size += realsize;\n" &
           "   mem->memory[mem->size] = 0;" &
           "\n\n" &
           "   return realsize;\n}")

' Compila il codice sorgente della libreria dinamica condivisa esterna:
 Shell "gcc -o /tmp/lib_mem.so /tmp/lib_mem.c -lcurl -shared -fPIC" Wait
  
End


Riferimenti