⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myftp_state_machine.c

📁 Linux下的ftp服务器
💻 C
📖 第 1 页 / 共 4 页
字号:
		 return -1;
	 }
	 if (0 == rmdir(p_thesession->p_cmd_line->arg))
	 {
		 write(p_thesession->cmd_cntl_fd, "250 Delete operation successful.\r\n", strlen("250 Delete operation successful.\r\n"));
	 }
	 else
		 write(p_thesession->cmd_cntl_fd, "550 Delete operation failed.\r\n", strlen("550 Delete operation failed.\r\n"));
	 return -1;
 }

 /*=================================================================================
 function:XRMD删除目录命令
 注:该命令与RMD命令类同
 =================================================================================*/
 int myftp_cmd_handle_xrmd(pMYFTP_SESSION p_thesession)
 {
	 return myftp_cmd_handle_rmd(p_thesession);
 }

 /*=================================================================================
 function:打印当前目录信息命令解释函数
 =================================================================================*/
 int myftp_cmd_handle_pwd(pMYFTP_SESSION p_thesession)
 {
	 if (*p_thesession->user_str=='\0'||*p_thesession->passwd_str==0)
	 {
		 write(p_thesession->cmd_cntl_fd,"530 Not logged in.\r\n", strlen("530 Not logged in.\r\n"));
		 return -1;
	 }
	 char tmp_wd[MAX_PATH]={0};
	 if (p_thesession->is_anonymous)//如果是匿名登录
	 {
		 if (strcmp("/var/ftp",getcwd(tmp_wd,MAX_PATH))==0)
		 {
			sprintf(tmp_wd,"257 \"/\"\r\n",p_thesession->cur_dir);
		 }
		 else
		 {
			strcpy(p_thesession->cur_dir,p_thesession->cur_dir+8);
			sprintf(tmp_wd,"257 \"%s\"\r\n",p_thesession->cur_dir);
		 }
	 }
	 else
		sprintf(tmp_wd,"257 \"%s\"\r\n",getcwd(p_thesession->cur_dir, MAX_PATH));
	 
	 write(p_thesession->cmd_cntl_fd, tmp_wd, strlen(tmp_wd));
	 return -1;
 }

 /*=================================================================================
 function:XPWD打印当前目录命令解释函数
 注:该命令与PWD类同
 =================================================================================*/
 int myftp_cmd_handle_xpwd(pMYFTP_SESSION p_thesession)
 {

	 return myftp_cmd_handle_pwd(p_thesession);
	
 }

 /*=================================================================================
 function:MKD创建目录命令解释函数
 =================================================================================*/
 int myftp_cmd_handle_mkd(pMYFTP_SESSION p_thesession)
 {
	 if ('\0' == *p_thesession->user_str||0 == *p_thesession->passwd_str)
	 {
		 write(p_thesession->cmd_cntl_fd,"530 Not logged in.\r\n", strlen("530 Not logged in.\r\n"));
		 return -1;
	 }
	 if (0 == mkdir(p_thesession->p_cmd_line->arg, USER_MASK))
	 {
		 strcat(p_thesession->cur_dir,"/");
		 strcat(p_thesession->cur_dir,p_thesession->p_cmd_line->arg);
		 
		 char tmp_wd[MAX_PATH];
		 
		 sprintf(tmp_wd,"257 \"%s\" created\r\n",p_thesession->cur_dir);
		 
		 write(p_thesession->cmd_cntl_fd, tmp_wd, strlen(tmp_wd));
	 }
	 else
	 {
		 if (p_thesession->is_anonymous)//默认匿名用户是不允许创建目录的
		 {
			 char* __pstr="550 Permission denied.\r\n";
			 write(p_thesession->cmd_cntl_fd, __pstr, strlen(__pstr));
		 }
		 else
		 {
			 char* pstr="550 Create directory operation failed.\r\n";
			 write(p_thesession->cmd_cntl_fd, pstr, strlen(pstr));
		 }
	 }
	 return -1;
 }

 /*=================================================================================
 function:XMKD命令解释函数
 注:该命令和MKD类同
 =================================================================================*/
 int myftp_cmd_handle_xmkd(pMYFTP_SESSION p_thesession)
 {
	 
	 return myftp_cmd_handle_mkd(p_thesession);
	 
 }

 /*=================================================================================
 function:LIST目录列表命令解释函数
 =================================================================================*/
 int myftp_cmd_handle_list(pMYFTP_SESSION p_thesession)
 {
	 if (*p_thesession->user_str=='\0'||*p_thesession->passwd_str==0)
	 {
		 write(p_thesession->cmd_cntl_fd,"530 Not logged in.\r\n", strlen("530 Not logged in.\r\n"));
		 return -1;
	 }
	 write(p_thesession->cmd_cntl_fd,"150 Here comes the directory listing.\r\n",strlen("150 Here comes the directory listing.\r\n"));
	 int port_data_fd=fork();//产生子进程,专用于数据传输

	 if (0 == port_data_fd)
	 {
	    struct stat sbuf;
		mode_t mode;
		char buf[1024];
		DIR *dp;
		struct dirent *entry;
		dp=opendir(".");
		if (dp==NULL)
		{
			return FALSE;
		}
		int tmp_data_fd=-1;
		if (p_thesession->is_port_or_pasv==PORT)
		{
			tmp_data_fd=p_thesession->port_data_fd;
		}
		else
		{
			MYFTP_SOCKADDR tmp_data_addr;
			int len=sizeof(MYFTP_SOCKADDR);
			p_thesession->pasv_data_fd=accept(p_thesession->pasv_listen_fd,&tmp_data_addr.un.u_sockaddr,&len);
			if(p_thesession->pasv_data_fd==-1)
			{
				perror("LIST accept client_id");
			}
			close(p_thesession->pasv_listen_fd);
			tmp_data_fd=p_thesession->pasv_data_fd;
		}
		
		while ((entry=readdir(dp))!=0)
		{
			if (lstat(entry->d_name, &sbuf)==-1)
				continue;
			char perms[] = "----------";
			getprio(&sbuf, perms);
			int off=0;
			memset(buf,0,sizeof(buf));			
			off += sprintf(buf + off, "%s ",perms);
			off += sprintf(buf + off, " %3d %-8d %-8d ",sbuf.st_nlink, sbuf.st_uid, sbuf.st_gid);
			off += sprintf(buf + off, "%8lu ", (unsigned long)sbuf.st_size);				
			
			char* p_date_format = "%b %e %H:%M";
			char datebuf[13]={0};
			struct tm* p_tm;
			p_tm = (struct tm*)localtime(&sbuf.st_mtime);
			strftime(datebuf, sizeof(datebuf), p_date_format, p_tm);
				
			off += sprintf (buf + off, "%s ", datebuf);
				
			if (S_ISLNK(sbuf.st_mode))
			{
				char tmp[1024]={0};
				readlink(entry->d_name,tmp,sizeof(tmp));
				off += sprintf (buf + off, "%s -> %s", entry->d_name,tmp);
			}
			else
			{
				off += sprintf (buf + off, "%s", entry->d_name);
			}
			off += sprintf (buf + off, "%s", "\r\n");
						    	
			write(tmp_data_fd,buf,strlen(buf));
		}
		 closedir(dp);
		 write(p_thesession->cmd_cntl_fd,"226 Directory send OK.\r\n",strlen("226 Directory send OK.\r\n"));
		 close(tmp_data_fd);
		 exit(0);
	}
	close(p_thesession->port_data_fd);
	close(p_thesession->pasv_data_fd);
	return -1;
 }

 /*=================================================================================
function:NLST命令解释函数
 =================================================================================*/
 int myftp_cmd_handle_nlst(pMYFTP_SESSION p_thesession)
 {
	 if (*p_thesession->user_str=='\0'||*p_thesession->passwd_str==0)//用户在注销后(REIN),不允许发送该命令
	 {
		 write(p_thesession->cmd_cntl_fd,"530 Not logged in.\r\n", strlen("530 Not logged in.\r\n"));
		 return -1;
	 }
	 write(p_thesession->cmd_cntl_fd,"150 Here comes the directory listing.\r\n",strlen("150 Here comes the directory listing.\r\n"));
	 
	 int port_data_fd=fork();
	 if (0 == port_data_fd)
	 {
		 struct stat sbuf;
		 mode_t mode;
		 char buf[1024];
		 DIR *dp;
		 struct dirent *entry;
		 dp=opendir(".");
		 if (dp==NULL)
		 {
			 return FALSE;
		 }
		 int tmp_data_fd=-1;
		 if (p_thesession->is_port_or_pasv==PORT)
		 {
			 tmp_data_fd=p_thesession->port_data_fd;
		 }
		 else
		 {
			 MYFTP_SOCKADDR tmp_data_addr;
			 int len=sizeof(MYFTP_SOCKADDR);
			 p_thesession->pasv_data_fd=accept(p_thesession->pasv_listen_fd,&tmp_data_addr.un.u_sockaddr,&len);
			 if(p_thesession->pasv_data_fd==-1)
			 {
				 perror("NLST accept client_id");
			 }
			 close(p_thesession->pasv_listen_fd);
			 tmp_data_fd=p_thesession->pasv_data_fd;
		 }
		 while ((entry=readdir(dp))!=0)
		 {
			 if (lstat(entry->d_name, &sbuf)==-1)
			 {
				 continue;
			 }
			 if(strcmp(entry->d_name,".")==0||strcmp("..",entry->d_name)==0)
			 {
				 continue;
			 }
			 int off=0;
			 memset(buf,0,sizeof(buf));			
			 if (S_ISLNK(sbuf.st_mode))
			 {
				 char tmp[1024]={0};
				 readlink(entry->d_name,tmp,sizeof(tmp));
				 off += sprintf (buf + off, "%s -> %s", entry->d_name,tmp);
			 }
			 else
			 {
				 off += sprintf (buf + off, "%s", entry->d_name);
			 }
			 off += sprintf (buf + off, "%s", "\r\n");
			 write(tmp_data_fd,buf,strlen(buf));
		 }
		 closedir(dp);
		 write(p_thesession->cmd_cntl_fd,"226 Directory send OK.\r\n",strlen("226 Directory send OK.\r\n"));
		 close(tmp_data_fd);
		 exit(0);
	 }
	 close(p_thesession->port_data_fd);
	 close(p_thesession->pasv_data_fd);
	 return -1;
 }

 /*=================================================================================
 function:SYST命令解释函数
 =================================================================================*/
 int myftp_cmd_handle_syst(pMYFTP_SESSION p_thesession)
 {
	 if (*p_thesession->user_str=='\0'||*p_thesession->passwd_str==0)
	 {
		 write(p_thesession->cmd_cntl_fd,"530 Not logged in.\r\n", strlen("530 Not logged in.\r\n"));
		 return -1;
	 }
	 write(p_thesession->cmd_cntl_fd,"215 UNIX Type: L8\r\n",strlen("215 UNIX Type: L8\r\n"));
	 return -1;
 }

 /*=================================================================================
 function:STAT命令解释函数
 注:主要向客户端发送连接信息、ftp服务器相关设置信息、本次会话上载,下载文件数及大小
 =================================================================================*/
 int myftp_cmd_handle_stat(pMYFTP_SESSION p_thesession)
 {
	 if (*p_thesession->user_str=='\0'||*p_thesession->passwd_str==0)
	 {
		 write(p_thesession->cmd_cntl_fd,"530 Not logged in.\r\n", strlen("530 Not logged in.\r\n"));
		 return -1;
	 }
	 char p_str[1024]={0};
	 p_thesession->size_of_retrfile+=retr_num;
	 p_thesession->size_of_storfile+=stor_num;
	 sprintf(p_str,"211-FTP server status for\r\n    User %s\r\n    From %s\r\n    TYPE:%s\r\n    Session timeout in seconds is %d\r\n    Stored %d files, %d bytes\r\n    Retrieved %d files, %d bytes\r\n",\
		 p_thesession->user_str,p_thesession->remote_data_ip_str,p_thesession->typemode,myftp_conf.timeout_val,p_thesession->up_file_num,p_thesession->size_of_storfile,p_thesession->down_file_num,p_thesession->size_of_retrfile);
	 strcat(p_str,"211 End of status.\r\n");
	 write(p_thesession->cmd_cntl_fd, p_str, strlen(p_str));
	 return -1;
 }

/*=================================================================================
function:SIZE命令解释函数
=================================================================================*/
 int myftp_cmd_handle_size(pMYFTP_SESSION p_thesession)
 {
	 if (*p_thesession->user_str=='\0'||*p_thesession->passwd_str==0)
	 {
		 write(p_thesession->cmd_cntl_fd,"530 Not logged in.\r\n", strlen("530 Not logged in.\r\n"));
		 return -1;
	 }
	 struct stat sbuf;
	 if (-1 == lstat(p_thesession->p_cmd_line->arg, &sbuf))
	 {
		 write(p_thesession->cmd_cntl_fd, "550 Could not get file size.\r\n",strlen("550 Could not get file size.\r\n"));
	 } 
	 else
	 {
		 char tmp_filesize[20]={0};
		 sprintf(tmp_filesize,"213 %d\r\n",sbuf.st_size);
		 write(p_thesession->cmd_cntl_fd, tmp_filesize,strlen(tmp_filesize));
	 }
	return -1;
 }

/*=================================================================================
function:HELP命令解释函数
=================================================================================*/
 int myftp_cmd_handle_help(pMYFTP_SESSION p_thesession)
 {
	 if (*p_thesession->user_str=='\0'||*p_thesession->passwd_str==0)
	 {
		 write(p_thesession->cmd_cntl_fd,"530 Not logged in.\r\n", strlen("530 Not logged in.\r\n"));
		 return -1;
	 }
	 char* tmp_str="214-The following commands are recognized.\r\n    REST APPE CDUP DELE HELP LIST MODE NLST NOOP PORT PWD\r\n    QUIT REIN ABOR RETR RNFR RNTO SIZE STOR PASS RMD CWD\r\n    SYST TYPE USER XCWD XMKD XPWD XRMD STAT PASV MKD\r\n214 Help OK.\r\n";
	 write(p_thesession->cmd_cntl_fd, tmp_str, strlen(tmp_str));
 }

/*=================================================================================
function:NOOP命令解释函数
=================================================================================*/
 int myftp_cmd_handle_noop(pMYFTP_SESSION p_thesession)
 {
	 write(p_thesession->cmd_cntl_fd,"200 NOOP ok.\r\n",strlen("200 NOOP ok.\r\n"));
	 return -1;
 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -