Отправка сообщения с SMTP аутентификацией в C++ через libcurl

Возникла задачка на С++ отправлять email сообщения из программы.
Удивительно, но libcurl, который есть практически на любой nix системе позволяет это делать, причем и используя SMTP аутентификацию.
В сети есть примеры реализации отправки сообщения в основном на Си, мой пример пригодится тем, кто использует С++.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <curl/curl.h>
#include <iostream>
#include <string.h>
#include <string>
#include <queue>
 
using namespace std;
 
queue<string> init_message( string to, string from, string subj, string message ){
 
  queue<string> msg;
  string s = "To: " + to + "\n";
  msg.push( s );
  s = "From: " + from + "\n";
  msg.push( s );
  s = "Subject: " + subj + "\n";
  msg.push( s );
  s = "\n";
  msg.push( s );
  msg.push( message );
  return msg;
}
 
static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp){
 
  queue<string> *msg = (queue<string>*)userp;
  string s;
  if( msg->empty()){
    return 0;
  }
  else{
    s = msg->front();
    msg->pop();
  }
 
  memcpy(ptr, s.c_str(), s.size() );
  return s.size();
}
 
 
int main(){
   
  CURL *curl;
  CURLcode res;
  struct curl_slist *recipients = NULL;
 
  curl = curl_easy_init();
  string to = "<to@domain.com>";
  string from = "<from@domain.com>";
  string subject = "Test";
  string message = "Test message";
 
  queue<string> msg = init_message( to, from, subject, message );
 
  if( curl ){
    curl_easy_setopt(curl, CURLOPT_URL, "smtp://smtp.domain.com:25");
    curl_easy_setopt(curl, CURLOPT_USERNAME, "smtp_login");
    curl_easy_setopt(curl, CURLOPT_PASSWORD, "smtp_pass");
    curl_easy_setopt(curl, CURLOPT_MAIL_FROM, from.c_str() );
    recipients = curl_slist_append(recipients, to.c_str() );
    curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
 
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
    curl_easy_setopt(curl, CURLOPT_READDATA, &msg );
 
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
 
    res = curl_easy_perform(curl);
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));
     
    curl_slist_free_all(recipients);
    curl_easy_cleanup(curl);
 
  }
  return 0;
 
}

Опция CURLOPT_VERBOSE здесь подключена для того, чтобы в стандартном выводе для отладки можно было посмотреть как идет отправка.