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