Page 1 of 1

ftp client program. this to see sample code.

Posted: Thu Nov 27, 2008 9:21 am
by yunbg1
This is sample code of ftp client.

push button counter----
1. so := ftp_open() -> test ok
2. ftp_login() ->test ok
3. ftp_command() -> test ok

Problem solving.............
Apply and use.

Code: Select all

#include "FiveLinux.ch" 

FUNC Main() 

publ oWnd, oBrw, oGet, aGet, so

aGet := ""

DEFINE WINDOW oWnd TITLE "Testing Socket" SIZE 822, 317 

   @  2,  0 GET oGet VAR aGet MEMO OF oWnd SIZE 820, 250

   @ 28,  2 BUTTON "_Exit" OF oWnd ACTION oWnd:End() 
   @ 28, 10 BUTTON "ftp_Open" OF oWnd ACTION so := ftp_open()
   @ 28, 18 BUTTON "ftp_Close" OF oWnd ACTION socketclose(so) 
   @ 28, 26 BUTTON "ftp_login" OF oWnd ACTION ftp_login(so, "test", "test1234")
   @ 28, 34 BUTTON "command" OF oWnd ACTION ftp_command(so, "dir")
ACTIVATE WINDOW oWnd 
RETU NIL 
//-----------------------------------------------------
FUNC C_CALL(hSm, lPa)

if lPa != 0
   aGet += tran(lPa, "999") + " " + hSm + chr(13) + chr(10) //+ cToken
   else
   aGet += hSm + chr(13) + chr(10) //+ cToken
endif
oGet:SetText(aGet)
RETU NIL

/*
Command
1. PWD : dir display => PWD
2. CWD : dir change => CWD change dir name
3. ls : current dir file list => ls
4. get : file download => get download file name
5. put : file upload => put upload filename
6. bye : quit => bye
*/

/*----------------------------------------*/ 
#pragma BEGINDUMP 

#include <hbapi.h> 
#include <gtk/gtk.h> 
#include <hbvm.h> 

#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <sys/ioctl.h>

#include <net/if.h>
#include <netinet/in.h>

#define _LINUX_NETDEVICE_H   // glibc2 
#include <linux/if_arp.h>
#include <arpa/inet.h>

#include <limits.h>
#include <malloc.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>

/*connect FTP Sever port*/
#define FTP_PORT 21

void* send_data_thread(void* sockfd);
void* recv_ctrl_thread(void* sockfd);
void* recv_data_thread(void* sockfd);
void get_remote_port(char * message);
void parse_filename(char * temp_buff, char * buff);

struct sockaddr_in ftp_send_addr;
struct sockaddr_in ftp_recv_data_addr;

int ftp_send_sockfd;

/*index : ls-1, put-2, get-3*/
int command_index;

/*download, upload filename*/
char file_name[1024];

HB_FUNC( FTP_OPEN ) 
{
    char cmd_ctrl_buff[1024] = {0};
    char temp_buff[1024] = {0};
    char mess[255];
    int len;

    /*FTP Server ip, port*/
    ftp_send_addr.sin_family = AF_INET;
    ftp_send_addr.sin_port = htons(FTP_PORT);
    ftp_send_addr.sin_addr.s_addr = inet_addr("192.168.1.51");
    memset(&(ftp_send_addr.sin_zero), 0, 8);

    ftp_send_sockfd = socket(AF_INET, SOCK_STREAM, 0);

    connect(ftp_send_sockfd, (struct sockaddr *) &ftp_send_addr, sizeof(struct sockaddr_in));

    memset(temp_buff, '\0', sizeof(temp_buff));
    len = read(ftp_send_sockfd, temp_buff, sizeof(temp_buff));

    memset(mess, 0x00, sizeof(mess));
    sprintf(mess, "%s\n", temp_buff); 

    hb_vmPushSymbol( hb_dynsymSymbol( hb_dynsymFindName( "C_CALL" ) ) );
    hb_vmPushNil();
    hb_vmPushString( mess, strlen(mess) );
    hb_vmPushLong(0);
    hb_vmFunction( 2 );

    hb_retni(ftp_send_sockfd);
}

HB_FUNC( FTP_LOGIN ) 
{
    char cmd_ctrl_buff[1024] = {0};
    char temp_buff[1024] = {0};
    char mess[255];
    int len;

    /*FTPServer login try 3 server connect close*/
     while(1) {

       /*FTP Command : USER name*/
       memset(temp_buff, '\0', sizeof(temp_buff));
       sprintf(cmd_ctrl_buff,"USER %s\n", hb_parc(2)); //USER ID
       write(hb_parni(1), cmd_ctrl_buff, strlen(cmd_ctrl_buff));

       memset(temp_buff, '\0', sizeof(temp_buff));
       len = read(hb_parni(1), temp_buff, sizeof(temp_buff));

       memset(mess, 0x00, sizeof(mess));
       sprintf(mess, "%s\n", temp_buff); 

       hb_vmPushSymbol( hb_dynsymSymbol( hb_dynsymFindName( "C_CALL" ) ) );
       hb_vmPushNil();
       hb_vmPushString( mess, strlen(mess) );
       hb_vmPushLong(len);
       hb_vmFunction( 2 );

       memset(temp_buff, '\0', sizeof(temp_buff));

       /*FTP Command : PASS password*/
       memset(cmd_ctrl_buff, '\0', sizeof(cmd_ctrl_buff));
       sprintf(cmd_ctrl_buff,"PASS %s\n", hb_parc(3)); //USER pass
       write(hb_parni(1), cmd_ctrl_buff, strlen(cmd_ctrl_buff));

       memset(temp_buff, '\0', sizeof(temp_buff));
       len = read(hb_parni(1), temp_buff, sizeof(temp_buff));

       memset(mess, 0x00, sizeof(mess));
       sprintf(mess, "%s\n", temp_buff); 

       hb_vmPushSymbol( hb_dynsymSymbol( hb_dynsymFindName( "C_CALL" ) ) );
       hb_vmPushNil();
       hb_vmPushString( mess, strlen(mess) );
       hb_vmPushLong(len);
       hb_vmFunction( 2 );

       if (strncmp(temp_buff, "530", 3) == 0)
          continue;
        else
          break;
     }
    hb_retni(0);
}

HB_FUNC( SOCKETCLOSE ) 
{ 
    close(hb_parni(1));
    hb_retni(0);
}

HB_FUNC( FTP_COMMAND ) 
{
    pthread_t recv_thread;

    char cmd_ctrl_buff[1024] = {0};
    char temp_buff[1024] = {0};
    char mess[255];
    int len;

    pthread_create(&recv_thread, NULL, recv_ctrl_thread, (void*) hb_parni(1));

    while(1) {

       memset(temp_buff, '\0', sizeof(temp_buff));
       memset(cmd_ctrl_buff, '\0',sizeof(cmd_ctrl_buff));

       sprintf(temp_buff, "%s\n", hb_parc(2));

       /*ls command process create*/ 
       if (strncmp(temp_buff, "ls", 2) == 0 || strncmp(temp_buff, "dir", 3) == 0) {  
           memset(temp_buff, '\0', sizeof(temp_buff));

           /*passive mode*/
           sprintf(temp_buff, "pasv\n");
           write(hb_parni(1), temp_buff, strlen(temp_buff)); 

           command_index = 1;
           memset(temp_buff, '\0', sizeof(temp_buff));

           /*dir, file list recv*/
           sprintf(temp_buff, "list -a\n");
           write(hb_parni(1), temp_buff, strlen(temp_buff));
           sleep(1); 

          } else if(strncmp(temp_buff, "put", 3) == 0) {

            /*put : data upload filename*/
            temp_buff[strlen(temp_buff)-1] = '\0';
            memset(cmd_ctrl_buff, '\0', sizeof(cmd_ctrl_buff));
            parse_filename(temp_buff, cmd_ctrl_buff);
            memset(file_name, '\0', sizeof(file_name));
            sprintf(file_name, "%s", cmd_ctrl_buff);

            memset(cmd_ctrl_buff, '\0', sizeof(cmd_ctrl_buff));
            command_index = 2;

            /*passive mode*/
            sprintf(cmd_ctrl_buff, "pasv\n");
            write(ftp_send_sockfd, cmd_ctrl_buff, strlen(cmd_ctrl_buff));
            sleep(1); 

          } else if(strncmp(temp_buff, "get", 3) == 0) {

            /*get : data*/
            temp_buff[strlen(temp_buff)-1] = '\0';
            memset(cmd_ctrl_buff, '\0', sizeof(cmd_ctrl_buff));

            /*passive mode*/
            sprintf(cmd_ctrl_buff, "pasv\n");
            write(ftp_send_sockfd, cmd_ctrl_buff, strlen(cmd_ctrl_buff));
            command_index = 3;

            /*download filename*/
            memset(cmd_ctrl_buff, '\0', sizeof(cmd_ctrl_buff));
            parse_filename(temp_buff, cmd_ctrl_buff);

            memset(file_name, '\0', sizeof(file_name));
            sprintf(file_name, "%s", cmd_ctrl_buff);

            memset(temp_buff, '\0', sizeof(temp_buff));
            /*server -> retr download filename*/

            sprintf(temp_buff, "retr %s\n", cmd_ctrl_buff);
            write(ftp_send_sockfd, temp_buff, strlen(temp_buff));
            sleep(1); 

         }  else if (strncmp(temp_buff, "bye", 3) == 0) {

            memset(temp_buff, '\0', sizeof(temp_buff));
            sprintf(temp_buff, "quit\n");
            write(ftp_send_sockfd, temp_buff, strlen(temp_buff));
            exit(0);

         }  else {

            /* PWD, CWD*/
            write(ftp_send_sockfd, temp_buff, strlen(temp_buff));
            sleep(1);
         }
     }
    hb_retni(1);
}

void parse_filename( char *temp_buff, char *buff)
{
     int index = 3;
     int count = 0;

     for (; index < strlen( (char *)temp_buff); index++) {
         if (temp_buff == ' ') {
            continue;

          } else {

            buff[count] = temp_buff;
            count++;
            }
       }
}

void * send_data_thread(void* sockfd)
{
     int fd;
     char data_buff[4096] = {0};

     int data_size;

     fd = open(file_name, O_RDONLY);

     if (fd == -1) {
        //printf("**>no exist file\n");

      } else {

        sprintf(data_buff, "stor %s\n", file_name);
        write((int)sockfd, data_buff, strlen(data_buff));

        while(1) {
           memset(data_buff, '\0', sizeof(data_buff));
           data_size = read(fd, data_buff, sizeof(data_buff));
           if (data_size == 0)
              break;
            else
              write((int)sockfd, data_buff, data_size);
           }
       }
     close((int)sockfd);
     close(fd);
}

void * recv_data_thread(void* sockfd)
{
     int fd;
     int data_size;
     char data_buff[4096] = {0};

     if (command_index == 3)
        fd = open(file_name, O_WRONLY|O_CREAT,0644);

     while(1) { 
        memset(data_buff, '\0', sizeof(data_buff));
        data_size = read((int)sockfd, data_buff, sizeof(data_buff));

        if (data_size == 0) {
           break;

         } else {

           if (command_index == 1) {

              //memset(mess, 0x00, sizeof(mess));
              //sprintf(mess, "%s\n", data_buff); 

              //hb_vmPushSymbol( hb_dynsymSymbol( hb_dynsymFindName( "C_CALL" ) ) );
              //hb_vmPushNil();
              //hb_vmPushString( mess, strlen(mess) );
              //hb_vmPushLong(0);
              //hb_vmFunction( 2 );

              printf("**>%s\n", data_buff); 

            } else if (command_index == 3) {
              write(fd, data_buff, data_size);
              }
           }
      }
    close((int)sockfd);

    if (command_index == 3)
       close(fd);
}

void * recv_ctrl_thread(void* sockfd)
{
     char ctrl_buff[1024] = {0};
     int msg_size;
     int temp_port;

     while(1) {
       memset(ctrl_buff, '\0', sizeof(ctrl_buff));
       msg_size = read((int)sockfd, ctrl_buff, sizeof(ctrl_buff));

       if (msg_size <= 0)
          continue;

       if (strncmp(ctrl_buff, "227", 3) == 0) {
          //printf("**>%s\n", ctrl_buff);
          get_remote_port(ctrl_buff); 

        } else if (strncmp(ctrl_buff, "550", 3) == 0 && command_index == 3) {

          //printf("**>%s\n", ctrl_buff);

          memset(ctrl_buff, '\0', sizeof(ctrl_buff));
          sprintf(ctrl_buff, "rm -f %s", file_name);
          system(ctrl_buff);

        } else {

          //printf("**>%s\n", ctrl_buff);
         }
      }
      close((int)sockfd);
      exit(0);
}

void get_remote_port(char * message)
{

     pthread_t t;
     int index;
     int parse_start = 0;

     char ip_buff[512] = {0};
     char port_buff1[10] = {0};
     char port_buff2[10] = {0};
     char cport_number[2];
     int iport_number;

     char * ref_number;

     int comma_count = 0;
     int buff_count = 0;

     struct sockaddr_in connect_addr;
     int connect_fd; 
     int connect_result;

     for (index = 0; index < strlen(message); index++) {
       if (message[index] == '(') {
          parse_start = 1;
          continue;

        } else if (message[index] == ')')

          break;

       /*addr process*/
       if (parse_start == 1) {
          if (message[index] == ',') {
             comma_count++;
             if (comma_count == 4) {
                buff_count = 0;
                parse_start = 2;
                continue;
              } else {
                ip_buff[buff_count] = '.';
                buff_count++;
                 }
           } else {
             ip_buff[buff_count] = message[index]; 
             buff_count++;
             } 
         }

       /*port process*/
       if (parse_start == 2) {
          if (message[index] == ',') {
             comma_count++;
             buff_count = 0;
           } else {
             if (comma_count == 5) {
                port_buff2[buff_count] = message[index];
                buff_count++;
              } else {
                port_buff1[buff_count] = message[index];
                buff_count++;
                 }
             }
         }
      }

    ref_number = (char*)&iport_number;

    ref_number[0] = (char)atoi(port_buff2);
    ref_number[1] = (char)atoi(port_buff1);

    connect_addr.sin_family = AF_INET;
    connect_addr.sin_port = htons(iport_number);
    connect_addr.sin_addr.s_addr = inet_addr(ip_buff);
    memset(&(connect_addr.sin_zero), 0, 8);

    connect_fd = socket(AF_INET, SOCK_STREAM, 0);

    connect_result = connect(connect_fd, (struct sockaddr*)&connect_addr, sizeof(connect_addr));

    if (command_index == 1 || command_index == 3)
       pthread_create(&t, NULL,recv_data_thread, (void*)connect_fd); 
     else if (command_index == 2)
       pthread_create(&t, NULL,send_data_thread, (void*)connect_fd);

}

#pragma ENDDUMP