VirtualBox

Changeset 75924 in vbox


Ignore:
Timestamp:
Dec 3, 2018 8:10:25 PM (6 years ago)
Author:
vboxsync
Message:

VBoxService/toolbox: More FS info, like username, group inode device, correct inode field name, char/block device number, generation, and flags. Left a bunch of todos behind for that owner to look at. bugref:9320

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp

    r71517 r75924  
    7171typedef enum VBOXSERVICETOOLBOXLSFLAG
    7272{
    73     VBOXSERVICETOOLBOXLSFLAG_NONE =             0x0,
    74     VBOXSERVICETOOLBOXLSFLAG_RECURSIVE =        0x1,
    75     VBOXSERVICETOOLBOXLSFLAG_SYMLINKS =         0x2
     73    VBOXSERVICETOOLBOXLSFLAG_NONE,
     74    VBOXSERVICETOOLBOXLSFLAG_RECURSIVE,
     75    VBOXSERVICETOOLBOXLSFLAG_SYMLINKS
    7676} VBOXSERVICETOOLBOXLSFLAG;
    7777
     
    7979typedef enum VBOXSERVICETOOLBOXOUTPUTFLAG
    8080{
    81     VBOXSERVICETOOLBOXOUTPUTFLAG_NONE =         0x0,
    82     VBOXSERVICETOOLBOXOUTPUTFLAG_LONG =         0x1,
    83     VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE =    0x2
     81    VBOXSERVICETOOLBOXOUTPUTFLAG_NONE,
     82    VBOXSERVICETOOLBOXOUTPUTFLAG_LONG,
     83    VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE
    8484} VBOXSERVICETOOLBOXOUTPUTFLAG;
    85 
    86 
    87 /*********************************************************************************************************************************
    88 *   Prototypes                                                                                                                   *
    89 *********************************************************************************************************************************/
    90 static RTEXITCODE vgsvcToolboxCat(int argc, char **argv);
    91 static RTEXITCODE vgsvcToolboxLs(int argc, char **argv);
    92 static RTEXITCODE vgsvcToolboxRm(int argc, char **argv);
    93 static RTEXITCODE vgsvcToolboxMkTemp(int argc, char **argv);
    94 static RTEXITCODE vgsvcToolboxMkDir(int argc, char **argv);
    95 static RTEXITCODE vgsvcToolboxStat(int argc, char **argv);
    9685
    9786
     
    141130} VBOXSERVICETOOLBOXDIRENTRY, *PVBOXSERVICETOOLBOXDIRENTRY;
    142131
     132/** ID cache entry. */
     133typedef struct VGSVCTOOLBOXUIDENTRY
     134{
     135    /** The identifier name. */
     136    uint32_t    id;
     137    /** Set if UID, clear if GID. */
     138    bool        fIsUid;
     139    /** The name. */
     140    char        szName[128 - 4 - 1];
     141} VGSVCTOOLBOXUIDENTRY;
     142typedef VGSVCTOOLBOXUIDENTRY *PVGSVCTOOLBOXUIDENTRY;
     143
     144
     145/** ID cache. */
     146typedef struct VGSVCTOOLBOXIDCACHE
     147{
     148    /** Number of valid cache entries. */
     149    uint32_t                cEntries;
     150    /** The next entry to replace. */
     151    uint32_t                iNextReplace;
     152    /** The cache entries. */
     153    VGSVCTOOLBOXUIDENTRY    aEntries[16];
     154} VGSVCTOOLBOXIDCACHE;
     155typedef VGSVCTOOLBOXIDCACHE *PVGSVCTOOLBOXIDCACHE;
     156
     157
     158/*********************************************************************************************************************************
     159*   Internal Functions                                                                                                           *
     160*********************************************************************************************************************************/
     161static RTEXITCODE vgsvcToolboxCat(int argc, char **argv);
     162static RTEXITCODE vgsvcToolboxLs(int argc, char **argv);
     163static RTEXITCODE vgsvcToolboxRm(int argc, char **argv);
     164static RTEXITCODE vgsvcToolboxMkTemp(int argc, char **argv);
     165static RTEXITCODE vgsvcToolboxMkDir(int argc, char **argv);
     166static RTEXITCODE vgsvcToolboxStat(int argc, char **argv);
     167
    143168
    144169/*********************************************************************************************************************************
     
    157182
    158183
     184
     185
    159186/**
    160187 * Displays a common header for all help text to stdout.
     
    183210             "\n"
    184211             "Commands:\n\n"
    185              "  cat    [<general options>] <file>...\n"
    186              "  ls     [<general options>] [--dereference|-L] [-l] [-R]\n"
    187              "                             [--verbose|-v] [<file>...]\n"
    188              "  rm     [<general options>] [-r|-R] <file>...\n"
    189              "  mktemp [<general options>] [--directory|-d] [--mode|-m <mode>]\n"
    190              "                             [--secure|-s] [--tmpdir|-t <path>]\n"
    191              "                             <template>\n"
    192              "  mkdir  [<general options>] [--mode|-m <mode>] [--parents|-p]\n"
    193              "                             [--verbose|-v] <directory>...\n"
    194              "  stat   [<general options>] [--file-system|-f]\n"
    195              "                             [--dereference|-L] [--terse|-t]\n"
    196              "                             [--verbose|-v] <file>...\n"
     212             "  vbox_cat    [<general options>] <file>...\n"
     213             "  vbox_ls     [<general options>] [--dereference|-L] [-l] [-R]\n"
     214             "      [--verbose|-v] [<file>...]\n"
     215             "  vbox_rm     [<general options>] [-r|-R] <file>...\n"
     216             "  vbox_mktemp [<general options>] [--directory|-d] [--mode|-m <mode>]\n"
     217             "      [--secure|-s] [--tmpdir|-t <path>] <template>\n"
     218             "  vbox_mkdir  [<general options>] [--mode|-m <mode>] [--parents|-p]\n"
     219             "      [--verbose|-v] <directory>...\n"
     220             "  vbox_stat   [<general options>] [--file-system|-f]\n"
     221             "      [--dereference|-L] [--terse|-t] [--verbose|-v] <file>...\n"
    197222             "\n");
    198223}
     
    558583}
    559584
     585
     586/**
     587 * Resolves the UID to a name as best as we can.
     588 *
     589 * @returns Read-only name string.  Only valid till the next cache call.
     590 * @param   pIdCache        The ID cache.
     591 * @param   uid             The UID to resolve.
     592 * @param   pszEntry        The filename of the UID.
     593 * @param   pszRelativeTo   What @a pszEntry is relative to, NULL if absolute.
     594 */
     595static const char *vgsvcToolboxIdCacheGetUidName(PVGSVCTOOLBOXIDCACHE pIdCache, RTUID uid,
     596                                                 const char *pszEntry, const char *pszRelativeTo)
     597{
     598    /* Check cached entries. */
     599    for (uint32_t i = 0; i < pIdCache->cEntries; i++)
     600        if (   pIdCache->aEntries[i].id == uid
     601            && pIdCache->aEntries[i].fIsUid)
     602            return pIdCache->aEntries[i].szName;
     603
     604    /* Miss. */
     605    RTFSOBJINFO ObjInfo;
     606    int rc;
     607    if (!pszRelativeTo)
     608        rc = RTPathQueryInfoEx(pszEntry, &ObjInfo, RTFSOBJATTRADD_UNIX_OWNER, RTPATH_F_ON_LINK);
     609    else
     610    {
     611        char szPath[RTPATH_MAX];
     612        rc = RTPathJoin(szPath, sizeof(szPath), pszRelativeTo, pszEntry);
     613        if (RT_SUCCESS(rc))
     614            rc = RTPathQueryInfoEx(szPath, &ObjInfo, RTFSOBJATTRADD_UNIX_OWNER, RTPATH_F_ON_LINK);
     615    }
     616
     617    if (   RT_SUCCESS(rc)
     618        && ObjInfo.Attr.u.UnixOwner.uid == uid)
     619    {
     620        uint32_t i = pIdCache->cEntries;
     621        if (i < RT_ELEMENTS(pIdCache->aEntries))
     622            pIdCache->cEntries = i + 1;
     623        else
     624            i = pIdCache->iNextReplace++ % RT_ELEMENTS(pIdCache->aEntries);
     625        pIdCache->aEntries[i].id     = uid;
     626        pIdCache->aEntries[i].fIsUid = true;
     627        RTStrCopy(pIdCache->aEntries[i].szName, sizeof(pIdCache->aEntries[i].szName), ObjInfo.Attr.u.UnixOwner.szName);
     628        return pIdCache->aEntries[i].szName;
     629    }
     630    return "";
     631}
     632
     633
     634/**
     635 * Resolves the GID to a name as best as we can.
     636 *
     637 * @returns Read-only name string.  Only valid till the next cache call.
     638 * @param   pIdCache        The ID cache.
     639 * @param   gid             The GID to resolve.
     640 * @param   pszEntry        The filename of the GID.
     641 * @param   pszRelativeTo   What @a pszEntry is relative to, NULL if absolute.
     642 */
     643static const char *vgsvcToolboxIdCacheGetGidName(PVGSVCTOOLBOXIDCACHE pIdCache, RTGID gid,
     644                                                 const char *pszEntry, const char *pszRelativeTo)
     645{
     646    /* Check cached entries. */
     647    for (uint32_t i = 0; i < pIdCache->cEntries; i++)
     648        if (   pIdCache->aEntries[i].id == gid
     649            && !pIdCache->aEntries[i].fIsUid)
     650            return pIdCache->aEntries[i].szName;
     651
     652    /* Miss. */
     653    RTFSOBJINFO ObjInfo;
     654    int rc;
     655    if (!pszRelativeTo)
     656        rc = RTPathQueryInfoEx(pszEntry, &ObjInfo, RTFSOBJATTRADD_UNIX_GROUP, RTPATH_F_ON_LINK);
     657    else
     658    {
     659        char szPath[RTPATH_MAX];
     660        rc = RTPathJoin(szPath, sizeof(szPath), pszRelativeTo, pszEntry);
     661        if (RT_SUCCESS(rc))
     662            rc = RTPathQueryInfoEx(szPath, &ObjInfo, RTFSOBJATTRADD_UNIX_GROUP, RTPATH_F_ON_LINK);
     663    }
     664
     665    if (   RT_SUCCESS(rc)
     666        && ObjInfo.Attr.u.UnixGroup.gid == gid)
     667    {
     668        uint32_t i = pIdCache->cEntries;
     669        if (i < RT_ELEMENTS(pIdCache->aEntries))
     670            pIdCache->cEntries = i + 1;
     671        else
     672            i = pIdCache->iNextReplace++ % RT_ELEMENTS(pIdCache->aEntries);
     673        pIdCache->aEntries[i].id     = gid;
     674        pIdCache->aEntries[i].fIsUid = false;
     675        RTStrCopy(pIdCache->aEntries[i].szName, sizeof(pIdCache->aEntries[i].szName), ObjInfo.Attr.u.UnixGroup.szName);
     676        return pIdCache->aEntries[i].szName;
     677    }
     678    return "";
     679}
     680
     681
    560682/**
    561683 * Prints information (based on given flags) of a file system object (file/directory/...)
     
    564686 * @return  IPRT status code.
    565687 * @param   pszName         Object name.
    566  * @param   cbName          Size of object name.
     688 * @param   cchName         Length of pszName.
    567689 * @param   fOutputFlags    Output / handling flags of type
    568690 *                          VBOXSERVICETOOLBOXOUTPUTFLAG.
     691 * @param   pszRelativeTo   What pszName is relative to.
     692 * @param   pIdCache        The ID cache.
    569693 * @param   pObjInfo        Pointer to object information.
    570694 */
    571 static int vgsvcToolboxPrintFsInfo(const char *pszName, size_t cbName, uint32_t fOutputFlags, PRTFSOBJINFO pObjInfo)
     695static int vgsvcToolboxPrintFsInfo(const char *pszName, size_t cchName, uint32_t fOutputFlags, const char *pszRelativeTo,
     696                                   PVGSVCTOOLBOXIDCACHE pIdCache, PRTFSOBJINFO pObjInfo)
    572697{
    573698    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
    574     AssertReturn(cbName, VERR_INVALID_PARAMETER);
     699    AssertReturn(cchName, VERR_INVALID_PARAMETER);
    575700    AssertPtrReturn(pObjInfo, VERR_INVALID_POINTER);
    576701
     
    591716    /** @todo sticy bits++ */
    592717
     718/** @todo r=bird: turns out the host doesn't use or need cname_len, so perhaps we could drop it? */
    593719    if (!(fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_LONG))
    594720    {
    595721        if (fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE)
    596722        {
    597             /** @todo Skip node_id if not present/available! */
    598             RTPrintf("ftype=%c%cnode_id=%RU64%cname_len=%zu%cname=%s%c",
     723            RTPrintf("ftype=%c%cnode_id=%RU64%inode_dev=%RU32%ccname_len=%zu%cname=%s%c",
    599724                     chFileType, 0, (uint64_t)pObjInfo->Attr.u.Unix.INodeId, 0,
    600                      cbName, 0, pszName, 0);
     725                     (uint32_t)pObjInfo->Attr.u.Unix.INodeIdDevice, 0, cchName, 0, pszName, 0);
     726            RTPrintf("%c%c", 0, 0);
    601727        }
    602728        else
    603             RTPrintf("%c %#18llx %3zu %s\n",
    604                      chFileType, (uint64_t)pObjInfo->Attr.u.Unix.INodeId, cbName, pszName);
    605 
    606         if (fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE) /* End of data block. */
    607             RTPrintf("%c%c", 0, 0);
     729            RTPrintf("%c %#18llx %3zu %s\n", chFileType, (uint64_t)pObjInfo->Attr.u.Unix.INodeId, cchName, pszName);
    608730    }
    609731    else
    610732    {
     733        char szTimeBirth[RTTIME_STR_LEN];
     734        char szTimeChange[RTTIME_STR_LEN];
     735        char szTimeModification[RTTIME_STR_LEN];
     736        char szTimeAccess[RTTIME_STR_LEN];
     737
    611738        if (fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE)
    612739        {
    613740            RTPrintf("ftype=%c%c", chFileType, 0);
    614             /** @todo Skip node_id if not present/available! */
    615             RTPrintf("cnode_id=%RU64%c", (uint64_t)pObjInfo->Attr.u.Unix.INodeId, 0);
     741            if (pObjInfo->Attr.u.Unix.INodeId || pObjInfo->Attr.u.Unix.INodeIdDevice)
     742                RTPrintf("node_id=%RU64%cinode_dev=%RU32%c", (uint64_t)pObjInfo->Attr.u.Unix.INodeId, 0,
     743                         (uint32_t)pObjInfo->Attr.u.Unix.INodeIdDevice, 0);
    616744            RTPrintf("owner_mask=%c%c%c%c",
    617745                     fMode & RTFS_UNIX_IRUSR ? 'r' : '-',
     
    626754                     fMode & RTFS_UNIX_IWOTH ? 'w' : '-',
    627755                     fMode & RTFS_UNIX_IXOTH ? 'x' : '-', 0);
     756            /** @todo sticky bits. */
    628757            RTPrintf("dos_mask=%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
    629758                     fMode & RTFS_DOS_READONLY          ? 'R' : '-',
     
    641770                     fMode & RTFS_DOS_NT_NOT_CONTENT_INDEXED ? 'I' : '-',
    642771                     fMode & RTFS_DOS_NT_ENCRYPTED      ? 'E' : '-', 0);
    643 
    644             char szTimeBirth[256];
    645             RTTimeSpecToString(&pObjInfo->BirthTime, szTimeBirth, sizeof(szTimeBirth));
    646             char szTimeChange[256];
    647             RTTimeSpecToString(&pObjInfo->ChangeTime, szTimeChange, sizeof(szTimeChange));
    648             char szTimeModification[256];
    649             RTTimeSpecToString(&pObjInfo->ModificationTime, szTimeModification, sizeof(szTimeModification));
    650             char szTimeAccess[256];
    651             RTTimeSpecToString(&pObjInfo->AccessTime, szTimeAccess, sizeof(szTimeAccess));
    652 
    653             RTPrintf("hlinks=%RU32%cuid=%RU32%cgid=%RU32%cst_size=%RI64%calloc=%RI64%c"
    654                      "st_birthtime=%s%cst_ctime=%s%cst_mtime=%s%cst_atime=%s%c",
     772            RTPrintf("hlinks=%RU32%cst_size=%RI64%calloc=%RI64%c",
    655773                     pObjInfo->Attr.u.Unix.cHardlinks, 0,
    656                      pObjInfo->Attr.u.Unix.uid, 0,
    657                      pObjInfo->Attr.u.Unix.gid, 0,
    658774                     pObjInfo->cbObject, 0,
    659                      pObjInfo->cbAllocated, 0,
    660                      szTimeBirth, 0,
    661                      szTimeChange, 0,
    662                      szTimeModification, 0,
    663                      szTimeAccess, 0);
    664             RTPrintf("cname_len=%zu%cname=%s%c",
    665                      cbName, 0, pszName, 0);
    666 
    667             /* End of data block. */
    668             RTPrintf("%c%c", 0, 0);
     775                     pObjInfo->cbAllocated, 0);
     776            RTPrintf("st_birthtime=%s%cst_ctime=%s%cst_mtime=%s%cst_atime=%s%c",
     777                     RTTimeSpecToString(&pObjInfo->BirthTime,        szTimeBirth,        sizeof(szTimeBirth)),        0,
     778                     RTTimeSpecToString(&pObjInfo->ChangeTime,       szTimeChange,       sizeof(szTimeChange)),       0,
     779                     RTTimeSpecToString(&pObjInfo->ModificationTime, szTimeModification, sizeof(szTimeModification)), 0,
     780                     RTTimeSpecToString(&pObjInfo->AccessTime,       szTimeAccess,       sizeof(szTimeAccess)),       0);
     781            if (pObjInfo->Attr.u.Unix.uid != NIL_RTUID)
     782                RTPrintf("uid=%RU32%cusername=%s%c", pObjInfo->Attr.u.Unix.uid, 0,
     783                         vgsvcToolboxIdCacheGetUidName(pIdCache, pObjInfo->Attr.u.Unix.uid, pszName, pszRelativeTo), 0);
     784            if (pObjInfo->Attr.u.Unix.gid != NIL_RTGID)
     785                RTPrintf("gid=%RU32%cgroupname=%s%c", pObjInfo->Attr.u.Unix.gid, 0,
     786                         vgsvcToolboxIdCacheGetGidName(pIdCache, pObjInfo->Attr.u.Unix.gid, pszName, pszRelativeTo), 0);
     787            if (   (RTFS_IS_DEV_BLOCK(pObjInfo->Attr.fMode) || RTFS_IS_DEV_CHAR(pObjInfo->Attr.fMode))
     788                && pObjInfo->Attr.u.Unix.Device)
     789                RTPrintf("st_rdev=%RU32%c", pObjInfo->Attr.u.Unix.Device, 0);
     790            if (pObjInfo->Attr.u.Unix.GenerationId)
     791                RTPrintf("st_gen=%RU32%c", pObjInfo->Attr.u.Unix.GenerationId, 0);
     792            if (pObjInfo->Attr.u.Unix.fFlags)
     793                RTPrintf("st_flags=%RU32%c", pObjInfo->Attr.u.Unix.fFlags, 0);
     794            RTPrintf("cname_len=%zu%cname=%s%c", cchName, 0, pszName, 0);
     795            RTPrintf("%c%c", 0, 0); /* End of data block. */
    669796        }
    670797        else
     
    698825                     fMode & RTFS_DOS_NT_NOT_CONTENT_INDEXED ? 'I' : '-',
    699826                     fMode & RTFS_DOS_NT_ENCRYPTED      ? 'E' : '-');
    700             RTPrintf(" %d %4d %4d %10lld %10lld %#llx %#llx %#llx %#llx",
     827            RTPrintf(" %d %4d %4d %10lld %10lld",
    701828                     pObjInfo->Attr.u.Unix.cHardlinks,
    702829                     pObjInfo->Attr.u.Unix.uid,
    703830                     pObjInfo->Attr.u.Unix.gid,
    704831                     pObjInfo->cbObject,
    705                      pObjInfo->cbAllocated,
    706                      RTTimeSpecGetNano(&pObjInfo->BirthTime), /** @todo really ns? */
    707                      RTTimeSpecGetNano(&pObjInfo->ChangeTime), /** @todo really ns? */
    708                      RTTimeSpecGetNano(&pObjInfo->ModificationTime), /** @todo really ns? */
    709                      RTTimeSpecGetNano(&pObjInfo->AccessTime)); /** @todo really ns? */
    710             RTPrintf(" %2zu %s\n", cbName, pszName);
     832                     pObjInfo->cbAllocated);
     833            RTPrintf(" %s %s %s %s",
     834                     RTTimeSpecToString(&pObjInfo->BirthTime,        szTimeBirth,        sizeof(szTimeBirth)),
     835                     RTTimeSpecToString(&pObjInfo->ChangeTime,       szTimeChange,       sizeof(szTimeChange)),
     836                     RTTimeSpecToString(&pObjInfo->ModificationTime, szTimeModification, sizeof(szTimeModification)),
     837                     RTTimeSpecToString(&pObjInfo->AccessTime,       szTimeAccess,       sizeof(szTimeAccess)) );
     838            RTPrintf(" %2zu %s\n", cchName, pszName);
    711839        }
    712840    }
     
    725853 * @param   fOutputFlags            Flags of type  VBOXSERVICETOOLBOXOUTPUTFLAG.
    726854 */
    727 static int vgsvcToolboxLsHandleDir(const char *pszDir, uint32_t fFlags, uint32_t fOutputFlags)
     855static int vgsvcToolboxLsHandleDir(const char *pszDir, uint32_t fFlags, uint32_t fOutputFlags, PVGSVCTOOLBOXIDCACHE pIdCache)
    728856{
    729857    AssertPtrReturn(pszDir, VERR_INVALID_PARAMETER);
     
    759887     * directory's content and second loop is diving deeper into
    760888     * sub directories (if wanted). */
    761     for (;RT_SUCCESS(rc);)
     889/** @todo r=bird: Which races are these exactly???  Please, do considering that directory with half a
     890 * million files in it, because this isn't going to fly well there (especially not in the recursive case)...
     891 * So, this needs to be rewritten unless there is an actual race you're avoiding by doing this! */
     892    do
    762893    {
    763894        RTDIRENTRYEX DirEntry;
     
    774905                rc = VERR_NO_MEMORY;
    775906        }
    776     }
     907        /** @todo r=bird: missing DirEntry overflow handling. */
     908    } while (RT_SUCCESS(rc));
    777909
    778910    if (rc == VERR_NO_MORE_FILES)
     
    793925        RTListForEach(&dirList, pNodeIt, VBOXSERVICETOOLBOXDIRENTRY, Node)
    794926        {
    795             rc = vgsvcToolboxPrintFsInfo(pNodeIt->dirEntry.szName, pNodeIt->dirEntry.cbName,
    796                                          fOutputFlags, &pNodeIt->dirEntry.Info);
     927            rc = vgsvcToolboxPrintFsInfo(pNodeIt->dirEntry.szName, pNodeIt->dirEntry.cbName, fOutputFlags,
     928                                         szPathAbs, pIdCache, &pNodeIt->dirEntry.Info);
    797929            if (RT_FAILURE(rc))
    798930                break;
     
    816948                    {
    817949                        const char *pszName = pNodeIt->dirEntry.szName;
    818                         if (   !RTStrICmp(pszName, ".")
    819                             || !RTStrICmp(pszName, ".."))
     950                        if (   !RTStrICmp(pszName, ".")  /** @todo r=bird: Please do explain what the upper/lower casing of  '.' is! I'm really curious. */ 
     951                            || !RTStrICmp(pszName, "..")) /** @todo r=bird: There is a RTDir API for checking these. Use it! */
    820952                        {
    821953                            /* Skip dot directories. */
     
    823955                        }
    824956
    825                         char szPath[RTPATH_MAX];
     957                        char szPath[RTPATH_MAX]; /** @todo r=bird: This is going to kill your stack pretty quickly if deep
     958                                                  * directory nesting.  There is another buffer further up the function too.
     959                                                  * You need to share the path buffer between recursions!  There should be
     960                                                  * several examples of how to efficiently traverse a tree. */
    826961                        rc = RTPathJoin(szPath, sizeof(szPath), pszDir, pNodeIt->dirEntry.szName);
    827962                        if (RT_SUCCESS(rc))
    828                             rc = vgsvcToolboxLsHandleDir(szPath, fFlags, fOutputFlags);
     963                            rc = vgsvcToolboxLsHandleDir(szPath, fFlags, fOutputFlags, pIdCache);
    829964                        break;
    830965                    }
     
    8931028
    8941029    while (   (ch = RTGetOpt(&GetState, &ValueUnion))
    895            && RT_SUCCESS(rc))
     1030           && RT_SUCCESS(rc) /** @todo r=bird: WTF is this doing here? rc isn't set in the loop!! And there is an AssertRCReturn after the previous place it was set. */)
    8961031    {
    8971032        /* For options that require an argument, ValueUnion has received the value. */
     
    9421077    }
    9431078
    944     if (RT_SUCCESS(rc))
     1079    if (RT_SUCCESS(rc)) /** @todo r=bird: WTF?!? The state handling here is certifiably insane. Crap like this drives me CRAZY!! */
    9451080    {
    9461081        /* Print magic/version. */
     
    9531088        }
    9541089
     1090        VGSVCTOOLBOXIDCACHE IdCache;
     1091        RT_ZERO(IdCache);
     1092
    9551093        ch = RTGetOpt(&GetState, &ValueUnion);
    9561094        do
    9571095        {
    958             char *pszEntry = NULL;
     1096            char *pszEntry = NULL; /** @todo r=bird: Bad name choice. pszEntry sounds like RTDIRENTRY::szName, i.e. no path. */
    9591097
    9601098            if (ch == 0) /* Use current directory if no element specified. */
    9611099            {
    962                 char szDirCur[RTPATH_MAX + 1];
     1100                char szDirCur[RTPATH_MAX + 1];  /** @todo r=bird: Just put this outside the if(ch==0) and make pszEntry point to it.  There is no need to duplicate any strings here! */
    9631101                rc = RTPathGetCurrent(szDirCur, sizeof(szDirCur));
    9641102                if (RT_FAILURE(rc))
     
    9761114            }
    9771115
     1116            /** @todo r=bird: RTFileExists == RTPathQueryInfo, so just do
     1117             *        RTPathQueryInfoEx here!  Also, you _need_ to figure out whether or
     1118             *        not to follow "commandline" links! */
    9781119            if (RTFileExists(pszEntry))
    9791120            {
     
    9911132                else
    9921133                {
    993                     rc2 = vgsvcToolboxPrintFsInfo(pszEntry, strlen(pszEntry) /* cbName */,
    994                                                   fOutputFlags, &objInfo);
     1134                    rc2 = vgsvcToolboxPrintFsInfo(pszEntry, strlen(pszEntry), fOutputFlags, NULL, &IdCache, &objInfo);
    9951135                    if (RT_FAILURE(rc2))
    9961136                        rc = rc2;
     
    9991139            else
    10001140            {
    1001                 int rc2 = vgsvcToolboxLsHandleDir(pszEntry, fFlags, fOutputFlags);
     1141                int rc2 = vgsvcToolboxLsHandleDir(pszEntry, fFlags, fOutputFlags, &IdCache);
    10021142                if (RT_FAILURE(rc2))
    10031143                    rc = rc2;
     
    10051145
    10061146            RTStrFree(pszEntry);
    1007         }
    1008         while ((ch = RTGetOpt(&GetState, &ValueUnion)));
     1147        } while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0);
    10091148
    10101149        if (fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE) /* Output termination. */
     
    14561595        }
    14571596
     1597        VGSVCTOOLBOXIDCACHE IdCache;
     1598        RT_ZERO(IdCache);
     1599
    14581600        while ((ch = RTGetOpt(&GetState, &ValueUnion)))
    14591601        {
     
    14661608            }
    14671609            else
    1468             {
    1469                 rc2 = vgsvcToolboxPrintFsInfo(ValueUnion.psz,
    1470                                               strlen(ValueUnion.psz) /* cbName */,
    1471                                               fOutputFlags,
    1472                                               &objInfo);
    1473             }
    1474 
     1610                rc2 = vgsvcToolboxPrintFsInfo(ValueUnion.psz, strlen(ValueUnion.psz), fOutputFlags, NULL, &IdCache, &objInfo);
     1611            /** @todo r=bird: You're checking rc not rc2 here...   */
    14751612            if (RT_SUCCESS(rc))
    14761613                rc = rc2;
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