VirtualBox

Ignore:
Timestamp:
Jan 23, 2020 10:40:42 AM (5 years ago)
Author:
vboxsync
Message:

IPRT/tools/FTPServer: Implemented VFS support for files also. bugref:9646

File:
1 edited

Legend:

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

    r82842 r82843  
    7373    /** The relative current working directory (CWD) to szRootDir. */
    7474    char szCWD[RTPATH_MAX];
    75     RTFILE hFile;
    7675} FTPSERVERDATA;
    7776typedef FTPSERVERDATA *PFTPSERVERDATA;
    7877
    79 typedef struct FTPDIRHANDLE
    80 {
    81     /** The VFS (chain) handle to use for this directory. */
    82     RTVFSDIR hVfsDir;
    83 } FTPDIRHANDLE;
    84 typedef FTPDIRHANDLE *PFTPDIRHANDLE;
     78/**
     79 * Enumeration specifying the VFS handle type of the FTP server.
     80 */
     81typedef enum FTPSERVERVFSHANDLETYPE
     82{
     83    FTPSERVERVFSHANDLETYPE_INVALID    = 0,
     84    FTPSERVERVFSHANDLETYPE_FILE,
     85    FTPSERVERVFSHANDLETYPE_DIR,
     86    /** The usual 32-bit hack. */
     87    FTPSERVERVFSHANDLETYPE_32BIT_HACK = 0x7fffffff
     88} FTPSERVERVFSHANDLETYPE;
     89
     90/**
     91 * Structure for keeping a VFS handle of the FTP server.
     92 */
     93typedef struct FTPSERVERVFSHANDLE
     94{
     95    /** The type of the handle, stored in the union below. */
     96    FTPSERVERVFSHANDLETYPE enmType;
     97    union
     98    {
     99        /** The VFS (chain) handle to use for this file. */
     100        RTVFSFILE hVfsFile;
     101        /** The VFS (chain) handle to use for this directory. */
     102        RTVFSDIR  hVfsDir;
     103    } u;
     104} FTPSERVERVFSHANDLE;
     105typedef FTPSERVERVFSHANDLE *PFTPSERVERVFSHANDLE;
    85106
    86107
     
    207228static DECLCALLBACK(int) onFileOpen(PRTFTPCALLBACKDATA pData, const char *pcszPath, uint32_t fMode, void **ppvHandle)
    208229{
    209     RT_NOREF(ppvHandle);
    210 
    211230    PFTPSERVERDATA pThis = (PFTPSERVERDATA)pData->pvUser;
    212231    Assert(pData->cbUser == sizeof(FTPSERVERDATA));
     232
     233    PFTPSERVERVFSHANDLE pHandle = (PFTPSERVERVFSHANDLE)RTMemAllocZ(sizeof(FTPSERVERVFSHANDLE));
     234    if (!pHandle)
     235        return VERR_NO_MEMORY;
    213236
    214237    char *pszPathAbs = NULL;
     
    216239        return VERR_NO_MEMORY;
    217240
    218     int rc = RTFileOpen(&pThis->hFile, pszPathAbs, fMode);
     241    int rc = RTVfsChainOpenFile(pszPathAbs, fMode, &pHandle->u.hVfsFile, NULL /*poffError */, NULL /* pErrInfo */);
     242    if (RT_SUCCESS(rc))
     243    {
     244        pHandle->enmType = FTPSERVERVFSHANDLETYPE_FILE;
     245
     246        *ppvHandle = pHandle;
     247    }
     248    else
     249        RTMemFree(pHandle);
    219250
    220251    RTStrFree(pszPathAbs);
     
    225256static DECLCALLBACK(int) onFileRead(PRTFTPCALLBACKDATA pData, void *pvHandle, void *pvBuf, size_t cbToRead, size_t *pcbRead)
    226257{
    227     RT_NOREF(pvHandle);
    228 
    229     PFTPSERVERDATA pThis = (PFTPSERVERDATA)pData->pvUser;
    230     Assert(pData->cbUser == sizeof(FTPSERVERDATA));
    231 
    232     return RTFileRead(pThis->hFile, pvBuf, cbToRead, pcbRead);
     258    RT_NOREF(pData);
     259
     260    PFTPSERVERVFSHANDLE pHandle = (PFTPSERVERVFSHANDLE)pvHandle;
     261    AssertPtrReturn(pHandle, VERR_INVALID_POINTER);
     262    AssertReturn(pHandle->enmType == FTPSERVERVFSHANDLETYPE_FILE, VERR_INVALID_PARAMETER);
     263
     264    return RTVfsFileRead(pHandle->u.hVfsFile, pvBuf, cbToRead, pcbRead);
    233265}
    234266
    235267static DECLCALLBACK(int) onFileClose(PRTFTPCALLBACKDATA pData, void *pvHandle)
    236268{
    237     RT_NOREF(pvHandle);
    238 
    239     PFTPSERVERDATA pThis = (PFTPSERVERDATA)pData->pvUser;
    240     Assert(pData->cbUser == sizeof(FTPSERVERDATA));
    241 
    242     int rc = RTFileClose(pThis->hFile);
     269    RT_NOREF(pData);
     270
     271    PFTPSERVERVFSHANDLE pHandle = (PFTPSERVERVFSHANDLE)pvHandle;
     272    AssertPtrReturn(pHandle, VERR_INVALID_POINTER);
     273    AssertReturn(pHandle->enmType == FTPSERVERVFSHANDLETYPE_FILE, VERR_INVALID_PARAMETER);
     274
     275    int rc = RTVfsFileRelease(pHandle->u.hVfsFile);
    243276    if (RT_SUCCESS(rc))
    244277    {
    245         pThis->hFile = NIL_RTFILE;
     278        RTMemFree(pvHandle);
     279        pvHandle = NULL;
    246280    }
    247281
     
    342376    Assert(pData->cbUser == sizeof(FTPSERVERDATA));
    343377
    344     PFTPDIRHANDLE pHandle = (PFTPDIRHANDLE)RTMemAllocZ(sizeof(FTPDIRHANDLE));
     378    PFTPSERVERVFSHANDLE pHandle = (PFTPSERVERVFSHANDLE)RTMemAllocZ(sizeof(FTPSERVERVFSHANDLE));
    345379    if (!pHandle)
    346380        return VERR_NO_MEMORY;
     
    353387    RTPrintf("Opening directory '%s'\n", pszPathAbs);
    354388
    355     int rc = RTVfsChainOpenDir(pszPathAbs, 0 /*fFlags*/, &pHandle->hVfsDir, NULL /* poffError */, NULL /* pErrInfo */);
     389    int rc = RTVfsChainOpenDir(pszPathAbs, 0 /*fFlags*/, &pHandle->u.hVfsDir, NULL /* poffError */, NULL /* pErrInfo */);
    356390    if (RT_SUCCESS(rc))
    357391    {
     392        pHandle->enmType = FTPSERVERVFSHANDLETYPE_DIR;
     393
    358394        *ppvHandle = pHandle;
    359395    }
     
    372408    RT_NOREF(pData);
    373409
    374     PFTPDIRHANDLE pHandle = (PFTPDIRHANDLE)pvHandle;
     410    PFTPSERVERVFSHANDLE pHandle = (PFTPSERVERVFSHANDLE)pvHandle;
    375411    AssertPtrReturn(pHandle, VERR_INVALID_POINTER);
    376 
    377     RTVfsDirRelease(pHandle->hVfsDir);
     412    AssertReturn(pHandle->enmType == FTPSERVERVFSHANDLETYPE_DIR, VERR_INVALID_PARAMETER);
     413
     414    RTVfsDirRelease(pHandle->u.hVfsDir);
    378415
    379416    RTMemFree(pHandle);
     
    389426    RT_NOREF(ppszTarget); /* No symlinks yet */
    390427
    391     PFTPDIRHANDLE pHandle = (PFTPDIRHANDLE)pvHandle;
     428    PFTPSERVERVFSHANDLE pHandle = (PFTPSERVERVFSHANDLE)pvHandle;
    392429    AssertPtrReturn(pHandle, VERR_INVALID_POINTER);
     430    AssertReturn(pHandle->enmType == FTPSERVERVFSHANDLETYPE_DIR, VERR_INVALID_PARAMETER);
    393431
    394432    size_t          cbDirEntryAlloced = sizeof(RTDIRENTRYEX);
     
    402440    {
    403441        size_t cbDirEntry = cbDirEntryAlloced;
    404         rc = RTVfsDirReadEx(pHandle->hVfsDir, pDirEntry, &cbDirEntry, RTFSOBJATTRADD_UNIX);
     442        rc = RTVfsDirReadEx(pHandle->u.hVfsDir, pDirEntry, &cbDirEntry, RTFSOBJATTRADD_UNIX);
    405443        if (RT_FAILURE(rc))
    406444        {
     
    422460            {
    423461                RTFSOBJINFO OwnerInfo;
    424                 rc = RTVfsDirQueryPathInfo(pHandle->hVfsDir,
     462                rc = RTVfsDirQueryPathInfo(pHandle->u.hVfsDir,
    425463                                           pDirEntry->szName, &OwnerInfo, RTFSOBJATTRADD_UNIX_OWNER, RTPATH_F_ON_LINK);
    426464                if (   RT_SUCCESS(rc)
     
    437475            {
    438476                RTFSOBJINFO GroupInfo;
    439                 rc = RTVfsDirQueryPathInfo(pHandle->hVfsDir,
     477                rc = RTVfsDirQueryPathInfo(pHandle->u.hVfsDir,
    440478                                           pDirEntry->szName, &GroupInfo, RTFSOBJATTRADD_UNIX_GROUP, RTPATH_F_ON_LINK);
    441479                if (   RT_SUCCESS(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