Skip to content

Instantly share code, notes, and snippets.

@Jnchi
Last active March 11, 2019 19:37
Show Gist options
  • Save Jnchi/83277f5559bbdc6af4554d3dec6ad64f to your computer and use it in GitHub Desktop.
Save Jnchi/83277f5559bbdc6af4554d3dec6ad64f to your computer and use it in GitHub Desktop.
libcurl example - smtp-mail.c extended
/*
* https://tools.ietf.org/html/rfc5322#section-3.3
*
* gcc -Wall -Wextra -Werror -o date date.c; ./date
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
int main(void)
{
struct tm *tm_info;
time_t timer;
char date[36];
time(&timer);
tm_info = localtime(&timer);
/* RFC 822 POSIX time stamp */
strftime(date, 36, "%a, %d %b %Y %H:%M:%S %z", tm_info);
printf("Date: %s\n", date);
return 0;
}
/*
* https://tools.ietf.org/html/rfc5322#section-3.6.4
*
* gcc -Wall -Wextra -Werror -o message_id message_id.c -luuid; ./message_id
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <uuid/uuid.h>
int main(void)
{
char domainname[64],
hostname[64],
msg_id[37];
size_t i;
uuid_t uuid;
uuid_generate(uuid);
for (i = 0; i < sizeof(uuid); i++) {
if(i == 0) {
snprintf(msg_id, sizeof(msg_id) - strlen(msg_id), "%02x", uuid[i]);
} else if(i == 3 || i == 5 || i == 7 || i == 9) {
snprintf(msg_id + strlen(msg_id), sizeof(msg_id) - strlen(msg_id) + 1, "%02x-", uuid[i]);
} else {
snprintf(msg_id + strlen(msg_id), sizeof(msg_id) - strlen(msg_id), "%02x", uuid[i]);
}
}
getdomainname(domainname, sizeof(domainname));
gethostname(hostname, sizeof(hostname));
printf("Message-ID: %s@%s.%s\n", msg_id, hostname, domainname);
return 0;
}
/*
* https://curl.haxx.se/libcurl/c/smtp-mail.html
*
* gcc -Wall -Wextra -Werror -o payload payload.c; ./payload
*/
#include <stdio.h>
#include <string.h>
#define FROM_ADDR "<sender@example.org>"
#define TO_ADDR "<addressee@example.net>"
#define FROM_MAIL "Sender Person " FROM_ADDR
#define TO_MAIL "A Receiver " TO_ADDR
static const char *payload_text[] = {
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n",
"To: " TO_MAIL "\r\n",
"From: " FROM_MAIL "\r\n",
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@"
"rfcpedant.example.org>\r\n",
"Subject: SMTP example message\r\n",
"\r\n", /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n",
"\r\n",
"It could be a lot of lines, could be MIME encoded, whatever.\r\n",
"Check RFC5322.\r\n",
NULL
};
int main(void)
{
const char *data;
for (size_t i = 0; i < (sizeof(payload_text) / sizeof(payload_text[0])); i++)
{
data = payload_text[i];
if(data) {
printf("%s", data);
}
}
return 0;
}
/*
* https://curl.haxx.se/libcurl/c/smtp-mail.html
*
* gcc -o send_email send_email.c -luuid -lcurl; ./send_email
*/
#include <curl/curl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <uuid/uuid.h>
#define FROM_ADDR "<sender@example.org>"
#define TO_ADDR "<addressee@example.net>"
#define FROM_MAIL "Sender Person " FROM_ADDR
#define TO_MAIL "A Receiver " TO_ADDR
#define SMTP_SERVER "smtp://mail.example.com"
struct message {
size_t lines_read;
char *data[];
};
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
{
struct message *msg = (struct message*)userp;
char *data;
if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
return 0;
}
printf("lines_read: %d\n", msg->lines_read);
data = msg->data[msg->lines_read];
if(data) {
size_t len = strlen(data);
memcpy(ptr, data, len);
msg->lines_read++;
return len;
}
return 0;
}
static char *get_date(void)
{
char *date;
int len = 56;
struct tm *tm_info;
time_t timer;
date = (char *) malloc(len * sizeof(char));
time(&timer);
tm_info = localtime(&timer);
/* RFC 822 POSIX time stamp */
strftime(date, len, "Date: %a, %d %b %Y %H:%M:%S %z\r\n", tm_info);
return date;
}
static char *get_message_id(void)
{
char domainname[64], hostname[64], msg_id[37], *message_id;
int len = 192;
size_t i;
uuid_t uuid;
message_id = (char *) malloc(len * sizeof(char));
uuid_generate(uuid);
for (i = 0; i < sizeof(uuid); i++) {
if(i == 0) {
snprintf(msg_id, sizeof(msg_id) - strlen(msg_id), "%02x", uuid[i]);
} else if(i == 3 || i == 5 || i == 7 || i == 9) {
snprintf(msg_id + strlen(msg_id), sizeof(msg_id) - strlen(msg_id) + 1, "%02x-", uuid[i]);
} else {
snprintf(msg_id + strlen(msg_id), sizeof(msg_id) - strlen(msg_id), "%02x", uuid[i]);
}
}
getdomainname(domainname, sizeof(domainname));
gethostname(hostname, sizeof(hostname));
snprintf(message_id, len, "Message-ID: <%s@%s.%s>\r\n", msg_id, hostname, domainname);
return message_id;
}
int main(void)
{
CURL *curl;
CURLcode res = CURLE_OK;
struct curl_slist *recipients = NULL;
int msg_len = 9;
struct message *msg;
msg = malloc(sizeof(struct message) + (msg_len * sizeof(char*)));
msg->lines_read = 0;
msg->data[0] = get_date();
msg->data[1] = "To: " TO_MAIL "\r\n";
msg->data[2] = "From: " FROM_MAIL "\r\n";
msg->data[3] = get_message_id();
msg->data[4] = "Subject: SMTP example message\r\n";
msg->data[5] = "\r\n";
msg->data[6] = "The body of the message starts here.\r\n";
msg->data[7] = "\r\n";
msg->data[8] = NULL;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_USE_SSL, (long) CURLUSESSL_ALL);
curl_easy_setopt(curl, CURLOPT_URL, SMTP_SERVER);
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM_ADDR);
recipients = curl_slist_append(recipients, TO_ADDR);
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
curl_easy_setopt(curl, CURLOPT_READDATA, msg);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
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);
}
free(msg->data[0]);
free(msg->data[3]);
free(msg);
return (int)res;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment