artdaq_mfextensions  v1_02_02
curl_send_message.c
1 #include "curl_send_message.h"
2 #include <curl/curl.h>
3 #include <time.h>
4 
5 
6 
7 static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp)
8 {
9  struct upload_status *upload_ctx = (struct upload_status *)userp;
10  size_t rdsize = size*nmemb;
11 
12  if ((size == 0) || (nmemb == 0) || (rdsize < 1) || (upload_ctx->pos >= upload_ctx->size))
13  {
14  return 0;
15  }
16 
17  if (rdsize + upload_ctx->pos > upload_ctx->size)
18  {
19  rdsize = upload_ctx->size - upload_ctx->pos;
20  }
21 
22  memcpy(ptr, &upload_ctx->payload[upload_ctx->pos], rdsize);
23  upload_ctx->pos += rdsize;
24 
25  return rdsize;
26 }
27 
28 void send_message(const char* dest, const char* to[], size_t to_size, const char* from, const char* payload, size_t payload_size)
29 {
30  CURL *curl;
31  CURLcode res;
32  struct curl_slist *recipients = NULL;
33  struct upload_status upload_ctx;
34 
35  upload_ctx.pos = 0;
36  upload_ctx.size = payload_size;
37  upload_ctx.payload = payload;
38 
39  curl = curl_easy_init();
40  if (curl)
41  {
42  /* This is the URL for your mailserver */
43  curl_easy_setopt(curl, CURLOPT_URL, dest);
44 
45  curl_easy_setopt(curl, CURLOPT_MAIL_FROM, from);
46 
47  /* Note that the CURLOPT_MAIL_RCPT takes a list, not a char array. */
48 
49  for (size_t ii = 0; ii < to_size; ++ii)
50  {
51  recipients = curl_slist_append(recipients, to[ii]);
52  }
53  curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
54 
55  curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
56  curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
57  curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
58 
59  /* send the message (including headers) */
60  res = curl_easy_perform(curl);
61 
62  /* Check for errors */
63  if (res != CURLE_OK)
64  fprintf(stderr, "curl_easy_perform() failed: %s\n",
65  curl_easy_strerror(res));
66 
67  /* free the list of recipients */
68  curl_slist_free_all(recipients);
69 
70  curl_easy_cleanup(curl);
71  }
72 }
73 
74 void send_message_ssl(const char* dest, const char* to[], size_t to_size, const char* from, const char* payload, size_t payload_size, const char* username, const char* pw, int disableVerify)
75 {
76  CURL *curl;
77  CURLcode res = CURLE_OK;
78  struct curl_slist *recipients = NULL;
79  struct upload_status upload_ctx;
80 
81  upload_ctx.pos = 0;
82  upload_ctx.size = payload_size;
83  upload_ctx.payload = payload;
84 
85  curl = curl_easy_init();
86  if (curl)
87  {
88  /* Set username and password */
89  curl_easy_setopt(curl, CURLOPT_USERNAME, username);
90  curl_easy_setopt(curl, CURLOPT_PASSWORD, pw);
91 
92  /* This is the URL for your mailserver. Note the use of port 587 here,
93  * instead of the normal SMTP port (25). Port 587 is commonly used for
94  * secure mail submission (see RFC4403), but you should use whatever
95  * matches your server configuration. */
96  curl_easy_setopt(curl, CURLOPT_URL, dest);
97 
98  /* In this example, we'll start with a plain text connection, and upgrade
99  * to Transport Layer Security (TLS) using the STARTTLS command. Be careful
100  * of using CURLUSESSL_TRY here, because if TLS upgrade fails, the transfer
101  * will continue anyway - see the security discussion in the libcurl
102  * tutorial for more details. */
103  curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
104 
105  if (disableVerify)
106  {
107  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
108  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
109  }
110 
111  /* Note that this option isn't strictly required, omitting it will result
112  * in libcurl sending the MAIL FROM command with empty sender data. All
113  * autoresponses should have an empty reverse-path, and should be directed
114  * to the address in the reverse-path which triggered them. Otherwise,
115  * they could cause an endless loop. See RFC 5321 Section 4.5.5 for more
116  * details.
117  */
118  curl_easy_setopt(curl, CURLOPT_MAIL_FROM, from);
119 
120  for (size_t ii = 0; ii < to_size; ++ii)
121  {
122  recipients = curl_slist_append(recipients, to[ii]);
123  }
124  curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
125 
126  /* We're using a callback function to specify the payload (the headers and
127  * body of the message). You could just use the CURLOPT_READDATA option to
128  * specify a FILE pointer to read from. */
129  curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
130  curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
131  curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
132 
133  /* Since the traffic will be encrypted, it is very useful to turn on debug
134  * information within libcurl to see what is happening during the transfer.
135  */
136  curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
137 
138  /* Send the message */
139  res = curl_easy_perform(curl);
140 
141  /* Check for errors */
142  if (res != CURLE_OK)
143  fprintf(stderr, "curl_easy_perform() failed: %s\n",
144  curl_easy_strerror(res));
145 
146  /* Free the list of recipients */
147  curl_slist_free_all(recipients);
148 
149  /* Always cleanup */
150  curl_easy_cleanup(curl);
151  }
152 }
size_t size
Size of payload.
void send_message_ssl(const char *dest, const char *to[], size_t to_size, const char *from, const char *payload, size_t payload_size, const char *username, const char *pw, int disableVerify)
Sends a message to the given SMTP server, using SSL encryption.
void send_message(const char *dest, const char *to[], size_t to_size, const char *from, const char *payload, size_t payload_size)
Sends a message to the given SMTP server.
const char * payload
payload string
size_t pos
Current position within payload.
Structure to track progress of upload in cURL send function.