]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellLevel2CommandsLib/TimeDate.c
EmulatorPkg: Remove framework pkgs dependency from EmulatorPkg
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / TimeDate.c
CommitLineData
a405b86d 1/** @file\r
2 Main file for time, timezone, and date shell level 2 and shell level 3 functions.\r
3\r
c011b6c9 4 (C) Copyright 2012-2015 Hewlett-Packard Development Company, L.P.<BR>\r
630cb850 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 "UefiShellLevel2CommandsLib.h"\r
11\r
b54fd049 12/**\r
13 Determine if String is a valid representation for a time or date.\r
14\r
15 @param[in] String The pointer to the string to test.\r
16 @param[in] Char The delimeter character.\r
17 @param[in] Min The minimum value allowed.\r
18 @param[in] Max The maximum value allowed.\r
19 @param[in] MinusOk Whether negative numbers are permitted.\r
a405b86d 20\r
b54fd049 21 @retval TRUE String is a valid representation.\r
22 @retval FALSE String is invalid.\r
23**/\r
a405b86d 24BOOLEAN\r
a405b86d 25InternalIsTimeLikeString (\r
26 IN CONST CHAR16 *String,\r
27 IN CONST CHAR16 Char,\r
28 IN CONST UINTN Min,\r
29 IN CONST UINTN Max,\r
30 IN CONST BOOLEAN MinusOk\r
31 )\r
32{\r
33 UINTN Count;\r
34 Count = 0;\r
35\r
36 if (MinusOk) {\r
37 //\r
38 // A single minus is ok.\r
39 //\r
40 if (*String == L'-') {\r
41 String++;\r
42 }\r
43 }\r
44\r
45 //\r
46 // the first char must be numeric.\r
47 //\r
48 if (!ShellIsDecimalDigitCharacter(*String)) {\r
49 return (FALSE);\r
50 }\r
51 //\r
52 // loop through the characters and use the lib function\r
53 //\r
54 for ( ; String != NULL && *String != CHAR_NULL ; String++){\r
55 if (*String == Char) {\r
56 Count++;\r
57 if (Count > Max) {\r
58 return (FALSE);\r
59 }\r
60 continue;\r
61 }\r
62 if (!ShellIsDecimalDigitCharacter(*String)) {\r
63 return (FALSE);\r
64 }\r
65 }\r
66 if (Count < Min) {\r
67 return (FALSE);\r
68 }\r
69 return (TRUE);\r
70}\r
71\r
b54fd049 72/**\r
ba0014b9 73 Verify that the DateString is valid and if so set that as the current\r
b54fd049 74 date.\r
75\r
76 @param[in] DateString The pointer to a string representation of the date.\r
77\r
78 @retval SHELL_INVALID_PARAMETER DateString was NULL.\r
79 @retval SHELL_INVALID_PARAMETER DateString was mis-formatted.\r
80 @retval SHELL_SUCCESS The operation was successful.\r
81**/\r
a405b86d 82SHELL_STATUS\r
a405b86d 83CheckAndSetDate (\r
84 IN CONST CHAR16 *DateString\r
85 )\r
86{\r
87 EFI_TIME TheTime;\r
88 EFI_STATUS Status;\r
b54fd049 89 CHAR16 *DateStringCopy;\r
90 CHAR16 *Walker;\r
91 CHAR16 *Walker1;\r
a405b86d 92\r
93 if (!InternalIsTimeLikeString(DateString, L'/', 2, 2, FALSE)) {\r
94 return (SHELL_INVALID_PARAMETER);\r
95 }\r
96\r
97 Status = gRT->GetTime(&TheTime, NULL);\r
35f26e73 98 if (EFI_ERROR(Status)) {\r
ba0014b9 99 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"date", L"gRT->GetTime", Status);\r
35f26e73 100 return (SHELL_DEVICE_ERROR);\r
101 }\r
a405b86d 102\r
b54fd049 103 DateStringCopy = NULL;\r
104 DateStringCopy = StrnCatGrow(&DateStringCopy, NULL, DateString, 0);\r
105 if (DateStringCopy == NULL) {\r
106 return (SHELL_OUT_OF_RESOURCES);\r
107 }\r
108 Walker = DateStringCopy;\r
a405b86d 109\r
110 TheTime.Month = 0xFF;\r
111 TheTime.Day = 0xFF;\r
112 TheTime.Year = 0xFFFF;\r
113\r
b54fd049 114 Walker1 = StrStr(Walker, L"/");\r
115 if (Walker1 != NULL && *Walker1 == L'/') {\r
116 *Walker1 = CHAR_NULL;\r
117 }\r
118\r
119 TheTime.Month = (UINT8)ShellStrToUintn (Walker);\r
120 if (Walker1 != NULL) {\r
121 Walker = Walker1 + 1;\r
122 }\r
33c031ee 123 Walker1 = Walker!=NULL?StrStr(Walker, L"/"):NULL;\r
b54fd049 124 if (Walker1 != NULL && *Walker1 == L'/') {\r
125 *Walker1 = CHAR_NULL;\r
a405b86d 126 }\r
127 if (Walker != NULL && Walker[0] != CHAR_NULL) {\r
b54fd049 128 TheTime.Day = (UINT8)ShellStrToUintn (Walker);\r
129 if (Walker1 != NULL) {\r
130 Walker = Walker1 + 1;\r
131 }\r
33c031ee 132 Walker1 = Walker!=NULL?StrStr(Walker, L"/"):NULL;\r
b54fd049 133 if (Walker1 != NULL && *Walker1 == L'/') {\r
134 *Walker1 = CHAR_NULL;\r
a405b86d 135 }\r
136 if (Walker != NULL && Walker[0] != CHAR_NULL) {\r
b54fd049 137 TheTime.Year = (UINT16)ShellStrToUintn (Walker);\r
a405b86d 138 }\r
139 }\r
140\r
141 if (TheTime.Year < 100) {\r
142 if (TheTime.Year >= 98) {\r
143 TheTime.Year = (UINT16)(1900 + TheTime.Year);\r
144 } else {\r
145 TheTime.Year = (UINT16)(2000 + TheTime.Year);\r
146 }\r
147 }\r
148\r
149 Status = gRT->SetTime(&TheTime);\r
150\r
151 if (!EFI_ERROR(Status)){\r
152 return (SHELL_SUCCESS);\r
153 }\r
154 return (SHELL_INVALID_PARAMETER);\r
155}\r
156\r
157/**\r
158 Function for 'date' command.\r
159\r
160 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
161 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
162**/\r
163SHELL_STATUS\r
164EFIAPI\r
165ShellCommandRunDate (\r
166 IN EFI_HANDLE ImageHandle,\r
167 IN EFI_SYSTEM_TABLE *SystemTable\r
168 )\r
169{\r
170 EFI_STATUS Status;\r
171 LIST_ENTRY *Package;\r
172 EFI_TIME TheTime;\r
173 CHAR16 *ProblemParam;\r
174 SHELL_STATUS ShellStatus;\r
beab0fc5 175 CONST CHAR16 *Param1;\r
a405b86d 176\r
177 ShellStatus = SHELL_SUCCESS;\r
178 ProblemParam = NULL;\r
179\r
180 //\r
181 // initialize the shell lib (we must be in non-auto-init...)\r
182 //\r
183 Status = ShellInitialize();\r
184 ASSERT_EFI_ERROR(Status);\r
185\r
186 //\r
187 // parse the command line\r
188 //\r
189 Status = ShellCommandLineParse (SfoParamList, &Package, &ProblemParam, TRUE);\r
190 if (EFI_ERROR(Status)) {\r
191 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
ba0014b9 192 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"date", ProblemParam);\r
a405b86d 193 FreePool(ProblemParam);\r
194 ShellStatus = SHELL_INVALID_PARAMETER;\r
195 } else {\r
196 ASSERT(FALSE);\r
197 }\r
198 } else {\r
199 //\r
200 // check for "-?"\r
201 //\r
202 if (ShellCommandLineGetFlag(Package, L"-?")) {\r
203 ASSERT(FALSE);\r
204 } else if (ShellCommandLineGetRawValue(Package, 2) != NULL) {\r
ba0014b9 205 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"date");\r
a405b86d 206 ShellStatus = SHELL_INVALID_PARAMETER;\r
207 } else {\r
208 //\r
209 // If there are 0 value parameters, then print the current date\r
210 // else If there are any value paramerers, then print error\r
211 //\r
212 if (ShellCommandLineGetRawValue(Package, 1) == NULL) {\r
213 //\r
214 // get the current date\r
215 //\r
216 Status = gRT->GetTime(&TheTime, NULL);\r
391206e7 217 if (EFI_ERROR(Status)) {\r
ba0014b9 218 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"date", L"gRT->GetTime", Status);\r
391206e7 219 return (SHELL_DEVICE_ERROR);\r
220 }\r
a405b86d 221\r
222 //\r
223 // ShellPrintEx the date in SFO or regular format\r
224 //\r
225 if (ShellCommandLineGetFlag(Package, L"-sfo")) {\r
deb21fd0
CP
226 //\r
227 // Match UEFI Shell spec:\r
228 // ShellCommand,"date"\r
229 // Date,"DD","MM","YYYY"\r
230 //\r
231 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellLevel2HiiHandle, L"date");\r
232 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DATE_SFO_FORMAT), gShellLevel2HiiHandle, TheTime.Day, TheTime.Month, TheTime.Year);\r
a405b86d 233 } else {\r
234 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DATE_FORMAT), gShellLevel2HiiHandle, TheTime.Month, TheTime.Day, TheTime.Year);\r
235 }\r
236 } else {\r
237 if (PcdGet8(PcdShellSupportLevel) == 2) {\r
ba0014b9 238 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"date");\r
a405b86d 239 ShellStatus = SHELL_INVALID_PARAMETER;\r
240 } else {\r
241 //\r
242 // perform level 3 operation here.\r
243 //\r
beab0fc5 244 Param1 = ShellCommandLineGetRawValue(Package, 1);\r
245 if (Param1 == NULL) {\r
246 ShellStatus = SHELL_INVALID_PARAMETER;\r
247 } else {\r
248 ShellStatus = CheckAndSetDate(Param1);\r
249 }\r
a405b86d 250 if (ShellStatus != SHELL_SUCCESS) {\r
ba0014b9 251 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"date", Param1);\r
a405b86d 252 ShellStatus = SHELL_INVALID_PARAMETER;\r
253 }\r
254 }\r
255 }\r
256 }\r
257 }\r
258 //\r
259 // free the command line package\r
260 //\r
261 ShellCommandLineFreeVarList (Package);\r
262\r
263 //\r
264 // return the status\r
265 //\r
266 return (ShellStatus);\r
267}\r
268\r
269//\r
270// Note "-tz" is invalid for this (non-interactive) version of 'time'.\r
271//\r
272STATIC CONST SHELL_PARAM_ITEM TimeParamList2[] = {\r
273 {L"-d", TypeValue},\r
274 {NULL, TypeMax}\r
275 };\r
276\r
277STATIC CONST SHELL_PARAM_ITEM TimeParamList3[] = {\r
278 {L"-d", TypeValue},\r
279 {L"-tz", TypeValue},\r
280 {NULL, TypeMax}\r
281 };\r
282\r
b54fd049 283/**\r
ba0014b9 284 Verify that the TimeString is valid and if so set that as the current\r
b54fd049 285 time.\r
286\r
287 @param[in] TimeString The pointer to a string representation of the time.\r
288 @param[in] Tz The value to set for TimeZone.\r
289 @param[in] Daylight The value to set for Daylight.\r
290\r
291 @retval SHELL_INVALID_PARAMETER TimeString was NULL.\r
292 @retval SHELL_INVALID_PARAMETER TimeString was mis-formatted.\r
293 @retval SHELL_SUCCESS The operation was successful.\r
294**/\r
a405b86d 295SHELL_STATUS\r
a405b86d 296CheckAndSetTime (\r
297 IN CONST CHAR16 *TimeString,\r
298 IN CONST INT16 Tz,\r
299 IN CONST UINT8 Daylight\r
300 )\r
301{\r
302 EFI_TIME TheTime;\r
303 EFI_STATUS Status;\r
b54fd049 304 CHAR16 *TimeStringCopy;\r
305 CHAR16 *Walker1;\r
306 CHAR16 *Walker2;\r
a405b86d 307\r
308 if (TimeString != NULL && !InternalIsTimeLikeString(TimeString, L':', 1, 2, FALSE)) {\r
309 return (SHELL_INVALID_PARAMETER);\r
310 }\r
f20076da 311 if (Daylight != 0xFF &&((Daylight & (EFI_TIME_IN_DAYLIGHT|EFI_TIME_ADJUST_DAYLIGHT)) != Daylight)) {\r
0841f3af 312 return (SHELL_INVALID_PARAMETER);\r
313 }\r
a405b86d 314\r
315 Status = gRT->GetTime(&TheTime, NULL);\r
391206e7 316 if (EFI_ERROR(Status)) {\r
ba0014b9 317 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"time", L"gRT->GetTime", Status);\r
391206e7 318 return (SHELL_DEVICE_ERROR);\r
319 }\r
a405b86d 320\r
321 if (TimeString != NULL) {\r
0841f3af 322 TimeStringCopy = NULL;\r
323 TimeStringCopy = StrnCatGrow(&TimeStringCopy, NULL, TimeString, 0);\r
b54fd049 324 Walker1 = TimeStringCopy;\r
a405b86d 325 TheTime.Hour = 0xFF;\r
326 TheTime.Minute = 0xFF;\r
327\r
33c031ee 328 Walker2 = Walker1!=NULL?StrStr(Walker1, L":"):NULL;\r
b54fd049 329 if (Walker2 != NULL && *Walker2 == L':') {\r
330 *Walker2 = CHAR_NULL;\r
a405b86d 331 }\r
b54fd049 332 TheTime.Hour = (UINT8)ShellStrToUintn (Walker1);\r
333 if (Walker2 != NULL) {\r
334 Walker1 = Walker2 + 1;\r
335 }\r
33c031ee 336 Walker2 = Walker1!=NULL?StrStr(Walker1, L":"):NULL;\r
b54fd049 337 if (Walker2 != NULL && *Walker2 == L':') {\r
338 *Walker2 = CHAR_NULL;\r
deb21fd0
CP
339 TheTime.Second = (UINT8)0;\r
340 }\r
341 else if (Walker2 == NULL) {\r
342 TheTime.Second = (UINT8)0;\r
b54fd049 343 }\r
344 if (Walker1 != NULL && Walker1[0] != CHAR_NULL) {\r
345 TheTime.Minute = (UINT8)ShellStrToUintn (Walker1);\r
346 if (Walker2 != NULL) {\r
347 Walker1 = Walker2 + 1;\r
deb21fd0
CP
348 if (Walker1 != NULL && Walker1[0] != CHAR_NULL) {\r
349 TheTime.Second = (UINT8)ShellStrToUintn (Walker1);\r
350 }\r
a405b86d 351 }\r
352 }\r
0841f3af 353 SHELL_FREE_NON_NULL(TimeStringCopy);\r
a405b86d 354 }\r
355\r
b54fd049 356\r
deb21fd0
CP
357 if (Tz >= -1440 && Tz <= 1440) {\r
358 //\r
359 // EFI_TIME TimeZone is stored to meet the following calculation (see UEFI Spec):\r
360 // Localtime = UTC - TimeZone\r
361 // This means the sign must be changed for the user provided Tz.\r
362 // EX: User wants to set TimeZone to Pacific Standard Time, so runs\r
363 // time -tz -480 # set to UTC-08:00\r
364 // To meet the calculation, the sign must be changed.\r
365 //\r
366 TheTime.TimeZone = -Tz;\r
367 } else if (Tz == EFI_UNSPECIFIED_TIMEZONE) {\r
a405b86d 368 TheTime.TimeZone = Tz;\r
369 }\r
0841f3af 370\r
f20076da 371 if (Daylight != 0xFF) {\r
372 TheTime.Daylight = Daylight;\r
373 }\r
0841f3af 374\r
a405b86d 375 Status = gRT->SetTime(&TheTime);\r
376\r
377 if (!EFI_ERROR(Status)){\r
378 return (SHELL_SUCCESS);\r
379 }\r
380\r
381 return (SHELL_INVALID_PARAMETER);\r
382}\r
383\r
384/**\r
385 Function for 'time' command.\r
386\r
387 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
388 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
389**/\r
390SHELL_STATUS\r
391EFIAPI\r
392ShellCommandRunTime (\r
393 IN EFI_HANDLE ImageHandle,\r
394 IN EFI_SYSTEM_TABLE *SystemTable\r
395 )\r
396{\r
397 EFI_STATUS Status;\r
398 LIST_ENTRY *Package;\r
a405b86d 399 EFI_TIME TheTime;\r
400 CHAR16 *ProblemParam;\r
401 SHELL_STATUS ShellStatus;\r
402 INT16 Tz;\r
403 UINT8 Daylight;\r
404 CONST CHAR16 *TempLocation;\r
405 UINTN TzMinutes;\r
406\r
a405b86d 407 //\r
408 // Initialize variables\r
409 //\r
e755a4ca 410 ShellStatus = SHELL_SUCCESS;\r
411 ProblemParam = NULL;\r
a405b86d 412\r
413 //\r
414 // initialize the shell lib (we must be in non-auto-init...)\r
415 //\r
416 Status = ShellInitialize();\r
417 ASSERT_EFI_ERROR(Status);\r
418\r
419 //\r
420 // parse the command line\r
421 //\r
422 if (PcdGet8(PcdShellSupportLevel) == 2) {\r
423 Status = ShellCommandLineParseEx (TimeParamList2, &Package, &ProblemParam, TRUE, TRUE);\r
424 } else {\r
425 ASSERT(PcdGet8(PcdShellSupportLevel) == 3);\r
426 Status = ShellCommandLineParseEx (TimeParamList3, &Package, &ProblemParam, TRUE, TRUE);\r
427 }\r
428 if (EFI_ERROR(Status)) {\r
429 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
ba0014b9 430 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"time", ProblemParam);\r
a405b86d 431 FreePool(ProblemParam);\r
432 ShellStatus = SHELL_INVALID_PARAMETER;\r
433 } else {\r
434 ASSERT(FALSE);\r
435 }\r
436 } else {\r
437 //\r
438 // check for "-?"\r
439 //\r
440 Status = gRT->GetTime(&TheTime, NULL);\r
391206e7 441 if (EFI_ERROR(Status)) {\r
ba0014b9 442 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"time", L"gRT->GetTime", Status);\r
391206e7 443 return (SHELL_DEVICE_ERROR);\r
444 }\r
445\r
a405b86d 446 if (ShellCommandLineGetFlag(Package, L"-?")) {\r
447 ASSERT(FALSE);\r
448 } else if (ShellCommandLineGetRawValue(Package, 2) != NULL) {\r
ba0014b9 449 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"time");\r
a405b86d 450 ShellStatus = SHELL_INVALID_PARAMETER;\r
451 } else {\r
452 //\r
453 // If there are no parameters, then print the current time\r
454 //\r
455 if (ShellCommandLineGetRawValue(Package, 1) == NULL\r
456 && !ShellCommandLineGetFlag(Package, L"-d")\r
457 && !ShellCommandLineGetFlag(Package, L"-tz")) {\r
458 //\r
459 // ShellPrintEx the current time\r
460 //\r
2e8e9ed5 461 if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) {\r
a405b86d 462 TzMinutes = 0;\r
463 } else {\r
b54fd049 464 TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
a405b86d 465 }\r
466\r
deb21fd0
CP
467 if (TheTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) {\r
468 ShellPrintHiiEx (\r
469 -1,\r
470 -1,\r
471 NULL,\r
472 STRING_TOKEN (STR_TIME_FORMAT),\r
473 gShellLevel2HiiHandle,\r
474 TheTime.Hour,\r
475 TheTime.Minute,\r
476 TheTime.Second,\r
477 (TheTime.TimeZone > 0?L"-":L"+"),\r
478 ((ABS(TheTime.TimeZone)) / 60),\r
479 TzMinutes\r
480 );\r
481 } else {\r
482 ShellPrintHiiEx (\r
483 -1,\r
484 -1,\r
485 NULL,\r
486 STRING_TOKEN (STR_TIME_FORMAT_LOCAL),\r
487 gShellLevel2HiiHandle,\r
488 TheTime.Hour,\r
489 TheTime.Minute,\r
490 TheTime.Second\r
491 );\r
492 }\r
493 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF), gShellLevel2HiiHandle);\r
a405b86d 494 } else if (ShellCommandLineGetFlag(Package, L"-d") && ShellCommandLineGetValue(Package, L"-d") == NULL) {\r
2e8e9ed5 495 if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) {\r
deb21fd0
CP
496 ShellPrintHiiEx (\r
497 -1,\r
498 -1,\r
499 NULL,\r
500 STRING_TOKEN (STR_TIME_FORMAT_LOCAL),\r
501 gShellLevel2HiiHandle,\r
502 TheTime.Hour,\r
503 TheTime.Minute,\r
504 TheTime.Second\r
505 );\r
a405b86d 506 } else {\r
b54fd049 507 TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
deb21fd0
CP
508 ShellPrintHiiEx (\r
509 -1,\r
510 -1,\r
511 NULL,\r
512 STRING_TOKEN (STR_TIME_FORMAT),\r
513 gShellLevel2HiiHandle,\r
514 TheTime.Hour,\r
515 TheTime.Minute,\r
516 TheTime.Second,\r
517 (TheTime.TimeZone > 0?L"-":L"+"),\r
518 ((ABS(TheTime.TimeZone)) / 60),\r
519 TzMinutes\r
520 );\r
a405b86d 521 }\r
a405b86d 522 switch (TheTime.Daylight) {\r
0841f3af 523 case 0:\r
524 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST0), gShellLevel2HiiHandle);\r
525 break;\r
a405b86d 526 case EFI_TIME_ADJUST_DAYLIGHT:\r
b54fd049 527 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST1), gShellLevel2HiiHandle);\r
a405b86d 528 break;\r
529 case EFI_TIME_IN_DAYLIGHT:\r
b54fd049 530 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST2), gShellLevel2HiiHandle);\r
531 break;\r
532 case EFI_TIME_IN_DAYLIGHT|EFI_TIME_ADJUST_DAYLIGHT:\r
533 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST3), gShellLevel2HiiHandle);\r
a405b86d 534 break;\r
535 default:\r
ba0014b9 536 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_ERROR), gShellLevel2HiiHandle, L"time", L"gRT->GetTime", L"TheTime.Daylight", TheTime.Daylight);\r
a405b86d 537 }\r
538 } else {\r
539 if (PcdGet8(PcdShellSupportLevel) == 2) {\r
ba0014b9 540 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"time");\r
a405b86d 541 ShellStatus = SHELL_INVALID_PARAMETER;\r
542 } else {\r
543 //\r
544 // perform level 3 operation here.\r
545 //\r
546 if ((TempLocation = ShellCommandLineGetValue(Package, L"-tz")) != NULL) {\r
630cb850 547 if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16 *)TempLocation, L"_local") == 0) {\r
deb21fd0
CP
548 Tz = EFI_UNSPECIFIED_TIMEZONE;\r
549 } else if (TempLocation[0] == L'-') {\r
550\r
551 Tz = (INT16) ShellStrToUintn (++TempLocation);\r
552 //\r
553 // When the argument of "time [-tz tz]" is not numeric, ShellStrToUintn() returns "-1".\r
554 // Here we can detect the argument error by checking the return of ShellStrToUintn().\r
555 //\r
556 if (Tz == -1) {\r
557 Tz = 1441; //make it to be out of bounds value\r
558 } else {\r
559 Tz *= (-1); //sign convert\r
560 }\r
a405b86d 561 } else {\r
deb21fd0
CP
562 if (TempLocation[0] == L'+') {\r
563 Tz = (INT16)ShellStrToUintn (++TempLocation);\r
564 } else {\r
565 Tz = (INT16)ShellStrToUintn (TempLocation);\r
566 }\r
567 //\r
568 // Detect the return of ShellStrToUintn() to make sure the argument is valid.\r
569 //\r
570 if (Tz == -1) {\r
571 Tz = 1441; //make it to be out of bounds value\r
572 }\r
a405b86d 573 }\r
2e8e9ed5 574 if (!(Tz >= -1440 && Tz <= 1440) && Tz != EFI_UNSPECIFIED_TIMEZONE) {\r
ba0014b9 575 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"time", TempLocation, L"-tz");\r
a405b86d 576 ShellStatus = SHELL_INVALID_PARAMETER;\r
577 }\r
578 } else {\r
579 //\r
580 // intentionally out of bounds value will prevent changing it...\r
581 //\r
582 Tz = 1441;\r
583 }\r
584 TempLocation = ShellCommandLineGetValue(Package, L"-d");\r
585 if (TempLocation != NULL) {\r
b54fd049 586 Daylight = (UINT8)ShellStrToUintn(TempLocation);\r
deb21fd0
CP
587 //\r
588 // The argument of "time [-d dl]" is unsigned, if the first character is '-',\r
589 // the argument is incorrect. That's because ShellStrToUintn() will skip past\r
590 // any '-' sign and convert what's next, forgetting the sign is here.\r
591 //\r
592 if (TempLocation[0] == '-') {\r
593 Daylight = 0xff; //make it invalid = will not use\r
594 }\r
a405b86d 595 if (Daylight != 0 && Daylight != 1 && Daylight != 3) {\r
ba0014b9 596 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"time", TempLocation, L"-d");\r
a405b86d 597 ShellStatus = SHELL_INVALID_PARAMETER;\r
598 }\r
599 } else {\r
600 //\r
601 // invalid = will not use\r
602 //\r
603 Daylight = 0xFF;\r
604 }\r
605 if (ShellStatus == SHELL_SUCCESS) {\r
606 ShellStatus = CheckAndSetTime(ShellCommandLineGetRawValue(Package, 1), Tz, Daylight);\r
607 if (ShellStatus != SHELL_SUCCESS) {\r
ba0014b9 608 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"time", ShellCommandLineGetRawValue(Package, 1));\r
a405b86d 609 ShellStatus = SHELL_INVALID_PARAMETER;\r
610 }\r
611 }\r
612 }\r
613 }\r
614 }\r
615 }\r
616\r
617 //\r
618 // free the command line package\r
619 //\r
620 ShellCommandLineFreeVarList (Package);\r
621\r
622 //\r
623 // return the status\r
624 //\r
625 return (ShellStatus);\r
626}\r
627\r
628typedef struct {\r
629 INT16 TimeZone;\r
630 EFI_STRING_ID StringId;\r
631} TIME_ZONE_ITEM;\r
632\r
633STATIC CONST SHELL_PARAM_ITEM TimeZoneParamList2[] = {\r
634 {L"-l", TypeFlag},\r
635 {L"-f", TypeFlag},\r
636 {NULL, TypeMax}\r
637 };\r
638STATIC CONST SHELL_PARAM_ITEM TimeZoneParamList3[] = {\r
639 {L"-l", TypeFlag},\r
640 {L"-f", TypeFlag},\r
658bf43e 641 {L"-s", TypeTimeValue},\r
a405b86d 642 {NULL, TypeMax}\r
643 };\r
644\r
645 STATIC CONST TIME_ZONE_ITEM TimeZoneList[] = {\r
646 {720, STRING_TOKEN (STR_TIMEZONE_M12)},\r
647 {660, STRING_TOKEN (STR_TIMEZONE_M11)},\r
648 {600, STRING_TOKEN (STR_TIMEZONE_M10)},\r
649 {540, STRING_TOKEN (STR_TIMEZONE_M9)},\r
650 {480, STRING_TOKEN (STR_TIMEZONE_M8)},\r
651 {420, STRING_TOKEN (STR_TIMEZONE_M7)},\r
652 {360, STRING_TOKEN (STR_TIMEZONE_M6)},\r
653 {300, STRING_TOKEN (STR_TIMEZONE_M5)},\r
654 {270, STRING_TOKEN (STR_TIMEZONE_M430)},\r
655 {240, STRING_TOKEN (STR_TIMEZONE_M4)},\r
656 {210, STRING_TOKEN (STR_TIMEZONE_M330)},\r
657 {180, STRING_TOKEN (STR_TIMEZONE_M3)},\r
658 {120, STRING_TOKEN (STR_TIMEZONE_M2)},\r
659 {60 , STRING_TOKEN (STR_TIMEZONE_M1)},\r
660 {0 , STRING_TOKEN (STR_TIMEZONE_0)},\r
661 {-60 , STRING_TOKEN (STR_TIMEZONE_P1)},\r
662 {-120 , STRING_TOKEN (STR_TIMEZONE_P2)},\r
663 {-180 , STRING_TOKEN (STR_TIMEZONE_P3)},\r
664 {-210 , STRING_TOKEN (STR_TIMEZONE_P330)},\r
665 {-240 , STRING_TOKEN (STR_TIMEZONE_P4)},\r
666 {-270 , STRING_TOKEN (STR_TIMEZONE_P430)},\r
667 {-300 , STRING_TOKEN (STR_TIMEZONE_P5)},\r
668 {-330 , STRING_TOKEN (STR_TIMEZONE_P530)},\r
669 {-345 , STRING_TOKEN (STR_TIMEZONE_P545)},\r
670 {-360 , STRING_TOKEN (STR_TIMEZONE_P6)},\r
671 {-390 , STRING_TOKEN (STR_TIMEZONE_P630)},\r
672 {-420 , STRING_TOKEN (STR_TIMEZONE_P7)},\r
673 {-480 , STRING_TOKEN (STR_TIMEZONE_P8)},\r
674 {-540 , STRING_TOKEN (STR_TIMEZONE_P9)},\r
675 {-570 , STRING_TOKEN (STR_TIMEZONE_P930)},\r
676 {-600 , STRING_TOKEN (STR_TIMEZONE_P10)},\r
677 {-660 , STRING_TOKEN (STR_TIMEZONE_P11)},\r
678 {-720 , STRING_TOKEN (STR_TIMEZONE_P12)},\r
679 {-780 , STRING_TOKEN (STR_TIMEZONE_P13)},\r
deb21fd0
CP
680 {-840 , STRING_TOKEN (STR_TIMEZONE_P14)},\r
681 {EFI_UNSPECIFIED_TIMEZONE, STRING_TOKEN (STR_TIMEZONE_LOCAL)}\r
b54fd049 682};\r
683\r
684/**\r
ba0014b9 685 Verify that the TimeZoneString is valid and if so set that as the current\r
b54fd049 686 timezone.\r
a405b86d 687\r
b54fd049 688 @param[in] TimeZoneString The pointer to a string representation of the timezone.\r
689\r
690 @retval SHELL_INVALID_PARAMETER TimeZoneString was NULL.\r
691 @retval SHELL_INVALID_PARAMETER TimeZoneString was mis-formatted.\r
692 @retval SHELL_SUCCESS The operation was successful.\r
693**/\r
a405b86d 694SHELL_STATUS\r
a405b86d 695CheckAndSetTimeZone (\r
696 IN CONST CHAR16 *TimeZoneString\r
697 )\r
698{\r
699 EFI_TIME TheTime;\r
700 EFI_STATUS Status;\r
b54fd049 701 CHAR16 *TimeZoneCopy;\r
702 CHAR16 *Walker;\r
703 CHAR16 *Walker2;\r
a405b86d 704 UINTN LoopVar;\r
705\r
706 if (TimeZoneString == NULL) {\r
707 return (SHELL_INVALID_PARAMETER);\r
708 }\r
709\r
630cb850 710 if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16 *)TimeZoneString, L"_local") == 0) {\r
deb21fd0
CP
711 Status = gRT->GetTime (&TheTime, NULL);\r
712 if (EFI_ERROR (Status)) {\r
713 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"gRT->GetTime", Status);\r
714 return (SHELL_DEVICE_ERROR);\r
715 }\r
716\r
717 TheTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE;\r
718 Status = gRT->SetTime (&TheTime);\r
719 if (!EFI_ERROR(Status)){\r
720 return (SHELL_SUCCESS);\r
721 }\r
722 return (SHELL_INVALID_PARAMETER);\r
723 }\r
a405b86d 724 if (TimeZoneString != NULL && !InternalIsTimeLikeString(TimeZoneString, L':', 1, 1, TRUE)) {\r
725 return (SHELL_INVALID_PARAMETER);\r
726 }\r
727\r
728 Status = gRT->GetTime(&TheTime, NULL);\r
532691c8 729 if (EFI_ERROR(Status)) {\r
ba0014b9 730 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"timezone", L"gRT->GetTime", Status);\r
532691c8 731 return (SHELL_DEVICE_ERROR);\r
732 }\r
a405b86d 733\r
b54fd049 734 TimeZoneCopy = NULL;\r
735 TimeZoneCopy = StrnCatGrow(&TimeZoneCopy, NULL, TimeZoneString, 0);\r
532691c8 736 if (TimeZoneCopy == NULL) {\r
737 return (SHELL_OUT_OF_RESOURCES);\r
738 }\r
b54fd049 739 Walker = TimeZoneCopy;\r
740 Walker2 = StrStr(Walker, L":");\r
741 if (Walker2 != NULL && *Walker2 == L':') {\r
742 *Walker2 = CHAR_NULL;\r
743 }\r
a405b86d 744 if (*Walker == L'-') {\r
b54fd049 745 TheTime.TimeZone = (INT16)((ShellStrToUintn (++Walker)) * 60);\r
a405b86d 746 } else {\r
28981267 747 TheTime.TimeZone = (INT16)((INT16)(ShellStrToUintn (Walker)) * -60);\r
a405b86d 748 }\r
b54fd049 749 if (Walker2 != NULL) {\r
750 Walker = Walker2 + 1;\r
a405b86d 751 }\r
752 if (Walker != NULL && Walker[0] != CHAR_NULL) {\r
753 if (TheTime.TimeZone < 0) {\r
b54fd049 754 TheTime.TimeZone = (INT16)(TheTime.TimeZone - (UINT8)ShellStrToUintn (Walker));\r
a405b86d 755 } else {\r
b54fd049 756 TheTime.TimeZone = (INT16)(TheTime.TimeZone + (UINT8)ShellStrToUintn (Walker));\r
a405b86d 757 }\r
758 }\r
759\r
760 Status = EFI_INVALID_PARAMETER;\r
761\r
762 for ( LoopVar = 0\r
763 ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0])\r
764 ; LoopVar++\r
765 ){\r
766 if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) {\r
767 Status = gRT->SetTime(&TheTime);\r
768 break;\r
769 }\r
770 }\r
771\r
b54fd049 772 FreePool(TimeZoneCopy);\r
773\r
a405b86d 774 if (!EFI_ERROR(Status)){\r
775 return (SHELL_SUCCESS);\r
776 }\r
777 return (SHELL_INVALID_PARAMETER);\r
778}\r
779\r
780\r
781/**\r
782 Function for 'timezone' command.\r
783\r
784 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
785 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
786**/\r
787SHELL_STATUS\r
788EFIAPI\r
789ShellCommandRunTimeZone (\r
790 IN EFI_HANDLE ImageHandle,\r
791 IN EFI_SYSTEM_TABLE *SystemTable\r
792 )\r
793{\r
794 //\r
795 // non interactive\r
796 //\r
797 EFI_STATUS Status;\r
798 LIST_ENTRY *Package;\r
799 CHAR16 *ProblemParam;\r
800 SHELL_STATUS ShellStatus;\r
801 UINT8 LoopVar;\r
802 EFI_TIME TheTime;\r
803 BOOLEAN Found;\r
804 UINTN TzMinutes;\r
805\r
806 ShellStatus = SHELL_SUCCESS;\r
807 ProblemParam = NULL;\r
808\r
809 //\r
810 // initialize the shell lib (we must be in non-auto-init...)\r
811 //\r
812 Status = ShellInitialize();\r
813 ASSERT_EFI_ERROR(Status);\r
814\r
815 //\r
816 // parse the command line\r
817 //\r
818 if (PcdGet8(PcdShellSupportLevel) == 2) {\r
8f04ca1a 819 Status = ShellCommandLineParse (TimeZoneParamList2, &Package, &ProblemParam, TRUE);\r
a405b86d 820 } else {\r
821 ASSERT(PcdGet8(PcdShellSupportLevel) == 3);\r
8f04ca1a 822 Status = ShellCommandLineParseEx (TimeZoneParamList3, &Package, &ProblemParam, TRUE, TRUE);\r
a405b86d 823 }\r
824 if (EFI_ERROR(Status)) {\r
825 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
ba0014b9 826 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"timezone", ProblemParam);\r
a405b86d 827 FreePool(ProblemParam);\r
828 ShellStatus = SHELL_INVALID_PARAMETER;\r
829 } else {\r
830 ASSERT(FALSE);\r
831 }\r
832 } else {\r
833 //\r
834 // check for "-?"\r
835 //\r
836 if (ShellCommandLineGetCount(Package) > 1) {\r
ba0014b9 837 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"timezone");\r
a405b86d 838 ShellStatus = SHELL_INVALID_PARAMETER;\r
839 } else if (ShellCommandLineGetFlag(Package, L"-?")) {\r
840 ASSERT(FALSE);\r
841 } else if (ShellCommandLineGetFlag(Package, L"-s")) {\r
842 if ((ShellCommandLineGetFlag(Package, L"-l")) || (ShellCommandLineGetFlag(Package, L"-f"))) {\r
ba0014b9 843 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"timezone", L"-l or -f");\r
a405b86d 844 ShellStatus = SHELL_INVALID_PARAMETER;\r
845 } else {\r
846 ASSERT(PcdGet8(PcdShellSupportLevel) == 3);\r
847 if (ShellCommandLineGetValue(Package, L"-s") == NULL) {\r
ba0014b9 848 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"timezone", L"-s");\r
a405b86d 849 ShellStatus = SHELL_INVALID_PARAMETER;\r
850 } else {\r
851 //\r
852 // Set the time zone\r
853 //\r
854 ShellStatus = CheckAndSetTimeZone(ShellCommandLineGetValue(Package, L"-s"));\r
855 if (ShellStatus != SHELL_SUCCESS) {\r
ba0014b9 856 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"timezone", ShellCommandLineGetValue(Package, L"-s"));\r
a405b86d 857 ShellStatus = SHELL_INVALID_PARAMETER;\r
858 }\r
859 }\r
860 }\r
861 } else if (ShellCommandLineGetFlag(Package, L"-l")) {\r
862 //\r
863 // Print a list of all time zones\r
864 //\r
865 for ( LoopVar = 0\r
866 ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0])\r
867 ; LoopVar++\r
868 ){\r
869 ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle);\r
870 }\r
871 } else {\r
872 //\r
873 // Get Current Time Zone Info\r
874 //\r
875 Status = gRT->GetTime(&TheTime, NULL);\r
391206e7 876 if (EFI_ERROR(Status)) {\r
ba0014b9 877 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"timezone", L"gRT->GetTime", Status);\r
391206e7 878 return (SHELL_DEVICE_ERROR);\r
879 }\r
a405b86d 880\r
2e8e9ed5 881 if (TheTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) {\r
a405b86d 882 Found = FALSE;\r
883 for ( LoopVar = 0\r
884 ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0])\r
885 ; LoopVar++\r
886 ){\r
887 if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) {\r
888 if (ShellCommandLineGetFlag(Package, L"-f")) {\r
889 //\r
890 // Print all info about current time zone\r
891 //\r
892 ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle);\r
893 } else {\r
894 //\r
895 // Print basic info only\r
896 //\r
deb21fd0 897 TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
a405b86d 898\r
899 ShellPrintHiiEx (\r
900 -1,\r
901 -1,\r
902 NULL,\r
903 STRING_TOKEN(STR_TIMEZONE_SIMPLE),\r
904 gShellLevel2HiiHandle,\r
deb21fd0
CP
905 (TheTime.TimeZone > 0?L"-":L"+"),\r
906 (ABS(TheTime.TimeZone)) / 60,\r
a405b86d 907 TzMinutes);\r
908 }\r
909 Found = TRUE;\r
910 break;\r
911 }\r
912 }\r
913 if (!Found) {\r
914 //\r
915 // Print basic info only\r
916 //\r
deb21fd0
CP
917 TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
918\r
a405b86d 919 ShellPrintHiiEx (\r
920 -1,\r
921 -1,\r
922 NULL,\r
923 STRING_TOKEN(STR_TIMEZONE_SIMPLE),\r
924 gShellLevel2HiiHandle,\r
deb21fd0
CP
925 (TheTime.TimeZone > 0?L"-":L"+"),\r
926 (ABS(TheTime.TimeZone)) / 60,\r
a405b86d 927 TzMinutes);\r
deb21fd0 928\r
a405b86d 929 if (ShellCommandLineGetFlag(Package, L"-f")) {\r
930 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_TIMEZONE_NI), gShellLevel2HiiHandle);\r
931 }\r
932 }\r
933 } else {\r
934 //\r
deb21fd0 935 // TimeZone was EFI_UNSPECIFIED_TIMEZONE (local) from GetTime()\r
a405b86d 936 //\r
deb21fd0
CP
937 if (ShellCommandLineGetFlag (Package, L"-f")) {\r
938 for ( LoopVar = 0\r
fe6c62fc 939 ; LoopVar < ARRAY_SIZE (TimeZoneList)\r
deb21fd0
CP
940 ; LoopVar++\r
941 ){\r
942 if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) {\r
943 //\r
944 // Print all info about current time zone\r
945 //\r
946 ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle);\r
947 break;\r
ba0014b9 948 }\r
deb21fd0
CP
949 }\r
950 } else {\r
951 //\r
952 // Print basic info only\r
953 //\r
954 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TIMEZONE_SIMPLE_LOCAL), gShellLevel2HiiHandle);\r
955 }\r
a405b86d 956 }\r
957 }\r
958 }\r
959\r
960 //\r
961 // free the command line package\r
962 //\r
963 ShellCommandLineFreeVarList (Package);\r
964\r
965 return (ShellStatus);\r
966}\r