]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c
Update code to ensure the pointer ‘CurrentName’ in function ‘PerformSingleMappingDisp...
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / Ls.c
index 61d48977f1d003e0269889ea3dabb9f0124c6e73..4d0a1563e3cce37f4b5a08babb02bb4b6236385b 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
   Main file for ls shell level 2 function.\r
 \r
-  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2013 Hewlett-Packard Development Company, L.P.\r
+  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -66,14 +67,42 @@ PrintLsOutput(
   CorrectedPath = NULL;\r
 \r
   CorrectedPath = StrnCatGrow(&CorrectedPath, NULL, Path, 0);\r
-  ASSERT(CorrectedPath != NULL);\r
-  ShellCommandCleanPath(CorrectedPath);\r
+  if (CorrectedPath == NULL) {\r
+    return (SHELL_OUT_OF_RESOURCES);\r
+  }\r
+\r
+  PathCleanUpDirectories(CorrectedPath);\r
+\r
+  if (!Sfo) {\r
+    //\r
+    // get directory name from path...\r
+    //\r
+    DirectoryName = GetFullyQualifiedPath(CorrectedPath);\r
+\r
+    //\r
+    // print header\r
+    //\r
+    ShellPrintHiiEx (\r
+      0,\r
+      gST->ConOut->Mode->CursorRow,\r
+      NULL,\r
+      STRING_TOKEN (STR_LS_HEADER_LINE1),\r
+      gShellLevel2HiiHandle,\r
+      DirectoryName\r
+     );\r
+    FreePool(DirectoryName);\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
+    }\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
@@ -184,25 +213,6 @@ PrintLsOutput(
     }\r
   }\r
 \r
-  if (!Sfo) {\r
-    //\r
-    // get directory name from path...\r
-    //\r
-    DirectoryName = GetFullyQualifiedPath(CorrectedPath);\r
-\r
-    //\r
-    // print header\r
-    //\r
-    ShellPrintHiiEx (\r
-      0,\r
-      gST->ConOut->Mode->CursorRow,\r
-      NULL,\r
-      STRING_TOKEN (STR_LS_HEADER_LINE1),\r
-      gShellLevel2HiiHandle,\r
-      DirectoryName\r
-     );\r
-    FreePool(DirectoryName);\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
@@ -222,21 +232,17 @@ PrintLsOutput(
        ){\r
         continue;\r
       }\r
-    } else if (Attribs != EFI_FILE_VALID_ATTR) {\r
-      if (Count == 1) {\r
-        //\r
-        // the bit must match\r
-        //\r
-        if ( (Node->Info->Attribute & Attribs) != Attribs) {\r
-          continue;\r
-        }\r
-      } else {\r
-        //\r
-        // exact match on all bits\r
-        //\r
-        if ( Node->Info->Attribute != Attribs) {\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
@@ -348,31 +354,41 @@ PrintLsOutput(
   }\r
 \r
   if (Rec){\r
-    DirectoryName = AllocatePool(LongestPath + 2*sizeof(CHAR16));\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
-      //\r
-      // recurse on any directory except the traversing ones...\r
-      //\r
-      if (((Node->Info->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY)\r
-        && StrCmp(Node->FileName, L".") != 0\r
-        && StrCmp(Node->FileName, L"..") != 0\r
-       ){\r
-        StrCpy(DirectoryName, Node->FullName);\r
-        StrCat(DirectoryName, L"\\*");\r
-        PrintLsOutput(\r
-          Rec,\r
-          Attribs,\r
-          Sfo,\r
-          DirectoryName,\r
-          FALSE,\r
-          Count,\r
-          TimeZone);\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
+      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
+         ){\r
+        if (ShellGetExecutionBreakFlag ()) {\r
+          ShellStatus = SHELL_ABORTED;\r
+          break;\r
+        }\r
+\r
+        //\r
+        // recurse on any directory except the traversing ones...\r
+        //\r
+        if (((Node->Info->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY)\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
+            Count,\r
+            TimeZone);\r
+        }\r
       }\r
+      FreePool(DirectoryName);\r
     }\r
-    FreePool(DirectoryName);\r
   }\r
 \r
   FreePool(CorrectedPath);\r
@@ -412,7 +428,7 @@ ShellCommandRunLs (
   UINTN         Count;\r
   CHAR16        *FullPath;\r
   UINTN         Size;\r
-  EFI_TIME      theTime;\r
+  EFI_TIME      TheTime;\r
   BOOLEAN       SfoMode;\r
 \r
   Size                = 0;\r
@@ -518,17 +534,40 @@ ShellCommandRunLs (
           }\r
         }\r
         if (PathName != NULL) {\r
-          ASSERT((FullPath == NULL && Size == 0) || (FullPath != NULL));\r
-          StrnCatGrow(&FullPath, &Size, PathName, 0);\r
-          if  (ShellIsDirectory(PathName) == EFI_SUCCESS) {\r
-            StrnCatGrow(&FullPath, &Size, L"\\*", 0);\r
+          if (StrStr(PathName, L":") == NULL && gEfiShellProtocol->GetCurDir(NULL) == NULL) {\r
+            ShellStatus = SHELL_NOT_FOUND;\r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle);\r
+          } else {\r
+            ASSERT((FullPath == NULL && Size == 0) || (FullPath != NULL));\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
           }\r
         } else {\r
           ASSERT(FullPath == NULL);\r
           StrnCatGrow(&FullPath, NULL, L"*", 0);\r
         }\r
-        Status = gRT->GetTime(&theTime, NULL);\r
-        ASSERT_EFI_ERROR(Status);\r
+        Status = gRT->GetTime(&TheTime, NULL);\r
+        if (EFI_ERROR(Status)) {\r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"gRT->GetTime", Status);\r
+          TheTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE;\r
+        }\r
+\r
         SfoMode = ShellCommandLineGetFlag(Package, L"-sfo");\r
         if (ShellStatus == SHELL_SUCCESS) {\r
           ShellStatus = PrintLsOutput(\r
@@ -538,12 +577,16 @@ ShellCommandRunLs (
             FullPath,\r
             TRUE,\r
             Count,\r
-            (INT16)(theTime.TimeZone==2047?0:theTime.TimeZone)\r
+            (INT16)(TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:TheTime.TimeZone)\r
            );\r
           if (ShellStatus == SHELL_NOT_FOUND) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_FILES), gShellLevel2HiiHandle);\r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LS_FILE_NOT_FOUND), gShellLevel2HiiHandle);\r
           } else if (ShellStatus == SHELL_INVALID_PARAMETER) {\r
             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle);\r
+          } else if (ShellStatus == SHELL_ABORTED) {\r
+            //\r
+            // Ignore aborting.\r
+            //\r
           } else if (ShellStatus != SHELL_SUCCESS) {\r
             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle);\r
           }\r