///////////////////////////////////////////////////////////////////////////// // Rev 11/12/2003 // // // SENDMAIL.C // ---------- // // // Sylvain MARECHAL - sylvain.marechal1@libertysurf.fr ///////////////////////////////////////////////////////////////////////////// // // VERY Simple SMTP client // This example doesn't delete messages in the POP3 server // // Unix port is be very simple but isn't done ... // // ///////////////////////////////////////////////////////////////////////////// #ifdef _WIN32 #include #define SOCKETERRNO WSAGetLastError() #else #define SOCKETERRNO errno // etc ... #endif #include #include #include #include ///////////////////////////////////////////////////////////////////////////// // // SOCKADDR TCPUDPFORMATADRESS ///////////////////////////////////////////////////////////////////////////// // // DESCRIPTION // --sockaddr TcpUdpFormatAdress-- // ARGUMENTS // Argument1: char * host // Argument2: u_short port // RETOUR/RESULTAT // static struct // REMARQUE // Rev 11/12/2003 ////////////////////////////////////////////////////////////////////////////// static struct sockaddr TcpUdpFormatAdress( char * host, u_short port ) { struct sockaddr_in addr; struct sockaddr addrRet; struct hostent FAR *lphost ; u_long IP; memset((char*)&addr, 0, sizeof(addr)); /* Soit on fournit une adresse IP, soit on fournit un nom */ if ((IP = inet_addr(host)) == (u_long)INADDR_NONE) { if ((lphost = gethostbyname(host))==NULL) { memset( (char * )&addrRet, sizeof(addrRet), 0 ); return addrRet; } addr.sin_family = lphost->h_addrtype; #ifdef _WIN16 /* A définir dans le projet WIN16 */ _fmemcpy (&addr.sin_addr, lphost->h_addr, lphost->h_length); #else /* WIN32, UNIX*/ memcpy (&addr.sin_addr, lphost->h_addr, lphost->h_length); #endif } else { addr.sin_family = AF_INET; addr.sin_addr.s_addr = IP; } /* Port destination */ addr.sin_port = htons((u_short)port ); memcpy( (char *)&addrRet, (char *)&addr, sizeof(addrRet) ); return addrRet; } ///////////////////////////////////////////////////////////////////////////// // // SENDSMTPBUFFER ///////////////////////////////////////////////////////////////////////////// // // DESCRIPTION // --SendSmtpBuffer-- // ARGUMENTS // Argument1: SOCKET hSocket // Argument2: char * pszBuffer // RETOUR/RESULTAT // static void // REMARQUE // Rev 11/12/2003 ////////////////////////////////////////////////////////////////////////////// static void SendSmtpBuffer( SOCKET hSocket, char * pszBuffer ) { int cb = strlen( pszBuffer ); if( cb > 0 ) send( hSocket, pszBuffer, cb, 0 ); } ///////////////////////////////////////////////////////////////////////////// // // SENDRECEIVE ///////////////////////////////////////////////////////////////////////////// // // DESCRIPTION // --SendReceive-- // ARGUMENTS // Argument1: SOCKET hSocket // Argument2: char * pszBuffer // RETOUR/RESULTAT // void // REMARQUE // Rev 11/12/2003 ////////////////////////////////////////////////////////////////////////////// static void SendReceive( SOCKET hSocket, char * pszBuffer ) { char Buffer[10240]; int cb, cbBuffer; SendSmtpBuffer( hSocket, pszBuffer ); /* Wait the \r\n*/ cbBuffer = 0; while( 1 ) { cb = recv( hSocket, Buffer + cbBuffer, sizeof(Buffer) - 1 - cbBuffer, 0 ); if( cb <= 0 ) { break; } cbBuffer += cb; if( memcmp( Buffer + cbBuffer - 2, "\r\n", 2 ) == 0 ) { break; } } if( cbBuffer > 0 ) { Buffer[cbBuffer] = 0; write( 1, Buffer, cbBuffer ); } else { printf( "Connection broken (%d)\n", SOCKETERRNO ); } } ///////////////////////////////////////////////////////////////////////////// // // MAIN ///////////////////////////////////////////////////////////////////////////// // // DESCRIPTION // --main-- // ARGUMENTS // Argument1: int argc // Argument2: char * argv[] // RETOUR/RESULTAT // void // REMARQUE // Rev 11/12/2003 ////////////////////////////////////////////////////////////////////////////// void main( int argc, char * argv[]) { struct sockaddr addrConnect; char Buffer[10240]; int cbBuffer; int cb; char szHost[256] = "localhost"; int nPort = 25; SOCKET hSocket; #ifdef _WIN32 WSADATA wsaData; WSAStartup(0x202, &wsaData); #endif // Print how it works printf( "Usage: %s [port (default is 25)] \n", argv[0] ); // get user / pass / port if( argc > 1 ) strcpy( szHost, argv[1] ); if( argc > 2 ) nPort = atoi( argv[2] ); if( nPort == 0 ) nPort = 25; // Connect to SMTP server hSocket = socket(AF_INET, SOCK_STREAM, 0); addrConnect = TcpUdpFormatAdress( szHost, (u_short )nPort ); if( connect(hSocket, &addrConnect, sizeof(addrConnect)) == SOCKET_ERROR ) { printf( "Can't connect (%d)\n", SOCKETERRNO ); exit(1); } // Receive server wellcome string cb = recv( hSocket, Buffer, sizeof(Buffer) - 1, 0 ); Buffer[cb] = 0; printf( Buffer ); // HELO remplaced by EHLO (rfc 1425) // // HELO // SendReceive( hSocket, "HELO MYMACHINE\r\n" ); SendReceive( hSocket, "EHLO MYMACHINE\r\n" ); // MAIL FROM: SendReceive( hSocket, "MAIL FROM: \r\n" ); // RCPT TO: // The destination address should exist ! SendReceive( hSocket, "RCPT TO: \r\n" ); // DATA SendReceive( hSocket, "DATA\r\n" ); // The text of the message // note that the mime header (with sender and addressee) are set only // for informationnal purposes (so it can be different)! cbBuffer = sprintf( Buffer, "Date: Fri, 25 Apr 2025 24:00:00 +0100 (CET)\r\n" "From: tutu@tutu\r\n" // No matter if MIME header is different ! "Subject: COUCOU\r\n" "MIME-Version: 1.0\r\n" "X-Priority: 3\r\n" "To: \"tata\" \r\n" // Idem "\r\n" "COUCOU \r\n\r\n.\r\n" ); SendReceive( hSocket, Buffer ); // QUIT SendReceive( hSocket, "QUIT\r\n" ); }