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