2 Main file for Touch shell level 3 function.
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
10 #include "UefiShellLevel3CommandsLib.h"
12 #include <Library/ShellLib.h>
15 Do the touch operation on a single handle.
17 @param[in] Handle The handle to update the date/time on.
19 @retval EFI_ACCESS_DENIED The file referenced by Handle is read only.
20 @retval EFI_SUCCESS The operation was successful.
24 IN SHELL_FILE_HANDLE Handle
28 EFI_FILE_INFO
*FileInfo
;
30 FileInfo
= gEfiShellProtocol
->GetFileInfo (Handle
);
31 if ((FileInfo
->Attribute
& EFI_FILE_READ_ONLY
) != 0) {
32 return (EFI_ACCESS_DENIED
);
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
);
41 CopyMem (&FileInfo
->LastAccessTime
, &FileInfo
->ModificationTime
, sizeof (EFI_TIME
));
43 Status
= gEfiShellProtocol
->SetFileInfo (Handle
, FileInfo
);
51 Touch a given file and potantially recurse down if it was a directory.
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.
58 @retval EFI_INVALID_PARAMETER A parameter was invalid.
59 @retval EFI_SUCCESS The operation was successful.
63 IN CONST CHAR16
*Name
,
65 IN SHELL_FILE_HANDLE Handle
,
70 EFI_SHELL_FILE_INFO
*FileList
;
71 EFI_SHELL_FILE_INFO
*Walker
;
79 FS
= StrnCatGrow (&FS
, NULL
, Name
, 0);
81 TempSpot
= StrStr (FS
, L
"\\");
82 if (TempSpot
!= NULL
) {
83 *TempSpot
= CHAR_NULL
;
89 return (EFI_INVALID_PARAMETER
);
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
);
102 // if it's a directory recurse...
104 if ((FileHandleIsDirectory (Handle
) == EFI_SUCCESS
) && Rec
) {
106 // get each file under this directory
108 if (EFI_ERROR (gEfiShellProtocol
->FindFilesInDir (Handle
, &FileList
))) {
109 Status
= EFI_INVALID_PARAMETER
;
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
)
120 if ( (StrCmp (Walker
->FileName
, L
".") != 0)
121 && (StrCmp (Walker
->FileName
, L
"..") != 0)
125 // Open the file since we need that handle.
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
;
132 Status
= DoTouchByHandle (Walker
->FullName
, FS
, Walker
->Handle
, TRUE
);
133 gEfiShellProtocol
->CloseFile (Walker
->Handle
);
134 Walker
->Handle
= NULL
;
142 if ((FileList
!= NULL
) && EFI_ERROR (gEfiShellProtocol
->FreeFileList (&FileList
))) {
143 Status
= EFI_INVALID_PARAMETER
;
150 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
156 Function for 'touch' command.
158 @param[in] ImageHandle Handle to the Image (NULL if Internal).
159 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
163 ShellCommandRunTouch (
164 IN EFI_HANDLE ImageHandle
,
165 IN EFI_SYSTEM_TABLE
*SystemTable
170 CHAR16
*ProblemParam
;
172 SHELL_STATUS ShellStatus
;
174 EFI_SHELL_FILE_INFO
*FileList
;
175 EFI_SHELL_FILE_INFO
*Node
;
178 ShellStatus
= SHELL_SUCCESS
;
183 // initialize the shell lib (we must be in non-auto-init...)
185 Status
= ShellInitialize ();
186 ASSERT_EFI_ERROR (Status
);
188 Status
= CommandInit ();
189 ASSERT_EFI_ERROR (Status
);
192 // parse the command line
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
;
207 if (ShellCommandLineGetFlag (Package
, L
"-?")) {
211 if (ShellCommandLineGetRawValue (Package
, 1) == NULL
) {
213 // we insufficient parameters
215 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel3HiiHandle
, L
"touch");
216 ShellStatus
= SHELL_INVALID_PARAMETER
;
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
222 for ( ParamCount
= 1, Param
= ShellCommandLineGetRawValue (Package
, ParamCount
)
224 ; ParamCount
++, Param
= ShellCommandLineGetRawValue (Package
, ParamCount
)
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
;
235 // make sure we completed the param parsing sucessfully...
236 // Also make sure that any previous action was sucessful
238 if (ShellStatus
== SHELL_SUCCESS
) {
240 // check that we have at least 1 file
242 if ((FileList
== NULL
) || IsListEmpty (&FileList
->Link
)) {
243 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_NF
), gShellLevel3HiiHandle
, L
"touch", Param
);
247 // loop through the list and make sure we are not aborting...
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
)
255 // make sure the file opened ok
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
;
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
;
275 if ((FileList
!= NULL
) && !IsListEmpty (&FileList
->Link
)) {
276 Status
= ShellCloseFileMetaArg (&FileList
);
277 ASSERT_EFI_ERROR (Status
);
285 // free the command line package
287 ShellCommandLineFreeVarList (Package
);
290 if (ShellGetExecutionBreakFlag ()) {
291 return (SHELL_ABORTED
);
294 return (ShellStatus
);