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