1/** @file
2  Script command allows the execution of commands from a text file
3
4  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
5  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
6  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
7
8  This program and the accompanying materials
9  are licensed and made available under the terms and conditions of the BSD License
10  which accompanies this distribution.  The full text of the license may be found at
11  http://opensource.org/licenses/bsd-license.php
12
13  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15
16  Module Name:  EfiDevice.c
17
18**/
19
20#include "Ebl.h"
21
22
23/**
24  Execute the passed in file like a series of commands. The ; can be used on
25  a single line to indicate multiple commands per line. The Ascii text file
26  can contain any number of lines. The following line termination forms are
27  supported:
28    LF   : Unix, Mac OS X*, BeOS
29    CR+LF: MS-DOS*, Microsoft Windows*
30    CR   : Commodore, Apple II, and really Mac OS
31    LF+CR: for simplicity and completeness
32
33  Argv[0] - "script"
34  Argv[1] - Device Name:path for the file to load
35
36  script fv1:\script.txt
37
38  @param  Argc   Number of command arguments in Argv
39  @param  Argv   Array of strings that represent the parsed command line.
40                 Argv[0] is the command name
41
42  @return EFI_SUCCESS
43
44**/
45EFI_STATUS
46EFIAPI
47EblScriptCmd (
48  IN UINTN  Argc,
49  IN CHAR8  **Argv
50  )
51{
52  EFI_STATUS                    Status;
53  EFI_OPEN_FILE                 *File;
54  VOID                          *Address;
55  UINTN                         Size;
56  CHAR8                         *Ptr;
57  CHAR8                         *ScanPtr;
58  UINTN                         CmdLineSize;
59
60
61
62  if (Argc < 2) {
63    // file name required
64    return EFI_SUCCESS;
65  }
66
67  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
68  if (File == NULL) {
69    AsciiPrint ("  %a is not a valid path\n", Argv[1]);
70    return EFI_SUCCESS;
71  }
72
73  Status = EfiReadAllocatePool (File, &Address, &Size);
74  if (!EFI_ERROR (Status)) {
75    // Loop through each line in the text file
76    for (Ptr = (CHAR8 *)Address; (Ptr < (((CHAR8 *)Address) + Size)) && !EFI_ERROR (Status); Ptr += CmdLineSize) {
77      for (CmdLineSize = 0, ScanPtr = Ptr; ; CmdLineSize++, ScanPtr++) {
78        // look for the end of the line
79        if ((*ScanPtr == EBL_CR) || (*ScanPtr == EBL_LF)) {
80          // convert to NULL as this is what input routine would do
81          *ScanPtr = 0;
82          if ((*(ScanPtr + 1) == EBL_CR) || (*(ScanPtr + 1) == EBL_LF)) {
83            // if its a set get the 2nd EOL char
84            CmdLineSize++;
85            *(ScanPtr + 1) = 0;
86          }
87          CmdLineSize++;
88          break;
89        }
90
91      }
92
93      Status = ProcessCmdLine (Ptr, CmdLineSize);
94    }
95
96    FreePool (Address);
97  }
98
99  EfiClose (File);
100  return Status;
101}
102
103
104
105GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mScriptTemplate[] = {
106  {
107    "script",
108    " device:path; load an ascii file and execute it like commands",
109    NULL,
110    EblScriptCmd
111  }
112};
113
114
115/**
116  Initialize the commands in this in this file
117**/
118
119VOID
120EblInitializeScriptCmd (
121  VOID
122  )
123{
124  if (FeaturePcdGet (PcdEmbeddedScriptCmd)) {
125    EblAddCommands (mScriptTemplate, sizeof (mScriptTemplate)/sizeof (EBL_COMMAND_TABLE));
126  }
127}
128
129