#include "public.h"
#include "net.h"
#include "cmd.h"
#include "hash.h"
#include "shem.h"
int aborflag; //中断标志 1:中断 0:没有中断
char oldfile[50]; //未修改前的文件名称
char port_ip[30]; //主动连接时,客户端IP
int port_port; //主动连接时,客户端端口号
char conn_type[10]; //用于存放判断连接类型的命令
unsigned long rest_num; //记录之前已传送记录字节数
int restflag; //续传标记 0存在续传 1不存在续传
FTP_CMD ctrl_com[]={
{"USER",s_user},{"PASS",s_pass},
{"SYST",s_syst},{"syst",s_syst},
{"PWD",s_pwd},{"pwd",s_pwd},
{"XPWD",s_pwd},{"xpwd",s_pwd},
{"TYPE",s_type},{"type",s_type},
{"PASV",s_pasv},{"PORT",s_port},
{"LIST",s_list},{"list",s_list},
{"NOOP",s_noop},{"noop",s_noop},
{"CDUP",s_cdup},{"cdup",s_cdup},
{"CWD",s_cwd},{"cwd",s_cwd},
{"XCWD",s_cwd},{"xcwd",s_cwd},
{"RNFR",s_rnfr},{"RNTO",s_rnto},
{"DELE",s_dele},{"dele",s_dele},
{"MKD",s_mkdir},{"mkd",s_mkdir},
{"XMKD",s_mkdir},{"xmkd",s_mkdir},
{"RMD",s_rmdir},{"rmd",s_rmdir},
{"XRMD",s_rmdir},{"xrmd",s_rmdir},
{"SITE",s_chmod},{"QUIT",s_quit},
{"STAT",s_stat},{"stat",s_stat},
{"SIZE",s_size},{"size",s_size},
{"HELP",s_help},{"help",s_help},
{"STOR",s_stor},{"RETR",s_retr},
{"APPE",s_appe},{"REST",s_rest},
{"ABOR",s_abor},{"abor",s_abor}
};
/**************************
函数功能:命令与执行的对应函数进hash
参数:无
返回值:无
***************************/
void init_hash_comm()
{
int i,max;
max=sizeof(ctrl_com)/sizeof(ctrl_com[0]);
for(i=0;i<max;i++)
hash_insert(hash_comm,ctrl_com[i].cmd,NULL,2,ctrl_com[i].fun);
}
/**************************
函数功能:USER命令
参数:无
返回值:无
***************************/
void s_user(SESSION *str)
{
strcpy(nowuser.user,str->charm);
write_loop(connsocket,_USER_OK,strlen(_USER_OK));
}
/**************************
函数功能:PASS命令
参数:无
返回值:无
***************************/
void s_pass(SESSION *str)
{
int res;
if(strcmp(nowuser.user,"anonymous")==0)
{
strcpy(nowuser.user,"ftp");
}
else
{
res=check_passwd(nowuser.user,nowuser.passwd);
if(res==-1)
{
write_loop(connsocket,_PASS_ERROR,strlen(_PASS_ERROR));
}
}
set_egid_euid(nowuser.user,0);
write_loop(connsocket,_PASS_OK,strlen(_PASS_OK));
}
/**************************
函数功能:SYST命令 获取系统信息
参数:无
返回值:无
***************************/
void s_syst(SESSION *str)
{
write_loop(connsocket,_SYST_VER,strlen(_SYST_VER));
}
/**************************
函数功能:PWD命令 打印当前目录
参数:无
返回值:无
***************************/
void s_pwd(SESSION *str)
{
char buf[100],dir[100];
memset(buf,0,sizeof(buf));
if(strcmp(nowuser.user,"ftp")==0)
{
if(strlen(str->dir)==8)
{
strcpy(buf,"257 \"/\" is current directory.\r\n");
}
else
{
sprintf(buf,"257 \"%s\" is current directory.\r\n",str->dir+8);
}
}
else
{
sprintf(buf,"257 \"%s\" is current directory.\r\n",str->dir);
}
write_loop(connsocket,buf,strlen(buf));
}
/**************************
函数功能:TYPE命令 文件类型
参数:无
返回值:无
***************************/
void s_type(SESSION *str)
{
if(strcmp(str->charm,"A")==0 || strcmp(str->charm,"a")==0)
{
write_loop(connsocket,_TYPE_A,strlen(_TYPE_A));
}
else if(strcmp(str->charm,"I")==0 || strcmp(str->charm,"i")==0)
{
write_loop(connsocket,_TYPE_I,strlen(_TYPE_I));
}
}
/**************************
函数功能:NOOP命令 等待
参数:无
返回值:无
***************************/
void s_noop(SESSION *str)
{
write_loop(connsocket,_NOOP_OK,strlen(_NOOP_OK));
}
/**************************
函数功能:CDUP命令 回到上一层目录
参数:无
返回值:无
***************************/
void s_cdup(SESSION *str)
{
int res;
res = chdir("..");
if(res==-1)
{
write_loop(connsocket,_CHANGED_ERROR,strlen(_CHANGED_ERROR));
}
else
{
write_loop(connsocket,_CHANGED_OK,strlen(_CHANGED_OK));
}
}
/**************************
函数功能:CWD命令 改变工作目录。
参数:无
返回值:无
***************************/
void s_cwd(SESSION *str)
{
int res;
if(strcmp(nowuser.user,"ftp")==0)
{
if(*(str->charm)!='/')
{
sprintf(str->dir,"%s/%s",str->dir,str->charm);
}
else
{
sprintf(str->dir,"/var/ftp%s",str->charm);
}
}
else
{
if(*(str->charm)=='/')
{
sprintf(str->dir,"%s",str->charm);
}
else
{
if(strcmp(str->dir,"/")==0)
{
sprintf(str->dir,"/%s",str->charm);
}
else
{
sprintf(str->dir,"%s/%s",str->dir,str->charm);
}
}
}
res=chdir(str->dir);
if(res==-1)
{
write_loop(connsocket,_CHANGED_ERROR,strlen(_CHANGED_ERROR));
}
else
{
write_loop(connsocket,_CHANGED_OK,strlen(_CHANGED_OK));
}
}
/**************************
函数功能:RNFR命令 重命名
参数:无
返回值:无
***************************/
void s_rnfr(SESSION *str)
{
memset(oldfile,0,sizeof(oldfile));
if(strcmp(nowuser.user,"ftp")==0)
{
write_loop(connsocket,_TURN_DOWN,strlen(_TURN_DOWN));
}
else
{
strcpy(oldfile,str->charm);
write_loop(connsocket,_RENAME_BEFORE,strlen(_RENAME_BEFORE));
}
}
/**************************
函数功能:RNTO命令 重命名
参数:无
返回值:无
***************************/
void s_rnto(SESSION *str)
{
int res;
res=rename(oldfile,str->charm);
if(res==-1)
return;
else
{
write_loop(connsocket,_RENAME_OK,strlen(_RENAME_OK));
}
return;
}
/**************************
函数功能:DELE命令 删除文件
参数:无
返回值:无
***************************/
void s_dele(SESSION *str)
{
int res;
if(strcmp(nowuser.user,"anonymous")!=0)
{
res=remove(str->charm);
if(res==-1)
{
write_loop(connsocket,_DELETE_ERROR,strlen(_DELETE_ERROR));
}
else
{
write_loop(connsocket,_DELETE_OK,strlen(_DELETE_OK));
}
}
else
{
write_loop(connsocket,_TURN_DOWN,strlen(_TURN_DOWN));
}
}
/**************************
函数功能:MKDIR命令 创建目录
参数:无
返回值:无
***************************/
void s_mkdir(SESSION *str)
{
int res;
char buf[1024],tempdir[100];
memset(buf,0,sizeof(buf));
memset(tempdir,0,sizeof(tempdir));
if(strcmp(nowuser.user,"anonymous")!=0)
{
res=mkdir(str->charm,0755);
if(res==-1)
{
write_loop(connsocket,_MKDIR_ERROR,strlen(_MKDIR_ERROR));
}
else
{
getcwd(tempdir,sizeof(tempdir));
sprintf(buf,"257 \"%s/%s\" created.\r\n",tempdir,str->charm);
write_loop(connsocket,buf,strlen(buf));
}
}
else
{
write_loop(connsocket,_TURN_DOWN,strlen(_TURN_DOWN));
}
}
/**************************
函数功能:RMDIR命令 删除目录
参数:无
返回值:无
***************************/
void s_rmdir(SESSION *str)
{
int res;
if(strcmp(nowuser.user,"anonymous")!=0)
{
res=rmdir(str->charm);
if(res==-1)
{
write_loop(connsocket,_DELDIR_ERROR,strlen(_DELDIR_ERROR));
}
else
{
write_loop(connsocket,_DELDIR_OK,strlen(_DELDIR_OK));
}
}
else
{
write_loop(connsocket,_TURN_DOWN,strlen(_TURN_DOWN));
}
}
/**************************
函数功能:CHMOD命令 权限
参数:*str:命令哈希中的关键字
返回值:无
***************************/
void s_chmod(SESSION *str)
{
int res;
char *p,filename[100],chmode[10];
mode_t mode;
memset(filename,0,sizeof(filename));
memset(chmode,0,sizeof(chmode));
p=rindex(str->charm,' ');
strcpy(filename,p+1);
*p='\0';
p=rindex(str->charm,' ');
strcpy(chmode,p+1);
printf("%s\n",chmod);
sscanf(chmode,"%04o",&mode);
if(strcmp(nowuser.user,"anonymous")!=0)
{
res=chmod(filename,mode);
if(res==-1)
{
write_loop(connsocket,_CHMOD_ERROR,strlen(_CHMOD_ERROR));
}
else
{
write_loop(connsocket,_CHMOD_OK,strlen(_CHMOD_OK));
}
}
else
{
write_loop(connsocket,_TURN_DOWN,strlen(_TURN_DOWN));
}
}
/**************************