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