📄 ftp_operation.c
字号:
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/socket.h>
#include "symbol_table.h"
#include "miniFTP.h"
#include "file_operation.h"
#include <stdio.h>
#define IP_LEN 16
static int ftp_open(int ftp_port) ;
static int ftp_ignore_sigpipe(void) ;
static int ftp_accept(int socket_fd) ;
static void handle_client_cmd(void) ;
//static void addr2name(struct in_addr addr) ;
extern void parse_cmd(char * buf) ;
extern struct user_env user_env;
extern struct run_env run_env;
int r_close(int fd)
{
int state;
while ((state = close(fd)) == -1 && errno == EINTR) {
continue;
}
return state;
}
void start_ftp_server(void){
write_log("[DEBUG_LOG] ---------->start_ftp_server begin. [%s]\n", _timestamp()) ;
int socket_fd = -1;
int connect_fd = -1 ;
pid_t child_pid = -1;
#ifdef DEBUG
run_env.ftp_port = 1999 ;
#endif
if((socket_fd = ftp_open(run_env.ftp_port)) == FTP_OPT_FAIL){
write_log("[ERR_LOG] ftp_open error.\n");
exit(1) ;
}
while(1){
if((connect_fd = ftp_accept(socket_fd)) == FTP_OPT_FAIL){
write_log("[ERR_LOG] ftp_accept error.\n") ;
if(r_close(socket_fd) == FTP_OPT_FAIL){
write_log("[ERR_LOG] close socket_fd error.") ;
}
exit(1) ;
}
write_log("[INFO_LOG] user connect_fd = %d\n", connect_fd) ;
user_env.connect_fd = connect_fd ;
#ifdef DEBUG
write_log("[INFO_LOG] run to fork.\n") ;
#endif
signal(SIGCLD,SIG_IGN) ;
if((child_pid = fork()) == -1){
write_log("[ERR_LOG] fork child proces error.\n") ;
}else if(child_pid){ /*parent process.*/
if(r_close(user_env.connect_fd) == FTP_OPT_FAIL){
write_log("[ERR_LOG] close child connect_fd error.\n") ;
}
continue ;
}else if(child_pid == 0){ /*child*/
if(r_close(socket_fd) == FTP_OPT_FAIL){
write_log("[ERR_LOG]close parent listen socket error.\n") ;
}
handle_client_cmd() ;
if(r_close(user_env.connect_fd) == FTP_OPT_FAIL){
write_log("[ERR_LOG]close user connect_fd error.\n");
}
exit(0) ;
}
}
}
static int ftp_open(int ftp_port){ write_log("[DEBUG_LOG] ---------->ftp_open begin. ftp_port = %d [%s]\n", ftp_port, _timestamp()) ;
int error ;
struct sockaddr_in server_addr ;
bzero((char*) &server_addr,sizeof(server_addr));
int socket_fd ;
int true = 1 ;
//if((ftp_ignore_sigpipe() == -1) ||
if((socket_fd = socket(AF_INET,SOCK_STREAM,0)) == FTP_OPT_FAIL){
write_log("[ERR_LOG] socket error in ftp_open.\n") ;
//perror("socket error\n") ;
if(errno == EPROTONOSUPPORT ){
write_log("[ERR_LOG] the protocal type or the specified protocal is not supported in the system.\n") ;
//perror("the protocal type or the specified protocal is not supported in the system.") ;
}else if(errno == ENFILE ){
write_log("[ERR_LOG] no enough memory to create the new socket.\n") ;
//perror("no enough memory to create the new socket.") ;
}else if(errno == EMFILE ){
write_log("[ERR_LOG] new socket cannot be create due to the process table overflow.\n") ;
//perror("new socket cannot be create due to the process table overflow.") ;
}else if(errno == EINVAL){
write_log("[ERR_LOG] These parms are invalid.\n") ;
//perror("These parms are invalid.") ;
}else{
write_log("[ERR_LOG] no enough memory.\n") ;
//perror("no enough memory.") ;
}
write_log("[ERR_LOG] ftp_open error is socket or ftp_ignore_sigpipe.[%s]\n", _timestamp()) ;
return FTP_OPT_FAIL ;
}
/**
if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&true,sizeof(true)) == -1) {
error = errno;
while ((close(socket_fd) == -1) && (errno == EINTR));
errno = error;
write_log("[ERR_LOG] ftp_open error is setsockopt.[%s]\n", _timestamp()) ;
return FTP_OPT_FAIL;
}
**/
server_addr.sin_family = AF_INET ;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY) ;
server_addr.sin_port = htons((short)ftp_port) ;
if((bind(socket_fd,(struct sockaddr *)&server_addr, sizeof(server_addr))) == FTP_OPT_FAIL){
//perror("bind error.") ;
write_log("[ERR_LOG] bind error in ftp_open.\n") ;
if(errno == EADDRINUSE){
write_log("[ERR_LOG] The given address is already in use.\n") ;
//perror("The given address is already in use.\n") ;
}else if(errno ==EACCES){
write_log("[ERR_LOG] The address is protected.\n") ;
//perror("The address is protected.\n");
}
if(r_close(socket_fd) == FTP_OPT_FAIL){
write_log("[ERR_LOG] close socket_fd error.\n") ;
//perror("close socket_fd error\n") ;
}
write_log("[ERR_LOG] ftp_open error is bind.[%s]\n", _timestamp()) ;
return FTP_OPT_FAIL ;
}
if((listen(socket_fd,run_env.backlog)) == FTP_OPT_FAIL){
//perror("listen error.") ;
write_log("[ERR_LOG] listen error in ftp_open.\n") ;
if(errno == EADDRINUSE){
write_log("[ERR_LOG] Another socket is already listening on the same port.\n") ;
//perror("Another socket is already listening on the same port.") ;
}
write_log("[ERR_LOG] ftp_open error is listen.[%s]\n", _timestamp()) ;
return FTP_OPT_FAIL ;
}
write_log("[DEBUG_LOG] <----------ftp_open end. socket_fd = %d [%s]\n", socket_fd, _timestamp()) ;
return socket_fd ;
}
/*
* ftp_ignore_sigpipe
* Ignore SIGPIPE if the default action is in effect.
*
* returns: 0 if successful
* -1 on error and sets errno
*/
static int ftp_ignore_sigpipe() {
struct sigaction act;
if (sigaction(SIGPIPE, (struct sigaction *)NULL, &act) == -1)
return -1;
if (act.sa_handler == SIG_DFL) {
act.sa_handler = SIG_IGN;
if (sigaction(SIGPIPE, &act, (struct sigaction *)NULL) == -1)
return -1;
}
return 0;
}
static int ftp_accept(int socket_fd) {
write_log("[DEBUG_LOG] ---------->ftp_accept begin. socket_fd = %d [%s]\n", socket_fd, _timestamp()) ;
printf("the listen socket_fd = %d\n", socket_fd) ;
//write_log("ftp_accept begin.",1) ;
socklen_t len = sizeof(struct sockaddr_in) ;
int connect_fd ;
char *ipstr ;
char add[IP_LEN] ;
struct sockaddr_in client_address ;
for(;;){
if((connect_fd = accept(socket_fd,(struct sockaddr *)(&client_address),&len)) == -1 &&(errno==EINTR) ){ continue ;
} if(connect_fd == -1){
//fprintf(stderr,"accept error, errno is %d\n",errno) ;
if(errno == ECONNABORTED){
write_log("[ERR_LOG] A connection has been aborted.\n") ;
//perror("A connection has been aborted.\n") ;
}else if(errno == EPERM){
write_log("[ERR_LOG] Firewall rules forbid connection.\n") ;
//perror("Firewall rules forbid connection.\n") ;
}else if(errno == ENFILE){
write_log("[ERR_LOG] The system limit on the total numbers of open files has been reached.\n") ;
//perror("The system limit on the total numbers of open files has been reached\n") ;
}else if(errno == EINTR){
}
}
break ;
}
//addr2name(client_address.sin_addr) ;
ipstr = inet_ntoa(client_address.sin_addr) ;
//if((user_env.client_ip =malloc(sizeof(char)*(strlen(add)+1))) != NULL ){
// strcpy(user_env.client_ip,ipstr) ;
//}else{
// user_env.client_ip = NULL ;
//}
printf("the connect_fd = %d, ipstr = %s\n",connect_fd, ipstr) ;
write_log("[DEBUG_LOG] <----------ftp_accept end, connect_fd = %d. [%s]\n",connect_fd, _timestamp()) ;
return connect_fd ;
}
static void handle_client_cmd(){
write_log("[DEBUG_LOG] ---------->handle_client_cmd begin.[%s]\n", _timestamp()) ;
int read_cnt ;
int write_cnt ;
char read_buf[BUF_LEN] ;
int banner_len = strlen(run_env.welcome_banner) + 8 ;
char welcome_msg[banner_len] ;
snprintf(welcome_msg,banner_len,"220 %s\r\n",run_env.welcome_banner ) ;
if((write_cnt = write(user_env.connect_fd,welcome_msg,strlen(welcome_msg))) == -1){
write_log("write error.", 0);
exit(errno) ;
}
while(1){
if((read_cnt = read(user_env.connect_fd,read_buf,BUF_LEN)) <= 0){
continue ;
}
parse_cmd(read_buf) ;
}
write_log("[DEBUG_LOG] <----------handle_client_cmd end. [%s]\n", _timestamp()) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -