2 Main file for Touch shell level 3 function.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved. <BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "UefiShellLevel3CommandsLib.h"
18 #include <Library/ShellLib.h>
21 Do the touch operation on a single handle.
23 @param[in] Handle The handle to update the date/time on.
25 @retval EFI_ACCESS_DENIED The file referenced by Handle is read only.
26 @retval EFI_SUCCESS The operation was successful.
35 EFI_FILE_INFO
*FileInfo
;
37 FileInfo
= gEfiShellProtocol
->GetFileInfo(Handle
);
38 if ((FileInfo
->Attribute
& EFI_FILE_READ_ONLY
) != 0){
39 return (EFI_ACCESS_DENIED
);
41 Status
= gRT
->GetTime(&FileInfo
->ModificationTime
, NULL
);
42 if (EFI_ERROR(Status
)) {
43 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel3HiiHandle
, L
"gRT->GetTime", Status
);
44 return (SHELL_DEVICE_ERROR
);
47 CopyMem(&FileInfo
->LastAccessTime
, &FileInfo
->ModificationTime
, sizeof(EFI_TIME
));
49 Status
= gEfiShellProtocol
->SetFileInfo(Handle
, FileInfo
);
57 Touch a given file and potantially recurse down if it was a directory.
59 @param[in] Name The name of this file.
60 @param[in] FS The name of the file system this file is on.
61 @param[in] Handle The handle of this file already opened.
62 @param[in] Rec TRUE to recurse if possible.
64 @retval EFI_INVALID_PARAMETER A parameter was invalid.
65 @retval EFI_SUCCESS The operation was successful.
70 IN CONST CHAR16
*Name
,
72 IN SHELL_FILE_HANDLE Handle
,
77 EFI_SHELL_FILE_INFO
*FileList
;
78 EFI_SHELL_FILE_INFO
*Walker
;
86 FS
= StrnCatGrow(&FS
, NULL
, Name
, 0);
88 TempSpot
= StrStr(FS
, L
"\\");
89 if (TempSpot
!= NULL
) {
90 *TempSpot
= CHAR_NULL
;
95 return (EFI_INVALID_PARAMETER
);
101 Status
= TouchFileByHandle(Handle
);
102 if (EFI_ERROR(Status
)) {
103 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellLevel3HiiHandle
, L
"touch", Name
);
108 // if it's a directory recurse...
110 if (FileHandleIsDirectory(Handle
) == EFI_SUCCESS
&& Rec
) {
112 // get each file under this directory
114 if (EFI_ERROR(gEfiShellProtocol
->FindFilesInDir(Handle
, &FileList
))) {
115 Status
= EFI_INVALID_PARAMETER
;
121 for (Walker
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
)
122 ; FileList
!= NULL
&& !IsNull(&FileList
->Link
, &Walker
->Link
) && !EFI_ERROR(Status
)
123 ; Walker
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&FileList
->Link
, &Walker
->Link
)
125 if ( (StrCmp(Walker
->FileName
, L
".") != 0)
126 && (StrCmp(Walker
->FileName
, L
"..") != 0)
129 // Open the file since we need that handle.
131 Status
= gEfiShellProtocol
->OpenFileByName (Walker
->FullName
, &Walker
->Handle
, EFI_FILE_MODE_READ
|EFI_FILE_MODE_WRITE
);
132 if (EFI_ERROR(Status
)) {
133 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellLevel3HiiHandle
, L
"touch", Walker
->FullName
);
134 Status
= EFI_ACCESS_DENIED
;
136 Status
= DoTouchByHandle(Walker
->FullName
, FS
, Walker
->Handle
, TRUE
);
137 gEfiShellProtocol
->CloseFile(Walker
->Handle
);
138 Walker
->Handle
= NULL
;
146 if (FileList
!= NULL
&& EFI_ERROR(gEfiShellProtocol
->FreeFileList(&FileList
))) {
147 Status
= EFI_INVALID_PARAMETER
;
154 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
160 Function for 'touch' command.
162 @param[in] ImageHandle Handle to the Image (NULL if Internal).
163 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
167 ShellCommandRunTouch (
168 IN EFI_HANDLE ImageHandle
,
169 IN EFI_SYSTEM_TABLE
*SystemTable
174 CHAR16
*ProblemParam
;
176 SHELL_STATUS ShellStatus
;
178 EFI_SHELL_FILE_INFO
*FileList
;
179 EFI_SHELL_FILE_INFO
*Node
;
182 ShellStatus
= SHELL_SUCCESS
;
187 // initialize the shell lib (we must be in non-auto-init...)
189 Status
= ShellInitialize();
190 ASSERT_EFI_ERROR(Status
);
192 Status
= CommandInit();
193 ASSERT_EFI_ERROR(Status
);
196 // parse the command line
198 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
199 if (EFI_ERROR(Status
)) {
200 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
201 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel3HiiHandle
, L
"touch", ProblemParam
);
202 FreePool(ProblemParam
);
203 ShellStatus
= SHELL_INVALID_PARAMETER
;
211 if (ShellCommandLineGetFlag(Package
, L
"-?")) {
214 if (ShellCommandLineGetRawValue(Package
, 1) == NULL
) {
216 // we insufficient parameters
218 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel3HiiHandle
, L
"touch");
219 ShellStatus
= SHELL_INVALID_PARAMETER
;
222 // get a list with each file specified by parameters
223 // if parameter is a directory then add all the files below it to the list
225 for ( ParamCount
= 1, Param
= ShellCommandLineGetRawValue(Package
, ParamCount
)
227 ; ParamCount
++, Param
= ShellCommandLineGetRawValue(Package
, ParamCount
)
229 Status
= ShellOpenFileMetaArg((CHAR16
*)Param
, EFI_FILE_MODE_READ
|EFI_FILE_MODE_WRITE
, &FileList
);
230 if (EFI_ERROR(Status
)) {
231 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellLevel3HiiHandle
, L
"touch", (CHAR16
*)Param
);
232 ShellStatus
= SHELL_NOT_FOUND
;
236 // make sure we completed the param parsing sucessfully...
237 // Also make sure that any previous action was sucessful
239 if (ShellStatus
== SHELL_SUCCESS
) {
241 // check that we have at least 1 file
243 if (FileList
== NULL
|| IsListEmpty(&FileList
->Link
)) {
244 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_NF
), gShellLevel3HiiHandle
, L
"touch", Param
);
248 // loop through the list and make sure we are not aborting...
250 for ( Node
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
)
251 ; !IsNull(&FileList
->Link
, &Node
->Link
) && !ShellGetExecutionBreakFlag()
252 ; 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
;
274 if (FileList
!= NULL
&& !IsListEmpty(&FileList
->Link
)) {
275 Status
= ShellCloseFileMetaArg(&FileList
);
276 ASSERT_EFI_ERROR(Status
);
283 // free the command line package
285 ShellCommandLineFreeVarList (Package
);
288 if (ShellGetExecutionBreakFlag()) {
289 return (SHELL_ABORTED
);
292 return (ShellStatus
);