X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=ShellPkg%2FLibrary%2FUefiShellLevel2CommandsLib%2FLs.c;fp=ShellPkg%2FLibrary%2FUefiShellLevel2CommandsLib%2FLs.c;h=b5ef6aa2a9fbce870ad8a24ade61bf7121f50a14;hp=fa588ff7f462fe167d2934c863b632bc8aeda5d3;hb=929fb3be4169eb520272056c00b11bb3fb3f6458;hpb=ebddddadff3ce37c21bf41b2b46252c0a9390cfb diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c index fa588ff7f4..b5ef6aa2a9 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c @@ -330,8 +330,9 @@ PrintNonSfoFooter( @param[in] Attribs List of required Attribute for display. If 0 then all non-system and non-hidden files will be printed. @param[in] Sfo TRUE to use Standard Format Output, FALSE otherwise - @param[in] Path String with starting path. - @param[in] First TRUE for the original and FALSE for any recursion spawned instances. + @param[in] RootPath String with starting path to search in. + @param[in] SearchString String with search string. + @param[in] Found Set to TRUE, if anyone were found. @param[in] Count The count of bits enabled in Attribs. @param[in] TimeZone The current time zone offset. @@ -343,8 +344,9 @@ PrintLsOutput( IN CONST BOOLEAN Rec, IN CONST UINT64 Attribs, IN CONST BOOLEAN Sfo, - IN CONST CHAR16 *Path, - IN CONST BOOLEAN First, + IN CONST CHAR16 *RootPath, + IN CONST CHAR16 *SearchString, + IN BOOLEAN *Found, IN CONST UINTN Count, IN CONST INT16 TimeZone ) @@ -356,10 +358,12 @@ PrintLsOutput( UINT64 FileCount; UINT64 DirCount; UINT64 FileSize; - CHAR16 *DirectoryName; UINTN LongestPath; CHAR16 *CorrectedPath; + BOOLEAN FoundOne; + BOOLEAN HeaderPrinted; + HeaderPrinted = FALSE; FileCount = 0; DirCount = 0; FileSize = 0; @@ -368,87 +372,96 @@ PrintLsOutput( LongestPath = 0; CorrectedPath = NULL; - CorrectedPath = StrnCatGrow(&CorrectedPath, NULL, Path, 0); + if (Found != NULL) { + FoundOne = *Found; + } else { + FoundOne = FALSE; + } + + CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, RootPath, 0); + if (CorrectedPath[StrLen(CorrectedPath)-1] != L'\\' + &&CorrectedPath[StrLen(CorrectedPath)-1] != L'/') { + CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, L"\\", 0); + } + CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, SearchString, 0); if (CorrectedPath == NULL) { return (SHELL_OUT_OF_RESOURCES); } PathCleanUpDirectories(CorrectedPath); - if (!Sfo) { - PrintNonSfoHeader(CorrectedPath); - } - Status = ShellOpenFileMetaArg((CHAR16*)CorrectedPath, EFI_FILE_MODE_READ, &ListHead); - if (EFI_ERROR(Status)) { - SHELL_FREE_NON_NULL(CorrectedPath); - if(Status == EFI_NOT_FOUND){ - return (SHELL_NOT_FOUND); + if (!EFI_ERROR(Status)) { + if (ListHead == NULL || IsListEmpty(&ListHead->Link)) { + SHELL_FREE_NON_NULL(CorrectedPath); + return (SHELL_SUCCESS); } - return (SHELL_DEVICE_ERROR); - } - if (ListHead == NULL || IsListEmpty(&ListHead->Link)) { - SHELL_FREE_NON_NULL(CorrectedPath); - // - // On the first one only we expect to find something... - // do we find the . and .. directories otherwise? - // - if (First) { - return (SHELL_NOT_FOUND); - } - return (SHELL_SUCCESS); - } - if (Sfo && First) { - PrintSfoVolumeInfoTableEntry(ListHead); - } - - for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&ListHead->Link) - ; !IsNull(&ListHead->Link, &Node->Link) - ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&ListHead->Link, &Node->Link) - ){ - ASSERT(Node != NULL); - if (LongestPath < StrSize(Node->FullName)) { - LongestPath = StrSize(Node->FullName); + if (Sfo && Found == NULL) { + PrintSfoVolumeInfoTableEntry(ListHead); } - ASSERT(Node->Info != NULL); - ASSERT((Node->Info->Attribute & EFI_FILE_VALID_ATTR) == Node->Info->Attribute); - if (Attribs == 0) { - // - // NOT system & NOT hidden - // - if ( (Node->Info->Attribute & EFI_FILE_SYSTEM) - || (Node->Info->Attribute & EFI_FILE_HIDDEN) - ){ - continue; + + for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&ListHead->Link), LongestPath = 0 + ; !IsNull(&ListHead->Link, &Node->Link) + ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&ListHead->Link, &Node->Link) + ){ + ASSERT(Node != NULL); + if (LongestPath < StrSize(Node->FullName)) { + LongestPath = StrSize(Node->FullName); } - } else if ((Attribs != EFI_FILE_VALID_ATTR) || - (Count == 5)) { - // - // Only matches the bits which "Attribs" contains, not - // all files/directories with any of the bits. - // Count == 5 is used to tell the difference between a user - // specifying all bits (EX: -arhsda) and just specifying - // -a (means display all files with any attribute). - // - if ( (Node->Info->Attribute & Attribs) != Attribs) { - continue; + ASSERT(Node->Info != NULL); + ASSERT((Node->Info->Attribute & EFI_FILE_VALID_ATTR) == Node->Info->Attribute); + if (Attribs == 0) { + // + // NOT system & NOT hidden + // + if ( (Node->Info->Attribute & EFI_FILE_SYSTEM) + || (Node->Info->Attribute & EFI_FILE_HIDDEN) + ){ + continue; + } + } else if ((Attribs != EFI_FILE_VALID_ATTR) || + (Count == 5)) { + // + // Only matches the bits which "Attribs" contains, not + // all files/directories with any of the bits. + // Count == 5 is used to tell the difference between a user + // specifying all bits (EX: -arhsda) and just specifying + // -a (means display all files with any attribute). + // + if ( (Node->Info->Attribute & Attribs) != Attribs) { + continue; + } } - } - PrintFileInformation(Sfo, Node, &FileCount, &FileSize, &DirCount); - } + if (!Sfo && HeaderPrinted == FALSE) { + PrintNonSfoHeader(CorrectedPath); + } + PrintFileInformation(Sfo, Node, &FileCount, &FileSize, &DirCount); + FoundOne = TRUE; + HeaderPrinted = TRUE; + } - if (!Sfo) { - PrintNonSfoFooter(FileCount, FileSize, DirCount); + if (!Sfo) { + PrintNonSfoFooter(FileCount, FileSize, DirCount); + } } - if (Rec){ - DirectoryName = AllocateZeroPool(LongestPath + 2*sizeof(CHAR16)); - if (DirectoryName == NULL) { - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellLevel2HiiHandle); - ShellStatus = SHELL_OUT_OF_RESOURCES; - } else { + if (Rec) { + // + // Re-Open all the files under the starting path for directories that didnt necessarily match our file filter + // + ShellCloseFileMetaArg(&ListHead); + CorrectedPath[0] = CHAR_NULL; + CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, RootPath, 0); + if (CorrectedPath[StrLen(CorrectedPath)-1] != L'\\' + &&CorrectedPath[StrLen(CorrectedPath)-1] != L'/') { + CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, L"\\", 0); + } + CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, L"*", 0); + Status = ShellOpenFileMetaArg((CHAR16*)CorrectedPath, EFI_FILE_MODE_READ, &ListHead); + + if (!EFI_ERROR(Status)) { for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&ListHead->Link) ; !IsNull(&ListHead->Link, &Node->Link) && ShellStatus == SHELL_SUCCESS ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&ListHead->Link, &Node->Link) @@ -465,24 +478,31 @@ PrintLsOutput( && StrCmp(Node->FileName, L".") != 0 && StrCmp(Node->FileName, L"..") != 0 ){ - StrCpy(DirectoryName, Node->FullName); - StrCat(DirectoryName, L"\\*"); ShellStatus = PrintLsOutput( Rec, Attribs, Sfo, - DirectoryName, - FALSE, + Node->FullName, + SearchString, + &FoundOne, Count, TimeZone); } } - FreePool(DirectoryName); } } - FreePool(CorrectedPath); + SHELL_FREE_NON_NULL(CorrectedPath); ShellCloseFileMetaArg(&ListHead); + + if (Found == NULL && FoundOne == FALSE) { + return (SHELL_NOT_FOUND); + } + + if (Found != NULL) { + *Found = FoundOne; + } + return (ShellStatus); } @@ -518,7 +538,7 @@ ShellCommandRunLs ( CHAR16 *FullPath; UINTN Size; EFI_TIME TheTime; - BOOLEAN SfoMode; + CHAR16 *SearchString; Size = 0; FullPath = NULL; @@ -527,6 +547,7 @@ ShellCommandRunLs ( ShellStatus = SHELL_SUCCESS; RequiredAttributes = 0; PathName = NULL; + SearchString = NULL; CurDir = NULL; Count = 0; @@ -616,40 +637,52 @@ ShellCommandRunLs ( if (ShellStatus == SHELL_SUCCESS) { PathName = ShellCommandLineGetRawValue(Package, 1); if (PathName == NULL) { + // + // Nothing specified... must start from current directory + // CurDir = gEfiShellProtocol->GetCurDir(NULL); if (CurDir == NULL) { ShellStatus = SHELL_NOT_FOUND; ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle); } - } - if (PathName != NULL) { + // + // Copy to the 2 strings for starting path and file search string + // + ASSERT(SearchString == NULL); + ASSERT(FullPath == NULL); + StrnCatGrow(&SearchString, NULL, L"*", 0); + StrnCatGrow(&FullPath, NULL, CurDir, 0); + } else { if (StrStr(PathName, L":") == NULL && gEfiShellProtocol->GetCurDir(NULL) == NULL) { + // + // If we got something and it doesnt have a fully qualified path, then we needed to have a CWD. + // ShellStatus = SHELL_NOT_FOUND; ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle); } else { + // + // We got a valid fully qualified path or we have a CWD + // ASSERT((FullPath == NULL && Size == 0) || (FullPath != NULL)); + if (StrStr(PathName, L":") == NULL) { + StrnCatGrow(&FullPath, &Size, gEfiShellProtocol->GetCurDir(NULL), 0); + } StrnCatGrow(&FullPath, &Size, PathName, 0); if (ShellIsDirectory(PathName) == EFI_SUCCESS) { - if (PathName[StrLen (PathName) - 1] == '\\') { - // - // For path ending with '\', just append '*'. - // - StrnCatGrow (&FullPath, &Size, L"*", 0); - } else if (PathName[StrLen (PathName) - 1] == '*') { - // - // For path ending with '*', do nothing. - // - } else { - // - // Otherwise, append '\*' to directory name. - // - StrnCatGrow (&FullPath, &Size, L"\\*", 0); - } + // + // is listing ends with a directory, then we list all files in that directory + // + StrnCatGrow(&SearchString, NULL, L"*", 0); + } else { + // + // must split off the search part that applies to files from the end of the directory part + // + for (StrnCatGrow(&SearchString, NULL, PathName, 0) + ; SearchString != NULL && StrStr(SearchString, L"\\") != NULL + ; CopyMem(SearchString, StrStr(SearchString, L"\\") + 1, 1 + StrSize(StrStr(SearchString, L"\\") + 1))) ; + FullPath[StrLen(FullPath) - StrLen(SearchString)] = CHAR_NULL; } } - } else { - ASSERT(FullPath == NULL); - StrnCatGrow(&FullPath, NULL, L"*", 0); } Status = gRT->GetTime(&TheTime, NULL); if (EFI_ERROR(Status)) { @@ -657,14 +690,14 @@ ShellCommandRunLs ( TheTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE; } - SfoMode = ShellCommandLineGetFlag(Package, L"-sfo"); if (ShellStatus == SHELL_SUCCESS) { ShellStatus = PrintLsOutput( ShellCommandLineGetFlag(Package, L"-r"), RequiredAttributes, - SfoMode, + ShellCommandLineGetFlag(Package, L"-sfo"), FullPath, - TRUE, + SearchString, + NULL, Count, (INT16)(TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:TheTime.TimeZone) ); @@ -684,12 +717,11 @@ ShellCommandRunLs ( } } - if (FullPath != NULL) { - FreePool(FullPath); - } // - // free the command line package + // Free memory allocated // + SHELL_FREE_NON_NULL(SearchString); + SHELL_FREE_NON_NULL(FullPath); ShellCommandLineFreeVarList (Package); return (ShellStatus);