void server_read(t_info *info, t_client **client) { t_client *c; c = add_client(info, (*client)->socket, 0, 0); begin_session(info, &c); }
void client_read(t_info *info, t_client **client) { int r; char buf[BUF_SIZE + 1]; char buff_perso[BUF_SIZE + 1]; char *p; t_client *check_respaw; if ((r = (int)xrecv((*client)->socket, buf, BUF_SIZE, 0)) > 0) { buf[r] = '\0'; strncat((*client)->buf_read, buf, BUF_SIZE - strlen(buf)); while ((p = strstr((*client)->buf_read, "\n"))) { *p = 0; strncpy(buff_perso, (*client)->buf_read, BUF_SIZE - 1); check_respaw = *client; if ((*client)->status < ST_CLIENT) begin_session(info, client); else execute_action(buff_perso, *client, info); if (check_respaw == *client) memmove((*client)->buf_read, p + 1, BUF_SIZE); } } else client_disconnect((*client), info); }
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(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; }