From deb21fd0ea32eee860768ae309bf4e06e7edaea9 Mon Sep 17 00:00:00 2001 From: Chris Phillips Date: Tue, 19 Aug 2014 23:05:44 +0000 Subject: ShellPkg: Fixes for timezone handling and 'date -sfo' - Update 'date -sfo' format to match UEFI Shell 2.1 spec - Fixes to correctly initialize Second - Set correct sign when setting timezone with the 'time -tz' command. Now matches UEFI spec calculation of "Localtime = UTC - TimeZone" - Display "LOCAL" when TimeZone == EFI_UNSPECIFIED_TIMEZONE - Allow a timezone of '_local' to be provided by user - Better invalid command line checking Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Chris Phillips Reviewed-by: Jaben Carsey git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15840 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Library/UefiShellLevel2CommandsLib/TimeDate.c | 206 +++++++++++++++------ .../UefiShellLevel2CommandsLib.uni | Bin 112782 -> 113210 bytes 2 files changed, 153 insertions(+), 53 deletions(-) (limited to 'ShellPkg/Library/UefiShellLevel2CommandsLib') diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/TimeDate.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/TimeDate.c index b8535139db..24dcae4682 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/TimeDate.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/TimeDate.c @@ -1,6 +1,7 @@ /** @file Main file for time, timezone, and date shell level 2 and shell level 3 functions. + (C) Copyright 2012-2014, Hewlett-Packard Development Company, L.P. Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -230,7 +231,13 @@ ShellCommandRunDate ( // ShellPrintEx the date in SFO or regular format // if (ShellCommandLineGetFlag(Package, L"-sfo")) { - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DATE_SFO_FORMAT), gShellLevel2HiiHandle, TheTime.Month, TheTime.Day, TheTime.Year); + // + // Match UEFI Shell spec: + // ShellCommand,"date" + // Date,"DD","MM","YYYY" + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellLevel2HiiHandle, L"date"); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DATE_SFO_FORMAT), gShellLevel2HiiHandle, TheTime.Day, TheTime.Month, TheTime.Year); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DATE_FORMAT), gShellLevel2HiiHandle, TheTime.Month, TheTime.Day, TheTime.Year); } @@ -338,21 +345,35 @@ CheckAndSetTime ( Walker2 = Walker1!=NULL?StrStr(Walker1, L":"):NULL; if (Walker2 != NULL && *Walker2 == L':') { *Walker2 = CHAR_NULL; + TheTime.Second = (UINT8)0; + } + else if (Walker2 == NULL) { + TheTime.Second = (UINT8)0; } if (Walker1 != NULL && Walker1[0] != CHAR_NULL) { TheTime.Minute = (UINT8)ShellStrToUintn (Walker1); if (Walker2 != NULL) { Walker1 = Walker2 + 1; - } - if (Walker1 != NULL && Walker1[0] != CHAR_NULL) { - TheTime.Second = (UINT8)ShellStrToUintn (Walker1); + if (Walker1 != NULL && Walker1[0] != CHAR_NULL) { + TheTime.Second = (UINT8)ShellStrToUintn (Walker1); + } } } SHELL_FREE_NON_NULL(TimeStringCopy); } - if ((Tz >= -1440 && Tz <= 1440)||(Tz == 0x7FF)) { + if (Tz >= -1440 && Tz <= 1440) { + // + // EFI_TIME TimeZone is stored to meet the following calculation (see UEFI Spec): + // Localtime = UTC - TimeZone + // This means the sign must be changed for the user provided Tz. + // EX: User wants to set TimeZone to Pacific Standard Time, so runs + // time -tz -480 # set to UTC-08:00 + // To meet the calculation, the sign must be changed. + // + TheTime.TimeZone = -Tz; + } else if (Tz == EFI_UNSPECIFIED_TIMEZONE) { TheTime.TimeZone = Tz; } @@ -452,40 +473,61 @@ ShellCommandRunTime ( TzMinutes = (ABS(TheTime.TimeZone)) % 60; } - ShellPrintHiiEx ( - -1, - -1, - NULL, - STRING_TOKEN (STR_TIME_FORMAT), - gShellLevel2HiiHandle, - TheTime.Hour, - TheTime.Minute, - TheTime.Second, - TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?L" ":(TheTime.TimeZone > 0?L"-":L"+"), - TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(ABS(TheTime.TimeZone)) / 60, - TzMinutes - ); - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF), gShellLevel2HiiHandle); + if (TheTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TIME_FORMAT), + gShellLevel2HiiHandle, + TheTime.Hour, + TheTime.Minute, + TheTime.Second, + (TheTime.TimeZone > 0?L"-":L"+"), + ((ABS(TheTime.TimeZone)) / 60), + TzMinutes + ); + } else { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TIME_FORMAT_LOCAL), + gShellLevel2HiiHandle, + TheTime.Hour, + TheTime.Minute, + TheTime.Second + ); + } + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF), gShellLevel2HiiHandle); } else if (ShellCommandLineGetFlag(Package, L"-d") && ShellCommandLineGetValue(Package, L"-d") == NULL) { if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) { - TzMinutes = 0; + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TIME_FORMAT_LOCAL), + gShellLevel2HiiHandle, + TheTime.Hour, + TheTime.Minute, + TheTime.Second + ); } else { TzMinutes = (ABS(TheTime.TimeZone)) % 60; + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TIME_FORMAT), + gShellLevel2HiiHandle, + TheTime.Hour, + TheTime.Minute, + TheTime.Second, + (TheTime.TimeZone > 0?L"-":L"+"), + ((ABS(TheTime.TimeZone)) / 60), + TzMinutes + ); } - - ShellPrintHiiEx ( - -1, - -1, - NULL, - STRING_TOKEN (STR_TIME_FORMAT), - gShellLevel2HiiHandle, - TheTime.Hour, - TheTime.Minute, - TheTime.Second, - TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?L" ":(TheTime.TimeZone > 0?L"-":L"+"), - TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(ABS(TheTime.TimeZone)) / 60, - TzMinutes - ); switch (TheTime.Daylight) { case 0: ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST0), gShellLevel2HiiHandle); @@ -511,10 +553,32 @@ ShellCommandRunTime ( // perform level 3 operation here. // if ((TempLocation = ShellCommandLineGetValue(Package, L"-tz")) != NULL) { - if (TempLocation[0] == L'-') { - Tz = (INT16)(0 - ShellStrToUintn(++TempLocation)); + if (StrniCmp (TempLocation, L"_local", StrLen (TempLocation)) == NULL) { + Tz = EFI_UNSPECIFIED_TIMEZONE; + } else if (TempLocation[0] == L'-') { + + Tz = (INT16) ShellStrToUintn (++TempLocation); + // + // When the argument of "time [-tz tz]" is not numeric, ShellStrToUintn() returns "-1". + // Here we can detect the argument error by checking the return of ShellStrToUintn(). + // + if (Tz == -1) { + Tz = 1441; //make it to be out of bounds value + } else { + Tz *= (-1); //sign convert + } } else { - Tz = (INT16)ShellStrToUintn(TempLocation); + if (TempLocation[0] == L'+') { + Tz = (INT16)ShellStrToUintn (++TempLocation); + } else { + Tz = (INT16)ShellStrToUintn (TempLocation); + } + // + // Detect the return of ShellStrToUintn() to make sure the argument is valid. + // + if (Tz == -1) { + Tz = 1441; //make it to be out of bounds value + } } if (!(Tz >= -1440 && Tz <= 1440) && Tz != EFI_UNSPECIFIED_TIMEZONE) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"-tz"); @@ -529,6 +593,14 @@ ShellCommandRunTime ( TempLocation = ShellCommandLineGetValue(Package, L"-d"); if (TempLocation != NULL) { Daylight = (UINT8)ShellStrToUintn(TempLocation); + // + // The argument of "time [-d dl]" is unsigned, if the first character is '-', + // the argument is incorrect. That's because ShellStrToUintn() will skip past + // any '-' sign and convert what's next, forgetting the sign is here. + // + if (TempLocation[0] == '-') { + Daylight = 0xff; //make it invalid = will not use + } if (Daylight != 0 && Daylight != 1 && Daylight != 3) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"-d"); ShellStatus = SHELL_INVALID_PARAMETER; @@ -614,7 +686,8 @@ STATIC CONST SHELL_PARAM_ITEM TimeZoneParamList3[] = { {-660 , STRING_TOKEN (STR_TIMEZONE_P11)}, {-720 , STRING_TOKEN (STR_TIMEZONE_P12)}, {-780 , STRING_TOKEN (STR_TIMEZONE_P13)}, - {-840 , STRING_TOKEN (STR_TIMEZONE_P14)} + {-840 , STRING_TOKEN (STR_TIMEZONE_P14)}, + {EFI_UNSPECIFIED_TIMEZONE, STRING_TOKEN (STR_TIMEZONE_LOCAL)} }; /** @@ -644,6 +717,20 @@ CheckAndSetTimeZone ( return (SHELL_INVALID_PARAMETER); } + if (StrniCmp (TimeZoneString, L"_local", StrLen (TimeZoneString)) == NULL) { + Status = gRT->GetTime (&TheTime, NULL); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"gRT->GetTime", Status); + return (SHELL_DEVICE_ERROR); + } + + TheTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE; + Status = gRT->SetTime (&TheTime); + if (!EFI_ERROR(Status)){ + return (SHELL_SUCCESS); + } + return (SHELL_INVALID_PARAMETER); + } if (TimeZoneString != NULL && !InternalIsTimeLikeString(TimeZoneString, L':', 1, 1, TRUE)) { return (SHELL_INVALID_PARAMETER); } @@ -817,11 +904,7 @@ ShellCommandRunTimeZone ( // // Print basic info only // - if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) { - TzMinutes = 0; - } else { - TzMinutes = (ABS(TheTime.TimeZone)) % 60; - } + TzMinutes = (ABS(TheTime.TimeZone)) % 60; ShellPrintHiiEx ( -1, @@ -829,8 +912,8 @@ ShellCommandRunTimeZone ( NULL, STRING_TOKEN(STR_TIMEZONE_SIMPLE), gShellLevel2HiiHandle, - TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(TheTime.TimeZone > 0?L"-":L"+"), - TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(ABS(TheTime.TimeZone)) / 60, + (TheTime.TimeZone > 0?L"-":L"+"), + (ABS(TheTime.TimeZone)) / 60, TzMinutes); } Found = TRUE; @@ -841,28 +924,45 @@ ShellCommandRunTimeZone ( // // Print basic info only // - if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) { - TzMinutes = 0; - } else { - TzMinutes = (ABS(TheTime.TimeZone)) % 60; - } + TzMinutes = (ABS(TheTime.TimeZone)) % 60; + ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN(STR_TIMEZONE_SIMPLE), gShellLevel2HiiHandle, - TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(TheTime.TimeZone > 0?L"-":L"+"), - TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(ABS(TheTime.TimeZone)) / 60, + (TheTime.TimeZone > 0?L"-":L"+"), + (ABS(TheTime.TimeZone)) / 60, TzMinutes); + if (ShellCommandLineGetFlag(Package, L"-f")) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_TIMEZONE_NI), gShellLevel2HiiHandle); } } } else { // - // TimeZone was EFI_UNSPECIFIED_TIMEZONE (unknown) from GetTime() + // TimeZone was EFI_UNSPECIFIED_TIMEZONE (local) from GetTime() // + if (ShellCommandLineGetFlag (Package, L"-f")) { + for ( LoopVar = 0 + ; LoopVar < sizeof (TimeZoneList) / sizeof (TimeZoneList[0]) + ; LoopVar++ + ){ + if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) { + // + // Print all info about current time zone + // + ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle); + break; + } + } + } else { + // + // Print basic info only + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TIMEZONE_SIMPLE_LOCAL), gShellLevel2HiiHandle); + } } } } diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni index 51ec7e1267..bd0738d94f 100644 Binary files a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni and b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni differ -- cgit v1.2.3