@param[in] Attribs List of required Attribute for display.\r
If 0 then all non-system and non-hidden files will be printed.\r
@param[in] Sfo TRUE to use Standard Format Output, FALSE otherwise\r
- @param[in] Path String with starting path.\r
- @param[in] First TRUE for the original and FALSE for any recursion spawned instances.\r
+ @param[in] RootPath String with starting path to search in.\r
+ @param[in] SearchString String with search string.\r
+ @param[in] Found Set to TRUE, if anyone were found.\r
@param[in] Count The count of bits enabled in Attribs.\r
@param[in] TimeZone The current time zone offset.\r
\r
IN CONST BOOLEAN Rec,\r
IN CONST UINT64 Attribs,\r
IN CONST BOOLEAN Sfo,\r
- IN CONST CHAR16 *Path,\r
- IN CONST BOOLEAN First,\r
+ IN CONST CHAR16 *RootPath,\r
+ IN CONST CHAR16 *SearchString,\r
+ IN BOOLEAN *Found,\r
IN CONST UINTN Count,\r
IN CONST INT16 TimeZone\r
)\r
UINT64 FileCount;\r
UINT64 DirCount;\r
UINT64 FileSize;\r
- CHAR16 *DirectoryName;\r
UINTN LongestPath;\r
CHAR16 *CorrectedPath;\r
+ BOOLEAN FoundOne;\r
+ BOOLEAN HeaderPrinted;\r
\r
+ HeaderPrinted = FALSE;\r
FileCount = 0;\r
DirCount = 0;\r
FileSize = 0;\r
LongestPath = 0;\r
CorrectedPath = NULL;\r
\r
- CorrectedPath = StrnCatGrow(&CorrectedPath, NULL, Path, 0);\r
+ if (Found != NULL) {\r
+ FoundOne = *Found;\r
+ } else {\r
+ FoundOne = FALSE;\r
+ }\r
+\r
+ CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, RootPath, 0);\r
+ if (CorrectedPath[StrLen(CorrectedPath)-1] != L'\\'\r
+ &&CorrectedPath[StrLen(CorrectedPath)-1] != L'/') {\r
+ CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, L"\\", 0);\r
+ }\r
+ CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, SearchString, 0);\r
if (CorrectedPath == NULL) {\r
return (SHELL_OUT_OF_RESOURCES);\r
}\r
\r
PathCleanUpDirectories(CorrectedPath);\r
\r
- if (!Sfo) {\r
- PrintNonSfoHeader(CorrectedPath);\r
- }\r
-\r
Status = ShellOpenFileMetaArg((CHAR16*)CorrectedPath, EFI_FILE_MODE_READ, &ListHead);\r
- if (EFI_ERROR(Status)) {\r
- SHELL_FREE_NON_NULL(CorrectedPath);\r
- if(Status == EFI_NOT_FOUND){\r
- return (SHELL_NOT_FOUND);\r
+ if (!EFI_ERROR(Status)) {\r
+ if (ListHead == NULL || IsListEmpty(&ListHead->Link)) {\r
+ SHELL_FREE_NON_NULL(CorrectedPath);\r
+ return (SHELL_SUCCESS);\r
}\r
- return (SHELL_DEVICE_ERROR);\r
- }\r
- if (ListHead == NULL || IsListEmpty(&ListHead->Link)) {\r
- SHELL_FREE_NON_NULL(CorrectedPath);\r
- //\r
- // On the first one only we expect to find something...\r
- // do we find the . and .. directories otherwise?\r
- //\r
- if (First) {\r
- return (SHELL_NOT_FOUND);\r
- }\r
- return (SHELL_SUCCESS);\r
- }\r
\r
- if (Sfo && First) {\r
- PrintSfoVolumeInfoTableEntry(ListHead);\r
- }\r
-\r
- for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&ListHead->Link)\r
- ; !IsNull(&ListHead->Link, &Node->Link)\r
- ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&ListHead->Link, &Node->Link)\r
- ){\r
- ASSERT(Node != NULL);\r
- if (LongestPath < StrSize(Node->FullName)) {\r
- LongestPath = StrSize(Node->FullName);\r
+ if (Sfo && Found == NULL) {\r
+ PrintSfoVolumeInfoTableEntry(ListHead);\r
}\r
- ASSERT(Node->Info != NULL);\r
- ASSERT((Node->Info->Attribute & EFI_FILE_VALID_ATTR) == Node->Info->Attribute);\r
- if (Attribs == 0) {\r
- //\r
- // NOT system & NOT hidden\r
- //\r
- if ( (Node->Info->Attribute & EFI_FILE_SYSTEM)\r
- || (Node->Info->Attribute & EFI_FILE_HIDDEN)\r
- ){\r
- continue;\r
+\r
+ for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&ListHead->Link), LongestPath = 0\r
+ ; !IsNull(&ListHead->Link, &Node->Link)\r
+ ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&ListHead->Link, &Node->Link)\r
+ ){\r
+ ASSERT(Node != NULL);\r
+ if (LongestPath < StrSize(Node->FullName)) {\r
+ LongestPath = StrSize(Node->FullName);\r
}\r
- } else if ((Attribs != EFI_FILE_VALID_ATTR) ||\r
- (Count == 5)) {\r
- //\r
- // Only matches the bits which "Attribs" contains, not\r
- // all files/directories with any of the bits.\r
- // Count == 5 is used to tell the difference between a user\r
- // specifying all bits (EX: -arhsda) and just specifying\r
- // -a (means display all files with any attribute).\r
- //\r
- if ( (Node->Info->Attribute & Attribs) != Attribs) {\r
- continue;\r
+ ASSERT(Node->Info != NULL);\r
+ ASSERT((Node->Info->Attribute & EFI_FILE_VALID_ATTR) == Node->Info->Attribute);\r
+ if (Attribs == 0) {\r
+ //\r
+ // NOT system & NOT hidden\r
+ //\r
+ if ( (Node->Info->Attribute & EFI_FILE_SYSTEM)\r
+ || (Node->Info->Attribute & EFI_FILE_HIDDEN)\r
+ ){\r
+ continue;\r
+ }\r
+ } else if ((Attribs != EFI_FILE_VALID_ATTR) ||\r
+ (Count == 5)) {\r
+ //\r
+ // Only matches the bits which "Attribs" contains, not\r
+ // all files/directories with any of the bits.\r
+ // Count == 5 is used to tell the difference between a user\r
+ // specifying all bits (EX: -arhsda) and just specifying\r
+ // -a (means display all files with any attribute).\r
+ //\r
+ if ( (Node->Info->Attribute & Attribs) != Attribs) {\r
+ continue;\r
+ }\r
}\r
- }\r
\r
- PrintFileInformation(Sfo, Node, &FileCount, &FileSize, &DirCount);\r
- }\r
+ if (!Sfo && HeaderPrinted == FALSE) {\r
+ PrintNonSfoHeader(CorrectedPath);\r
+ }\r
+ PrintFileInformation(Sfo, Node, &FileCount, &FileSize, &DirCount);\r
+ FoundOne = TRUE;\r
+ HeaderPrinted = TRUE;\r
+ }\r
\r
- if (!Sfo) {\r
- PrintNonSfoFooter(FileCount, FileSize, DirCount);\r
+ if (!Sfo) {\r
+ PrintNonSfoFooter(FileCount, FileSize, DirCount);\r
+ }\r
}\r
\r
- if (Rec){\r
- DirectoryName = AllocateZeroPool(LongestPath + 2*sizeof(CHAR16));\r
- if (DirectoryName == NULL) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellLevel2HiiHandle);\r
- ShellStatus = SHELL_OUT_OF_RESOURCES;\r
- } else {\r
+ if (Rec) {\r
+ //\r
+ // Re-Open all the files under the starting path for directories that didnt necessarily match our file filter\r
+ //\r
+ ShellCloseFileMetaArg(&ListHead);\r
+ CorrectedPath[0] = CHAR_NULL;\r
+ CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, RootPath, 0);\r
+ if (CorrectedPath[StrLen(CorrectedPath)-1] != L'\\'\r
+ &&CorrectedPath[StrLen(CorrectedPath)-1] != L'/') {\r
+ CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, L"\\", 0);\r
+ }\r
+ CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, L"*", 0);\r
+ Status = ShellOpenFileMetaArg((CHAR16*)CorrectedPath, EFI_FILE_MODE_READ, &ListHead);\r
+ \r
+ if (!EFI_ERROR(Status)) {\r
for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&ListHead->Link)\r
; !IsNull(&ListHead->Link, &Node->Link) && ShellStatus == SHELL_SUCCESS\r
; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&ListHead->Link, &Node->Link)\r
&& StrCmp(Node->FileName, L".") != 0\r
&& StrCmp(Node->FileName, L"..") != 0\r
){\r
- StrCpy(DirectoryName, Node->FullName);\r
- StrCat(DirectoryName, L"\\*");\r
ShellStatus = PrintLsOutput(\r
Rec,\r
Attribs,\r
Sfo,\r
- DirectoryName,\r
- FALSE,\r
+ Node->FullName,\r
+ SearchString,\r
+ &FoundOne,\r
Count,\r
TimeZone);\r
}\r
}\r
- FreePool(DirectoryName);\r
}\r
}\r
\r
- FreePool(CorrectedPath);\r
+ SHELL_FREE_NON_NULL(CorrectedPath);\r
ShellCloseFileMetaArg(&ListHead);\r
+\r
+ if (Found == NULL && FoundOne == FALSE) {\r
+ return (SHELL_NOT_FOUND);\r
+ }\r
+\r
+ if (Found != NULL) {\r
+ *Found = FoundOne;\r
+ }\r
+\r
return (ShellStatus);\r
}\r
\r
CHAR16 *FullPath;\r
UINTN Size;\r
EFI_TIME TheTime;\r
- BOOLEAN SfoMode;\r
+ CHAR16 *SearchString;\r
\r
Size = 0;\r
FullPath = NULL;\r
ShellStatus = SHELL_SUCCESS;\r
RequiredAttributes = 0;\r
PathName = NULL;\r
+ SearchString = NULL;\r
CurDir = NULL;\r
Count = 0;\r
\r
if (ShellStatus == SHELL_SUCCESS) {\r
PathName = ShellCommandLineGetRawValue(Package, 1);\r
if (PathName == NULL) {\r
+ //\r
+ // Nothing specified... must start from current directory\r
+ //\r
CurDir = gEfiShellProtocol->GetCurDir(NULL);\r
if (CurDir == NULL) {\r
ShellStatus = SHELL_NOT_FOUND;\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle);\r
}\r
- }\r
- if (PathName != NULL) {\r
+ //\r
+ // Copy to the 2 strings for starting path and file search string\r
+ //\r
+ ASSERT(SearchString == NULL);\r
+ ASSERT(FullPath == NULL);\r
+ StrnCatGrow(&SearchString, NULL, L"*", 0);\r
+ StrnCatGrow(&FullPath, NULL, CurDir, 0);\r
+ } else {\r
if (StrStr(PathName, L":") == NULL && gEfiShellProtocol->GetCurDir(NULL) == NULL) {\r
+ //\r
+ // If we got something and it doesnt have a fully qualified path, then we needed to have a CWD.\r
+ //\r
ShellStatus = SHELL_NOT_FOUND;\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle);\r
} else {\r
+ //\r
+ // We got a valid fully qualified path or we have a CWD\r
+ //\r
ASSERT((FullPath == NULL && Size == 0) || (FullPath != NULL));\r
+ if (StrStr(PathName, L":") == NULL) {\r
+ StrnCatGrow(&FullPath, &Size, gEfiShellProtocol->GetCurDir(NULL), 0);\r
+ }\r
StrnCatGrow(&FullPath, &Size, PathName, 0);\r
if (ShellIsDirectory(PathName) == EFI_SUCCESS) {\r
- if (PathName[StrLen (PathName) - 1] == '\\') {\r
- //\r
- // For path ending with '\', just append '*'.\r
- //\r
- StrnCatGrow (&FullPath, &Size, L"*", 0);\r
- } else if (PathName[StrLen (PathName) - 1] == '*') {\r
- //\r
- // For path ending with '*', do nothing.\r
- //\r
- } else {\r
- //\r
- // Otherwise, append '\*' to directory name.\r
- //\r
- StrnCatGrow (&FullPath, &Size, L"\\*", 0);\r
- }\r
+ //\r
+ // is listing ends with a directory, then we list all files in that directory\r
+ //\r
+ StrnCatGrow(&SearchString, NULL, L"*", 0);\r
+ } else {\r
+ //\r
+ // must split off the search part that applies to files from the end of the directory part\r
+ //\r
+ for (StrnCatGrow(&SearchString, NULL, PathName, 0)\r
+ ; SearchString != NULL && StrStr(SearchString, L"\\") != NULL\r
+ ; CopyMem(SearchString, StrStr(SearchString, L"\\") + 1, 1 + StrSize(StrStr(SearchString, L"\\") + 1))) ;\r
+ FullPath[StrLen(FullPath) - StrLen(SearchString)] = CHAR_NULL;\r
}\r
}\r
- } else {\r
- ASSERT(FullPath == NULL);\r
- StrnCatGrow(&FullPath, NULL, L"*", 0);\r
}\r
Status = gRT->GetTime(&TheTime, NULL);\r
if (EFI_ERROR(Status)) {\r
TheTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE;\r
}\r
\r
- SfoMode = ShellCommandLineGetFlag(Package, L"-sfo");\r
if (ShellStatus == SHELL_SUCCESS) {\r
ShellStatus = PrintLsOutput(\r
ShellCommandLineGetFlag(Package, L"-r"),\r
RequiredAttributes,\r
- SfoMode,\r
+ ShellCommandLineGetFlag(Package, L"-sfo"),\r
FullPath,\r
- TRUE,\r
+ SearchString,\r
+ NULL,\r
Count,\r
(INT16)(TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:TheTime.TimeZone)\r
);\r
}\r
}\r
\r
- if (FullPath != NULL) {\r
- FreePool(FullPath);\r
- }\r
//\r
- // free the command line package\r
+ // Free memory allocated\r
//\r
+ SHELL_FREE_NON_NULL(SearchString);\r
+ SHELL_FREE_NON_NULL(FullPath);\r
ShellCommandLineFreeVarList (Package);\r
\r
return (ShellStatus);\r