Sending email using C++
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4

Thread: Sending email using C++

Hybrid View

  1. #1
    Join Date
    Jan 2005
    Location
    Clemson, South Carolina
    Posts
    651

    Sending email using C++

    I am experimenting with sending email directly from an .exe created by Visual Studio 2010, using C++. I've taken some code originally posted by Andreas Masur (with minor modifications) as a starting point to start learning about this.

    When I call the function SendEmail("mail.mydomain.com","targetaddress@mydomain.com","sentfromaddress@mydomain.com","email"), it makes it all the way through the function,and fills m_ErrorLogListBox with: "Sent email as email message to targetaddress@mydomain.com." (In other words, it seems to go through without problems, connecting as needed). When I check my email, however, nothing arrives. My domain host says that I need a user name and password in order to send email (which is reassuring). Unfortunately, I don't know how to modify the code to include these things.

    Can anyone give me some pointers on where to go from here? (Specifically, how do I include passwords and so forth...)

    Code:
    void CTestEmailProgramDlg::Check(int iStatus, char *szFunction)
    {
    	if((iStatus != SOCKET_ERROR) && (iStatus))
    		return;
     
    	string text_string(szFunction);
    	string error_string("Error during call to " + text_string + ": " + DataManip::itos(iStatus) + " - " + DataManip::itos(GetLastError()));
    	m_ErrorLogListBox.AddString(error_string.c_str());
    }
    
    bool CTestEmailProgramDlg::SendEmail(char* smtpserver, char* toaddress, char* fromaddress, char* message)
    {
    	int         iProtocolPort        = 0;
    	char        szSmtpServerName[64] = "";
    	char        szToAddr[64]         = "";
    	char        szFromAddr[64]       = "";
    	char        szBuffer[4096]       = "";
    	char        szLine[255]          = "";
    	char        szMsgLine[255]       = "";
    	SOCKET      hServer;
    	WSADATA     WSData;
    	LPHOSTENT   lpHostEntry;
    	LPSERVENT   lpServEntry;
    	SOCKADDR_IN SockAddr;
    
    	// Load command-line args
    	lstrcpy(szSmtpServerName, smtpserver);
    	lstrcpy(szToAddr, toaddress);
    	lstrcpy(szFromAddr, fromaddress);
    
    	// Create input stream for reading email message file
    	ifstream MsgFile(message);
    
    	// Attempt to intialize WinSock (1.1 or later)
    	if(WSAStartup(MAKEWORD(VERSION_MAJOR, VERSION_MINOR), &WSData))
    	{
    		string error_string = "Cannot find Winsock v" + DataManip::itos(VERSION_MAJOR) + "." + DataManip::itos(VERSION_MINOR) + " or later!\n";
    		m_ErrorLogListBox.AddString(error_string.c_str());
    
    		return false;
    	}
    
    	// Lookup email server's IP address.
    	lpHostEntry = gethostbyname(szSmtpServerName);
    	if(!lpHostEntry)
    	{
    		string servername(szSmtpServerName);
    		string error_string = "Cannot find SMTP mail server " + servername + "\n";
    		m_ErrorLogListBox.AddString(error_string.c_str());
    
    		return false;
    	}
    
    	// Create a TCP/IP socket, no specific protocol
    	hServer = socket(PF_INET, SOCK_STREAM, 0);
    	if(hServer == INVALID_SOCKET)
    	{
    		string error_string = "Cannot open mail server socket\n";
    		m_ErrorLogListBox.AddString(error_string.c_str());
      
    		return false;
    	}
    
    	// Get the mail service port
    	lpServEntry = getservbyname("mail", 0);
    
    	// Use the SMTP default port if no other port is specified
    	if(!lpServEntry)
    		iProtocolPort = htons(IPPORT_SMTP);
    	else
    		iProtocolPort = lpServEntry->s_port;
    
    	// Setup a Socket Address structure
    	SockAddr.sin_family = AF_INET;
    	SockAddr.sin_port   = iProtocolPort;
    	SockAddr.sin_addr   = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
    
    	// Connect the Socket
    	if(connect(hServer, (PSOCKADDR) &SockAddr, sizeof(SockAddr)))
    	{
    		string error_string = "Error connecting to Server socket\n";
    		m_ErrorLogListBox.AddString(error_string.c_str());
    
    		return false;
    	}
    
    	// Receive initial response from SMTP server
    	Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() Reply");
    
    	// Send HELO server.com
    	sprintf(szMsgLine, "HELO %s%s", szSmtpServerName, CRLF);
    	Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() HELO");
    	Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() HELO");
    
    	// Send MAIL FROM: <sender@mydomain.com>
    	sprintf(szMsgLine, "MAIL FROM:<%s>%s", szFromAddr, CRLF);
    	Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() MAIL FROM");
    	Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() MAIL FROM");
    
    	// Send RCPT TO: <receiver@domain.com>
    	sprintf(szMsgLine, "RCPT TO:<%s>%s", szToAddr, CRLF);
    	Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() RCPT TO");
    	Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() RCPT TO");
    
    	// Send DATA
    	sprintf(szMsgLine, "DATA%s", CRLF);
    	Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() DATA");
    	Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() DATA");
    
    	// Send all lines of message body (using supplied text file)
    	MsgFile.getline(szLine, sizeof(szLine));             // Get first line
    
    	do         // for each line of message text...
    	{
    		sprintf(szMsgLine, "%s%s", szLine, CRLF);
    		Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() message-line");
    		MsgFile.getline(szLine, sizeof(szLine)); // get next line.
    	} while(MsgFile.good());
    
    	// Send blank line and a period
    	sprintf(szMsgLine, "%s.%s", CRLF, CRLF);
    	Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() end-message");
    	Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() end-message");
    
    	// Send QUIT
    	sprintf(szMsgLine, "QUIT%s", CRLF);
    	Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() QUIT");
    	Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() QUIT");
    
    	// Report message has been sent
    	string text_message(message);
    	string to_address_string(szToAddr);
    	string error_string = "Sent " + text_message + " as email message to " + szToAddr;
    	m_ErrorLogListBox.AddString(error_string.c_str());
    
    	// Close server socket and prepare to exit.
    	closesocket(hServer);
    
    	WSACleanup();
    
    	return true;
    }
    error C2146a : syntax error : nebulizer stained in the tower floppy apple rider. Go rubble in flee smite. Bleeble snip snip.

    Documentation says: error C2146a - This means there is an error somewhere in the course of human endeavor. Fix in the usual way.

  2. #2
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,632

    Re: Sending email using C++

    Today many mail-servers require authentication before allowing you to send a mail. How this signalling is done I don't know but you can run the same commands as in the code by using Telnet to see what the server responds with. See http://en.wikipedia.org/wiki/Simple_...nsfer_Protocol
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    http://www.microsoft.com/visualstudio/eng/downloads

  3. #3
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,654

    Re: Sending email using C++

    if your server allows for a plain text user name and password, things are fairly easy, you just give the commands after the HELO (or EHLO) command.

    This usually will only work with internal domain authentication (meaning the SMTP server will need to be in the same domain as you).

    If you need actual SMTP authentication, then things are going to be considerably harder...
    You'll need to take a look at RFC5321, RFC2821, RFC1869, RFC1870, RFC2554, RFC1731, RFC2195...


    Here's the "simple" version of it all (http://www.fehcom.de/qmail/smtpauth.html)

    if you want a full implemention, you'll also need to handle SSL and TLS type encryption (needed for public SMTP sites like yahoo and gmail).

  4. #4
    Join Date
    May 2004
    Location
    45,000FT Above Nevada
    Posts
    1,538

    Re: Sending email using C++

    Or you could use these lib's and forget about all the strange stuff...

    http://www.marshallsoft.com/

    Select SMTP/POP3/IMAP Email component.
    Jim
    ATP BE400 CE500 (C550B-SPW) CE560XL MU300 CFI CFII

    "The speed of non working code is irrelevant"... Of course that is just my opinion, I could be wrong.

    "Nothing in the world can take the place of persistence. Talent will not; nothing is more common than unsuccessful men with talent. Genius will not; unrewarded genius is almost a proverb. Education will not; the world is full of educated derelicts. Persistence and determination are omnipotent. The slogan 'press on' has solved and always will solve the problems of the human race."...Calvin Coolidge 30th President of the USA.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center