]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellLevel3CommandsLib/Touch.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel3CommandsLib / Touch.c
1 /** @file
2 Main file for Touch shell level 3 function.
3
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved. <BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "UefiShellLevel3CommandsLib.h"
11
12 #include <Library/ShellLib.h>
13
14 /**
15 Do the touch operation on a single handle.
16
17 @param[in] Handle The handle to update the date/time on.
18
19 @retval EFI_ACCESS_DENIED The file referenced by Handle is read only.
20 @retval EFI_SUCCESS The operation was successful.
21 **/
22 EFI_STATUS
23 TouchFileByHandle (
24 IN SHELL_FILE_HANDLE Handle
25 )
26 {
27 EFI_STATUS Status;
28 EFI_FILE_INFO *FileInfo;
29
30 FileInfo = gEfiShellProtocol->GetFileInfo (Handle);
31 if ((FileInfo->Attribute & EFI_FILE_READ_ONLY) != 0) {
32 return (EFI_ACCESS_DENIED);
33 }
34
35 Status = gRT->GetTime (&FileInfo->ModificationTime, NULL);
36 if (EFI_ERROR (Status)) {
37 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel3HiiHandle, L"gRT->GetTime", Status);
38 return (SHELL_DEVICE_ERROR);
39 }
40
41 CopyMem (&FileInfo->LastAccessTime, &FileInfo->ModificationTime, sizeof (EFI_TIME));
42
43 Status = gEfiShellProtocol->SetFileInfo (Handle, FileInfo);
44
45 FreePool (FileInfo);
46
47 return (Status);
48 }
49
50 /**
51 Touch a given file and potantially recurse down if it was a directory.
52
53 @param[in] Name The name of this file.
54 @param[in] FS The name of the file system this file is on.
55 @param[in] Handle The handle of this file already opened.
56 @param[in] Rec TRUE to recurse if possible.
57
58 @retval EFI_INVALID_PARAMETER A parameter was invalid.
59 @retval EFI_SUCCESS The operation was successful.
60 **/
61 EFI_STATUS
62 DoTouchByHandle (
63 IN CONST CHAR16 *Name,
64 IN CHAR16 *FS,
65 IN SHELL_FILE_HANDLE Handle,
66 IN BOOLEAN Rec
67 )
68 {
69 EFI_STATUS Status;
70 EFI_SHELL_FILE_INFO *FileList;
71 EFI_SHELL_FILE_INFO *Walker;
72 CHAR16 *TempSpot;
73
74 Status = EFI_SUCCESS;
75 FileList = NULL;
76 Walker = NULL;
77
78 if (FS == NULL) {
79 FS = StrnCatGrow (&FS, NULL, Name, 0);
80 if (FS != NULL) {
81 TempSpot = StrStr (FS, L"\\");
82 if (TempSpot != NULL) {
83 *TempSpot = CHAR_NULL;
84 }
85 }
86 }
87
88 if (FS == NULL) {
89 return (EFI_INVALID_PARAMETER);
90 }
91
92 //
93 // do it
94 //
95 Status = TouchFileByHandle (Handle);
96 if (EFI_ERROR (Status)) {
97 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel3HiiHandle, L"touch", Name);
98 return (Status);
99 }
100
101 //
102 // if it's a directory recurse...
103 //
104 if ((FileHandleIsDirectory (Handle) == EFI_SUCCESS) && Rec) {
105 //
106 // get each file under this directory
107 //
108 if (EFI_ERROR (gEfiShellProtocol->FindFilesInDir (Handle, &FileList))) {
109 Status = EFI_INVALID_PARAMETER;
110 }
111
112 //
113 // recurse on each
114 //
115 for (Walker = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link)
116 ; FileList != NULL && !IsNull (&FileList->Link, &Walker->Link) && !EFI_ERROR (Status)
117 ; Walker = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Walker->Link)
118 )
119 {
120 if ( (StrCmp (Walker->FileName, L".") != 0)
121 && (StrCmp (Walker->FileName, L"..") != 0)
122 )
123 {
124 //
125 // Open the file since we need that handle.
126 //
127 Status = gEfiShellProtocol->OpenFileByName (Walker->FullName, &Walker->Handle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE);
128 if (EFI_ERROR (Status)) {
129 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel3HiiHandle, L"touch", Walker->FullName);
130 Status = EFI_ACCESS_DENIED;
131 } else {
132 Status = DoTouchByHandle (Walker->FullName, FS, Walker->Handle, TRUE);
133 gEfiShellProtocol->CloseFile (Walker->Handle);
134 Walker->Handle = NULL;
135 }
136 }
137 }
138
139 //
140 // free stuff
141 //
142 if ((FileList != NULL) && EFI_ERROR (gEfiShellProtocol->FreeFileList (&FileList))) {
143 Status = EFI_INVALID_PARAMETER;
144 }
145 }
146
147 return (Status);
148 }
149
150 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
151 { L"-r", TypeFlag },
152 { NULL, TypeMax }
153 };
154
155 /**
156 Function for 'touch' command.
157
158 @param[in] ImageHandle Handle to the Image (NULL if Internal).
159 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
160 **/
161 SHELL_STATUS
162 EFIAPI
163 ShellCommandRunTouch (
164 IN EFI_HANDLE ImageHandle,
165 IN EFI_SYSTEM_TABLE *SystemTable
166 )
167 {
168 EFI_STATUS Status;
169 LIST_ENTRY *Package;
170 CHAR16 *ProblemParam;
171 CONST CHAR16 *Param;
172 SHELL_STATUS ShellStatus;
173 UINTN ParamCount;
174 EFI_SHELL_FILE_INFO *FileList;
175 EFI_SHELL_FILE_INFO *Node;
176
177 ProblemParam = NULL;
178 ShellStatus = SHELL_SUCCESS;
179 ParamCount = 0;
180 FileList = NULL;
181
182 //
183 // initialize the shell lib (we must be in non-auto-init...)
184 //
185 Status = ShellInitialize ();
186 ASSERT_EFI_ERROR (Status);
187
188 Status = CommandInit ();
189 ASSERT_EFI_ERROR (Status);
190
191 //
192 // parse the command line
193 //
194 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
195 if (EFI_ERROR (Status)) {
196 if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
197 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel3HiiHandle, L"touch", ProblemParam);
198 FreePool (ProblemParam);
199 ShellStatus = SHELL_INVALID_PARAMETER;
200 } else {
201 ASSERT (FALSE);
202 }
203 } else {
204 //
205 // check for "-?"
206 //
207 if (ShellCommandLineGetFlag (Package, L"-?")) {
208 ASSERT (FALSE);
209 }
210
211 if (ShellCommandLineGetRawValue (Package, 1) == NULL) {
212 //
213 // we insufficient parameters
214 //
215 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel3HiiHandle, L"touch");
216 ShellStatus = SHELL_INVALID_PARAMETER;
217 } else {
218 //
219 // get a list with each file specified by parameters
220 // if parameter is a directory then add all the files below it to the list
221 //
222 for ( ParamCount = 1, Param = ShellCommandLineGetRawValue (Package, ParamCount)
223 ; Param != NULL
224 ; ParamCount++, Param = ShellCommandLineGetRawValue (Package, ParamCount)
225 )
226 {
227 Status = ShellOpenFileMetaArg ((CHAR16 *)Param, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, &FileList);
228 if (EFI_ERROR (Status)) {
229 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel3HiiHandle, L"touch", (CHAR16 *)Param);
230 ShellStatus = SHELL_NOT_FOUND;
231 break;
232 }
233
234 //
235 // make sure we completed the param parsing sucessfully...
236 // Also make sure that any previous action was sucessful
237 //
238 if (ShellStatus == SHELL_SUCCESS) {
239 //
240 // check that we have at least 1 file
241 //
242 if ((FileList == NULL) || IsListEmpty (&FileList->Link)) {
243 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel3HiiHandle, L"touch", Param);
244 continue;
245 } else {
246 //
247 // loop through the list and make sure we are not aborting...
248 //
249 for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link)
250 ; !IsNull (&FileList->Link, &Node->Link) && !ShellGetExecutionBreakFlag ()
251 ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link)
252 )
253 {
254 //
255 // make sure the file opened ok
256 //
257 if (EFI_ERROR (Node->Status)) {
258 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel3HiiHandle, L"touch", Node->FileName);
259 ShellStatus = SHELL_NOT_FOUND;
260 continue;
261 }
262
263 Status = DoTouchByHandle (Node->FullName, NULL, Node->Handle, ShellCommandLineGetFlag (Package, L"-r"));
264 if (EFI_ERROR (Status) && (Status != EFI_ACCESS_DENIED)) {
265 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel3HiiHandle, L"touch", Node->FileName);
266 ShellStatus = SHELL_NOT_FOUND;
267 }
268 }
269 }
270 }
271
272 //
273 // Free the fileList
274 //
275 if ((FileList != NULL) && !IsListEmpty (&FileList->Link)) {
276 Status = ShellCloseFileMetaArg (&FileList);
277 ASSERT_EFI_ERROR (Status);
278 }
279
280 FileList = NULL;
281 }
282 }
283
284 //
285 // free the command line package
286 //
287 ShellCommandLineFreeVarList (Package);
288 }
289
290 if (ShellGetExecutionBreakFlag ()) {
291 return (SHELL_ABORTED);
292 }
293
294 return (ShellStatus);
295 }