VirtualBox

Changeset 82822 in vbox for trunk/src/VBox/Runtime/tools


Ignore:
Timestamp:
Jan 22, 2020 11:48:43 AM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
135791
Message:

IPRT/FTP: More work on directory listing.

File:
1 edited

Legend:

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

    r82813 r82822  
    5151#include <iprt/getopt.h>
    5252#include <iprt/initterm.h>
     53#include <iprt/mem.h>
    5354#include <iprt/message.h>
    5455#include <iprt/path.h>
     
    7374} FTPSERVERDATA;
    7475typedef FTPSERVERDATA *PFTPSERVERDATA;
     76
     77typedef struct FTPDIRHANDLE
     78{
     79    /** The VFS (chain) handle to use for this directory. */
     80    RTVFSDIR hVfsDir;
     81} FTPDIRHANDLE;
     82typedef FTPDIRHANDLE *PFTPDIRHANDLE;
    7583
    7684
     
    308316}
    309317
    310 static DECLCALLBACK(int) onList(PRTFTPCALLBACKDATA pData, const char *pcszPath, void *pvData, size_t cbData, size_t *pcbRead)
    311 {
    312     RT_NOREF(pData, pcszPath, pvData, cbData, pcbRead);
    313 
    314 #if 0
     318static DECLCALLBACK(int) onDirOpen(PRTFTPCALLBACKDATA pData, const char *pcszPath, void **ppvHandle)
     319{
    315320    PFTPSERVERDATA pThis = (PFTPSERVERDATA)pData->pvUser;
    316321    Assert(pData->cbUser == sizeof(FTPSERVERDATA));
    317322
    318     RTFILE hFile;
    319     int rc = RTFileOpen(&hFile, pcszPath ? pcszPath : pThis->szCWD,
    320                         RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
     323    PFTPDIRHANDLE pHandle = (PFTPDIRHANDLE)RTMemAllocZ(sizeof(FTPDIRHANDLE));
     324    if (!pHandle)
     325        return VERR_NO_MEMORY;
     326
     327    /* Construct absolute path. */
     328    char *pszPathAbs = NULL;
     329    int rc = RTStrAAppend(&pszPathAbs, pThis->szRootDir);
     330    AssertRCReturn(rc, rc);
     331    rc = RTStrAAppend(&pszPathAbs, pcszPath);
     332    AssertRCReturn(rc, rc);
     333
     334    RTPrintf("Opening directory '%s'\n", pszPathAbs);
     335
     336    rc = RTVfsChainOpenDir(pszPathAbs, 0 /*fFlags*/, &pHandle->hVfsDir, NULL /* poffError */, NULL /* pErrInfo */);
    321337    if (RT_SUCCESS(rc))
    322338    {
    323         RTFSOBJINFO fsObjInfo;
    324         rc = RTFileQueryInfo(hFile, &fsObjInfo, RTFSOBJATTRADD_NOTHING);
     339        *ppvHandle = pHandle;
     340    }
     341    else
     342    {
     343        RTMemFree(pHandle);
     344    }
     345
     346    RTStrFree(pszPathAbs);
     347
     348    return rc;
     349}
     350
     351static DECLCALLBACK(int) onDirClose(PRTFTPCALLBACKDATA pData, void *pvHandle)
     352{
     353    RT_NOREF(pData);
     354
     355    PFTPDIRHANDLE pHandle = (PFTPDIRHANDLE)pvHandle;
     356    AssertPtrReturn(pHandle, VERR_INVALID_POINTER);
     357
     358    RTVfsDirRelease(pHandle->hVfsDir);
     359
     360    RTMemFree(pHandle);
     361    pHandle = NULL;
     362
     363    return VINF_SUCCESS;
     364}
     365
     366static DECLCALLBACK(int) onDirRead(PRTFTPCALLBACKDATA pData, void *pvHandle, char **ppszEntry,
     367                                   PRTFSOBJINFO pInfo, char **ppszOwner, char **ppszGroup, char **ppszTarget)
     368{
     369    RT_NOREF(pData);
     370    RT_NOREF(ppszTarget); /* No symlinks yet */
     371
     372    PFTPDIRHANDLE pHandle = (PFTPDIRHANDLE)pvHandle;
     373    AssertPtrReturn(pHandle, VERR_INVALID_POINTER);
     374
     375    size_t          cbDirEntryAlloced = sizeof(RTDIRENTRYEX);
     376    PRTDIRENTRYEX   pDirEntry         = (PRTDIRENTRYEX)RTMemTmpAlloc(cbDirEntryAlloced);
     377    if (!pDirEntry)
     378        return VERR_NO_MEMORY;
     379
     380    int rc;
     381
     382    for (;;)
     383    {
     384        size_t cbDirEntry = cbDirEntryAlloced;
     385        rc = RTVfsDirReadEx(pHandle->hVfsDir, pDirEntry, &cbDirEntry, RTFSOBJATTRADD_UNIX);
     386        if (RT_FAILURE(rc))
     387        {
     388            if (rc == VERR_BUFFER_OVERFLOW)
     389            {
     390                RTMemTmpFree(pDirEntry);
     391                cbDirEntryAlloced = RT_ALIGN_Z(RT_MIN(cbDirEntry, cbDirEntryAlloced) + 64, 64);
     392                pDirEntry  = (PRTDIRENTRYEX)RTMemTmpAlloc(cbDirEntryAlloced);
     393                if (pDirEntry)
     394                    continue;
     395            }
     396            else if (rc != VERR_NO_MORE_FILES)
     397                break;
     398        }
     399
    325400        if (RT_SUCCESS(rc))
    326401        {
    327             rc = fsObjInfoToStr(&fsObjInfo, (char *)pvData, cbData);
     402            if (pDirEntry->Info.Attr.u.Unix.uid != NIL_RTUID)
     403            {
     404                RTFSOBJINFO OwnerInfo;
     405                rc = RTVfsDirQueryPathInfo(pHandle->hVfsDir,
     406                                           pDirEntry->szName, &OwnerInfo, RTFSOBJATTRADD_UNIX_OWNER, RTPATH_F_ON_LINK);
     407                if (   RT_SUCCESS(rc)
     408                    && OwnerInfo.Attr.u.UnixOwner.szName[0])
     409                {
     410                    *ppszOwner = RTStrDup(&OwnerInfo.Attr.u.UnixOwner.szName[0]);
     411                    if (!*ppszOwner)
     412                        rc = VERR_NO_MEMORY;
     413                }
     414            }
     415
     416            if (   RT_SUCCESS(rc)
     417                && pDirEntry->Info.Attr.u.Unix.gid != NIL_RTGID)
     418            {
     419                RTFSOBJINFO GroupInfo;
     420                rc = RTVfsDirQueryPathInfo(pHandle->hVfsDir,
     421                                           pDirEntry->szName, &GroupInfo, RTFSOBJATTRADD_UNIX_GROUP, RTPATH_F_ON_LINK);
     422                if (   RT_SUCCESS(rc)
     423                    && GroupInfo.Attr.u.UnixGroup.szName[0])
     424                {
     425                    *ppszGroup = RTStrDup(&GroupInfo.Attr.u.UnixGroup.szName[0]);
     426                    if (!*ppszGroup)
     427                        rc = VERR_NO_MEMORY;
     428                }
     429            }
    328430        }
    329431
    330         RTFileClose(hFile);
    331     }
    332 #endif
    333 
    334     RTStrPrintf((char *)pvData, cbData, "-rwxr-xr-x 1 johndoe users    0 Apr  6  2017 foobar\r\n");
    335 
    336     *pcbRead = strlen((char *)pvData);
    337 
    338     /** @todo We ASSUME we're done here for now. */
    339     return VINF_EOF;
     432        *ppszEntry = RTStrDup(pDirEntry->szName);
     433        AssertPtrReturn(*ppszEntry, VERR_NO_MEMORY);
     434
     435        *pInfo = pDirEntry->Info;
     436
     437        break;
     438
     439    } /* for */
     440
     441    RTMemTmpFree(pDirEntry);
     442    pDirEntry = NULL;
     443
     444    return rc;
    340445}
    341446
     
    451556        Callbacks.pfnOnPathGetCurrent   = onPathGetCurrent;
    452557        Callbacks.pfnOnPathUp           = onPathUp;
    453         Callbacks.pfnOnList             = onList;
     558        Callbacks.pfnOnDirOpen          = onDirOpen;
     559        Callbacks.pfnOnDirClose         = onDirClose;
     560        Callbacks.pfnOnDirRead          = onDirRead;
    454561
    455562        RTFTPSERVER hFTPServer;
Note: See TracChangeset for help on using the changeset viewer.

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