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