int main(int argc, char const *argv[]) { check_permission(); setup_signal_chld(); parseconf_load_file("ftpserver.conf"); print_conf(); init_hash(); //创建一个监听fd int listenfd = tcp_server(tunable_listen_address, tunable_listen_port); pid_t pid; session_t sess; session_init(&sess); p_sess = &sess; //配置全局变量 while(1) { struct sockaddr_in addr; int peerfd = accept_timeout(listenfd, &addr, tunable_accept_timeout); if(peerfd == -1 && errno == ETIMEDOUT) continue; else if(peerfd == -1) ERR_EXIT("accept_timeout"); //获取ip地址,并在hash中添加一条记录 uint32_t ip = addr.sin_addr.s_addr; sess.ip = ip; add_clients_to_hash(&sess, ip); if((pid = fork()) == -1) ERR_EXIT("fork"); else if(pid == 0) { close(listenfd); sess.peerfd = peerfd; limit_num_clients(&sess); session_begin(&sess); exit(EXIT_SUCCESS); } else { //pid_to_ip add_pid_ip_to_hash(pid, ip); close(peerfd); } } return 0; }
int main(int argc, const char *argv[]) { parseconf_load_file("conf/ftpserver.conf"); printf("tunable_pasv_enable=%d\n", tunable_pasv_enable); printf("tunable_port_enable=%d\n", tunable_port_enable); printf("tunable_listen_port=%u\n", tunable_listen_port); printf("tunable_max_clients=%u\n", tunable_max_clients); printf("tunable_max_per_ip=%u\n", tunable_max_per_ip); printf("tunable_accept_timeout=%u\n", tunable_accept_timeout); printf("tunable_connect_timeout=%u\n", tunable_connect_timeout); printf("tunable_idle_session_timeout=%u\n", tunable_idle_session_timeout); printf("tunable_data_connection_timeout=%u\n", tunable_data_connection_timeout); printf("tunable_local_umask=0%o\n", tunable_local_umask); printf("tunable_upload_max_rate=%u\n", tunable_upload_max_rate); printf("tunable_download_max_rate=%u\n", tunable_download_max_rate); if (tunable_listen_address == NULL) printf("tunable_listen_address=NULL\n"); else printf("tunable_listen_address=%s\n", tunable_listen_address); return 0; }
int main(int argc, char *argv[]) { daemon(1, 0); // list_common(NULL); // 测试配置文件读取 parseconf_load_file(MINIFTP_CONF); /* printf("tunable_pasv_enable=%d\n", tunable_pasv_enable); printf("tunable_port_enable%d\n", tunable_port_enable); printf("tunable_listen_port=%u\n", tunable_listen_port); printf("tunable_max_clients=%u\n", tunable_max_clients); printf("tunable_max_per_ip=%u\n", tunable_max_per_ip); printf("tunable_accept_timeout=%u\n", tunable_accept_timeout); printf("tunable_connect_timeout=%u\n", tunable_connect_timeout); printf("tunable_idle_session_timeout=%u\n", tunable_idle_session_timeout); printf("tunable_data_connection_timeout=%u\n", tunable_data_connection_timeout); printf("tunable_local_umask=0%o\n", tunable_local_umask); printf("tunable_upload_max_rate=%u\n", tunable_upload_max_rate); printf("tunable_download_max_rate=%u\n", tunable_download_max_rate); if (tunable_listen_address == NULL) printf("tunable_listen_address=NULL\n"); else printf("tunable_listen_address=%s\n", tunable_listen_address); */ if (getuid() != 0) { fprintf(stderr, "miniftpd: must be started as root\n"); exit(EXIT_FAILURE); } /* typedef struct session { // 控制连接 int ctrl_fd; uid_t uid; char cmdline[MAX_COMMAND_LINE]; char cmd[MAX_COMMAND]; char arg[MAX_ARG]; // 数据连接 struct sockaddr_in *port_addr; // port 模式下对方的port_addr int pasv_listen_fd; int data_fd; // 父子进程通道 int parent_fd; int child_fd; // FTP协议状态 int is_ascii; long long restart_pos; char *rnft_name; } session_t; * */ session_t sess = { /* 控制连接 */ -1, 0, "", "", "", /* 数据连接 */ NULL, -1, -1, 0, /* 父子进程通道 */ -1, -1, /* FTP协议状态 */ 0, 0, NULL, /* 连接数限制*/ 0 }; signal(SIGCHLD, handle_sig_chld); int listenfd = tcp_server(tunable_listen_address, 21); int conn; pid_t pid; num_child = 0; while (1) { if ((conn = accept(listenfd, NULL, NULL)) < 0) err_sys("accept"); ++num_child; sess.num_clients = num_child; pid = fork(); if (pid == -1) { --num_child; err_sys("fork"); } if (pid == 0) { close(listenfd); sess.ctrl_fd = conn; // 判断连接数 if (tunable_max_clients > 0 && sess.num_clients > tunable_max_clients) { char msg[1024]; sprintf(msg, "%d %s\r\n", FTP_TRANSFEROK, "There are too many connected users, pleasr try later."); writen(sess.ctrl_fd, msg, sizeof(msg)); exit(EXIT_FAILURE); } begin_session(&sess); } else { close(conn); } } return 0; }
int main(void) { daemon(1, 0); parseconf_load_file(MINIFTPD_CONF); if (getuid() != 0) { fprintf(stderr, "must be started by root.\n"); exit(EXIT_FAILURE); } int listenfd = tcp_server(tunable_listen_address, tunable_listen_port); int conn; session_t sess = { //控制连接 0, -1, "", "", "", // ftp协议进程与nobody进程通信 -1, -1, //限速 0, 0, 0, 0, // 数据连接 NULL, -1, -1, 0, // ftp协议控制 0, 0, NULL, 0, //客户端连接数控制 0, 0 }; p_sess = &sess; sess.upload_speed_max = tunable_upload_max_rate; sess.download_speed_max = tunable_download_max_rate; signal(SIGCHLD, handle_sigchld); struct sockaddr_in peeraddr; s_ip_count_hash = hash_alloc(256, hash_func); s_pid_ip_hash = hash_alloc(256, hash_func); while(1) { if ((conn = accept_timeout(listenfd, &peeraddr, 0)) < 0) ERR_EXIT("accept_timeout"); unsigned int ip = (unsigned int)peeraddr.sin_addr.s_addr; sess.num_this_ip = handle_ip_count(&ip); ++cur_childrens; sess.num_clients = cur_childrens; pid_t pid = fork(); if (pid == -1) { --cur_childrens; ERR_EXIT("fork"); } if (pid == 0) { sess.ctrl_fd = conn; close(listenfd); check_clients_limit(&sess); signal(SIGCHLD, SIG_IGN); begin_session(&sess); } else if (pid > 0) { hash_add_entry(s_pid_ip_hash, &pid, sizeof(pid), &ip, sizeof(unsigned int)); close(conn); } } hash_free(s_ip_count_hash); hash_free(s_pid_ip_hash); return 0; }