perosoft
<pre>
// ---------------------------------------------------------
// Send text + n files attached
//
// command line compile
//
// g++ -Wall -fexceptions -Wno-write-strings -DCURL_STATICLIB -I/usr/local/include -g -c send_email.cpp -o send_email.o
// g++ -o send_email send_email.o -lgthread-2.0 -pthread -lglib-2.0 -L/usr/local/lib -lcurl -lssh2 -lssl -lcrypto
//
// ---------------------------------------------------------
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <curl/curl.h>
using namespace std;
#define __FILENAME 100
#define __BUFSIZ 512
static const int CHARS = 256;
static const int SEND_BUF_SIZE = 54;
static char (*fileBuf)[CHARS] = NULL;
static const char cb64[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
#define __MAIL_BUFSIZ 65536
typedef struct sMailFile sMAILFILE, *psMAILFILE;
struct sMailFile {
FILE *pIn;
char szMailFile[ __FILENAME + 1 ];
char szBuffer [ __BUFSIZ + 1 ];
};
typedef class cSendMail cSENDMAIL, *pcSENDMAIL;
class cSendMail {
protected:
char *pszMailBuffer;
psMAILFILE psFile;
public:
cSendMail( bool *pbInitStatus );
~cSendMail( void );
char * MailBuffer( void ) {
return( &pszMailBuffer[ 0 ] );
}
int SendMail( char *pszFrom,
char *pszPassword,
char *pszSMTP,
char *pszSender,
char *pszMailTo,
char *pszSubject,
char *pszText ... );
};
cSENDMAIL::cSendMail( bool *pbInitStatus ) {
pszMailBuffer = NULL;
psFile = NULL;
if (( pszMailBuffer = ( char * )malloc( __MAIL_BUFSIZ )) == NULL ) {
*pbInitStatus = 0;
return;
}
if (( psFile = ( psMAILFILE )malloc( sizeof( sMAILFILE ))) == NULL ) {
*pbInitStatus = 0;
return;
}
psFile->pIn = NULL;
strcpy( psFile->szMailFile, "mail.txt" );
} // ***** Constructor cSENDMAIL::cSendMail ***** //
cSENDMAIL::~cSendMail( void ) {
if ( pszMailBuffer != NULL ) free( pszMailBuffer );
if ( psFile != NULL ) free( psFile );
} // ***** Destructor cSENDMAIL::cSendMail ***** //
static size_t my_payload_source( void *ptr,
size_t size,
size_t nmemb,
void *userp ) {
psMAILFILE psMailFile = ( psMAILFILE )userp;
if ( psMailFile->pIn == NULL ) {
if (( psMailFile->pIn = fopen( psMailFile->szMailFile, "rt" )) == NULL )
return( 0 );
}
if ( fgets( psMailFile->szBuffer, __BUFSIZ, psMailFile->pIn ) != NULL ) {
size_t len = strlen( psMailFile->szBuffer );
memcpy( ptr, psMailFile->szBuffer, len );
return( len );
}
fclose( psMailFile->pIn );
return( 0 );
}
static void encodeblock( unsigned char in[ 3 ],
unsigned char out[ 4 ],
int len ) {
out[0] = cb64[ in[0] >> 2 ];
out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=');
out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '=');
}
static void encode( FILE *infile,
unsigned char *output_buf,
int rowcount ) {
unsigned char in[3], out[4];
int i, len;
*output_buf = 0;
while( !feof( infile )) {
len = 0;
for ( i = 0; i < 3; i++ ) {
in[i] = (unsigned char) getc(infile);
if ( !feof( infile )) {
len++;
} else {
in[i] = 0;
}
}
if ( len ) {
encodeblock(in, out, len);
strncat((char*)output_buf, (char*)out, 4);
}
}
}
int cSENDMAIL::SendMail( char *pszFrom,
char *pszPassword,
char *pszSMTP,
char *pszSender,
char *pszMailTo,
char *pszSubject,
char *pszText ... ) {
bool bError = 0;
CURL *curl;
CURLcode res = CURLE_OK;
struct curl_slist *recipients = NULL;
char szFrom[ __BUFSIZ + 1 ];
char szTo [ __BUFSIZ + 1 ];
va_list ArgsPointer;
char *file_name;
FILE *hFile;
FILE *hOut;
size_t fileSize(0);
size_t len(0);
size_t buffer_size(0);
int no_of_rows;
int charsize;
int j;
unsigned char *b64encode;
string encoded_buf;
int pos;
string sub_encoded_buf;
va_start( ArgsPointer, pszText );
file_name = ( char * )va_arg( ArgsPointer, char * );
sprintf( szFrom, "<%s>", pszFrom );
sprintf( szTo , "<%s>", pszMailTo );
hOut = fopen( psFile->szMailFile, "wt" );
fprintf( hOut, "To: <%s>%s\r\n", pszMailTo, pszSender );
fprintf( hOut, "From: <%s>\r\n", pszFrom );
fprintf( hOut, "Sender_Email: <%s>\r\n", pszFrom );
fprintf( hOut, "Return-Path: <%s>\r\n", pszFrom );
fprintf( hOut, "Reply-To: <%s>\r\n", pszFrom );
fprintf( hOut, "Subject: %s\r\n", pszSubject );
if ( file_name != NULL ) {
fprintf( hOut, "Content-Type: multipart/mixed; boundary=\"MyBoundaryString\"\r\n" );
fprintf( hOut, "\r\n" );
fprintf( hOut, "--MyBoundaryString\r\n" );
fprintf( hOut, "Content-Type: text/plain; charset=UTF-8\r\n" );
fprintf( hOut, "\r\n" );
} else {
fprintf( hOut, "Content-Type: text/plain; charset=UTF-8\r\n" );
fprintf( hOut, "\r\n" );
}
fprintf( hOut, "%s\r\n", pszText );
if ( file_name != NULL )
do {
fileSize = 0;
len = 0;
buffer_size = 0;
fprintf( hOut, "--MyBoundaryString\r\n" );
fprintf( hOut, "Content-Type: application/x-msdownload; name=\"%s\"\r\n", file_name );
fprintf( hOut, "Content-Transfer-Encoding: base64\r\n" );
fprintf( hOut, "Content-Disposition: attachment; filename=\"%s\"\r\n", file_name );
fprintf( hOut, "\r\n" );
if (( hFile = fopen( file_name, "rb" )) != NULL ) {
fseek( hFile, 0, SEEK_END );
fileSize = +ftell( hFile );
fseek( hFile, 0, SEEK_SET );
no_of_rows = fileSize / SEND_BUF_SIZE + 1;
charsize = ( no_of_rows*72 ) + ( no_of_rows*2 );
b64encode = new unsigned char[charsize];
*b64encode = 0;
encode( hFile, b64encode, no_of_rows );
encoded_buf = ( char * )b64encode;
fileBuf = new char[no_of_rows][CHARS];
pos = 0;
for ( j = 0; j <= no_of_rows - 1; j++ ) {
sub_encoded_buf = encoded_buf.substr( pos*72, 72 );
sub_encoded_buf += "\r\n";
strcpy(fileBuf [len++ ], sub_encoded_buf.c_str());
buffer_size += sub_encoded_buf.size();
pos++;
}
for ( j = 0; j < no_of_rows; j++ )
fprintf( hOut, "%s", fileBuf[ j ] );
delete[] fileBuf;
delete[] b64encode;
} else {
printf( "File not found: %s\n", file_name );
bError = 1;
break;
}
} while (( file_name = ( char * )va_arg( ArgsPointer, char * )) != NULL );
va_end( ArgsPointer );
if ( file_name != NULL )
fprintf( hOut, "--MyBoundaryString--\r\n" );
fclose( hOut );
if ( !bError ) {
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_USERNAME, pszFrom );
curl_easy_setopt(curl, CURLOPT_PASSWORD, pszPassword );
curl_easy_setopt(curl, CURLOPT_URL, pszSMTP );
curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
// curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/certificate.pem");
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, szFrom );
recipients = curl_slist_append( recipients, szTo );
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients );
curl_easy_setopt(curl, CURLOPT_READFUNCTION, my_payload_source);
curl_easy_setopt(curl, CURLOPT_READDATA, psFile );
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);
}
return (int)res;
} // ***** Function cSENDMAIL::SendMail ***** //
char *pszFrom = "sender_email@gmail.com";
char *pszPassword = "sender_pasword";
char *pszSMTP = "smtp.gmail.com:587";
char *pszSender = "Send by Me";
char *pszTo = "send_to_e-mail";
char *pszSubject = "Subject";
void main( void ) {
bool bInitStatus = 1;
cSENDMAIL cSend( &bInitStatus );
if ( bInitStatus ) {
char *pszFormat = "Send by me: %s\r\n";
sprintf( cSend.MailBuffer(), pszFormat, "My Name" );
cSend.SendMail( pszFrom,
pszPassword,
pszSMTP,
pszSender,
pszTo,
pszSubject,
cSend.MailBuffer(),
/*
"file_1",
"file_2",
.
.
.