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