int EnterPassiveMode(CFtpParam& ftpParam) { CString strCmd = "PASV\r\n"; CString strMessage = _T(""); if(FTP_COMMAND(ftpParam.ctrlSocket, strCmd, strMessage) < 0) return 1; int index = 0, index2 = 0; index = strMessage.Find('(', 0); index2 = strMessage.Find(')', 0); CString strMid = strMessage.Mid(index + 1, index2 - index - 1); int s1, s2, s3, s4, s5, s6; if(sscanf(strMid, "%d,%d,%d,%d,%d,%d", &s1, &s2, &s3, &s4, &s5, &s6) != 6) return 1; sprintf(ftpParam.remote_host, "%d.%d.%d.%d", s1, s2, s3, s4); ftpParam.remote_port = s5 * 256 + s6; return 0; }
int fd; /*! persistent open file descriptor between callbacks */ }; }; /*! ftp command descriptor */ typedef struct ftp_command { const char *name; /*!< command name */ int (*handler)(ftp_session_t*, const char*); /*!< command callback */ } ftp_command_t; static ftp_command_t ftp_commands[] = { #define FTP_COMMAND(x) { #x, x, } #define FTP_ALIAS(x,y) { #x, y, } FTP_COMMAND(ALLO), FTP_COMMAND(APPE), FTP_COMMAND(CDUP), FTP_COMMAND(CWD), FTP_COMMAND(DELE), FTP_COMMAND(FEAT), FTP_COMMAND(LIST), FTP_COMMAND(MKD), FTP_COMMAND(MODE), FTP_COMMAND(NLST), FTP_COMMAND(NOOP), FTP_COMMAND(OPTS), FTP_COMMAND(PASS), FTP_COMMAND(PASV), FTP_COMMAND(PORT), FTP_COMMAND(PWD),
int OpenControlChannel(char *hostname, int port, char *username, char *password, int timeout, char *retrfile, int ptype, char *pserver, int pport, char *puid, char *ppwd, char *szReturn, CFtpParam& ftpParam) { struct sockaddr_in sa; struct hostent *hp; char buffer[1024] = {0}; int ret = 0; CString strCmd = _T(""); CString strMessage = _T(""); if(*pserver) { // Use Proxy switch(ptype) { case 0: // Common Proxy hp = gethostbyname(pserver); if(!hp) { sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_PROXY", "PROXY_DOMAIN_NAME_PARSER_ERROR"));//<%IDS_FTP_1%> return 1; } memcpy(&sa.sin_addr,hp->h_addr_list[0],hp->h_length); sa.sin_family = AF_INET; sa.sin_port=htons(pport); if (connect_timeo(ftpParam.ctrlSocket, (struct sockaddr *)&sa, sizeof(sa), timeout)) { shutdown(ftpParam.ctrlSocket, 0x02); closesocket(ftpParam.ctrlSocket); sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_PROXY", "PROXY_CONNECT_FAILED"));//<%IDS_FTP_2%> return 1; } break; case 1: // Socks5 Proxy if(socks5_protocol(ftpParam.ctrlSocket, hostname, port, pserver, pport, puid, ppwd, timeout)) { sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_PROXY", "PROXY_SERVER_ERROR"));//<%IDS_FTP_3%> return 1; } break; default: sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_FTP", "FTP_UNKNOWN_PROXY_TYPE"));//<%IDS_FTP_4%> return 1; } } else { // Direct Connect hp = gethostbyname(hostname); if(!hp) { sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_DNS", "DNS_DOMAIN_NAME_PARSE_ERROR"));//<%IDS_FTP_5%> return 1; } memcpy(&sa.sin_addr,hp->h_addr_list[0],hp->h_length); sa.sin_family = AF_INET; sa.sin_port=htons(port); if (connect_timeo(ftpParam.ctrlSocket, (struct sockaddr *)&sa, sizeof(sa), timeout)) { shutdown(ftpParam.ctrlSocket, 0x02); closesocket(ftpParam.ctrlSocket); sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_FTP", "FTP_CONNET_FAILED"));//<%IDS_FTP_6%> return 1; } } CString retMsg = _T(""); if(WaitVersionInfo(ftpParam.ctrlSocket, timeout)) { sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_FTP", "FTP_WAIT_INIT_INFO_TIMEOUT"));//<%IDS_FTP_7%> return 1; } // Send USER Command if(*pserver && ptype == 0) strCmd.Format("USER %s@%s\r\n", username, hostname); else strCmd.Format("USER %s\r\n", username); ret = FTP_COMMAND(ftpParam.ctrlSocket, strCmd, strMessage); if(ret != 2 && ret != 3) { sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_FTP", "FTP_SEND_USERNAME_FAILED"));//<%IDS_FTP_8%> return 1; } // Send PASS Command strCmd.Format("PASS %s\r\n", password); ret = FTP_COMMAND(ftpParam.ctrlSocket, strCmd, strMessage); if(ret != 2 && ret != 3) { sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_FTP", "FTP_SEND_PWD_FAILED"));//<%IDS_FTP_9%> return 1; } // Binary Mode strCmd = "TYPE I\r\n"; ret = FTP_COMMAND(ftpParam.ctrlSocket, strCmd, strMessage); if(ret != 2 && ret != 3) { sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_FTP", "FTP_APPLY_BINARY_MODE_ERROR"));//<%IDS_FTP_10%> return 1; } if(ftpParam.passive_mode) { // Passive Mode if(EnterPassiveMode(ftpParam)) { sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_FTP", "FTP_APPLY_PASSIVITY_MODE_ERROR"));//<%IDS_FTP_11%> return 1; } } else { int Count = 0; while(1) { ftpParam.local_port = rand() % 55536 + 10000; sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_ANY); sa.sin_port=htons(ftpParam.local_port); if(bind(ftpParam.dataSocket, (struct sockaddr *)&sa, sizeof(sa)) == SOCKET_ERROR) { if(Count < 5) { Count ++; continue; } else { sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_FTP", "FTP_LOCATE_BIND_ERROR"));//<%IDS_FTP_12%> return 1; } } if(listen(ftpParam.dataSocket, 10) == SOCKET_ERROR) { if(Count < 5) { Count ++; continue; } else { sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_FTP", "FTP_LOCATE_CREATE_COMMUNICATE_ERROR"));//<%IDS_FTP_13%> return 1; } } break; } struct sockaddr_in lsa; int salen = sizeof(lsa); if(getsockname(ftpParam.ctrlSocket, (struct sockaddr *)&lsa, &salen) == SOCKET_ERROR) { sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_FTP", "FTP_GET_LOCATE_INFO_ERROR"));//<%IDS_FTP_14%> return 1; } strcpy(ftpParam.local_host, inet_ntoa(lsa.sin_addr)); strCmd.Format("PORT %s,%d,%d\r\n", ftpParam.local_host, ftpParam.local_port/256, ftpParam.local_port%256); strCmd.Replace('.', ','); ret = FTP_COMMAND(ftpParam.ctrlSocket, strCmd, strMessage); if(ret < 0 || ret != 2) { if(!ftpParam.passive_mode) { //closesocket(dataSocket); ftpParam.passive_mode = 1; if(EnterPassiveMode(ftpParam)) { sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_FTP", "FTP_APPLY_PASSIVITY_MODE_ERROR"));//<%IDS_FTP_15%> return 1; } } } } if(strlen(retrfile) > 0) { strCmd.Format("RETR %s\r\n", retrfile); WriteString(ftpParam.ctrlSocket, strCmd); ret = ReadString2(ftpParam.ctrlSocket,buffer); if(ret != 1 && ret != 2 && ret != 3 && ret != 9) { if(ret == 5) sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_FTP", "FTP_FILE_NOT_FOUND"));//<%IDS_FTP_16%> else sprintf(szReturn, "error=%s$", FuncGetStringFromIDS("SV_FTP", "FTP_UNKNOWN_ERROR"));//<%IDS_FTP_17%> return 1; } } return 0; }