VirtualBox

Changeset 82772 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Jan 15, 2020 4:41:07 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
135725
Message:

IPRT/FTP: First working version for listing stuff. bugref:9646

Location:
trunk/src/VBox/Runtime
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/generic/ftp-server.cpp

    r82771 r82772  
    201201    /** Actual client state. */
    202202    RTFTPSERVERCLIENTSTATE      State;
     203    /** The last set data connection IP. */
     204    RTNETADDRIPV4               DataConnAddr;
     205    /** The last set data connection port number. */
     206    uint16_t                    uDataConnPort;
    203207    /** Data connection information.
    204208     *  At the moment we only allow one data connection per client at a time. */
     
    274278*********************************************************************************************************************************/
    275279
    276 static int rtFtpServerDataConnOpen(PRTFTPSERVERDATACONN pDataConn, PRTNETADDRIPV4 pAddr, uint16_t uPort);
     280static int  rtFtpServerDataConnOpen(PRTFTPSERVERDATACONN pDataConn, PRTNETADDRIPV4 pAddr, uint16_t uPort);
     281static int  rtFtpServerDataConnClose(PRTFTPSERVERDATACONN pDataConn);
    277282static void rtFtpServerDataConnReset(PRTFTPSERVERDATACONN pDataConn);
    278 static int rtFtpServerDataConnStart(PRTFTPSERVERDATACONN pDataConn, PFNRTTHREAD pfnThread,
    279                                     uint8_t cArgs, const char * const *apcszArgs);
    280 static int rtFtpServerDataConnDestroy(PRTFTPSERVERDATACONN pDataConn);
     283static int  rtFtpServerDataConnStart(PRTFTPSERVERDATACONN pDataConn, PFNRTTHREAD pfnThread, uint8_t cArgs, const char * const *apcszArgs);
     284static int  rtFtpServerDataConnStop(PRTFTPSERVERDATACONN pDataConn);
     285static void rtFtpServerDataConnDestroy(PRTFTPSERVERDATACONN pDataConn);
    281286
    282287static void rtFtpServerClientStateReset(PRTFTPSERVERCLIENTSTATE pState);
     
    398403    AssertReturn(cch > 0, VERR_NO_MEMORY);
    399404
    400     int rc = RTStrAPrintf(&pszMsg, "%RU32", enmReply);
     405    int rc = RTStrAPrintf(&pszMsg, "%RU32 -", enmReply);
    401406    AssertRCReturn(rc, rc);
    402407
     408    /** @todo Support multi-line replies (see 4.2ff). */
     409
    403410    if (pszFmt)
    404411    {
    405         rc = RTStrAAppend(&pszMsg, " - ");
     412        rc = RTStrAAppend(&pszMsg, " ");
    406413        AssertRCReturn(rc, rc);
    407414
     
    514521    } while (0);
    515522
    516     char szTemp[32];
     523    char szTemp[128];
    517524
    518525    INFO_TO_STR("%c", chFileType);
     
    698705    AssertReturn(cchAdddress > 0, VERR_NO_MEMORY);
    699706
    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;
    701720}
    702721
     
    715734        LogFlowFuncEnter();
    716735
    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);
    725741    return rc;
    726742}
     
    837853
    838854    pDataConn->pClient = pClient;
     855
     856    /* Use the last configured addr + port. */
     857    pDataConn->Addr    = pClient->DataConnAddr;
     858    pDataConn->uPort   = pClient->uDataConnPort;
    839859
    840860    *ppDataConn = pDataConn;
     
    909929
    910930/**
    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 rtFtpServerDataConnDestroy(PRTFTPSERVERDATACONN pDataConn)
     931 * Stops a data connection.
     932 *
     933 * @returns VBox status code.
     934 * @param   pDataConn           Data connection to stop.
     935 */
     936static int rtFtpServerDataConnStop(PRTFTPSERVERDATACONN pDataConn)
    917937{
    918938    if (!pDataConn)
     
    933953
    934954    if (RT_SUCCESS(rc))
    935     {
    936955        rtFtpServerDataConnClose(pDataConn);
    937         rtFtpCmdArgsFree(pDataConn->cArgs, pDataConn->papszArgs);
    938 
    939         RTMemFree(pDataConn);
    940         pDataConn = NULL;
    941 
    942         /** @todo Also check / handle rcThread? */
    943     }
    944956
    945957    LogFlowFuncLeaveRC(rc);
    946958    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 */
     967static 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;
    947982}
    948983
     
    9751010    RT_NOREF(cArgs, apcszArgs);
    9761011
    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);
    9801016        pClient->pDataConn = NULL;
    9811017
     
    10981134    int rc;
    10991135
    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        }
    11041162    }
    11051163    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;
    11131165
    11141166    return rc;
     
    11631215        return rtFtpServerSendReplyRc(pClient, RTFTPSERVER_REPLY_ERROR_INVALID_PARAMETERS);
    11641216
    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;
    11831228
    11841229    return rc;
     
    12051250    RT_NOREF(cArgs, apcszArgs);
    12061251
    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);
    12091258        pClient->pDataConn = NULL;
     1259    }
     1260
     1261    int rc2 = rtFtpServerSendReplyRc(pClient, RTFTPSERVER_REPLY_OKAY);
     1262    if (RT_SUCCESS(rc))
     1263        rc = rc2;
    12101264
    12111265    return rc;
     
    12301284            rc = rtFtpServerDataConnStart(pClient->pDataConn, rtFtpServerDataConnFileWriteThread, cArgs, apcszArgs);
    12311285            if (RT_SUCCESS(rc))
    1232                 rc = rtFtpServerSendReplyRc(pClient, RTFTPSERVER_REPLY_FILE_STATUS_OKAY);
     1286                rc = rtFtpServerSendReplyRc(pClient, RTFTPSERVER_REPLY_FILE_STS_OK_OPENING_DATA_CONN);
    12331287        }
    12341288        else
     
    16071661                Assert(pClient->pDataConn->rc != VERR_IPE_UNINITIALIZED_STATUS);
    16081662
    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);
    16151667                    pClient->pDataConn = NULL;
    1616 
    1617                 if (RT_SUCCESS(rc))
    1618                     rc = rc2;
     1668                }
    16191669            }
    16201670        }
     
    16221672
    16231673    /* 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;
    16301676
    16311677    LogFlowFuncLeaveRC(rc);
  • trunk/src/VBox/Runtime/tools/RTFTPServer.cpp

    r82770 r82772  
    253253static DECLCALLBACK(int) onFileStat(PRTFTPCALLBACKDATA pData, const char *pcszPath, PRTFSOBJINFO pFsObjInfo)
    254254{
    255     RT_NOREF(pData);
     255    PFTPSERVERDATA pThis = (PFTPSERVERDATA)pData->pvUser;
     256    Assert(pData->cbUser == sizeof(FTPSERVERDATA));
    256257
    257258    RTFILE hFile;
    258     int rc = RTFileOpen(&hFile, pcszPath,
     259    int rc = RTFileOpen(&hFile, pcszPath ? pcszPath : pThis->szCWD,
    259260                        RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
    260261    if (RT_SUCCESS(rc))
     
    309310    RT_NOREF(pData, pcszPath, pvData, cbData, pcbRead);
    310311
     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. */
    311337    return VINF_EOF;
    312338}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette