Changeset 82772 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Jan 15, 2020 4:41:07 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 135725
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/generic/ftp-server.cpp
r82771 r82772 201 201 /** Actual client state. */ 202 202 RTFTPSERVERCLIENTSTATE State; 203 /** The last set data connection IP. */ 204 RTNETADDRIPV4 DataConnAddr; 205 /** The last set data connection port number. */ 206 uint16_t uDataConnPort; 203 207 /** Data connection information. 204 208 * At the moment we only allow one data connection per client at a time. */ … … 274 278 *********************************************************************************************************************************/ 275 279 276 static int rtFtpServerDataConnOpen(PRTFTPSERVERDATACONN pDataConn, PRTNETADDRIPV4 pAddr, uint16_t uPort); 280 static int rtFtpServerDataConnOpen(PRTFTPSERVERDATACONN pDataConn, PRTNETADDRIPV4 pAddr, uint16_t uPort); 281 static int rtFtpServerDataConnClose(PRTFTPSERVERDATACONN pDataConn); 277 282 static void rtFtpServerDataConnReset(PRTFTPSERVERDATACONN pDataConn); 278 static int rtFtpServerDataConnStart(PRTFTPSERVERDATACONN pDataConn, PFNRTTHREAD pfnThread,279 uint8_t cArgs, const char * const *apcszArgs);280 static intrtFtpServerDataConnDestroy(PRTFTPSERVERDATACONN pDataConn);283 static int rtFtpServerDataConnStart(PRTFTPSERVERDATACONN pDataConn, PFNRTTHREAD pfnThread, uint8_t cArgs, const char * const *apcszArgs); 284 static int rtFtpServerDataConnStop(PRTFTPSERVERDATACONN pDataConn); 285 static void rtFtpServerDataConnDestroy(PRTFTPSERVERDATACONN pDataConn); 281 286 282 287 static void rtFtpServerClientStateReset(PRTFTPSERVERCLIENTSTATE pState); … … 398 403 AssertReturn(cch > 0, VERR_NO_MEMORY); 399 404 400 int rc = RTStrAPrintf(&pszMsg, "%RU32 ", enmReply);405 int rc = RTStrAPrintf(&pszMsg, "%RU32 -", enmReply); 401 406 AssertRCReturn(rc, rc); 402 407 408 /** @todo Support multi-line replies (see 4.2ff). */ 409 403 410 if (pszFmt) 404 411 { 405 rc = RTStrAAppend(&pszMsg, " -");412 rc = RTStrAAppend(&pszMsg, " "); 406 413 AssertRCReturn(rc, rc); 407 414 … … 514 521 } while (0); 515 522 516 char szTemp[ 32];523 char szTemp[128]; 517 524 518 525 INFO_TO_STR("%c", chFileType); … … 698 705 AssertReturn(cchAdddress > 0, VERR_NO_MEMORY); 699 706 700 return RTTcpClientConnect(szAddress, uPort, &pDataConn->hSocket); 707 int rc; 708 709 /* Try a bit harder if the data connection is not ready (yet). */ 710 for (int i = 0; i < 10; i++) 711 { 712 rc = RTTcpClientConnect(szAddress, uPort, &pDataConn->hSocket); 713 if (RT_SUCCESS(rc)) 714 break; 715 RTThreadSleep(100); 716 } 717 718 LogFlowFuncLeaveRC(rc); 719 return rc; 701 720 } 702 721 … … 715 734 LogFlowFuncEnter(); 716 735 717 rc = RTTcpFlush(pDataConn->hSocket); 718 if (RT_SUCCESS(rc)) 719 { 720 rc = RTTcpClientClose(pDataConn->hSocket); 721 pDataConn->hSocket = NIL_RTSOCKET; 722 } 723 } 724 736 rc = RTTcpClientClose(pDataConn->hSocket); 737 pDataConn->hSocket = NIL_RTSOCKET; 738 } 739 740 LogFlowFuncLeaveRC(rc); 725 741 return rc; 726 742 } … … 837 853 838 854 pDataConn->pClient = pClient; 855 856 /* Use the last configured addr + port. */ 857 pDataConn->Addr = pClient->DataConnAddr; 858 pDataConn->uPort = pClient->uDataConnPort; 839 859 840 860 *ppDataConn = pDataConn; … … 909 929 910 930 /** 911 * Destroys a data connection.912 * 913 * @returns VBox status code. 914 * @param pDataConn Data connection to destroy. The pointer is not valid anymore after successful return.915 */ 916 static int rtFtpServerDataConn Destroy(PRTFTPSERVERDATACONN pDataConn)931 * Stops a data connection. 932 * 933 * @returns VBox status code. 934 * @param pDataConn Data connection to stop. 935 */ 936 static int rtFtpServerDataConnStop(PRTFTPSERVERDATACONN pDataConn) 917 937 { 918 938 if (!pDataConn) … … 933 953 934 954 if (RT_SUCCESS(rc)) 935 {936 955 rtFtpServerDataConnClose(pDataConn); 937 rtFtpCmdArgsFree(pDataConn->cArgs, pDataConn->papszArgs);938 939 RTMemFree(pDataConn);940 pDataConn = NULL;941 942 /** @todo Also check / handle rcThread? */943 }944 956 945 957 LogFlowFuncLeaveRC(rc); 946 958 return rc; 959 } 960 961 /** 962 * Destroys a data connection. 963 * 964 * @returns VBox status code. 965 * @param pDataConn Data connection to destroy. The pointer is not valid anymore after successful return. 966 */ 967 static void rtFtpServerDataConnDestroy(PRTFTPSERVERDATACONN pDataConn) 968 { 969 if (!pDataConn) 970 return; 971 972 LogFlowFuncEnter(); 973 974 rtFtpServerDataConnClose(pDataConn); 975 rtFtpCmdArgsFree(pDataConn->cArgs, pDataConn->papszArgs); 976 977 RTMemFree(pDataConn); 978 pDataConn = NULL; 979 980 LogFlowFuncLeave(); 981 return; 947 982 } 948 983 … … 975 1010 RT_NOREF(cArgs, apcszArgs); 976 1011 977 int rc = rtFtpServerDataConnDestroy(pClient->pDataConn); 978 if (RT_SUCCESS(rc)) 979 { 1012 int rc = rtFtpServerDataConnClose(pClient->pDataConn); 1013 if (RT_SUCCESS(rc)) 1014 { 1015 rtFtpServerDataConnDestroy(pClient->pDataConn); 980 1016 pClient->pDataConn = NULL; 981 1017 … … 1098 1134 int rc; 1099 1135 1100 /* Note: Data connection gets created when the PORT command was sent. */ 1101 if (pClient->pDataConn) 1102 { 1103 rc = rtFtpServerDataConnStart(pClient->pDataConn, rtFtpServerDataConnListThread, cArgs, apcszArgs); 1136 RTFTPSERVER_HANDLE_CALLBACK_VA(pfnOnFileStat, cArgs ? apcszArgs[0] : NULL, NULL /* PRTFSOBJINFO */); 1137 1138 RTFTPSERVER_REPLY rcClient = RTFTPSERVER_REPLY_INVALID; 1139 1140 if (RT_SUCCESS(rc)) 1141 { 1142 int rc2 = rtFtpServerSendReplyRc(pClient, pClient->pDataConn 1143 ? RTFTPSERVER_REPLY_DATACONN_ALREADY_OPEN 1144 : RTFTPSERVER_REPLY_FILE_STS_OK_OPENING_DATA_CONN); 1145 if (RT_SUCCESS(rc)) 1146 rc = rc2; 1147 1148 if (RT_SUCCESS(rc)) 1149 { 1150 rc = rtFtpServerDataConnCreate(pClient, &pClient->pDataConn); 1151 if (RT_SUCCESS(rc)) 1152 { 1153 rc = rtFtpServerDataConnStart(pClient->pDataConn, rtFtpServerDataConnListThread, cArgs, apcszArgs); 1154 } 1155 1156 rc2 = rtFtpServerSendReplyRc(pClient, RT_SUCCESS(rc) 1157 ? RTFTPSERVER_REPLY_FILE_ACTION_OKAY_COMPLETED 1158 : RTFTPSERVER_REPLY_CLOSING_DATA_CONN); 1159 if (RT_SUCCESS(rc)) 1160 rc = rc2; 1161 } 1104 1162 } 1105 1163 else 1106 rc = VERR_FTP_DATA_CONN_NOT_FOUND; 1107 1108 int rc2 = rtFtpServerSendReplyRc(pClient, RT_SUCCESS(rc) 1109 ? RTFTPSERVER_REPLY_PATHNAME_OK 1110 : RTFTPSERVER_REPLY_CANT_OPEN_DATA_CONN); 1111 if (RT_SUCCESS(rc)) 1112 rc = rc2; 1164 rcClient = RTFTPSERVER_REPLY_CONN_REQ_FILE_ACTION_NOT_TAKEN; 1113 1165 1114 1166 return rc; … … 1163 1215 return rtFtpServerSendReplyRc(pClient, RTFTPSERVER_REPLY_ERROR_INVALID_PARAMETERS); 1164 1216 1165 PRTFTPSERVERDATACONN pDataConn; 1166 int rc = rtFtpServerDataConnCreate(pClient, &pDataConn); 1167 if (RT_SUCCESS(rc)) 1168 { 1169 pClient->pDataConn = pDataConn; 1170 1171 rc = rtFtpParseHostAndPort(apcszArgs[0], &pDataConn->Addr, &pDataConn->uPort); 1172 if (RT_SUCCESS(rc)) 1173 { 1174 rc = rtFtpServerSendReplyRc(pClient, RTFTPSERVER_REPLY_OKAY); 1175 } 1176 } 1177 1178 if (RT_FAILURE(rc)) 1179 { 1180 int rc2 = rtFtpServerSendReplyRc(pClient, RTFTPSERVER_REPLY_CANT_OPEN_DATA_CONN); 1181 AssertRC(rc2); 1182 } 1217 RTFTPSERVER_REPLY rcClient; 1218 1219 int rc = rtFtpParseHostAndPort(apcszArgs[0], &pClient->DataConnAddr, &pClient->uDataConnPort); 1220 if (RT_SUCCESS(rc)) 1221 rcClient = RTFTPSERVER_REPLY_OKAY; 1222 else 1223 rcClient = RTFTPSERVER_REPLY_ERROR_INVALID_PARAMETERS; 1224 1225 int rc2 = rtFtpServerSendReplyRc(pClient, rcClient); 1226 if (RT_SUCCESS(rc)) 1227 rc = rc2; 1183 1228 1184 1229 return rc; … … 1205 1250 RT_NOREF(cArgs, apcszArgs); 1206 1251 1207 int rc = rtFtpServerDataConnDestroy(pClient->pDataConn); 1208 if (RT_SUCCESS(rc)) 1252 rtFtpServerClientStateReset(&pClient->State); 1253 1254 int rc = rtFtpServerDataConnClose(pClient->pDataConn); 1255 if (RT_SUCCESS(rc)) 1256 { 1257 rtFtpServerDataConnDestroy(pClient->pDataConn); 1209 1258 pClient->pDataConn = NULL; 1259 } 1260 1261 int rc2 = rtFtpServerSendReplyRc(pClient, RTFTPSERVER_REPLY_OKAY); 1262 if (RT_SUCCESS(rc)) 1263 rc = rc2; 1210 1264 1211 1265 return rc; … … 1230 1284 rc = rtFtpServerDataConnStart(pClient->pDataConn, rtFtpServerDataConnFileWriteThread, cArgs, apcszArgs); 1231 1285 if (RT_SUCCESS(rc)) 1232 rc = rtFtpServerSendReplyRc(pClient, RTFTPSERVER_REPLY_FILE_ST ATUS_OKAY);1286 rc = rtFtpServerSendReplyRc(pClient, RTFTPSERVER_REPLY_FILE_STS_OK_OPENING_DATA_CONN); 1233 1287 } 1234 1288 else … … 1607 1661 Assert(pClient->pDataConn->rc != VERR_IPE_UNINITIALIZED_STATUS); 1608 1662 1609 rc = rtFtpServerSendReplyRc(pClient, RT_SUCCESS(pClient->pDataConn->rc) 1610 ? RTFTPSERVER_REPLY_CLOSING_DATA_CONN 1611 : RTFTPSERVER_REPLY_CONN_CLOSED_TRANSFER_ABORTED); 1612 1613 int rc2 = rtFtpServerDataConnDestroy(pClient->pDataConn); 1614 if (RT_SUCCESS(rc2)) 1663 rc = rtFtpServerDataConnStop(pClient->pDataConn); 1664 if (RT_SUCCESS(rc)) 1665 { 1666 rtFtpServerDataConnDestroy(pClient->pDataConn); 1615 1667 pClient->pDataConn = NULL; 1616 1617 if (RT_SUCCESS(rc)) 1618 rc = rc2; 1668 } 1619 1669 } 1620 1670 } … … 1622 1672 1623 1673 /* Make sure to destroy all data connections. */ 1624 int rc2 = rtFtpServerDataConnDestroy(pClient->pDataConn); 1625 if (RT_SUCCESS(rc2)) 1626 pClient->pDataConn = NULL; 1627 1628 if (RT_SUCCESS(rc)) 1629 rc = rc2; 1674 rtFtpServerDataConnDestroy(pClient->pDataConn); 1675 pClient->pDataConn = NULL; 1630 1676 1631 1677 LogFlowFuncLeaveRC(rc); -
trunk/src/VBox/Runtime/tools/RTFTPServer.cpp
r82770 r82772 253 253 static DECLCALLBACK(int) onFileStat(PRTFTPCALLBACKDATA pData, const char *pcszPath, PRTFSOBJINFO pFsObjInfo) 254 254 { 255 RT_NOREF(pData); 255 PFTPSERVERDATA pThis = (PFTPSERVERDATA)pData->pvUser; 256 Assert(pData->cbUser == sizeof(FTPSERVERDATA)); 256 257 257 258 RTFILE hFile; 258 int rc = RTFileOpen(&hFile, pcszPath ,259 int rc = RTFileOpen(&hFile, pcszPath ? pcszPath : pThis->szCWD, 259 260 RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 260 261 if (RT_SUCCESS(rc)) … … 309 310 RT_NOREF(pData, pcszPath, pvData, cbData, pcbRead); 310 311 312 #if 0 313 PFTPSERVERDATA pThis = (PFTPSERVERDATA)pData->pvUser; 314 Assert(pData->cbUser == sizeof(FTPSERVERDATA)); 315 316 RTFILE hFile; 317 int rc = RTFileOpen(&hFile, pcszPath ? pcszPath : pThis->szCWD, 318 RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 319 if (RT_SUCCESS(rc)) 320 { 321 RTFSOBJINFO fsObjInfo; 322 rc = RTFileQueryInfo(hFile, &fsObjInfo, RTFSOBJATTRADD_NOTHING); 323 if (RT_SUCCESS(rc)) 324 { 325 rc = fsObjInfoToStr(&fsObjInfo, (char *)pvData, cbData); 326 } 327 328 RTFileClose(hFile); 329 } 330 #endif 331 332 RTStrPrintf((char *)pvData, cbData, "-rwxr-xr-x 1 johndoe users 0 Apr 6 2017 foobar\r\n"); 333 334 *pcbRead = strlen((char *)pvData); 335 336 /** @todo We ASSUME we're done here for now. */ 311 337 return VINF_EOF; 312 338 }
Note:
See TracChangeset
for help on using the changeset viewer.