C socket issue with SMTP

Hey guys, im trying to write a program that'll create a report then email the report... my problem is when it comes to the socket trying to send the second command after EHLO smtp,*.*

When the first command is sent its working fine... but when the program tries to send the second command it jams on bzero(buffer,256);... My understanding is bzero resets all values to 0 hence... clear the array buffer[] so it can be used again right? Why would the program execution stop???

/*---------EHLO SMTP-------------*/

    printf("Sending EHLO to SMTP\n");
   
    
    
    buffer[255] = "EHLO smtp.primus.ca";

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);

/*---------MAIL FROM-------------*/

    printf("Sending EHLO to SMTP\n");
   
    bzero(buffer,256);
    
    buffer[255] = "MAIL FROM: smtp.primus.ca";

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);

/*------------------------------*/ 

When im doing a fgets as below and enter the the commands to be sent to the SMTP it works perfectly...

printf("SMTP Command to be sent\n");
    bzero(buffer,256);
    fgets(buffer,255,stdin);
    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);

BUT if I take off the fget because I need the things to be automated then it fails...

printf("Automated way\n");
    
    buffer[255] = "MAIL FROM: test@primustel.ca";

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);

Now I assume it fails to SMTP code 500 (unrecognized command) because the buffer array values wasn't cleared but when I add the bzero the halt the execution of the software then timeout the connection...

printf("Automated way\n");
     
    bzero(buffer,255);
    
    buffer[255] = "MAIL FROM: test@primustel.ca";

     n = write(sockfd,buffer,strlen(buffer));
     if (n < 0) 
          error("ERROR writing to socket");
     bzero(buffer,256);
     n = read(sockfd,buffer,255);
     if (n < 0) 
          error("ERROR reading from socket");
     printf("%s\n",buffer);

-------------------Whole codes----------------------

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> 

void error(char *msg)
{
    perror(msg);
    exit(0);
}

int main(int argc, char *argv[])
{

    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];
    if (argc < 3) {
       fprintf(stderr,"usage %s hostname port\n", argv[0]);
       exit(0);
    }
    portno = atoi(argv[2]);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");
    server = gethostbyname(argv[1]);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr, 
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);
    serv_addr.sin_port = htons(portno);
    if (connect(sockfd,&serv_addr,sizeof(serv_addr)) < 0) 
        error("ERROR connecting");


/*---------EHLO SMTP-------------*/

    printf("Sending EHLO to SMTP\n");
   
    
    
    buffer[255] = "EHLO smtp.primus.ca";

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);

/*---------MAIL FROM-------------*/

    printf("Sending EHLO to SMTP\n");
   
    
    
    buffer[255] = "MAIL FROM: test@primustel.ca";

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);

/*------------------------------*/    


return 0;
}

Always remember you must not be assigning a string to array. You have to copy string to a array.
Changing

buffer[255] = "MAIL FROM: test@primustel.ca";

to

strcpy(buffer, "MAIL FROM: test@primustel.ca)";

solves the problem.

Alright good to know, I tried as you said and it seems to work like the program pass the commands to the SMTP however it returns an error 501 (invalid characters or command) so im assuming its because strcpy is copying the \0 nul character at the end of the line and send it too... i tried using

strcpy(buffer, "MAIL FROM: test@primustel.ca)";

And it jams there to im not getting any further reply... for shit n' giggle i tried to make it one less character and im getting error 501 so im lost here... anyone as an idea of how i could send this command without the nul character properly? i tried it all by inputing the commands by hand and it works fine it just when it comes to store it in the buffer... i tried everything i just past the whole night on this im about to slam my PC in the middle of the road... lol

It's not. strlen() doesn't count the null in its length. It needs a null to work anyway, a string's not a string without it!

strcpy(buffer, "MAIL FROM: test@primustel.ca)";

I'm shocked this even compiles. Anyway that's plainly not what you intended.

I think mail servers need their commands finished with \r\n, not just \n.

Tried the \n and \r\n didnt work same thing...

strcpy(buffer, "MAIL FROM: test@primustel.ca)";

Yeah i had noticed, i fixed it prior to try to compile but I dont think it would of neither :slight_smile:

Im lost... like if I use it works fine with all commands...

printf("SMTP Command to be sent\n");
    bzero(buffer,256);
    fgets(buffer,255,stdin);
    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);

Shouldn't

    fgets(buffer,255,stdin);
    n = write(sockfd,buffer,strlen(buffer));

be the same as

char *ehlo = "EHLO smtp.primus.ca";
n = write(sockfd,ehlo,strlen(buffer));

???

I was thinking could it be related to the fact that u can't really store letters but the decimal values of the letter but is converted in printf() as example with the %s ??? hence when sending whats stored in *ehlo it sends the decimal values and is not recognized by the smtp server???

Why not fix your quotes?

s/b strcpy(buffer, "MAIL FROM: test@primustel.ca");

Oh sorry that's already fixed but I was lazy and cut n' paste from the forum previous posts and forgot to change it after i cut n' pasted :slight_smile: I had notice it right away when gautamdheeraj posted it... That wouldn't compile anyways hehe :slight_smile: well i dont think it would... didnt try it but im sure it doesn't

---------- Post updated at 04:20 AM ---------- Previous update was at 12:18 AM ----------

Got it working, it worked with the \r\n I was making an error when negotiating with the smtp i had to put \n\n after the body and then ".\n" to close if it can be useful to anyone have fun.

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> 

void error(char *msg)
{
    perror(msg);
    exit(0);
}

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];
    if (argc < 3) {
       fprintf(stderr,"usage %s hostname port\n", argv[0]);
       exit(0);
    }
    portno = atoi(argv[2]);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");
    server = gethostbyname(argv[1]);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr, 
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);
    serv_addr.sin_port = htons(portno);
    if (connect(sockfd,&serv_addr,sizeof(serv_addr)) < 0) 
        error("ERROR connecting");
    
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);

 bzero(buffer,256);

/*------------------------------*/

printf("EHLO");

    strcpy(buffer,"ehlo smtp.primus.ca\n");

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);

/*------------------------------*/    

/*------------------------------*/

printf("AUTH");

    strcpy(buffer,"AUTH LOGIN\n");

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);

/*------------------------------*/ 

/*------------------------------*/

printf("AUTH UID");

    strcpy(buffer,"amR1bnBoeUBwcmltdXMuY2E=\n");

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);

/*------------------------------*/ 

/*------------------------------*/

printf("AUTH PWD");

    strcpy(buffer,"YXAwbGwwMTE=\n");

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);

/*------------------------------*/ 

/*------------------------------*/

printf("MAIL FROM");

    strcpy(buffer,"MAIL FROM: test1@primus.ca\n");

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);

/*------------------------------*/ 

/*------------------------------*/

printf("MAIL TO");

        
    strcpy(buffer,"RCPT TO: test2@primustel.ca\n");

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);

/*------------------------------*/       

/*------------------------------*/

printf("DATA");

    strcpy(buffer,"DATA\r\n");

    n = write(sockfd,buffer,strlen(buffer));

    strcpy(buffer,"Subject: test\r\n");

    n = write(sockfd,buffer,strlen(buffer));

    strcpy(buffer,"SMTP MAIL TOOL TEST WORKS!!!\r\n");

    n = write(sockfd,buffer,strlen(buffer));

    strcpy(buffer,"\n\n");

    n = write(sockfd,buffer,strlen(buffer));

    strcpy(buffer,".\n");

    n = write(sockfd,buffer,strlen(buffer));


/*------------------------------*/ 

/*------------------------------*/ 

    strcpy(buffer,"quit\n");

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);

/*------------------------------*/

return 0;
}