int get_transfer_fd(session_t *pses) { int iret = 0; //可能是主动模式,或者被动模式 //检测是否收到PORT命令或者PASV命令 if((port_active(pses) < 0) && (pasv_active(pses) < 0)) { ftp_reply(pses->ctrl_fd, FTP_BADSENDCONN, "Use PORT or PASV first."); iret = -1; return iret; } //主动模式 if(port_active(pses) == 0) { //向nobody进程发送命令 priv_sock_send_cmd(pses->child_fd, PRIV_SOCK_GET_DATA_SOCK); unsigned short port = ntohs(pses->port_addr->sin_port); char *ip = inet_ntoa(pses->port_addr->sin_addr); //发送port priv_sock_send_int(pses->child_fd, (int)port); //发送ip priv_sock_send_buf(pses->child_fd, ip, strlen(ip)); //接收应答 char res = priv_sock_get_result(pses->child_fd); if(res == PRIV_SOCK_RESULT_BAD) { iret = -1; } else if(res == PRIV_SOCK_RESULT_OK) { //接收文件描述符 pses->data_fd = priv_sock_recv_fd(pses->child_fd); } } else if(pasv_active(pses) == 0)//被动模式 { //发送命令给nobody进程,完成客户端和服务端的连接 priv_sock_send_cmd(pses->child_fd, PRIV_SOCK_PASV_ACCEPT); //接收nobody进程的应答 char res = priv_sock_get_result(pses->child_fd); if(res == PRIV_SOCK_RESULT_BAD) { iret = -1; } else if(res == PRIV_SOCK_RESULT_OK) { pses->data_fd = priv_sock_recv_fd(pses->child_fd); } } //连接成功后,该内存空间就不需要了 if(pses->port_addr != NULL) { free(pses->port_addr); pses->port_addr = NULL; } return iret; }
int get_port_fd(session_t* sess) { priv_sock_send_cmd(sess->child_fd, PRIV_SOCK_GET_DATA_SOCK); unsigned short port = ntohs(sess->port_addr->sin_port); char* ip = inet_ntoa(sess->port_addr->sin_addr); priv_sock_send_int(sess->child_fd, (int)port); priv_sock_send_buf(sess->child_fd, ip, strlen(ip)); char res = priv_sock_get_result(sess->child_fd); if(res == PRIV_SOCK_RESULT_BAD) return 0; else if(res == PRIV_SOCK_RESULT_OK) sess->data_fd = priv_sock_recv_fd(sess->child_fd); return 1; }
int ftp_write_data(const struct vsf_session* p_sess, const char* p_buf, unsigned int len) { if (p_sess->data_use_ssl && p_sess->ssl_slave_active) { int ret; priv_sock_send_cmd(p_sess->ssl_consumer_fd, PRIV_SOCK_DO_SSL_WRITE); priv_sock_send_buf(p_sess->ssl_consumer_fd, p_buf, len); ret = priv_sock_get_int(p_sess->ssl_consumer_fd); /* Need to do this here too because it is useless in the slave process. */ vsf_sysutil_check_pending_actions(kVSFSysUtilIO, ret, p_sess->data_fd); return ret; } else if (p_sess->data_use_ssl) { return ssl_write(p_sess->p_data_ssl, p_buf, len); } else { return vsf_sysutil_write_loop(p_sess->data_fd, p_buf, len); } }