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