Reputation: 2484
I'm trying to create an application which will send an email with an attachment. The mail sending works fine, but i can't attach anything. I found this code on the net. Could someone help me, how to attach a file? My code so far:
int sendmail( char * smtpserver, char * from, char * to, char * subject, char * msg )
{
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
lstrcpyA( szSmtpServerName, smtpserver );
lstrcpyA( szToAddr, to );
lstrcpyA( szFromAddr, from );
// Attempt to intialize WinSock (1.1 or later)
if ( WSAStartup( MAKEWORD( VERSION_MAJOR, VERSION_MINOR ), &WSData ) )
{
printf( "\nCannot find Winsock v%d.%d or later", VERSION_MAJOR, VERSION_MAJOR );
return 1;
}
// Lookup email server's IP address.
lpHostEntry = gethostbyname( szSmtpServerName );
if ( !lpHostEntry )
{
printf( "\nCannot find SMTP mail server %s", szSmtpServerName );
return 1;
}
// Create a TCP/IP socket, no specific protocol
hServer = socket( PF_INET, SOCK_STREAM, 0 );
if ( hServer == INVALID_SOCKET )
{
printf( "\nCannot open mail server socket!" );
return 1;
}
// 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 ) ) )
{
printf( "\nError connecting to Server socket!" );
return 1;
}
// Receive initial response from SMTP server
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0), "recv() Reply" );
// Send HELO server.com
sprintf_s( szMsgLine, "HELO %s%s", smtpserver, CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() HELO" );
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0 ), "recv() HELO" );
// Send MAIL FROM: <[email protected]>
sprintf_s( szMsgLine, "MAIL FROM:<%s>%s", from, CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() MAIL FROM" );
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0 ), "recv() MAIL FROM" );
char buf[ 128 ], str[ 512 ];
char * pch;
memset( str, 0, sizeof( str ) );
strcpy_s( str, to );
pch = strtok( str, "," );//separate email addresses at ','
while (pch != NULL)
{
memset( buf, 0, sizeof( buf ) );
//printf("Buf: %s\n",pch);
strcpy_s( buf, pch );
pch = strtok (NULL, ",");
// Send RCPT TO: <[email protected]>
sprintf_s( szMsgLine, "RCPT TO:<%s>%s", buf, CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() RCPT TO" );
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0 ), "recv() RCPT TO" );
}
// Send DATA
sprintf_s( szMsgLine, "DATA%s", CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() DATA" );
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0 ), "recv() DATA" );
//Send Cc
sprintf_s( szMsgLine, "Cc: %s%s", "[email protected]",CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() Cc" );
// Send Subject
sprintf_s( szBuffer, "Subject: %s\n", subject );
Check( send( hServer, szBuffer, strlen( szBuffer ), 0 ), "send() Subject" );
//Send From
sprintf_s( szBuffer, "From: %s\n", "BIOS Update" );
Check( send( hServer, szBuffer, strlen( szBuffer ), 0 ), "send() From" );
//Send To
sprintf_s( szBuffer, "To: %s\n\n", to );
Check( send( hServer, szBuffer, strlen( szBuffer ), 0 ), "send() To" );
//Attach
sprintf_s( szMsgLine, "Attachment: %s%s", "d:\\test.txt",CRLF ); //this doesn't work
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() Attachment" );
sprintf_s( szMsgLine, "%s%s", msg, CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() message-line" );
// Send blank line and a period
sprintf_s( 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_s( 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
printf( "\nMail sent!" );
// Close server socket and prepare to exit.
closesocket( hServer );
WSACleanup();
return 0;
}
Thanks!
Upvotes: 3
Views: 5117
Reputation: 4314
I suggest you do some reading up on the SMTP protocol.
In the old days the content would be UUENCODED, and merely embedding it in the body of the email with a UUENCODE header was sufficient. I've done that a lot in my time :)
These days everything uses MIME as far as I know. Follow Rup's link (see his comment) or search the internet to understand what MIME does. Searching the internet should also give you two things:
You may also find SMTP libraries to handle all the SMTP protocol.
You also need to understand a little more about sockets. Did you honestly expect that writing Attachment: %s%s", "d:\\test.txt",CRLF
to a socket would cause the system to open the file and somehow stream the contents of the file to the socket?
Side notes on code:
Why CRLF? All the other email headers send \n
to terminate a line. It's all that is needed.
Sending two newlines after an email header (as done for the "To:" header) indicates the end of the email headers. Your "Attachment:" header actually forms the first line of the email body.
Upvotes: 2