VirtualBox

Ignore:
Timestamp:
Jan 10, 2020 2:04:36 PM (5 years ago)
Author:
vboxsync
Message:

IPRT/FTP: More protocol handling and callback work. bugref:9437

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/tools/RTFTPServer.cpp

    r82699 r82715  
    2323 * You may elect to license modified versions of this file under the
    2424 * terms and conditions of either the GPL or the CDDL or both.
     25 */
     26
     27/*
     28 * Use this setup to best see what's going on:
     29 *
     30 *    VBOX_LOG=rt_ftp=~0
     31 *    VBOX_LOG_DEST="nofile stderr"
     32 *    VBOX_LOG_FLAGS="unbuffered enabled thread msprog"
     33 *
    2534 */
    2635
     
    5463
    5564/*********************************************************************************************************************************
     65*   Definitations                                                                                                                *
     66*********************************************************************************************************************************/
     67typedef struct FTPSERVERDATA
     68{
     69    char szRootDir[RTPATH_MAX];
     70    char szCWD[RTPATH_MAX];
     71} FTPSERVERDATA;
     72typedef FTPSERVERDATA *PFTPSERVERDATA;
     73
     74
     75/*********************************************************************************************************************************
    5676*   Global Variables                                                                                                             *
    5777*********************************************************************************************************************************/
    5878/** Set by the signal handler when the FTP server shall be terminated. */
    5979static volatile bool  g_fCanceled  = false;
    60 static char          *g_pszRootDir = NULL;
     80static FTPSERVERDATA  g_FTPServerData;
    6181
    6282
     
    150170    RT_NOREF(pData, pcszUser);
    151171
    152     RTPrintf("User '%s' connected", pcszUser);
     172    RTPrintf("User '%s' connected\n", pcszUser);
    153173
    154174    return VINF_SUCCESS;
     
    159179    RT_NOREF(pData, pcszUser, pcszPassword);
    160180
    161     RTPrintf("Authenticating user '%s' ...", pcszUser);
     181    RTPrintf("Authenticating user '%s' ...\n", pcszUser);
    162182
    163183    return VINF_SUCCESS;
     
    168188    RT_NOREF(pData);
    169189
    170     RTPrintf("User disconnected");
     190    RTPrintf("User disconnected\n");
    171191
    172192    return VINF_SUCCESS;
     
    175195static DECLCALLBACK(int) onPathSetCurrent(PRTFTPCALLBACKDATA pData, const char *pcszCWD)
    176196{
    177     RT_NOREF(pData, pcszCWD);
     197    PFTPSERVERDATA pThis = (PFTPSERVERDATA)pData->pvUser;
     198    Assert(pData->cbUser == sizeof(FTPSERVERDATA));
    178199
    179200    RTPrintf("Setting current directory to '%s'\n", pcszCWD);
    180201
    181     return VINF_SUCCESS;
     202    /** @todo BUGBUG Santiy checks! */
     203
     204    return RTStrCopy(pThis->szCWD, sizeof(pThis->szCWD), pcszCWD);
    182205}
    183206
    184207static DECLCALLBACK(int) onPathGetCurrent(PRTFTPCALLBACKDATA pData, char *pszPWD, size_t cbPWD)
    185208{
    186     RT_NOREF(pData, pszPWD, cbPWD);
    187 
    188     return VINF_SUCCESS;
    189 }
    190 
    191 static DECLCALLBACK(int) onList(PRTFTPCALLBACKDATA pData, void **ppvData, size_t *pcbData)
    192 {
    193     RT_NOREF(pData, ppvData, pcbData);
     209    PFTPSERVERDATA pThis = (PFTPSERVERDATA)pData->pvUser;
     210    Assert(pData->cbUser == sizeof(FTPSERVERDATA));
     211
     212    RTPrintf("Current directory is: '%s'\n", pThis->szCWD);
     213
     214    RTStrPrintf(pszPWD, cbPWD, "%s", pThis->szCWD);
     215
     216    return VINF_SUCCESS;
     217}
     218
     219static DECLCALLBACK(int) onPathUp(PRTFTPCALLBACKDATA pData)
     220{
     221    RT_NOREF(pData);
     222
     223    return VINF_SUCCESS;
     224}
     225
     226static DECLCALLBACK(int) onList(PRTFTPCALLBACKDATA pData, const char *pcszPath, void **ppvData, size_t *pcbData)
     227{
     228    RT_NOREF(pData, pcszPath, ppvData, pcbData);
    194229
    195230    return VINF_SUCCESS;
     
    203238
    204239    /* Use some sane defaults. */
    205     char     szAddress[64]         = "localhost";
    206     uint16_t uPort                 = 2121;
     240    char     szAddress[64] = "localhost";
     241    uint16_t uPort         = 2121;
     242
     243    RT_ZERO(g_FTPServerData);
    207244
    208245    /*
     
    238275
    239276            case 'r':
    240                 g_pszRootDir = RTStrDup(ValueUnion.psz);
     277                RTStrCopy(g_FTPServerData.szRootDir, sizeof(g_FTPServerData.szRootDir), ValueUnion.psz);
    241278                break;
    242279
     
    273310    }
    274311
    275     if (!g_pszRootDir)
    276     {
    277         char szRootDir[RTPATH_MAX];
    278 
     312    if (!strlen(g_FTPServerData.szRootDir))
     313    {
    279314        /* By default use the current directory as serving root directory. */
    280         rc = RTPathGetCurrent(szRootDir, sizeof(szRootDir));
     315        rc = RTPathGetCurrent(g_FTPServerData.szRootDir, sizeof(g_FTPServerData.szRootDir));
    281316        if (RT_FAILURE(rc))
    282317            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Retrieving current directory failed: %Rrc", rc);
    283 
    284         g_pszRootDir = RTStrDup(szRootDir);
    285         if (!g_pszRootDir)
    286             return RTMsgErrorExit(RTEXITCODE_FAILURE, "Allocating current directory failed");
    287     }
     318    }
     319
     320    /* Initialize CWD. */
     321    RTStrPrintf2(g_FTPServerData.szCWD, sizeof(g_FTPServerData.szCWD), "/");
    288322
    289323    /* Install signal handler. */
     
    296330        RTFTPSERVERCALLBACKS Callbacks;
    297331        RT_ZERO(Callbacks);
     332
     333        Callbacks.pvUser                = &g_FTPServerData;
     334        Callbacks.cbUser                = sizeof(g_FTPServerData);
     335
    298336        Callbacks.pfnOnUserConnect      = onUserConnect;
    299337        Callbacks.pfnOnUserAuthenticate = onUserAuthenticate;
     
    301339        Callbacks.pfnOnPathSetCurrent   = onPathSetCurrent;
    302340        Callbacks.pfnOnPathGetCurrent   = onPathGetCurrent;
     341        Callbacks.pfnOnPathUp           = onPathUp;
     342        Callbacks.pfnOnList             = onList;
    303343        Callbacks.pfnOnList             = onList;
    304344
     
    308348        {
    309349            RTPrintf("Starting FTP server at %s:%RU16 ...\n", szAddress, uPort);
    310             RTPrintf("Root directory is '%s'\n", g_pszRootDir);
     350            RTPrintf("Root directory is '%s'\n", g_FTPServerData.szRootDir);
    311351
    312352            RTPrintf("Running FTP server ...\n");
     
    336376    }
    337377
    338     RTStrFree(g_pszRootDir);
    339 
    340378    /* Set rcExit on failure in case we forgot to do so before. */
    341379    if (RT_FAILURE(rc))
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