Thread: file download through ftp using C under Unix

  1. #1
    Registered User
    Join Date
    Apr 2005
    Posts
    3

    file download through ftp using C under Unix

    Hi,
    I am learning socket programming for a project coming up at work.
    I have to write a C program for downloading files from a ftp server.
    So far I have this code,
    [
    Code:
    #include <stdio.h>        /* for printf() and fprintf() */
    #include <sys/socket.h>   /* for socket(), connect(), send(), and recv() */
    #include <arpa/inet.h>    /* for sockaddr_in and inet_addr() */
    #include <stdlib.h>       /* for atoi() */
    #include <string.h>       /* for memset() */
    #include <unistd.h>       /* for close() */
    #define RCVBUFSIZE 32     /* Size of receive buffer */
    #include <netdb.h>
    void DieWithError(char *errorMessage);    /* Error handling function */
    int ftpSendFile(char * buf, char * host, int port);
    int ftpRecvResponse(int sock, char * buf);
    int main(int argc, char *argv[])
    {
        int sock;                          /*  Socket descriptor */
        int dataSock;		       /* Data sockeet Descriptor*/
        int numberOfConn;
        struct sockaddr_in ftpServAddr;   /*  server address */
        struct sockaddr_in dataServAddr;  /* data address*/
        struct hostent *pt_clientAddress;
        unsigned short ftpServPort;       /*  server port */
        unsigned short dataServPort;
        unsigned int PORTBUFFER;
        char *servlP;                      /*  Server IP address (dotted quad) */
        char * host_name;
        char *echoString;                  /*  String to send to echo server */
        char *command;
        char *p;
        char echoBuffer[RCVBUFSIZE];       /* Buffer for echo string */
        unsigned int echoStringLen;        /* Length of string to echo */
        int bytesRcvd, totalBytesRcvd;     /* Bytes read in single recv()
                                               and total bytes read */
       
                                     /* First arg' server IP address (dotted quad) */
    /*servlP = argv[0] ;*/
     servlP = "10.3.11.194";;                                /* Second arg' string to echo */
    
    /*echoString = argv[2] ;*/
    char buf[1024];
    
    ftpServPort = 21;
    printf(servlP);
    printf("Creating Socket");
    /* Create a reliable, stream socket using TCP */
    if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
         DieWithError(" socket () failed") ;
    
    
    /*Create a data socket for ftp file transfer */
    if ((dataSock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
         DieWithError(" data socket () failed") ;
    
    /* Construct the server address structure */
    memset(&ftpServAddr, 0, sizeof(ftpServAddr));         /* Zero out structure */
    ftpServAddr.sin_family         = AF_INET;              /* Internet address family */
    ftpServAddr.sin_addr.s_addr 	= inet_addr(servlP);       /* Server IP address */
    ftpServAddr.sin_port           = htons(ftpServPort); /* Server port */
    /* Establish the connection to the echo server */
    if (connect(sock, (struct sockaddr *) &ftpServAddr, sizeof(ftpServAddr)) < 0)
         DieWithError(" connect () failed") ;
    else
    	printf("Connection Successful");
    
    dataServPort = 20;
    /* Construct the server address structure */
    memset(&dataServAddr, 0, sizeof(dataServAddr));         /* Zero out structure */
    dataServAddr.sin_family         = AF_INET;              /* Internet address family */
    dataServAddr.sin_addr.s_addr 	= htonl(INADDR_ANY);       /* Server IP address */
    dataServAddr.sin_port           = htons(dataServPort); /* Server port */
    
    /* BIND socket to (sockaddr_in) clientAddr */
    bind(dataSock,(struct sockaddr *) &dataServAddr, sizeof(dataServAddr));
    
    /* LISTEN on data_socket */
    listen(dataSock, numberOfConn);
    
    gethostname(host_name, PORTBUFFER);
    printf("*******PORT********\n");
    printf(host_name);
    printf("\n*******\n");
    /* Determine input length */
    echoStringLen = strlen(echoString) ;
    printf("Sending HTTP Request");
    printf(echoString);
    
    p = strcpy(command, "USER username\r\n");
    send(sock, command, strlen(command), 0);
    ftpRecvResponse(sock, buf);
    p= strcpy(command, "PASS password\r\n");
    send(sock, command, strlen(command), 0);
    ftpRecvResponse(sock, buf);
    p = strcpy(command,"MODE S\r\n");
    send(sock,command, strlen(command), 0);
    ftpRecvResponse(sock, buf);
    p = strcpy(command,"TYPE A\r\n");
    send(sock,command, strlen(command), 0);
    ftpRecvResponse(sock, buf);
    //p= strcpy(command, "STRU F\r\n");
    //send(sock, command, strlen(command), 0);
    //ftpRecvResponse(sock, buf);
    /*p = strcpy(command,"LIST\r\n");
    send(sock,command, strlen(command), 0);*/
    p= strcpy(command, "PASV\r\n");
    send(sock, command, strlen(command), 0);
    ftpRecvResponse(sock, buf);
    if (connect(dataSock, (struct sockaddr *) &dataServAddr, sizeof(dataServAddr)) < 0)
         DieWithError(" connect () failed") ;
    else
    	printf("Connection Successful");
    
    
    p=strcpy(command, "RETR remote-filename\r\n");
    send(sock, command, strlen(command), 0);
    char *host;
    int tmpPort;
    host = "hostname";
    tmpPort = 20;
    
    ftpRecvResponse(sock, buf);
    
    printf("\n");     /* Print a final linefeed */
      close(sock);
      exit(0);
    
    }
    int ftpSendFile(char * buf, char * host, int port) {
       int sd;
       struct sockaddr_in pin;
       struct hostent *hp;
    
       if ((hp = gethostbyname(host)) == 0) {
          perror("gethostbyname");
          return -1;
       }
       memset(&pin, 0, sizeof(pin));
       pin.sin_family = AF_INET;
       pin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
       pin.sin_port = htons(port);
       if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
          perror("socket");
          return -1;
       }
       if (connect(sd,(struct sockaddr *)  &pin, sizeof(pin)) == -1) {
          perror("connect");
          return -1;
       }
       if(send(sd, buf, strlen(buf), 0) == -1) {
          perror("send");
          return -1;
       }
       /*closesocket(sd); //close the socket*/
       return 0;
    }
    int ftpRecvResponse(int sock, char * buf) {
       int i;
    
       if (recv(sock, buf, 5120, 0) == -1) {//receive the data
          perror("recv");
          return 0;;
       }
       for(i=(strlen(buf) - 1);i>0;i--) {
          if(buf[i]=='.' || buf[i]=='\r') { 
             buf[i+1]='\0';
             break;
          }
       }
       printf("%s\n",buf); //print response to the screen
       return 0;
    }
    With this code I can connect to the ftp server with my username and pass however I am not sure how to download the file after connecting to the server, I am getting seg. fault error after successfull connection.
    Appreciate any help in this regards.
    Thanks,

  2. #2
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    You never allocate memory for the variable "command".

  3. #3
    Registered User
    Join Date
    Apr 2005
    Posts
    3
    Hi,
    Can you please point me in the right direction

  4. #4
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Sigh, another copy-and-paste coder.

    Tutorial on C Strings

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. opening empty file causes access violation
    By trevordunstan in forum C Programming
    Replies: 10
    Last Post: 10-21-2008, 11:19 PM
  2. Formatting a text file...
    By dagorsul in forum C Programming
    Replies: 12
    Last Post: 05-02-2008, 03:53 AM
  3. Need Help Fixing My C Program. Deals with File I/O
    By Matus in forum C Programming
    Replies: 7
    Last Post: 04-29-2008, 07:51 PM
  4. Can we have vector of vector?
    By ketu1 in forum C++ Programming
    Replies: 24
    Last Post: 01-03-2008, 05:02 AM
  5. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM