/*有丰富的注释,很好理解,这是我自己第一次写linux中的网络协议。
* =====================================================================================
*
* Filename: ftpclient.c
*
* Description: ftpclient 能上传下载,断点,list 列表等基本的简单东西。下载的时候有时会出现下载不全的问题
* 如果大家能解决,请给我留言,或者回复,也可发送到下面的邮箱里面。谢谢!让我们一同进步!
*
* Version: 1.0
* Created: 2010年08月04日 08时40分15秒
* Revision: none
* Compiler: gcc
*
* Author: Yang Shao Kun (), cdutyangshaokun@163.com
* Company: College of Information Engineering of CDUT
*
* =====================================================================================
*/
#include<stdio.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<string.h>
#include<strings.h>
#include<unistd.h>
#include<netinet/in.h>
#include<netdb.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define SERV_PORT 21
#define MAXSIZE 1024
#define SA struct sockaddr
static int control_sockfd;
int npsupport;
int login_yes;
int f;//f=0时为默认文件结构
int login();
void ftp_list(int control_sockfd);
void zeromery(char *a,int len);
void ftp_pwd(int control_sockfd);
void ftp_changdir(char dir[],int control_sockfd);
void ftp_quit(int control_sockfd);
void ftp_creat_mkd(char *path,int control_sockfd);
void ftp_back(int control_sockfd);
void ftp_stru(int control_sockfd);
void ftp_rest(int control_sockfd);
int ftp_download(int control_sockfd);
char *itoa(int value, char *string, int radix);
int main(int argc,char **argv)
{
printf("ftp>");
char command[MAXSIZE];
char*cmd;
scanf("%s",command);
cmd=command;
while(*(cmd)==' ')
cmd++;
if(strncmp(cmd,"login",5)==0)
{
login();
if(login_yes==1)
{
while(1)
{
comm:
sleep(1);
printf("ftp>");
zeromery(command,1024);
scanf("%s",command);
cmd=command;
while(*(cmd)==' ')
cmd++;
if(strncmp(cmd,"pasv",4)==0)
{
ftp_list(control_sockfd);
}
if(strncmp(cmd,"port",4)==0)
{
ftp_list(control_sockfd);
}
if(strncmp(cmd,"list",4)==0)
{
ftp_pwd(control_sockfd);
ftp_list(control_sockfd);
}
if(strncmp(cmd,"pwd",3)==0)
{
ftp_pwd(control_sockfd);
}
if(strncmp(cmd,"mkdir",5)==0)
{
char path[60];
zeromery(path,60);
printf("创建的路径名: ");
scanf("%s",path);
printf("s/n",path);
ftp_creat_mkd(path,control_sockfd);
}
if(strncmp(cmd,"back",4)==0)
{
ftp_back(control_sockfd);
ftp_pwd(control_sockfd);
}
if(strncmp(cmd,"cd",2)==0)
{
int i;
char path[60];
zeromery(path,60);
printf("要到的路径:");
scanf("%s",path);
printf("%s/n",path);
ftp_changdir(path,control_sockfd);
}
if(strncmp(cmd,"get",3)==0)
{
ftp_pwd(control_sockfd);
ftp_download(control_sockfd);
}
if(strncmp(cmd,"up",3)==0)
{
ftp_pwd(control_sockfd);
ftp_up(control_sockfd);
}
if(strncmp(cmd,"quit",4)==0)
{
printf("bye^_^/n");
close(control_sockfd);
break;
}
printf("支持 list,pwd,mkdir,back,cd,up,get/n");
}
}
else if(login_yes==0)
{
int i;//不成功登录下最多还有两次机会,如果不能在两次登录,则,关闭链接。
printf("Can not login vsftpd");
for(i=2;i>0;i--)
{
printf("你还有 %d 登录机会/n",i);
login();
if(login_yes==1)
{
goto comm;
}
}
if(i==0)
{
printf("你不能在登录!/n");
close(control_sockfd);
}
}
else if (strncmp(cmd,"quit",4)==0)
{
ftp_quit(control_sockfd);
close(control_sockfd);
}
}
return 0;
}
int login()
{
//初始化端口信息
struct sockaddr_in serv_addr;
char senddate,recvdate;
char sendline[MAXSIZE],recvline[MAXSIZE];
struct hostent *host;
//获取hostent中相关参数
char name[MAXSIZE],password[MAXSIZE];
printf("please enter the hostname/n");
printf("ftp-> ");
scanf("%s",name);
host=gethostbyname(name);
if(host==NULL)
{
printf("get host by name is error!/n");
login_yes=0;
}
else
{
//创建socket
control_sockfd=socket(AF_INET,SOCK_STREAM,0);
if(control_sockfd<0)
{
printf("socket is error/n");
login_yes=0;
}
//设置sockaddr_in 结构体中的相关参数
bzero(&serv_addr,sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(SERV_PORT);
serv_addr.sin_addr.s_addr=INADDR_ANY;
//调用connect函数发起连接
char addr[MAXSIZE];
if((connect(control_sockfd,(SA*)&serv_addr,sizeof(serv_addr)))<0)
{
printf("connect is error/n");
login_yes=0;
}
printf("connect to %s/n",inet_ntop(AF_INET,host->h_addr,addr,1024));
recvdate=recv(control_sockfd,recvline,sizeof(recvline),0);
if(recvdate==-1)
{
printf("recvdate is connect error/n");
login_yes=0;
}
else if(strncmp(recvline,"220",3)==0)
{
printf("connect success,pelase enter username/n");
login_yes=1;
}
else
{
printf("220 connect is error!");
login_yes=0;
}
//ftp用户登录主体部分
int sendbytes,recvbytes;
zeromery(name,1024);
zeromery(password,1024);
zeromery(recvline,1024);
zeromery(sendline,1024);
printf("ftp-> ");
scanf("%s",name);//可以支持匿名登录vsftpd
strcat(sendline,"USER ");
strcat(sendline,name);
strcat(sendline,"/r/n");