#include "ftp_cmd.h"
#include "pub.h"
#include <stdio.h>
#include <pwd.h>
#include <sys/types.h>
#include <shadow.h>
#include <stdlib.h>
#include <crypt.h>
#include <sys/socket.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/time.h>
#include <time.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/in.h>
#include <sys/shm.h>
//命令集
CMD_STATE cmd_list[]=
{
{"USER",do_user},
{"PASS",do_pass},
{"SYST",do_syst},
{"REST",do_rest},
{"PWD" ,do_pwd },
{"XPWD",do_pwd },
{"CWD" ,do_cwd },
{"CDUP",do_cdup},
{"TYPE",do_type},
{"PORT",do_port},
{"PASV",do_pasv},
{"LIST",do_list},
{"RNFR",do_rnfr},
{"RNTO",do_rnto},
{"RETR",do_retr},
{"STOR",do_stor},
{"APPE",do_appe},
{"DELE",do_dele},
{"RMD" ,do_rmd },
{"XRMD",do_rmd },
{"NOOP",do_noop},
{"MKD" ,do_mkd },
{"XMKD",do_mkd },
{"ABOR",do_abor},
{"STAT",do_stat},
{"SIZE",do_size},
{"HELP",do_help},
{"QUIT",do_quit},
{"SITE",do_chmod},
{NULL,NULL},
};
/*********************
*功能:获取IP地址和端口
*参数:
* buffer:要分析的字符串
* ip_address:存放IP地址
* ip_address:存放端口
*返回值:无
*********************/
void get_ip_address(char *buffer,char *ip_address,int *port)
{
char *p,*q;
int i;
char port1[6]={0};
char port2[6]={0};
p=buffer;
for (i=0; i<4; i++)
{
p=strchr(p,',');
*p='.';
}
*p='\0';
strcpy(ip_address,buffer);
p = p+1;
if((q=strchr(p,','))!=NULL)
{
*q='\0';
strcpy(port1,p);
q=q+1;
strcpy(port2,q);
}
*port = atoi(port1)*256 + atoi(port2);
printf("%s %d\n",ip_address,*port);
}
/*********************
*功能:执行USER命令
*参数:
* param:USER命令附带的参数
*返回值:整形退出码
*********************/
int do_user(char *param)
{
printf("do_user\n");
strcpy(u_info.user_name,param);
write(accept_socket,USER_READY,strlen(USER_READY));
return 0;
}
/*********************
*功能:执行PASS命令
*参数:
* param:PASS命令附带的参数
*返回值:整形退出码
*********************/
int do_pass(char *param)
{
struct passwd *user;
struct spwd *spwd_info;
char *enc_passwd;
printf("do_pass\n");
strcpy(u_info.user_pass,param);
if (strcmp(u_info.user_name,"anonymous")==0)
{
strcpy(u_info.user_name,"ftp");
is_anonymous = 1;
user=getpwnam(u_info.user_name);
setegid(user->pw_gid);
seteuid(user->pw_uid);
strcpy(u_info.user_wdir,user->pw_dir);
strcpy(current_dir,u_info.user_wdir);
chdir(current_dir);
write(accept_socket,LOGIN_SUCCESS,strlen(LOGIN_SUCCESS));
return 0;
}
else if ((user=getpwnam(u_info.user_name))!=NULL)
{
spwd_info=getspnam(u_info.user_name);
enc_passwd = crypt(u_info.user_pass, spwd_info->sp_pwdp);
printf("%s\n",enc_passwd);
if (strcmp(enc_passwd,spwd_info->sp_pwdp) == 0)
{
setegid(user->pw_gid);
seteuid(user->pw_uid);
strcpy(u_info.user_wdir,user->pw_dir);
strcpy(current_dir,u_info.user_wdir);
chdir(current_dir);
write(accept_socket,LOGIN_SUCCESS,strlen(LOGIN_SUCCESS));
return 0;
}
}
write(accept_socket,LOGIN_INCORRECT,strlen(LOGIN_INCORRECT));
return 1;
}
/*********************
*功能:执行SYST命令
*参数:
* param:SYST命令附带的参数
*返回值:整形退出码
*********************/
int do_syst(char *param)
{
printf("do_syst\n");
write(accept_socket,SYST_ACT,strlen(SYST_ACT));
return 0;
}
/*********************
*功能:执行REST命令
*参数:
* param:REST命令附带的参数
*返回值:整形退出码
*********************/
int do_rest(char *param)
{
printf("do_rest\n");
char buf[512]={0};
sprintf(buf,"350 Restart position accecpt(%s)\r\n",param);
break_point = atol(param);
write(accept_socket,buf,strlen(buf));
return 0;
}
/*********************
*功能:执行PWD命令
*参数:
* param:PWD命令附带的参数
*返回值:整形退出码
*********************/
int do_pwd(char *param)
{
printf("do_pwd\n");
char buffer[512]={0};
char buf[512]={0};
char sbuf[512]="/";
getcwd(buffer,sizeof(buffer));
strcpy(current_dir,buffer);
if (is_anonymous==1)
{
if (strcmp(current_dir,ANONYMOUS_DIR)!=0)
{
strcat(sbuf,current_dir+9);
}
sprintf(buf,"257 \"%s\"\r\n",sbuf);
}
else sprintf(buf,"257 \"%s\"\r\n",current_dir);
write(accept_socket,buf,strlen(buf));
return 0;
}
/*********************
*功能:执行CWD命令
*参数:
* param:CWD命令附带的参数
*返回值:整形退出码
*********************/
int do_cwd(char *param)
{
printf("do_cwd\n");
char buffer[512]={0};
if (is_anonymous==1 && param[0]=='/' && (strstr(param,ANONYMOUS_DIR)!=param || strstr(param,ANONYMOUS_DIR)==NULL))
{
chdir(current_dir);
}
else
{
chdir(param);
getcwd(buffer,sizeof(buffer));
strcpy(current_dir,buffer);
}
write(accept_socket,DIR_CHANGED,strlen(DIR_CHANGED));
return 0;
}
/*********************
*功能:执行CDUP命令
*参数:
* param:PASS命令附带的参数
*返回值:整形退出码
*********************/
int do_cdup(char *param)
{
printf("do_cdup\n");
char buffer[512]={0};
chdir("..");
getcwd(buffer,sizeof(buffer));
strcpy(current_dir,buffer);
printf("%s\n",current_dir);
write(accept_socket,DIR_CHANGED,strlen(DIR_CHANGED));
return 0;
}
/*********************
*功能:执行TYPE命令
*参数:
* param:TYPE命令附带的参数
*返回值:整形退出码
*********************/
int do_type(char *param)
{
printf("do_type\n");
if (strcmp(param,"A")==0)
{
write(accept_socket,SWITCH_A_MODE,strlen(SWITCH_A_MODE));
}
else if (strcmp(param,"I")==0)
{
write(accept_socket,SWITCH_I_MODE,strlen(SWITCH_I_MODE));
}
return 0;
}
/*********************
*功能:执行PORT命令
*参数:
* param:PORT命令附带的参数
*返回值:整形退出码
*********************/
int do_port(char *param)
{
printf("do_port\n");
init_unix_client_socket();
char ip_address[32]={0};
int port=0;
UNIX_DATA unix_info;
get_ip_address(param,ip_address,&port);
printf("%s %d\n",ip_address,port);
strcpy(unix_info.opt,"PORT");
unix_info.state=0;
unix_info.ip_addr.sin_family=AF_INET;
unix_info.ip_addr.sin_port=htons(port);
unix_info.ip_addr.sin_addr.s_addr=inet_addr(ip_address);
write(unix_client_socket,&unix_info,sizeof(UNIX_DATA));
memset(&unix_info,0,sizeof(UNIX_DATA));
read(unix_client_socket,&unix_info,sizeof(UNIX_DATA));
if (unix_info.state==PORT_OK)
{
write(accept_socket,PORT_SUCCESS,strlen(PORT_SUCCESS));
}
return 0;
}
/*********************
*功能:执行PASV命令
*参数:
* param:PASV命令附带的参数
*返回值:整形退出码
*********************/
int do_pasv(char *param)
{
printf("do_pasv\n");
init_unix_client_socket();
char ip_address[32];
char *ptr = ip_address;
int port,port1,port2,i;
int addrlen=sizeof(struct sockaddr_in);
char sbuffer[256]={0};
UNIX_DATA unix_info;
struct sockaddr_in ser_addr;
getsockname(accept_socket,(struct sockaddr*)&ser_addr,&addrlen);
strcpy(unix_info.opt,"PASV");
unix_info.state=0;
unix_info.ip_addr=ser_addr;
unix_info.ip_addr.sin_port = htons(0);
strcpy(ip_address, inet_ntoa(unix_info.ip_addr.sin_addr));
for (i=0; i<3; i++)
{
ptr = strchr(ptr,'.');
*ptr = ',';
}
write(unix_client_socket,&unix_info,sizeof(UNIX_DATA));
read(unix_client_socket,&unix_info,sizeof(UNIX_DATA));
if (unix_info.state==PASV_OK)
{
port = ntohs(unix_info.ip_addr.sin_port);
port1 = port/256;
port2 = port%256;
sprintf(sbuffer,"227 Entering Passive Mode (%s,%d,%d).\r\n",ip_address,port1,port2);
write(accept_socket,sbuffer,strlen(sbuffer));
}
return 0;
}
/*********************
*功能:执行LIST命令
*参数:
* param:LIST命令附带的参数
*返回值:整形退出码
*********************/
int do_list(char *param)
{
printf("do_list\n");
chdir(current_dir);
int addr_len;
addr_len = sizeof(struct sockaddr_un);
UNIX_DATA unix_info;
strcpy(unix_info.opt,"LIST");
strcpy(unix_info.cur_dir,current_dir);
write(accept_socket,LIST_READY,strlen(LIST_READY));
write(unix_client_socket,&unix_info,sizeof(UNIX_DATA));
memset(&unix_info,0,sizeof(UNIX_DATA));
read(unix_client_socket,&unix_info,sizeof(UNIX_DATA));
if (unix_info.state==LIST_OK)
{
write(accept_socket,TRANSFER_COMPLETE,strlen(TRANSFER_COMP