static void privop_pasv_accept(session_t *sess) { int fd = accept_timeout(sess->pasv_listen_fd, NULL, tunable_accept_timeout); close(sess->pasv_listen_fd); sess->pasv_listen_fd = -1; if(fd == -1) { priv_sock_send_result(sess->parent_fd, PRIV_SOCK_RESULT_BAD); return; } priv_sock_send_result(sess->parent_fd, PRIV_SOCK_RESULT_OK); priv_sock_send_fd(sess->parent_fd, fd); close(fd); }
int main(int argc, char const *argv[]) { if(getuid()) { fprintf(stderr, "FtpServer must be started by root\n"); exit(EXIT_FAILURE); } //创建一个监听fd int listenfd = tcp_server(NULL, 9981); pid_t pid; session_t sess; session_init(&sess); while(1) { int peerfd = accept_timeout(listenfd, NULL, 10); if(peerfd == -1 && errno == ETIMEDOUT) continue; else if(peerfd == -1) ERR_EXIT("accept_timeout"); if((pid = fork()) == -1) ERR_EXIT("fork"); else if(pid == 0) { close(listenfd); // sess.peerfd = peerfd; session_begin(&sess); } else { close(peerfd); } } return 0; }
int main() { //配置文件模块测试代码 /*parseconf_load_file(MINIFTP_CONF); cout << tunable_pasv_enable << endl; cout << tunable_port_enable << endl; cout << tunable_listen_port << endl; cout << tunable_max_clients << endl; cout << tunable_max_per_ip << endl; cout << tunable_accept_timeout << endl; cout << tunable_connect_timeout << endl; cout << tunable_idle_session_timeout << endl; cout << tunable_data_connection_timeout << endl; cout << tunable_local_umask << endl; cout << tunable_upload_max_rate << endl; cout << tunable_download_max_rate << endl; cout << tunable_listen_address << endl; //*/ //list_common(); if (getuid() != 0)//只能由root用户启动 { fprintf(stderr, "miniftpd: must be started as root\n"); exit(EXIT_FAILURE); } session_t sess = {//会话结构体,用于通信 //控制连接 -1, -1, "", "", "", //数据连接 NULL, -1, -1, //父子进程通信 -1, -1, //FTP协议状态 0, 0, NULL }; signal(SIGCHLD, SIG_IGN);//忽略僵尸进程状态的回收 int listenfd = tcp_server(NULL, 21); int conn; pid_t pid; while (1) { if ((conn = accept_timeout(listenfd, NULL, 0)) == -1)//永久阻塞等待接收连接 ERR_EXIT("accept_timeout::select"); pid = fork(); if (pid == -1) ERR_EXIT("fork"); if (pid == 0) {//子进程处理新用户 close(listenfd); sess.ctrl_fd = conn; begin_session(&sess); } else if (pid > 0) {//父进程继续等待新连接 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; }