]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - ShellPkg/Library/UefiShellLevel3CommandsLib/Type.c
ShellPkg/mkdir: support creating nested directories
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel3CommandsLib / Type.c
... / ...
CommitLineData
1/** @file\r
2 Main file for Type shell level 3 function.\r
3\r
4 (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>\r
5 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved. <BR>\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "UefiShellLevel3CommandsLib.h"\r
17\r
18#include <Library/ShellLib.h>\r
19\r
20/**\r
21 Display a single file to StdOut.\r
22\r
23 If both Ascii and UCS2 are FALSE attempt to discover the file type.\r
24\r
25 @param[in] Handle The handle to the file to display.\r
26 @param[in] Ascii TRUE to force ASCII, FALSE othewise.\r
27 @param[in] UCS2 TRUE to force UCS2, FALSE othewise.\r
28\r
29 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
30 @retval EFI_SUCCESS The operation was successful.\r
31**/\r
32EFI_STATUS\r
33TypeFileByHandle (\r
34 IN SHELL_FILE_HANDLE Handle,\r
35 IN BOOLEAN Ascii,\r
36 IN BOOLEAN UCS2\r
37 )\r
38{\r
39 UINTN ReadSize;\r
40 VOID *Buffer;\r
41 VOID *AllocatedBuffer;\r
42 EFI_STATUS Status;\r
43 UINTN LoopVar;\r
44 UINTN LoopSize;\r
45 CHAR16 AsciiChar;\r
46 CHAR16 Ucs2Char;\r
47\r
48 ReadSize = PcdGet32(PcdShellFileOperationSize);\r
49 AllocatedBuffer = AllocateZeroPool(ReadSize);\r
50 if (AllocatedBuffer == NULL) {\r
51 return (EFI_OUT_OF_RESOURCES);\r
52 }\r
53\r
54 Status = ShellSetFilePosition(Handle, 0);\r
55 ASSERT_EFI_ERROR(Status);\r
56\r
57 while (ReadSize == ((UINTN)PcdGet32(PcdShellFileOperationSize))) {\r
58 Buffer = AllocatedBuffer;\r
59 ZeroMem(Buffer, ReadSize);\r
60 Status = ShellReadFile(Handle, &ReadSize, Buffer);\r
61 if (EFI_ERROR(Status)){\r
62 break;\r
63 }\r
64\r
65 if (!(Ascii|UCS2)) {\r
66 if (*(UINT16*)Buffer == gUnicodeFileTag) {\r
67 UCS2 = TRUE;\r
68 } else {\r
69 Ascii = TRUE;\r
70 }\r
71 }\r
72\r
73 if (Ascii) {\r
74 LoopSize = ReadSize;\r
75 for (LoopVar = 0 ; LoopVar < LoopSize ; LoopVar++) {\r
76 //\r
77 // The valid range of ASCII characters is 0x20-0x7E.\r
78 // Display "." when there is an invalid character.\r
79 //\r
80 AsciiChar = CHAR_NULL;\r
81 AsciiChar = ((CHAR8*)Buffer)[LoopVar];\r
82 if (AsciiChar == '\r' || AsciiChar == '\n') {\r
83 //\r
84 // Allow Line Feed (LF) (0xA) & Carriage Return (CR) (0xD)\r
85 // characters to be displayed as is.\r
86 // \r
87 if (AsciiChar == '\n' && ((CHAR8*)Buffer)[LoopVar-1] != '\r') {\r
88 //\r
89 // In case Line Feed (0xA) is encountered & Carriage Return (0xD)\r
90 // was not the previous character, print CR and LF. This is because\r
91 // Shell 2.0 requires carriage return with line feed for displaying\r
92 // each new line from left.\r
93 //\r
94 ShellPrintEx (-1, -1, L"\r\n");\r
95 continue;\r
96 }\r
97 } else {\r
98 //\r
99 // For all other characters which are not printable, display '.'\r
100 //\r
101 if (AsciiChar < 0x20 || AsciiChar >= 0x7F) {\r
102 AsciiChar = '.';\r
103 }\r
104 }\r
105 ShellPrintEx (-1, -1, L"%c", AsciiChar);\r
106 }\r
107 } else {\r
108 if (*(UINT16*)Buffer == gUnicodeFileTag) {\r
109 //\r
110 // For unicode files, skip displaying the byte order marker.\r
111 //\r
112 Buffer = ((UINT16*)Buffer) + 1;\r
113 LoopSize = (ReadSize / (sizeof (CHAR16))) - 1;\r
114 } else {\r
115 LoopSize = ReadSize / (sizeof (CHAR16));\r
116 }\r
117 \r
118 for (LoopVar = 0 ; LoopVar < LoopSize ; LoopVar++) {\r
119 //\r
120 // An invalid range of characters is 0x0-0x1F.\r
121 // Display "." when there is an invalid character.\r
122 //\r
123 Ucs2Char = CHAR_NULL;\r
124 Ucs2Char = ((CHAR16*)Buffer)[LoopVar];\r
125 if (Ucs2Char == '\r' || Ucs2Char == '\n') {\r
126 //\r
127 // Allow Line Feed (LF) (0xA) & Carriage Return (CR) (0xD)\r
128 // characters to be displayed as is.\r
129 // \r
130 if (Ucs2Char == '\n' && ((CHAR16*)Buffer)[LoopVar-1] != '\r') {\r
131 //\r
132 // In case Line Feed (0xA) is encountered & Carriage Return (0xD)\r
133 // was not the previous character, print CR and LF. This is because\r
134 // Shell 2.0 requires carriage return with line feed for displaying\r
135 // each new line from left.\r
136 //\r
137 ShellPrintEx (-1, -1, L"\r\n");\r
138 continue;\r
139 }\r
140 } \r
141 else if (Ucs2Char < 0x20) {\r
142 //\r
143 // For all other characters which are not printable, display '.'\r
144 //\r
145 Ucs2Char = L'.';\r
146 }\r
147 ShellPrintEx (-1, -1, L"%c", Ucs2Char);\r
148 }\r
149 }\r
150\r
151 if (ShellGetExecutionBreakFlag()) {\r
152 break;\r
153 }\r
154 }\r
155 FreePool (AllocatedBuffer);\r
156 ShellPrintEx (-1, -1, L"\r\n");\r
157 return (Status);\r
158}\r
159\r
160STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
161 {L"-a", TypeFlag},\r
162 {L"-u", TypeFlag},\r
163 {NULL, TypeMax}\r
164 };\r
165\r
166/**\r
167 Function for 'type' command.\r
168\r
169 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
170 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
171**/\r
172SHELL_STATUS\r
173EFIAPI\r
174ShellCommandRunType (\r
175 IN EFI_HANDLE ImageHandle,\r
176 IN EFI_SYSTEM_TABLE *SystemTable\r
177 )\r
178{\r
179 EFI_STATUS Status;\r
180 LIST_ENTRY *Package;\r
181 CHAR16 *ProblemParam;\r
182 CONST CHAR16 *Param;\r
183 SHELL_STATUS ShellStatus;\r
184 UINTN ParamCount;\r
185 EFI_SHELL_FILE_INFO *FileList;\r
186 EFI_SHELL_FILE_INFO *Node;\r
187 BOOLEAN AsciiMode;\r
188 BOOLEAN UnicodeMode;\r
189\r
190 ProblemParam = NULL;\r
191 ShellStatus = SHELL_SUCCESS;\r
192 ParamCount = 0;\r
193 FileList = NULL;\r
194\r
195 //\r
196 // initialize the shell lib (we must be in non-auto-init...)\r
197 //\r
198 Status = ShellInitialize();\r
199 ASSERT_EFI_ERROR(Status);\r
200\r
201 Status = CommandInit();\r
202 ASSERT_EFI_ERROR(Status);\r
203\r
204 //\r
205 // parse the command line\r
206 //\r
207 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
208 if (EFI_ERROR(Status)) {\r
209 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
210 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel3HiiHandle, L"type", ProblemParam); \r
211 FreePool(ProblemParam);\r
212 ShellStatus = SHELL_INVALID_PARAMETER;\r
213 } else {\r
214 ASSERT(FALSE);\r
215 }\r
216 } else {\r
217 //\r
218 // check for "-?"\r
219 //\r
220 if (ShellCommandLineGetFlag(Package, L"-?")) {\r
221 ASSERT(FALSE);\r
222 }\r
223 AsciiMode = ShellCommandLineGetFlag(Package, L"-a");\r
224 UnicodeMode = ShellCommandLineGetFlag(Package, L"-u");\r
225\r
226 if (AsciiMode && UnicodeMode) {\r
227 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel3HiiHandle, L"type", L"-a & -u"); \r
228 ShellStatus = SHELL_INVALID_PARAMETER;\r
229 } else if (ShellCommandLineGetRawValue(Package, 1) == NULL) {\r
230 //\r
231 // we insufficient parameters\r
232 //\r
233 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel3HiiHandle, L"type"); \r
234 ShellStatus = SHELL_INVALID_PARAMETER;\r
235 } else {\r
236 //\r
237 // get a list with each file specified by parameters\r
238 // if parameter is a directory then add all the files below it to the list\r
239 //\r
240 for ( ParamCount = 1, Param = ShellCommandLineGetRawValue(Package, ParamCount)\r
241 ; Param != NULL\r
242 ; ParamCount++, Param = ShellCommandLineGetRawValue(Package, ParamCount)\r
243 ){\r
244 Status = ShellOpenFileMetaArg((CHAR16*)Param, EFI_FILE_MODE_READ, &FileList);\r
245 if (EFI_ERROR(Status)) {\r
246 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel3HiiHandle, L"type", (CHAR16*)Param); \r
247 ShellStatus = SHELL_NOT_FOUND;\r
248 break;\r
249 }\r
250 //\r
251 // make sure we completed the param parsing sucessfully...\r
252 // Also make sure that any previous action was sucessful\r
253 //\r
254 if (ShellStatus == SHELL_SUCCESS) {\r
255 //\r
256 // check that we have at least 1 file\r
257 //\r
258 if (FileList == NULL || IsListEmpty(&FileList->Link)) {\r
259 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel3HiiHandle, L"type", Param); \r
260 continue;\r
261 } else {\r
262 //\r
263 // loop through the list and make sure we are not aborting...\r
264 //\r
265 for ( Node = (EFI_SHELL_FILE_INFO*)GetFirstNode(&FileList->Link)\r
266 ; !IsNull(&FileList->Link, &Node->Link) && !ShellGetExecutionBreakFlag()\r
267 ; Node = (EFI_SHELL_FILE_INFO*)GetNextNode(&FileList->Link, &Node->Link)\r
268 ){\r
269\r
270 if (ShellGetExecutionBreakFlag()) {\r
271 break;\r
272 }\r
273\r
274 //\r
275 // make sure the file opened ok\r
276 //\r
277 if (EFI_ERROR(Node->Status)){\r
278 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel3HiiHandle, L"type", Node->FileName); \r
279 ShellStatus = SHELL_NOT_FOUND;\r
280 continue;\r
281 }\r
282\r
283 //\r
284 // make sure its not a directory\r
285 //\r
286 if (FileHandleIsDirectory(Node->Handle) == EFI_SUCCESS) {\r
287 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_IS_DIR), gShellLevel3HiiHandle, L"type", Node->FileName); \r
288 ShellStatus = SHELL_NOT_FOUND;\r
289 continue;\r
290 }\r
291\r
292 //\r
293 // do it\r
294 //\r
295 Status = TypeFileByHandle (Node->Handle, AsciiMode, UnicodeMode);\r
296 if (EFI_ERROR(Status)) {\r
297 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TYP_ERROR), gShellLevel3HiiHandle, L"type", Node->FileName);\r
298 ShellStatus = SHELL_INVALID_PARAMETER;\r
299 }\r
300 ASSERT(ShellStatus == SHELL_SUCCESS);\r
301 }\r
302 }\r
303 }\r
304 //\r
305 // Free the fileList\r
306 //\r
307 if (FileList != NULL && !IsListEmpty(&FileList->Link)) {\r
308 Status = ShellCloseFileMetaArg(&FileList);\r
309 }\r
310 ASSERT_EFI_ERROR(Status);\r
311 FileList = NULL;\r
312 }\r
313 }\r
314\r
315 //\r
316 // free the command line package\r
317 //\r
318 ShellCommandLineFreeVarList (Package);\r
319 }\r
320\r
321 if (ShellGetExecutionBreakFlag()) {\r
322 return (SHELL_ABORTED);\r
323 }\r
324\r
325 return (ShellStatus);\r
326}\r
327\r