]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Application/Shell/Shell.c
Add default way for switch in function 'RunCommandOrFile' of 'Shell.c'.
[mirror_edk2.git] / ShellPkg / Application / Shell / Shell.c
index fe722e955448bd0c60d6901da4bf3f9d350e85fc..ef821a5c5d021bc5ce20dfb8abb6ba37774af35b 100644 (file)
@@ -91,9 +91,9 @@ TrimSpaces(
   }\r
 \r
   //\r
-  // Remove any spaces at the end of the (*String).\r
+  // Remove any spaces and tabs at the end of the (*String).\r
   //\r
-  while ((*String)[StrLen((*String))-1] == L' ') {\r
+  while ((StrLen (*String) > 0) && (((*String)[StrLen((*String))-1] == L' ') || ((*String)[StrLen((*String))-1] == L'\t'))) {\r
     (*String)[StrLen((*String))-1] = CHAR_NULL;\r
   }\r
 \r
@@ -1596,6 +1596,96 @@ GetOperationType(
   return (UNKNOWN_INVALID);\r
 }\r
 \r
+EFI_STATUS \r
+EFIAPI\r
+IsValidSplit(\r
+  IN CONST CHAR16 *CmdLine\r
+  )\r
+{\r
+  CHAR16        *Temp;\r
+  CHAR16        *FirstParameter;\r
+  CHAR16        *TempWalker;\r
+  EFI_STATUS    Status;\r
+\r
+  Temp           = NULL;\r
+\r
+  Temp = StrnCatGrow(&Temp, NULL, CmdLine, 0);\r
+  if (Temp == NULL) {\r
+    return (EFI_OUT_OF_RESOURCES);\r
+  }\r
+\r
+  FirstParameter = StrStr(Temp, L"|");\r
+  if (FirstParameter != NULL) {\r
+    *FirstParameter = CHAR_NULL;\r
+  }\r
+\r
+  FirstParameter = NULL;\r
+\r
+  //\r
+  // Process the command line\r
+  //\r
+  Status = ProcessCommandLineToFinal(&Temp);\r
+\r
+  if (!EFI_ERROR(Status)) {\r
+    FirstParameter = AllocateZeroPool(StrSize(CmdLine));\r
+    if (FirstParameter == NULL) {\r
+      SHELL_FREE_NON_NULL(Temp);\r
+      return (EFI_OUT_OF_RESOURCES);\r
+    }\r
+    TempWalker = (CHAR16*)Temp;\r
+    GetNextParameter(&TempWalker, &FirstParameter);\r
+\r
+    if (GetOperationType(FirstParameter) == UNKNOWN_INVALID) {\r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);\r
+      SetLastError(SHELL_NOT_FOUND);\r
+      Status = EFI_NOT_FOUND;\r
+    }\r
+  }\r
+\r
+  SHELL_FREE_NON_NULL(Temp);\r
+  SHELL_FREE_NON_NULL(FirstParameter);\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Determine if a command line contains with a split contains only valid commands\r
+\r
+  @param[in] CmdLine      The command line to parse.\r
+\r
+  @retval EFI_SUCCESS     CmdLine has only valid commands, application, or has no split.\r
+  @retval EFI_ABORTED     CmdLine has at least one invalid command or application.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VerifySplit(\r
+  IN CONST CHAR16 *CmdLine\r
+  )\r
+{\r
+  CONST CHAR16  *TempSpot;\r
+  EFI_STATUS    Status;\r
+\r
+  //\r
+  // Verify up to the pipe or end character\r
+  //\r
+  Status = IsValidSplit(CmdLine);\r
+  if (EFI_ERROR(Status)) {\r
+    return (Status);\r
+  }\r
+\r
+  //\r
+  // If this was the only item, then get out\r
+  //\r
+  if (!ContainsSplit(CmdLine)) {\r
+    return (EFI_SUCCESS);\r
+  }\r
+\r
+  //\r
+  // recurse to verify the next item\r
+  //\r
+  TempSpot = FindSplit(CmdLine)+1;\r
+  return (VerifySplit(TempSpot));\r
+}\r
+\r
 /**\r
   Process a split based operation.\r
 \r
@@ -1613,6 +1703,11 @@ ProcessNewSplitCommandLine(
   SPLIT_LIST                *Split;\r
   EFI_STATUS                Status;\r
 \r
+  Status = VerifySplit(CmdLine);\r
+  if (EFI_ERROR(Status)) {\r
+    return (Status);\r
+  }\r
+\r
   Split = NULL;\r
 \r
   //\r
@@ -1728,7 +1823,7 @@ DoHelpUpdate(
 EFI_STATUS\r
 EFIAPI\r
 SetLastError(\r
-  IN CONST UINT64   ErrorCode\r
+  IN CONST SHELL_STATUS   ErrorCode\r
   )\r
 {\r
   CHAR16 LeString[19];\r
@@ -1754,7 +1849,7 @@ SetLastError(
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-ProcessCommandLineAliasVariable(\r
+ProcessCommandLineToFinal(\r
   IN OUT CHAR16 **CmdLine\r
   )\r
 {\r
@@ -1840,8 +1935,19 @@ RunInternalCommand(
       // Pass thru the exitcode from the app.\r
       //\r
       if (ShellCommandGetExit()) {\r
+        //\r
+        // An Exit was requested ("exit" command), pass its value up.\r
+        //\r
         Status = CommandReturnedStatus;\r
-      } else if (CommandReturnedStatus != 0 && IsScriptOnlyCommand(FirstParameter)) {\r
+      } else if (CommandReturnedStatus != SHELL_SUCCESS && IsScriptOnlyCommand(FirstParameter)) {\r
+        //\r
+        // Always abort when a script only command fails for any reason\r
+        //\r
+        Status = EFI_ABORTED;\r
+      } else if (ShellCommandGetCurrentScriptFile() != NULL && CommandReturnedStatus == SHELL_ABORTED) {\r
+        //\r
+        // Abort when in a script and a command aborted\r
+        //\r
         Status = EFI_ABORTED;\r
       }\r
     }\r
@@ -1853,11 +1959,17 @@ RunInternalCommand(
   //\r
   RestoreArgcArgv(ParamProtocol, &Argv, &Argc);\r
 \r
-  if (ShellCommandGetCurrentScriptFile() != NULL &&  !IsScriptOnlyCommand(FirstParameter)) {\r
-    //\r
-    // if this is NOT a scipt only command return success so the script won't quit.\r
-    // prevent killing the script - this is the only place where we know the actual command name (after alias and variable replacement...)\r
-    //\r
+  //\r
+  // If a script is running and the command is not a scipt only command, then\r
+  // change return value to success so the script won't halt (unless aborted).\r
+  //\r
+  // Script only commands have to be able halt the script since the script will\r
+  // not operate if they are failing.\r
+  //\r
+  if ( ShellCommandGetCurrentScriptFile() != NULL\r
+    && !IsScriptOnlyCommand(FirstParameter)\r
+    && Status != EFI_ABORTED\r
+    ) {\r
     Status = EFI_SUCCESS;\r
   }\r
 \r
@@ -1926,7 +2038,7 @@ RunCommandOrFile(
       //\r
       if (!EFI_ERROR(ShellIsDirectory(CommandWithPath))) {\r
         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);\r
-        SetLastError(EFI_NOT_FOUND);\r
+        SetLastError(SHELL_NOT_FOUND);\r
       }\r
       switch (Type) {\r
         case   SCRIPT_FILE_NAME:\r
@@ -1960,8 +2072,18 @@ RunCommandOrFile(
           //\r
           SetLastError(StatusCode);\r
           break;\r
+        default:\r
+          //\r
+          // Do nothing.\r
+          //\r
+          break;\r
       }\r
       break;\r
+    default:\r
+      //\r
+      // Do nothing.\r
+      //\r
+      break;\r
   }\r
 \r
   SHELL_FREE_NON_NULL(CommandWithPath);\r
@@ -2069,7 +2191,7 @@ RunCommand(
     return (EFI_SUCCESS);\r
   }\r
 \r
-  Status = ProcessCommandLineAliasVariable(&CleanOriginal);\r
+  Status = ProcessCommandLineToFinal(&CleanOriginal);\r
   if (EFI_ERROR(Status)) {\r
     SHELL_FREE_NON_NULL(CleanOriginal);\r
     return (Status);\r
@@ -2112,7 +2234,7 @@ RunCommand(
       // Whatever was typed, it was invalid.\r
       //\r
       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);\r
-      SetLastError(EFI_NOT_FOUND);\r
+      SetLastError(SHELL_NOT_FOUND);\r
       break;\r
   }\r
  \r