KouyeÏr
KouyeÏr

Reputation: 23

Send an email in c, server never reply after i send the body

I have created a little program to send an email in c. I did 3 functions : Connect : to connect to a server by using socket, SendAndRecieve : to send and recieve message to the mail server, SendAnEmail : to write the text that will be send by SendAndRecieve.

Connect and SendAndRecieve are working perfectly. My problem is in SendAnEmail. I don't know how to do finish the data step.

For each command, i recieve the answer of the server : 250 ****** But for the data one, it reply in first 354 but never 250 after the final full stop. I though it is the same protocol as telnet. The final full stop = end of the body. But it don't work. The mail server never reply.

Anyone know the solution to tell to the server that i finish to write the body ?

Code

SOCKET connexion(char* server_name,unsigned short port)
{
    char buf[1024]={0};
    int res_l= 0;
    int nbrecv;
    struct sockaddr_in   serverSockAddr;
    struct hostent     * serverHostEnt;
    SOCKET to_server_socket = 0;
    serverHostEnt = gethostbyname( server_name );
    if ( serverHostEnt == NULL )  {
        res_l = h_errno;
        return (SOCKET)-1;         }
    memcpy(&serverSockAddr.sin_addr,serverHostEnt->h_addr, serverHostEnt->h_length );
    serverSockAddr.sin_port = htons( port );/
    serverSockAddr.sin_family = AF_INET;            


/* Create socket */                                        
    to_server_socket = socket( AF_INET, SOCK_STREAM, 0 );

/* connexion request*/
    if( connect( to_server_socket, ( struct sockaddr * ) &serverSockAddr,sizeof( serverSockAddr ) ) < 0 ) 
        return (SOCKET)-3;
    while( !buf[0] ) nbrecv = recv( to_server_socket, buf, 1024, 0 );
    printf("Welcome message : %s\n",buf);
    return to_server_socket;
}

void SendAndReceive(SOCKET to_server_socket, char * messagesend)
{
    char bufreceive[1024];                                                             
    int size,retVal,nbrecv;                                         
    size  = (int)strlen( messagesend );                                                

    // SEND THE MESSAGE
    retVal = send( to_server_socket, messagesend, size, 0 );
    printf("Envoye : %s\n",messagesend)   ;

    // WAIT THE ANSWER    
    memset(bufreceive,0,1024);                                                                                       
    while(!bufreceive[0])  
        nbrecv = recv( to_server_socket, bufreceive, 1024, 0 );
    printf("Recu : %s\n",bufreceive);                                                  
}             

void SendAnEmail(SOCKET sock)
{
    //ehlo
    SendAndReceive(sock, "EHLO localhost\r\n");
    //mail from
    SendAndReceive(sock, "MAIL FROM:<[email protected]\r\n");
    //rcpt to
    SendAndReceive(sock, "RCPT TO:<[email protected]>\r\n");
    /data
    SendAndReceive(sock, "DATA\r\n");
    //Subject : Subject
    //
    //Body
    //.
    SendAndReceive(sock, "Subject : Subject\r\n\r\nBody\r\n.\r\n");
    //quit
    SendAndReceive(sock, "QUIT\r\n");
}

In your main, you must set the port =25, use a real smtp server for server_name, and add a library that contain Winsock2.h


CMD :

Welcome message : 220 mwinf5d05 ME ESMTP server ready

S: EHLO localhost

R: 250-mwinf5d05 hello [10.162.66.36], pleased to meet you
250-HELP
250-AUTH LOGIN PLAIN
250-SIZE 44000000
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 OK

S: MAIL FROM: <[email protected]>

R: 250 2.1.0 <[email protected]> sender ok

S: RCPT TO: <[email protected]>

R: 250 2.1.5 <[email protected]> recipient ok

S: DATA

R: 354 enter mail, end with "." on a line by itself

S: Subject: FlashRad

Ceci est un test.
.

I expected to be able to do like when i use telnet by myself :

Like it's explain in this website.

So anyone know what how to say that i finish to write the body ? Like the final full stop with telnet.

Upvotes: 1

Views: 146

Answers (1)

infixed
infixed

Reputation: 1155

RFC 821 says

The third step in the procedure is the DATA command.

        DATA <CRLF>

     If accepted, the receiver-SMTP returns a 354 Intermediate reply
     and considers all succeeding lines to be the message text.
     When the end of text is received and stored the SMTP-receiver
     sends a 250 OK reply.

     Since the mail data is sent on the transmission channel the end
     of the mail data must be indicated so that the command and
     reply dialog can be resumed.  SMTP indicates the end of the
     mail data by sending a line containing only a period.  A
     transparency procedure is used to prevent this from interfering
     with the user's text (see Section 4.5.2).

So you need to send a line with a only a single period after your body.

If you are waiting for a 250 after DATA, that would be a mistake too. You get 354 first, and then the 250 after the period only line

RFC 821

Upvotes: 1

Related Questions