abc_master
December 12th, 2001, 11:00 PM
How can you send emails in C++ by using system commands in Unix?. I have heard of mailx. what does it do? and can it help solve my problem?
|
Click to See Complete Forum and Search --> : C++ sending Email abc_master December 12th, 2001, 11:00 PM How can you send emails in C++ by using system commands in Unix?. I have heard of mailx. what does it do? and can it help solve my problem? Axter December 13th, 2001, 01:29 PM Here's a class that can do what you need. I added two example functions at the end. #include <stdio.h> #ifdef WIN32 #include <afxsock.h> #include <winsock.h> #pragma warning(disable:4786) #else //WIN32 typedef unsigned int SOCKET; #endif //WIN32 #include <string> #include <fstream> #include <list> #include <time.h> #include <ctype.h> class GeneralSendMailClass { public: class EmailAddr { public: EmailAddr(const std::string &EmailID, std::string UserName) : m_EmailID(EmailID), m_UserName(UserName) { } EmailAddr(const char*EmailID) : m_EmailID(EmailID), m_UserName("") { } const std::string m_EmailID; const std::string m_UserName; }; enum {SMTP_OUTGOING_MAIL_PORT = 25, BASE64_MAXLINE = 76, MAX_LINE_SIZE = 4094, AUTHENTICATION_PORT = 113}; enum LoginMethod{AUTH_LOGIN_METHOD, LOGIN_PLAIN_METHOD}; GeneralSendMailClass(std::string X_Mailer = "X-Mailer: GeneralSendMailClass By David Maisonave\r\n", std::string X_Phone = "") :m_socket(NULL), m_InitiateGood(true),m_UniqueContentID(0), m_X_Mailer(X_Mailer), m_X_Phone(X_Phone), Auth_UserID(""), Auth_Password(""), m_LoginMethod(AUTH_LOGIN_METHOD) { #ifdef WIN32 WORD wVersion = MAKEWORD( 1, 1 ); WSADATA wsaData; if (WSAStartup(wVersion, &wsaData)) m_InitiateGood=false; else m_InitiateGood = true; #endif //WIN32 } ~GeneralSendMailClass() { #ifdef WIN32 WSACleanup(); #endif //WIN32 } std::string SendEmail(const EmailAddr &To, const std::string &Subject, const std::string &Body, const std::string &EmailSenderHostName, const std::string &EmailSenderUserID, const EmailAddr &Sender = EmptyEmailAddr, const std::list<EmailAddr> *CC_List = NULL, const std::list<EmailAddr> *BCC_List = NULL, const std::list<std::string> *AttachmentPath_List = NULL, const EmailAddr &ReplyToAddr = EmptyEmailAddr, const std::string *MessageID = NULL) { if (!m_InitiateGood) return "Error: GeneralSendMailClass failed to initiate properly"; if( (m_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET ) return "Error: socket function return INVALID_SOCKET"; std::string ReturnValue = NO_ERRORS; bool SendResetIf_Throw = false; ReturnValueFromReceive=""; try { hostent *mailhost = NULL; if( isdigit(*EmailSenderHostName.c_str()) && strchr(EmailSenderHostName.c_str(), '.') ) { unsigned long tmp_iaddr = inet_addr(EmailSenderHostName.c_str()); mailhost = gethostbyaddr( (const char *)&tmp_iaddr, 4, PF_INET ); } else mailhost = gethostbyname(EmailSenderHostName.c_str()); if(mailhost == NULL) throw("Error: hostent *mailhost = NULL"); struct sockaddr_in my_addr; my_addr.sin_family = AF_INET; my_addr.sin_port = htons(SMTP_OUTGOING_MAIL_PORT); memcpy( &my_addr.sin_addr, mailhost->h_addr_list[0], sizeof(struct in_addr) ); if (connect(m_socket, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))) throw("Error: connect failed"); if (!VerifyReply(CHK_220_REPLY)) throw("Error: Did not Recv 220 before hello"); if (Auth_Password.size()) { // send EHLO message sprintf(m_EmailBuffer, "EHLO %s%s", EmailSenderHostName.c_str(),CRLF_SET.c_str()); if (!SendStr()) throw("Error: Failed to send EHLO"); if (!VerifyReply(CHK_250_REPLY )) throw("Error: Failed to Recv 250 after sending EHLO"); // Send Auth Login switch(m_LoginMethod) { case AUTH_LOGIN_METHOD: sprintf(m_EmailBuffer, "AUTH LOGIN%s", CRLF_SET.c_str()); break; case LOGIN_PLAIN_METHOD: sprintf(m_EmailBuffer, "AUTH LOGIN PLAIN%s", CRLF_SET.c_str()); break; } if (!SendStr()) throw("Error: Failed to send AUTH LOGIN"); if (!VerifyReply(CHK_334_REPLY )) throw("Error: Failed to Recv 334 after sending AUTH LOGIN"); // Send AuthUserID if (Auth_UserID.size() == 0) Auth_UserID = EmailSenderUserID; sprintf(m_EmailBuffer, "%s%s", (m_LoginMethod == AUTH_LOGIN_METHOD)?Encode64(Auth_UserID).c_str():Auth_UserID.c_str(), CRLF_SET.c_str()); if (!SendStr()) throw("Error: Failed to send Auth_UserID"); if (!VerifyReply(CHK_334_REPLY )) throw("Error: Failed to Recv 334 after sending Auth_UserID"); // Send AuthPassword sprintf(m_EmailBuffer, "%s%s", (m_LoginMethod == AUTH_LOGIN_METHOD)?Encode64(Auth_Password).c_str():Auth_Password.c_str(), CRLF_SET.c_str()); if (!SendStr()) throw("Error: Failed to send Auth_Password"); if (!VerifyReply(CHK_235_REPLY )) throw("Error: Failed to Recv 235 after sending Auth_Password"); } else { // send HELO message sprintf(m_EmailBuffer, "HELO %s%s", EmailSenderHostName.c_str(),CRLF_SET.c_str()); if (!SendStr()) throw("Error: Failed to send Hello"); if (!VerifyReply(CHK_250_REPLY )) throw("Error: Failed to Recv 250 after sending hello"); } SendResetIf_Throw = true; // send MAIL message if(Sender.m_EmailID.size()) {//Need to add code for Sender.m_UserName sprintf(m_EmailBuffer, "MAIL FROM: <%s", Sender.m_EmailID.c_str()); if( strchr(Sender.m_EmailID.c_str(), '@' ) ) strcat( m_EmailBuffer, ">"); else sprintf(m_EmailBuffer + strlen(m_EmailBuffer), "@%s>", EmailSenderHostName.c_str()); strcat(m_EmailBuffer, CRLF_SET.c_str()); } else sprintf(m_EmailBuffer, "MAIL FROM:<%s@%s>%s", EmailSenderUserID.c_str(), EmailSenderHostName.c_str(), CRLF_SET.c_str()); // send MAIL FROM message if (!SendStr()) throw("Error: Failed to send From"); if (!VerifyReply(CHK_250_REPLY )) throw("Error: Failed to Recv 250 after sending From"); // send RCPT message sprintf(m_EmailBuffer, "RCPT TO: <%s>%s", To.m_EmailID.c_str(), CRLF_SET.c_str()); if (!SendStr()) throw("Error: Failed to send TO"); if (!VerifyReply(CHK_250_REPLY )) throw("Error: Failed to Recv 250 after sending RCPT TO"); // send DATA message sprintf( m_EmailBuffer, "DATA%s", CRLF_SET.c_str()); if (!SendStr()) throw("Error: Failed to send DATA line"); if (!VerifyReply(CHK_354_REPLY )) throw("Error: Failed to Recv 354 after sending DATA line"); // construct date string time_t tTime = time( NULL ); strftime(m_EmailBuffer, MAX_LINE_SIZE, "Date: %a, %d %b %Y %H:%M:%S %Z", localtime(&tTime)); strcat(m_EmailBuffer, CRLF_SET.c_str()); // send mail headers // Date: if(!SendStr()) throw("Error: Failed to send DATE"); // X-Mailer: if (m_X_Mailer.size()) { if(!Send(m_X_Mailer.c_str(), m_X_Mailer.size())) throw("Error: Failed to send X-Mailer"); } // X-Phone: if (m_X_Phone.size()) { if(!Send(m_X_Phone.c_str(), m_X_Phone.size())) throw("Error: Failed to send X-Phone"); } // Message-ID: if(MessageID) { sprintf(m_EmailBuffer, "Message-ID: %s%s", MessageID->c_str(), CRLF_SET.c_str()); if(!SendStr()) throw("Error: Failed to send Message-ID"); } // To: sprintf(m_EmailBuffer, "To: <%s>", To.m_EmailID.c_str()); if(To.m_UserName.size()) { sprintf(m_EmailBuffer + strlen(m_EmailBuffer), " (%s)",To.m_UserName.c_str()); } strcat(m_EmailBuffer, CRLF_SET.c_str()); if(!SendStr()) throw("Error: Failed to send TO"); // From: if(Sender.m_EmailID.size()) { sprintf( m_EmailBuffer, "From: <%s>", Sender.m_EmailID.c_str()); if(Sender.m_UserName.size()) sprintf(m_EmailBuffer + strlen(m_EmailBuffer), " (%s)",Sender.m_UserName.c_str()); strcat(m_EmailBuffer, CRLF_SET.c_str()); } else sprintf( m_EmailBuffer, "From: <%s@%s>%s", EmailSenderUserID.c_str(), EmailSenderHostName.c_str(), CRLF_SET.c_str()); if(!SendStr()) throw("Error: Failed to send From"); // Reply-To: if(ReplyToAddr.m_EmailID.size()) { sprintf( m_EmailBuffer, "Reply-To: <%s>", ReplyToAddr.m_EmailID.c_str()); if(ReplyToAddr.m_UserName.size()) sprintf(m_EmailBuffer + strlen(m_EmailBuffer), " (%s)",ReplyToAddr.m_UserName.c_str()); strcat(m_EmailBuffer, CRLF_SET.c_str()); if(!SendStr()) throw("Error: Failed to send Reply-To"); } // CC: if(CC_List) { strcpy(m_EmailBuffer,"CC: "); for (std::list<EmailAddr>::const_iterator email_addr_item = CC_List->begin(); email_addr_item != CC_List->end();email_addr_item++) { std::list<EmailAddr>::const_iterator test_item = email_addr_item; test_item++; sprintf(m_EmailBuffer + strlen(m_EmailBuffer), "<%s>", email_addr_item->m_EmailID.c_str()); if(email_addr_item->m_UserName.size()) sprintf(m_EmailBuffer + strlen(m_EmailBuffer), " (%s)%s",email_addr_item->m_UserName.c_str(), (test_item==CC_List->end())?"":EMAIL_ADDR_DIV_CHR); else strcat(m_EmailBuffer, (test_item==CC_List->end())?"":EMAIL_ADDR_DIV_CHR); } strcat(m_EmailBuffer, CRLF_SET.c_str()); if(!SendStr()) throw("Error: Failed to send CC_List"); } // BCC: if(BCC_List) { strcpy(m_EmailBuffer,"BCC: "); for (std::list<EmailAddr>::const_iterator email_addr_item = BCC_List->begin(); email_addr_item != BCC_List->end();email_addr_item++) { std::list<EmailAddr>::const_iterator test_item = email_addr_item; test_item++; sprintf(m_EmailBuffer + strlen(m_EmailBuffer), "<%s>", email_addr_item->m_EmailID.c_str()); if(email_addr_item->m_UserName.size()) sprintf(m_EmailBuffer + strlen(m_EmailBuffer), " (%s)%s",email_addr_item->m_UserName.c_str(), (test_item==BCC_List->end())?"":EMAIL_ADDR_DIV_CHR); else strcat(m_EmailBuffer, (test_item==BCC_List->end())?"":EMAIL_ADDR_DIV_CHR); } strcat(m_EmailBuffer, CRLF_SET.c_str()); if(!SendStr()) throw("Error: Failed to send BCC_List"); } // Subject: sprintf(m_EmailBuffer, "Subject: %s%s", Subject.c_str(), CRLF_SET.c_str()); if(!SendStr()) throw("Error: Failed to send Subject"); if(AttachmentPath_List) { sprintf(m_EmailBuffer, "MIME-Version: 1.0%sContent-type: multipart/mixed; boundary=\"#BOUNDARY#\"%s", CRLF_SET.c_str(), CRLF_SET.c_str()); SendStr(); } ///////////////////////////////////////////////////////// // 08/13/98 rlb // empty line needed after headers, RFC822 strcpy(m_EmailBuffer, CRLF_SET.c_str()); if(!SendStr()) throw("Error: Failed to send empty line needed after headers(1)"); strcpy(m_EmailBuffer, CRLF_SET.c_str()); if(!SendStr()) throw("Error: Failed to send empty line needed after headers(2)"); if(AttachmentPath_List) { sprintf(m_EmailBuffer, "%s--#BOUNDARY#%sContent-Type: text/plain; charset=ISO-8859-1%sContent-Transfer-Encoding: quoted-printable%s%s", CRLF_SET.c_str(), CRLF_SET.c_str(), CRLF_SET.c_str(), CRLF_SET.c_str(), CRLF_SET.c_str()); SendStr(); } ///////////////////////////////////////////////////////// // send message text if(!Send(Body.c_str(), Body.size())) throw("Error: Failed to send send message text"); // AttachmentPath_List: if(AttachmentPath_List) { for (std::list<std::string>::const_iterator attachment_file_item = AttachmentPath_List->begin(); attachment_file_item != AttachmentPath_List->end();attachment_file_item++) { std::string DestStringForEncodeData; if (Encode64(*attachment_file_item, DestStringForEncodeData)) { if(!Send(DestStringForEncodeData.c_str(), DestStringForEncodeData.size())) throw("Error: Failed to send BCC_List"); } } strcpy(m_EmailBuffer, CRLF_SET.c_str()); strcat(m_EmailBuffer, "--#BOUNDARY#--"); SendStr(); } // send message terminator and receive reply if(!Send("\r\n.\r\n", 5)) throw("Error: Failed to send message terminator"); if(!VerifyReply(CHK_250_REPLY )) throw("Error: Failed to Recv 250 reply after sending message terminator"); SendResetIf_Throw=false; //No use sending reset if fail at this point // send QUIT message strcpy(m_EmailBuffer, "QUIT" ); strcat(m_EmailBuffer, CRLF_SET.c_str()); if(!SendStr()) throw("Error: Failed to send QUIT message"); if(!VerifyReply(CHK_221_REPLY )) throw("Error: Failed to Recv 221 reply after sending QUIT message"); } catch(const char* ErrMsg) { ReturnValue = ErrMsg; if (ReturnValueFromReceive.size()) { ReturnValue += " Last Rcvd = " + ReturnValueFromReceive; } if (SendResetIf_Throw) { strcpy(m_EmailBuffer, "RESET"); strcat(m_EmailBuffer, CRLF_SET.c_str()); SendStr(); strcpy(m_EmailBuffer, "QUIT"); strcat(m_EmailBuffer, CRLF_SET.c_str()); SendStr(); } } shutdown (m_socket, 2); #ifdef WIN32 closesocket(m_socket); #else #endif m_socket = NULL; return ReturnValue; } static const char* NO_ERRORS; std::string Auth_Password; std::string Auth_UserID; LoginMethod m_LoginMethod; private: SOCKET m_socket; bool m_InitiateGood; char m_EmailBuffer[MAX_LINE_SIZE + 1]; const std::string m_X_Mailer; const std::string m_X_Phone; int m_UniqueContentID; std::string ReturnValueFromReceive; static const char* m_base64Table; static const char* CHK_220_REPLY; static const char* CHK_221_REPLY; static const char* CHK_235_REPLY; static const char* CHK_250_REPLY; static const char* CHK_334_REPLY; static const char* CHK_354_REPLY; static const char* EMAIL_ADDR_DIV_CHR; static const std::string CRLF_SET; static const EmailAddr EmptyEmailAddr; bool SendStr(void) { return Send(m_EmailBuffer, strlen(m_EmailBuffer)); } bool VerifyReply(const char* szReplyString) { return Receive(m_EmailBuffer, MAX_LINE_SIZE, 0, szReplyString); } bool Receive(char* szBuffer, int nLenMax, int nFlags, const char* szReplyString) { int nRes = recv(m_socket, szBuffer, nLenMax, nFlags); ReturnValueFromReceive = szBuffer; if (nRes == SOCKET_ERROR ) return false; #if defined(_DEBUG) || defined(DEBUG) static bool FirstPass = true; std::ofstream file("log_recv.txt",std::ios::out|((FirstPass)?0:std::ios::app)); FirstPass=false; if (!file.fail()) { file.seekp(0, std::ios::end); file.write(szBuffer,nRes); file.close(); } #endif //defined(_DEBUG) || defined(DEBUG) *(szBuffer + nRes ) = '\0'; char* szPtr = strtok( szBuffer, "\n" ); while(szPtr) { if(*(szPtr + 3) == ' ') { if(!strncmp(szPtr, szReplyString, strlen(szReplyString))) return true; else return false; } else szPtr = strtok( NULL, "\n" ); } return false; } bool Send(const char *szBuffer, size_t nLen) { int nCnt = 0; while( nCnt < nLen ) { int nRes = send( m_socket, szBuffer + nCnt, nLen - nCnt, 0); if( nRes == SOCKET_ERROR) return false; else nCnt += nRes; } return true; } bool Encode64(const unsigned char *in, unsigned inlen, unsigned char *out, unsigned outmax) { unsigned olen = (inlen + 2) / 3 * 4; if (outmax < olen) return false; while (inlen >= 3) { /* user provided max buffer size; make sure we don't go over it */ *out++ = m_base64Table[in[0] >> 2]; *out++ = m_base64Table[((in[0] << 4) & 0x30) | (in[1] >> 4)]; *out++ = m_base64Table[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; *out++ = m_base64Table[in[2] & 0x3f]; in += 3; inlen -= 3; } if (inlen > 0) { /* user provided max buffer size; make sure we don't go over it */ *out++ = m_base64Table[in[0] >> 2]; unsigned char oval = (in[0] << 4) & 0x30; if (inlen > 1) oval |= in[1] >> 4; *out++ = m_base64Table[oval]; *out++ = (inlen < 2) ? '=' : m_base64Table[(in[1] << 2) & 0x3c]; *out++ = '='; } if (olen < outmax) *out = '\0'; return true; } std::string Encode64(const char *in, unsigned inlen) { char *TmpBuf = new char[inlen*2]; std::string ReturnValue = ""; if (Encode64((const unsigned char *)in, inlen, (unsigned char *)TmpBuf, inlen*2)) { ReturnValue = TmpBuf; } delete [] TmpBuf; return ReturnValue; } std::string Encode64(const std::string &Src) { return Encode64(Src.c_str(), Src.size()); } bool Encode64(const std::string &FileName, std::string &encodedFile) { std::ifstream file(FileName.c_str(), std::ios::binary); if (file.fail()) { encodedFile = ""; return false; } file.seekg(0, std::ios::end); unsigned int FileLen = file.tellg(); file.seekg(0, std::ios::beg); unsigned char *SrcBuf = new unsigned char[FileLen]; file.read((char *)SrcBuf,FileLen); file.close(); unsigned int DestLen = FileLen * 1.5; unsigned char *DestBuf = new unsigned char[DestLen]; bool ReturnValue = Encode64(SrcBuf, FileLen, DestBuf, DestLen); if (ReturnValue) { encodedFile = CRLF_SET + CRLF_SET + "--#BOUNDARY#"; encodedFile += CRLF_SET + "Content-Type: text/plain; charset=ISO-8859-1; name=" + FileName; encodedFile += CRLF_SET + "Content-Transfer-Encoding: base64"; encodedFile += CRLF_SET + "Content-Disposition: attachment; filename=" + FileName; encodedFile += CRLF_SET + CRLF_SET; encodedFile += (char *)DestBuf; } delete [] SrcBuf; delete [] DestBuf; return ReturnValue; } }; const char* GeneralSendMailClass::NO_ERRORS = "OK"; const char* GeneralSendMailClass::CHK_220_REPLY = "220"; const char* GeneralSendMailClass::CHK_221_REPLY = "221"; const char* GeneralSendMailClass::CHK_235_REPLY = "235"; const char* GeneralSendMailClass::CHK_250_REPLY = "250"; const char* GeneralSendMailClass::CHK_334_REPLY = "334"; const char* GeneralSendMailClass::CHK_354_REPLY = "354"; const char* GeneralSendMailClass::EMAIL_ADDR_DIV_CHR = ","; const std::string GeneralSendMailClass::CRLF_SET = "\r\n"; const GeneralSendMailClass::EmailAddr GeneralSendMailClass::EmptyEmailAddr = ""; const char* GeneralSendMailClass::m_base64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"; void SimpleExampleFunctionUsingGeneralSendMailClass(void) { GeneralSendMailClass MyGeneralSendMailClass; MyGeneralSendMailClass.Auth_Password = "MyPasswordHere"; //Not needed if server does NOT require Auth MyGeneralSendMailClass.SendEmail( "JoneDoe@axter.com", // Recipient Email address "*File Test x99: Please ignore this email.", //Subject "Test from GeneralSendMailClass. Please ignore this email.", //Email Body "foofoo.com", //Host Name (sender's Hostname) "MyUserID" //Sender's UserID ); } void Example1FunctionUsingGeneralSendMailClass(void) { GeneralSendMailClass MyGeneralSendMailClass; MyGeneralSendMailClass.Auth_Password = "MyPasswordHere";//Not needed if server does NOT require Auth MyGeneralSendMailClass.Auth_UserID = "TheUserID"; //This is usually the same as EmailSenderUserID passed to SendEmail function std::list<std::string> ListOfAttachments; //optional list of attachments ListOfAttachments.push_back("c:\\test10.txt"); ListOfAttachments.push_back("c:\\test11.txt"); ListOfAttachments.push_back("c:\\test12.txt"); std::string Results = MyGeneralSendMailClass.SendEmail( "BenLaden@dip.com", // Recipient Email address "Hello",//Subject "You can run, but you can't hide.",//Email Body "af.mil", "MyUserID", "", NULL, //CC list NULL, //BCC list &ListOfAttachments); if (Results != GeneralSendMailClass::NO_ERRORS) { printf("Error:\r\n"); printf(Results.c_str()); printf("\r\n\r\nPress ENTER to quit\r\n"); getchar(); } } int main(int argc, char* argv[]) { SimpleExampleFunctionUsingGeneralSendMailClass(); Example1FunctionUsingGeneralSendMailClass(); return 0; } codeguru.com
Copyright Internet.com Inc., All Rights Reserved. |