Changeset 75924 in vbox
- Timestamp:
- Dec 3, 2018 8:10:25 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp
r71517 r75924 71 71 typedef enum VBOXSERVICETOOLBOXLSFLAG 72 72 { 73 VBOXSERVICETOOLBOXLSFLAG_NONE = 0x0,74 VBOXSERVICETOOLBOXLSFLAG_RECURSIVE = 0x1,75 VBOXSERVICETOOLBOXLSFLAG_SYMLINKS = 0x273 VBOXSERVICETOOLBOXLSFLAG_NONE, 74 VBOXSERVICETOOLBOXLSFLAG_RECURSIVE, 75 VBOXSERVICETOOLBOXLSFLAG_SYMLINKS 76 76 } VBOXSERVICETOOLBOXLSFLAG; 77 77 … … 79 79 typedef enum VBOXSERVICETOOLBOXOUTPUTFLAG 80 80 { 81 VBOXSERVICETOOLBOXOUTPUTFLAG_NONE = 0x0,82 VBOXSERVICETOOLBOXOUTPUTFLAG_LONG = 0x1,83 VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE = 0x281 VBOXSERVICETOOLBOXOUTPUTFLAG_NONE, 82 VBOXSERVICETOOLBOXOUTPUTFLAG_LONG, 83 VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE 84 84 } 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);96 85 97 86 … … 141 130 } VBOXSERVICETOOLBOXDIRENTRY, *PVBOXSERVICETOOLBOXDIRENTRY; 142 131 132 /** ID cache entry. */ 133 typedef 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; 142 typedef VGSVCTOOLBOXUIDENTRY *PVGSVCTOOLBOXUIDENTRY; 143 144 145 /** ID cache. */ 146 typedef 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; 155 typedef VGSVCTOOLBOXIDCACHE *PVGSVCTOOLBOXIDCACHE; 156 157 158 /********************************************************************************************************************************* 159 * Internal Functions * 160 *********************************************************************************************************************************/ 161 static RTEXITCODE vgsvcToolboxCat(int argc, char **argv); 162 static RTEXITCODE vgsvcToolboxLs(int argc, char **argv); 163 static RTEXITCODE vgsvcToolboxRm(int argc, char **argv); 164 static RTEXITCODE vgsvcToolboxMkTemp(int argc, char **argv); 165 static RTEXITCODE vgsvcToolboxMkDir(int argc, char **argv); 166 static RTEXITCODE vgsvcToolboxStat(int argc, char **argv); 167 143 168 144 169 /********************************************************************************************************************************* … … 157 182 158 183 184 185 159 186 /** 160 187 * Displays a common header for all help text to stdout. … … 183 210 "\n" 184 211 "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" 197 222 "\n"); 198 223 } … … 558 583 } 559 584 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 */ 595 static 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 */ 643 static 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 560 682 /** 561 683 * Prints information (based on given flags) of a file system object (file/directory/...) … … 564 686 * @return IPRT status code. 565 687 * @param pszName Object name. 566 * @param c bName Size of object name.688 * @param cchName Length of pszName. 567 689 * @param fOutputFlags Output / handling flags of type 568 690 * VBOXSERVICETOOLBOXOUTPUTFLAG. 691 * @param pszRelativeTo What pszName is relative to. 692 * @param pIdCache The ID cache. 569 693 * @param pObjInfo Pointer to object information. 570 694 */ 571 static int vgsvcToolboxPrintFsInfo(const char *pszName, size_t cbName, uint32_t fOutputFlags, PRTFSOBJINFO pObjInfo) 695 static int vgsvcToolboxPrintFsInfo(const char *pszName, size_t cchName, uint32_t fOutputFlags, const char *pszRelativeTo, 696 PVGSVCTOOLBOXIDCACHE pIdCache, PRTFSOBJINFO pObjInfo) 572 697 { 573 698 AssertPtrReturn(pszName, VERR_INVALID_POINTER); 574 AssertReturn(c bName, VERR_INVALID_PARAMETER);699 AssertReturn(cchName, VERR_INVALID_PARAMETER); 575 700 AssertPtrReturn(pObjInfo, VERR_INVALID_POINTER); 576 701 … … 591 716 /** @todo sticy bits++ */ 592 717 718 /** @todo r=bird: turns out the host doesn't use or need cname_len, so perhaps we could drop it? */ 593 719 if (!(fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_LONG)) 594 720 { 595 721 if (fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE) 596 722 { 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", 599 724 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); 601 727 } 602 728 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); 608 730 } 609 731 else 610 732 { 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 611 738 if (fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE) 612 739 { 613 740 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); 616 744 RTPrintf("owner_mask=%c%c%c%c", 617 745 fMode & RTFS_UNIX_IRUSR ? 'r' : '-', … … 626 754 fMode & RTFS_UNIX_IWOTH ? 'w' : '-', 627 755 fMode & RTFS_UNIX_IXOTH ? 'x' : '-', 0); 756 /** @todo sticky bits. */ 628 757 RTPrintf("dos_mask=%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", 629 758 fMode & RTFS_DOS_READONLY ? 'R' : '-', … … 641 770 fMode & RTFS_DOS_NT_NOT_CONTENT_INDEXED ? 'I' : '-', 642 771 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", 655 773 pObjInfo->Attr.u.Unix.cHardlinks, 0, 656 pObjInfo->Attr.u.Unix.uid, 0,657 pObjInfo->Attr.u.Unix.gid, 0,658 774 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. */ 669 796 } 670 797 else … … 698 825 fMode & RTFS_DOS_NT_NOT_CONTENT_INDEXED ? 'I' : '-', 699 826 fMode & RTFS_DOS_NT_ENCRYPTED ? 'E' : '-'); 700 RTPrintf(" %d %4d %4d %10lld %10lld %#llx %#llx %#llx %#llx",827 RTPrintf(" %d %4d %4d %10lld %10lld", 701 828 pObjInfo->Attr.u.Unix.cHardlinks, 702 829 pObjInfo->Attr.u.Unix.uid, 703 830 pObjInfo->Attr.u.Unix.gid, 704 831 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); 711 839 } 712 840 } … … 725 853 * @param fOutputFlags Flags of type VBOXSERVICETOOLBOXOUTPUTFLAG. 726 854 */ 727 static int vgsvcToolboxLsHandleDir(const char *pszDir, uint32_t fFlags, uint32_t fOutputFlags )855 static int vgsvcToolboxLsHandleDir(const char *pszDir, uint32_t fFlags, uint32_t fOutputFlags, PVGSVCTOOLBOXIDCACHE pIdCache) 728 856 { 729 857 AssertPtrReturn(pszDir, VERR_INVALID_PARAMETER); … … 759 887 * directory's content and second loop is diving deeper into 760 888 * 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 762 893 { 763 894 RTDIRENTRYEX DirEntry; … … 774 905 rc = VERR_NO_MEMORY; 775 906 } 776 } 907 /** @todo r=bird: missing DirEntry overflow handling. */ 908 } while (RT_SUCCESS(rc)); 777 909 778 910 if (rc == VERR_NO_MORE_FILES) … … 793 925 RTListForEach(&dirList, pNodeIt, VBOXSERVICETOOLBOXDIRENTRY, Node) 794 926 { 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); 797 929 if (RT_FAILURE(rc)) 798 930 break; … … 816 948 { 817 949 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! */ 820 952 { 821 953 /* Skip dot directories. */ … … 823 955 } 824 956 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. */ 826 961 rc = RTPathJoin(szPath, sizeof(szPath), pszDir, pNodeIt->dirEntry.szName); 827 962 if (RT_SUCCESS(rc)) 828 rc = vgsvcToolboxLsHandleDir(szPath, fFlags, fOutputFlags );963 rc = vgsvcToolboxLsHandleDir(szPath, fFlags, fOutputFlags, pIdCache); 829 964 break; 830 965 } … … 893 1028 894 1029 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. */) 896 1031 { 897 1032 /* For options that require an argument, ValueUnion has received the value. */ … … 942 1077 } 943 1078 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!! */ 945 1080 { 946 1081 /* Print magic/version. */ … … 953 1088 } 954 1089 1090 VGSVCTOOLBOXIDCACHE IdCache; 1091 RT_ZERO(IdCache); 1092 955 1093 ch = RTGetOpt(&GetState, &ValueUnion); 956 1094 do 957 1095 { 958 char *pszEntry = NULL; 1096 char *pszEntry = NULL; /** @todo r=bird: Bad name choice. pszEntry sounds like RTDIRENTRY::szName, i.e. no path. */ 959 1097 960 1098 if (ch == 0) /* Use current directory if no element specified. */ 961 1099 { 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! */ 963 1101 rc = RTPathGetCurrent(szDirCur, sizeof(szDirCur)); 964 1102 if (RT_FAILURE(rc)) … … 976 1114 } 977 1115 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! */ 978 1119 if (RTFileExists(pszEntry)) 979 1120 { … … 991 1132 else 992 1133 { 993 rc2 = vgsvcToolboxPrintFsInfo(pszEntry, strlen(pszEntry) /* cbName */, 994 fOutputFlags, &objInfo); 1134 rc2 = vgsvcToolboxPrintFsInfo(pszEntry, strlen(pszEntry), fOutputFlags, NULL, &IdCache, &objInfo); 995 1135 if (RT_FAILURE(rc2)) 996 1136 rc = rc2; … … 999 1139 else 1000 1140 { 1001 int rc2 = vgsvcToolboxLsHandleDir(pszEntry, fFlags, fOutputFlags );1141 int rc2 = vgsvcToolboxLsHandleDir(pszEntry, fFlags, fOutputFlags, &IdCache); 1002 1142 if (RT_FAILURE(rc2)) 1003 1143 rc = rc2; … … 1005 1145 1006 1146 RTStrFree(pszEntry); 1007 } 1008 while ((ch = RTGetOpt(&GetState, &ValueUnion))); 1147 } while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0); 1009 1148 1010 1149 if (fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE) /* Output termination. */ … … 1456 1595 } 1457 1596 1597 VGSVCTOOLBOXIDCACHE IdCache; 1598 RT_ZERO(IdCache); 1599 1458 1600 while ((ch = RTGetOpt(&GetState, &ValueUnion))) 1459 1601 { … … 1466 1608 } 1467 1609 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... */ 1475 1612 if (RT_SUCCESS(rc)) 1476 1613 rc = rc2;
Note:
See TracChangeset
for help on using the changeset viewer.