ftp.cpp
上传用户:wangying89
上传日期:2007-01-07
资源大小:61k
文件大小:7k
源码类别:

Ftp客户端

开发平台:

Visual C++

  1. #include <windows.h>
  2. #include <winsock.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <time.h>
  6. #include "tcp.h"
  7. #include "ftp.h"
  8. int g_code =0;
  9. char g_reply[2000];
  10. int sd_login =-1;
  11. void log_msg(char *);
  12. int ftp_cmd(int sd, char *cmd, int success_code)
  13. {
  14.   int code;
  15.   if(tcp_send(sd, cmd, strlen(cmd), 5) !=(int)strlen(cmd))
  16.   {
  17.   log_msg("ftp_cmd: tcp_send failed");
  18.   return -1;
  19.   }
  20.   if((code =get_reply(sd)) !=success_code)
  21.   {
  22.       log_msg(cmd);
  23.   log_msg(g_reply);
  24.   return -2;
  25.   }
  26.   return 0;
  27. }
  28. int ftp_login(char *hostname, char *user_name, char *passwd)
  29. {
  30.   int sd, ret;
  31.   char cmds[100];
  32.   
  33.   if((sd =tcp_connect(hostname, 21, 10)) <0)
  34.     return -1;
  35.   if((ret =get_reply(sd)) !=220)
  36.   {
  37.     closesocket(sd);
  38.     return -1;
  39.   }
  40.   sprintf(cmds, "USER %srn", user_name);
  41.   if(ftp_cmd(sd, cmds, 331) <0)
  42.   {
  43.     closesocket(sd);
  44.     return -1;
  45.   }
  46.   sprintf(cmds, "PASS %srn", passwd);
  47.   if(ftp_cmd(sd, cmds, 230) <0)
  48.   {
  49.     closesocket(sd);
  50.     return -1;
  51.   }
  52.   sd_login =sd;
  53.   return sd;
  54. }
  55. int ftp_chdir(int sd, char *path)
  56. {
  57.   char cmds[100];
  58.   
  59.   sprintf(cmds, "CWD %srn", path);
  60.   if(ftp_cmd(sd, cmds, 250) <0)
  61.   return -1;
  62.   return 0;
  63. }
  64. int ftp_get_size(int sd, char *file_remote)
  65. {
  66.   int size =0;
  67.   char cmds[100];
  68.   
  69.   sprintf(cmds, "SIZE %srn", file_remote);
  70.   if(ftp_cmd(sd, cmds, 213) <0)
  71.     return 0;
  72.   if(sscanf(g_reply, "%*d %d", &size) !=1)
  73.     return 0;
  74.   return size;
  75. }
  76. int ftp_get_time(int sd, char *file_remote, char *pstime)
  77. {
  78.   char cmds[100];
  79.   sprintf(cmds, "MDTM %srn", file_remote);
  80.   if(ftp_cmd(sd, cmds, 213) <0)
  81.     return -1;
  82.   strncpy(pstime, &g_reply[4], 14);
  83.   return 0;
  84. }
  85. int ftp_get_file(int sd, char *file_remote, char *file_local, int file_len, int max_wait_time)
  86. {
  87.   char temp[200], cmds[300];
  88.   int len, len_recved =0, ret =0, code;
  89.   char buf[4096];
  90.   FILE *fp =NULL;
  91.   int sd_data =-1;
  92.   
  93.   temp[0] =0;
  94.   if(ftp_cmd(sd, "TYPE Irn", 200) <0)
  95.   {
  96.     sprintf(temp, "ftp_get_file:TYPE I failed! sd=%d, file_remote:%s", sd, file_remote);
  97.     ret =-2;
  98.     goto f_exit;
  99.   }
  100.   if(file_len <=0)
  101.   if((file_len =ftp_get_size(sd, file_remote)) <=0)
  102.   {
  103.     sprintf(temp, "ftp_get_file:ftp_get_size failed! sd =%d, file_remote=%s, ret_len=%d", sd, file_remote, file_len);
  104.     ret =-3;
  105.     goto f_exit;
  106.   }
  107.   if((sd_data =initconn(sd)) <0)
  108.   {
  109.     sprintf(temp, "ftp_get_file:initconn failed! sd =%d, file_remote:%s", sd, file_remote);
  110.     ret =-4;
  111.     goto f_exit;
  112.   }
  113.   sprintf(cmds, "RETR %srn", file_remote);
  114.   if(ftp_cmd(sd, cmds, 150) <0)
  115.   {
  116.     sprintf(temp, "ftp_get_file:ftp_cmd failed! cmd:%s", cmds);
  117.     ret =-5;
  118.     goto f_exit;
  119.   }
  120.   if((sd_accept =tcp_accept(sd_data, 20)) <0)
  121.   {
  122.     sprintf(temp, "ftp_get_file:ftp_accept failed! sd=%d, sd_data=%d, file_remote=%s", sd, sd_data, file_remote);
  123.     ret =-6;
  124.     goto f_exit;
  125.   } 
  126.   len_recved =0;
  127.   if((fp =fopen(file_local, "wb")) ==NULL)
  128.   {
  129.     sprintf(temp, "ftp_get_file:open file for write failed! local_file:%s", file_local);
  130.     ret =-1;
  131.     goto f_exit;
  132.   }
  133.   while(len_recved < file_len)
  134.   {
  135.     if(file_len-len_recved <sizeof(buf)) len =file_len-len_recved;
  136.     else len =sizeof(buf);
  137.     if(tcp_recv(sd_accept, buf, len, max_wait_time) !=len)
  138.     {
  139.       sprintf(temp, "ftp_get_file:tcp_recv failed! len_recved:%d, file_len:%d, file_remote:%s", len_recved, file_len, file_remote);
  140.       ret =-7;
  141.       get_reply(sd);
  142.       goto f_exit;
  143.     }
  144.     if(fwrite(buf, len, 1, fp) !=1)
  145.     {
  146.       sprintf(temp, "ftp_get_file: fwrite failed! len_recved:%d, file_local:%s", len_recved, file_local);
  147.       get_reply(sd);
  148.       ret =-8;
  149.       goto f_exit;
  150.     }
  151.     len_recved +=len;
  152.   }
  153.   tcp_close(sd_accept); sd_accept =-1;
  154.   ret =len_recved;
  155.   if((code =get_reply(sd)) !=226)
  156.   {
  157.     sprintf(temp, "ftp_get_file:get_reply failed after recv success! ret_code:%d, reply string:%s", code, g_reply);
  158.     goto f_exit;
  159.   }
  160. f_exit:
  161.   if(sd_accept >=0) tcp_close(sd_accept);
  162.   if(sd_data >=0) tcp_close(sd_data);
  163.   sd_accept =-1;
  164.   sd_data =-1;
  165.   if(fp) fclose(fp);
  166.   if(ret <0)
  167.   {
  168.   sprintf(temp, "ftp_get_file failed. ret=%d", ret);
  169.   log_msg(temp);
  170.   remove(file_local);
  171.   }
  172.   return ret;
  173. }
  174. int ftp_put_file(int sd, char *file_local, int pos, char *file_remote, int max_wait_time)
  175. {
  176.   char cmds[300];
  177.   int len, file_len =0, len_sent =0, ret =0, code;
  178.   char buf[4096];
  179.   FILE *fp =NULL;
  180.   int sd_data;
  181.   
  182.   if((fp =fopen(file_local, "r")) ==NULL)
  183.   {
  184.     ret =-1;
  185.     goto f_exit;
  186.   }
  187.   fseek(fp, 0, SEEK_END);
  188.   file_len =ftell(fp)-pos;
  189.   if(file_len <0) return -1;
  190.   if(file_len ==0) return 0;
  191.   fseek(fp, pos, SEEK_SET);
  192.   if(ftp_cmd(sd, "TYPE Irn", 200) <0)
  193.   {
  194.     ret =-1;
  195.     goto f_exit;
  196.   }
  197.   if((sd_data =initconn(sd)) <0)
  198.   {
  199.     ret =-1;
  200.     goto f_exit;
  201.   }
  202.   sprintf(cmds, "STOR %srn", file_remote);
  203.   if(ftp_cmd(sd, cmds, 150) <0)
  204.   {
  205.     ret =-1;
  206.     goto f_exit;
  207.   }
  208.   if((sd_accept =tcp_accept(sd_data, 20)) <0)
  209.   {
  210.     ret =-1;
  211.     goto f_exit;
  212.   }
  213.   
  214.   len_sent =0;
  215.   while(len_sent < file_len)
  216.   {
  217.     if(file_len-len_sent <sizeof(buf)) len =file_len-len_sent;
  218.     else len =sizeof(buf);
  219.     if(fread(buf, len, 1, fp) !=1)
  220.     {
  221.       get_reply(sd);
  222.       ret =-1;
  223.       goto f_exit;
  224.     }
  225.     if(tcp_send(sd_accept, buf, len, max_wait_time) !=len)
  226.     {
  227.       ret =-1;
  228.       get_reply(sd);
  229.       goto f_exit;
  230.     }
  231.     len_sent +=len;
  232.   }
  233.   closesocket(sd_accept); sd_accept =-1;
  234.   if((code =get_reply(sd)) !=226)
  235.   {
  236.   goto f_exit;
  237.   }
  238.   ret =len_sent;
  239. f_exit:
  240.   if(sd_accept >=0) closesocket(sd_accept);
  241.   if(sd_data >=0) closesocket(sd_data);
  242.   sd_accept =-1;
  243.   sd_data =-1;
  244.   if(fp) fclose(fp);
  245.   if(buf) free(buf);
  246.   return ret;
  247. }
  248. int initconn(int sd)
  249. {
  250.   char *p1, *p2;
  251.   struct sockaddr_in addr1, addr2;
  252.   char temp[256];
  253.   int len;
  254.   int code, sd_data=-1;
  255.   
  256.   if((sd_data =tcp_bind(NULL, 0)) <0)
  257.     return -1;
  258.   len =sizeof(addr1);
  259.   if(getsockname(sd_login, (struct sockaddr *)&addr1, &len) <0)
  260.     return -1;
  261.   if(getsockname(sd_data, (struct sockaddr *)&addr2, &len) <0)
  262.     return -1;
  263.   p1 =(char *)&addr1.sin_addr;
  264.   p2 =(char *)&addr2.sin_port;
  265.   sprintf(temp, "PORT %d,%d,%d,%d,%d,%drn", ((int)p1[0]) &0xff, ((int)p1[1]) &0xff, (int)p1[2] &0xff, (int)p1[3]&0xff, (int)p2[0]&0xff, (int)p2[1]&0xff);
  266.   if(tcp_send(sd, temp, strlen(temp), 10) !=(int)strlen(temp))
  267.   {
  268.     closesocket(sd_data);
  269.     return -1;
  270.   }
  271.   if((code =get_reply(sd)) !=200)
  272.   {
  273.     closesocket(sd_data);
  274.     return -1;
  275.   }
  276.   return sd_data;
  277. }
  278. int get_reply(int sd)
  279. {
  280.   int i, code =0;
  281. again:
  282.   i =0;
  283.   memset(g_reply, 0, sizeof(g_reply));
  284.   while(1)
  285.   {
  286.     if(tcp_recv(sd, &g_reply[i], 1, 10) <=0)
  287.       break;
  288.     if(g_reply[i] =='r') g_reply[i] =' ';
  289.     if(g_reply[i] =='n')
  290.     {
  291.       g_reply[i] =' ';
  292.       if(sscanf(g_reply, "%d", &code) !=1)
  293.       {
  294.         return -1;
  295.       }
  296.       else break;
  297.     }
  298.     i++;
  299.   }
  300.   if(g_reply[3] =='-')
  301.   {
  302.   i =0;
  303.   goto again;
  304.   }
  305.   g_code =code;
  306.   return code;
  307. }
  308. void ftp_quit(int sd)
  309. {
  310.   ftp_cmd(sd, "QUITrn", 221);
  311.   closesocket(sd);
  312. }