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