예제 #1
0
파일: privparent.c 프로젝트: xsun89/miniftp
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);
}
예제 #2
0
파일: main.c 프로젝트: HTomsmith/FtpServer
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;
}
예제 #3
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;
}
예제 #4
0
파일: main.c 프로젝트: JnuSimba/UNP
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;
}