Created
November 5, 2011 22:30
-
-
Save sehe/1342118 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
one | |
two | |
three | |
Hello, this is CURL email SMTP | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
all:test cppversion | |
%:%.c | |
gcc -O0 -g $^ -o $@ -lcurl | |
cppversion: test.cpp | |
g++ -O0 -g $^ -o $@ -lcurl |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "curl/curl.h" | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <memory.h> | |
#include <string.h> | |
#define GetCurrentDir getcwd | |
#define USERNAME "yaya@gmail.com" | |
#define PASSWORD "yaya" | |
#define SMTPSERVER "smtp.gmail.com" | |
#define SMTPPORT ":587" | |
#define RECIPIENT "<yaya@gmail.com>" | |
#define MAILFROM "<yaya@gmail.com>" | |
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000 | |
/* Note that you should include the actual meta data headers here as well if | |
you want the mail to have a Subject, another From:, show a To: or whatever | |
you think your mail should feature! */ | |
char **text = 0; | |
void free_text() | |
{ | |
if (text) | |
{ | |
char** it; | |
for (it = text; *it; ++it) | |
free(*it); | |
free(text); | |
text = 0; | |
} | |
} | |
static int read_text(char* fname) | |
{ | |
unsigned capacity = 10; | |
int linecount = 0; | |
free_text(); | |
text = realloc(text, capacity*sizeof(*text)); | |
FILE* file = fopen(fname, "r"); | |
if (!file) | |
{ perror("Opening file"); return 1; } | |
char buf[2048]; | |
char* line = 0; | |
while (line = fgets(buf, sizeof(buf), file)) | |
{ | |
if (linecount>=capacity) | |
{ | |
capacity *= 2; | |
text = realloc(text, capacity*sizeof(*text)); | |
} | |
text[linecount++] = strdup(line); | |
} | |
if (linecount>=capacity) | |
text = realloc(text, (++capacity)*sizeof(*text)); | |
text[linecount] = 0; // terminate | |
fclose(file); | |
return 0; | |
} | |
struct WriteThis { | |
int counter; | |
}; | |
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp) | |
{ | |
/* This was already in. */ | |
struct WriteThis *pooh = (struct WriteThis *)userp; | |
const char *data; | |
if(size*nmemb < 1) | |
return 0; | |
data = text[pooh->counter]; | |
if(data) { | |
size_t len = strlen(data); | |
memcpy(ptr, data, len); | |
pooh->counter++; /* advance pointer */ | |
return len; | |
} | |
return 0; /* no more data left to deliver */ | |
} | |
static struct timeval tvnow(void) | |
{ | |
/* | |
** time() returns the value of time in seconds since the Epoch. | |
*/ | |
struct timeval now; | |
now.tv_sec = (long)time(NULL); | |
now.tv_usec = 0; | |
return now; | |
} | |
static long tvdiff(struct timeval newer, struct timeval older) | |
{ | |
return (newer.tv_sec-older.tv_sec)*1000+ | |
(newer.tv_usec-older.tv_usec)/1000; | |
} | |
int main(int argc, char** argv) | |
{ | |
if (argc<2) | |
{ | |
printf("Usage: %s <email.eml>\n", argv[0]); | |
exit(255); | |
} else | |
{ | |
printf("Reading email body from %s\n", argv[1]); | |
if (0 != read_text(argv[1])) | |
exit(254); | |
} | |
CURL *curl; | |
CURLM *mcurl; | |
int still_running = 1; | |
struct timeval mp_start; | |
char mp_timedout = 0; | |
struct WriteThis pooh; | |
struct curl_slist* rcpt_list = NULL; | |
pooh.counter = 0; | |
curl_global_init(CURL_GLOBAL_DEFAULT); | |
curl = curl_easy_init(); | |
if(!curl) | |
return 1; | |
mcurl = curl_multi_init(); | |
if(!mcurl) | |
return 2; | |
rcpt_list = curl_slist_append(rcpt_list, RECIPIENT); | |
/* more addresses can be added here | |
rcpt_list = curl_slist_append(rcpt_list, "<others@example.com>"); | |
*/ | |
curl_easy_setopt(curl, CURLOPT_URL, "smtp://" SMTPSERVER SMTPPORT); | |
curl_easy_setopt(curl, CURLOPT_USERNAME, USERNAME); | |
curl_easy_setopt(curl, CURLOPT_PASSWORD, PASSWORD); | |
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); | |
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, MAILFROM); | |
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt_list); | |
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); | |
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,0); | |
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); | |
curl_easy_setopt(curl, CURLOPT_READDATA, &pooh); | |
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); | |
curl_easy_setopt(curl, CURLOPT_SSLVERSION, 0); | |
curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0); | |
curl_multi_add_handle(mcurl, curl); | |
mp_timedout = 0; | |
mp_start = tvnow(); | |
/* we start some action by calling perform right away */ | |
curl_multi_perform(mcurl, &still_running); | |
while(still_running) { | |
struct timeval timeout; | |
int rc; /* select() return code */ | |
fd_set fdread; | |
fd_set fdwrite; | |
fd_set fdexcep; | |
int maxfd = -1; | |
long curl_timeo = -1; | |
FD_ZERO(&fdread); | |
FD_ZERO(&fdwrite); | |
FD_ZERO(&fdexcep); | |
/* set a suitable timeout to play around with */ | |
timeout.tv_sec = 1; | |
timeout.tv_usec = 0; | |
curl_multi_timeout(mcurl, &curl_timeo); | |
if(curl_timeo >= 0) { | |
timeout.tv_sec = curl_timeo / 1000; | |
if(timeout.tv_sec > 1) | |
timeout.tv_sec = 1; | |
else | |
timeout.tv_usec = (curl_timeo % 1000) * 1000; | |
} | |
/* get file descriptors from the transfers */ | |
curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd); | |
/* In a real-world program you OF COURSE check the return code of the | |
function calls. On success, the value of maxfd is guaranteed to be | |
greater or equal than -1. We call select(maxfd + 1, ...), specially in | |
case of (maxfd == -1), we call select(0, ...), which is basically equal | |
to sleep. */ | |
//rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); | |
if (tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) { | |
fprintf(stderr, "ABORTING TEST, since it seems " | |
"that it would have run forever.\n"); | |
break; | |
} | |
switch(rc) { | |
case -1: | |
/* select error */ | |
break; | |
case 0: /* timeout */ | |
default: /* action */ | |
curl_multi_perform(mcurl, &still_running); | |
break; | |
} | |
} | |
curl_slist_free_all(rcpt_list); | |
curl_multi_remove_handle(mcurl, curl); | |
curl_multi_cleanup(mcurl); | |
curl_easy_cleanup(curl); | |
curl_global_cleanup(); | |
free_text(); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "curl/curl.h" | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <memory.h> | |
#include <string.h> | |
#define GetCurrentDir getcwd | |
#include <vector> | |
#include <fstream> | |
#define USERNAME "yaya@gmail.com" | |
#define PASSWORD "yaya" | |
#define SMTPSERVER "smtp.gmail.com" | |
#define SMTPPORT ":587" | |
#define RECIPIENT "<yaya@gmail.com>" | |
#define MAILFROM "<yaya@gmail.com>" | |
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000 | |
/* Note that you should include the actual meta data headers here as well if | |
you want the mail to have a Subject, another From:, show a To: or whatever | |
you think your mail should feature! */ | |
std::vector<std::string> text; | |
static int read_text(char* fname) | |
{ | |
//Read the text file, add each line to the char array. | |
std::ifstream myfile (fname); | |
std::string line; | |
while (std::getline(myfile, line)) | |
text.push_back(line + '\n'); | |
return 0; | |
} | |
struct WriteThis { | |
int counter; | |
}; | |
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp) | |
{ | |
/* This was already in. */ | |
struct WriteThis *pooh = (struct WriteThis *)userp; | |
if(size*nmemb < 1) | |
return 0; | |
if (pooh->counter < text.size()) | |
{ | |
const std::string& data = text[pooh->counter]; | |
memcpy(ptr, data.data(), data.length()); | |
pooh->counter++; /* advance pointer */ | |
return data.length(); | |
} | |
return 0; /* no more data left to deliver */ | |
} | |
static struct timeval tvnow(void) | |
{ | |
/* | |
** time() returns the value of time in seconds since the Epoch. | |
*/ | |
struct timeval now; | |
now.tv_sec = (long)time(NULL); | |
now.tv_usec = 0; | |
return now; | |
} | |
static long tvdiff(struct timeval newer, struct timeval older) | |
{ | |
return (newer.tv_sec-older.tv_sec)*1000+ | |
(newer.tv_usec-older.tv_usec)/1000; | |
} | |
int main(int argc, char** argv) | |
{ | |
if (argc<2) | |
{ | |
printf("Usage: %s <email.eml>\n", argv[0]); | |
exit(255); | |
} else | |
{ | |
printf("Reading email body from %s\n", argv[1]); | |
if (0 != read_text(argv[1])) | |
exit(254); | |
} | |
CURL *curl; | |
CURLM *mcurl; | |
int still_running = 1; | |
struct timeval mp_start; | |
char mp_timedout = 0; | |
struct WriteThis pooh; | |
struct curl_slist* rcpt_list = NULL; | |
pooh.counter = 0; | |
curl_global_init(CURL_GLOBAL_DEFAULT); | |
curl = curl_easy_init(); | |
if(!curl) | |
return 1; | |
mcurl = curl_multi_init(); | |
if(!mcurl) | |
return 2; | |
rcpt_list = curl_slist_append(rcpt_list, RECIPIENT); | |
/* more addresses can be added here | |
rcpt_list = curl_slist_append(rcpt_list, "<others@example.com>"); | |
*/ | |
curl_easy_setopt(curl, CURLOPT_URL, "smtp://" SMTPSERVER SMTPPORT); | |
curl_easy_setopt(curl, CURLOPT_USERNAME, USERNAME); | |
curl_easy_setopt(curl, CURLOPT_PASSWORD, PASSWORD); | |
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); | |
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, MAILFROM); | |
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt_list); | |
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); | |
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,0); | |
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); | |
curl_easy_setopt(curl, CURLOPT_READDATA, &pooh); | |
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); | |
curl_easy_setopt(curl, CURLOPT_SSLVERSION, 0); | |
curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0); | |
curl_multi_add_handle(mcurl, curl); | |
mp_timedout = 0; | |
mp_start = tvnow(); | |
/* we start some action by calling perform right away */ | |
curl_multi_perform(mcurl, &still_running); | |
while(still_running) { | |
struct timeval timeout; | |
int rc; /* select() return code */ | |
fd_set fdread; | |
fd_set fdwrite; | |
fd_set fdexcep; | |
int maxfd = -1; | |
long curl_timeo = -1; | |
FD_ZERO(&fdread); | |
FD_ZERO(&fdwrite); | |
FD_ZERO(&fdexcep); | |
/* set a suitable timeout to play around with */ | |
timeout.tv_sec = 1; | |
timeout.tv_usec = 0; | |
curl_multi_timeout(mcurl, &curl_timeo); | |
if(curl_timeo >= 0) { | |
timeout.tv_sec = curl_timeo / 1000; | |
if(timeout.tv_sec > 1) | |
timeout.tv_sec = 1; | |
else | |
timeout.tv_usec = (curl_timeo % 1000) * 1000; | |
} | |
/* get file descriptors from the transfers */ | |
curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd); | |
/* In a real-world program you OF COURSE check the return code of the | |
function calls. On success, the value of maxfd is guaranteed to be | |
greater or equal than -1. We call select(maxfd + 1, ...), specially in | |
case of (maxfd == -1), we call select(0, ...), which is basically equal | |
to sleep. */ | |
//rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); | |
if (tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) { | |
fprintf(stderr, "ABORTING TEST, since it seems " | |
"that it would have run forever.\n"); | |
break; | |
} | |
switch(rc) { | |
case -1: | |
/* select error */ | |
break; | |
case 0: /* timeout */ | |
default: /* action */ | |
curl_multi_perform(mcurl, &still_running); | |
break; | |
} | |
} | |
curl_slist_free_all(rcpt_list); | |
curl_multi_remove_handle(mcurl, curl); | |
curl_multi_cleanup(mcurl); | |
curl_easy_cleanup(curl); | |
curl_global_cleanup(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment