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