summaryrefslogtreecommitdiff
path: root/ShellPkg/Library/UefiShellLevel2CommandsLib
diff options
context:
space:
mode:
Diffstat (limited to 'ShellPkg/Library/UefiShellLevel2CommandsLib')
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c240
1 files changed, 136 insertions, 104 deletions
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);