1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
| #include <QCoreApplication>
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
#include <sstream>
#include <fstream>
#include <iostream>
/* The libcurl options want plain addresses, the viewable headers in the mail
* can get a full name as well.
*/
#define FROM_ADDR "m.mourad@gmail.com"
#define TO_ADDR "moha@gmail.com"
#define CC_ADDR "moha@outlook.com"
#define FROM_MAIL "Sender Person <" FROM_ADDR ">"
#define TO_MAIL "A Receiver <" TO_ADDR ">"
#define CC_MAIL "John CC Smith <" CC_ADDR ">"
struct UploadStatus {
int lines_read;
};
static const std::string payload_text[] = {
"To: moha@gmail.com\r\n",
"From: m.mourad@gmail.com\r\n",
"Subject: Test Email with Attachment\r\n",
"\r\n", /* empty line to divide headers from body */
"This is a test email with an attachment.\r\n",
nullptr // Change from NULL to nullptr
};
size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp) {
struct UploadStatus *upload_ctx = (struct UploadStatus *)userp;
const char *data;
if((size == 0) || (nmemb == 0) || ((size * nmemb) < 1)) {
return 0;
}
data = payload_text[upload_ctx->lines_read].c_str();
if(data) {
size_t len = strlen(data);
memcpy(ptr, data, len);
upload_ctx->lines_read++;
return len;
}
return 0;
}
std::string read_file(const std::string &file_path) {
std::ifstream file(file_path, std::ios::binary);
std::ostringstream oss;
oss << file.rdbuf();
return oss.str();
}
int main(int argc, char *argv[]) {
try
{
QCoreApplication a(argc, argv);
CURL *curl;
CURLcode res = CURLE_OK;
struct curl_slist *recipients = nullptr;
struct UploadStatus upload_ctx;
upload_ctx.lines_read = 0;
curl = curl_easy_init();
if(curl)
{
std::string attachment = read_file("messagetest.txt");
curl_easy_setopt(curl, CURLOPT_USERNAME, FROM_ADDR);
curl_easy_setopt(curl, CURLOPT_PASSWORD, "Mohamedmourad2024");
curl_easy_setopt(curl, CURLOPT_URL, "smtp://smtp.gmail.com:465");
curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
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, payload_source);
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: multipart/mixed; boundary=frontier");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
std::string body =
"--frontier\r\n"
"Content-Type: text/plain\r\n\r\n"
"This is a test email with an attachment.\r\n"
"--frontier\r\n"
"Content-Type: text/plain\r\n"
"Content-Disposition: attachment; filename=\"messagetest.txt\"\r\n\r\n" +
attachment + "\r\n"
"--frontier--";
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
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_slist_free_all(headers);
curl_easy_cleanup(curl);
}
return a.exec();
}
catch (const std::logic_error& e)
{
std::cerr << "Logic error: " << e.what() << std::endl;
return 1;
}
catch (const std::exception& e)
{
std::cerr << "Exception: " << e.what() << std::endl;
return 1;
}
catch (...)
{
std::cerr << "Unknown error occurred." << std::endl;
return 1;
}
} |
Partager