X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=ShellPkg%2FLibrary%2FUefiShellLevel2CommandsLib%2FLs.c;h=7d2e15f5206b334ff79bedde2871f5f558335836;hp=64ce4ae2c02b9e6a3130bfc8ad7681bb4e3d055a;hb=2d70c90d2e8bf4405c5c16c0c7ea5b2446d1517a;hpb=4f344fffc7fb541d11edf4cf657f84549b334244 diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c index 64ce4ae2c0..7d2e15f520 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c @@ -1,8 +1,8 @@ /** @file Main file for ls shell level 2 function. - Copyright (c) 2013 Hewlett-Packard Development Company, L.P. - Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
+ (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2009 - 2017, 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 which accompanies this distribution. The full text of the license may be found at @@ -16,13 +16,14 @@ #include "UefiShellLevel2CommandsLib.h" #include +UINTN mDayOfMonth[] = {31, 28, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30}; + /** print out the standard format output volume entry. @param[in] TheList a list of files from the volume. **/ EFI_STATUS -EFIAPI PrintSfoVolumeInfoTableEntry( IN CONST EFI_SHELL_FILE_INFO *TheList ) @@ -152,7 +153,6 @@ PrintSfoVolumeInfoTableEntry( **/ VOID -EFIAPI PrintFileInformation( IN CONST BOOLEAN Sfo, IN CONST EFI_SHELL_FILE_INFO *TheNode, @@ -263,7 +263,6 @@ PrintFileInformation( @param[in] Path String with starting path. **/ VOID -EFIAPI PrintNonSfoHeader( IN CONST CHAR16 *Path ) @@ -300,7 +299,6 @@ PrintNonSfoHeader( @param[in] Dirs The number of directories. **/ VOID -EFIAPI PrintNonSfoFooter( IN UINT64 Files, IN UINT64 Size, @@ -322,6 +320,96 @@ PrintNonSfoFooter( ); } +/** + Change the file time to local time based on the timezone. + + @param[in] Time The file time. + @param[in] LocalTimeZone Local time zone. +**/ +VOID +FileTimeToLocalTime ( + IN EFI_TIME *Time, + IN INT16 LocalTimeZone + ) +{ + INTN MinuteDiff; + INTN TempMinute; + INTN HourNumberOfTempMinute; + INTN TempHour; + INTN DayNumberOfTempHour; + INTN TempDay; + INTN MonthNumberOfTempDay; + INTN TempMonth; + INTN YearNumberOfTempMonth; + INTN MonthRecord; + + ASSERT ((Time->TimeZone >= -1440) && (Time->TimeZone <=1440)); + ASSERT ((LocalTimeZone >= -1440) && (LocalTimeZone <=1440)); + ASSERT ((Time->Month >= 1) && (Time->Month <= 12)); + + if(Time->TimeZone == LocalTimeZone) { + // + //if the file timezone is equal to the local timezone, there is no need to adjust the file time. + // + return; + } + + if((Time->Year % 4 == 0 && Time->Year / 100 != 0)||(Time->Year % 400 == 0)) { + // + // Day in February of leap year is 29. + // + mDayOfMonth[1] = 29; + } + + MinuteDiff = Time->TimeZone - LocalTimeZone; + TempMinute = Time->Minute + MinuteDiff; + + // + // Calculate Time->Minute + // TempHour will be used to calculate Time->Hour + // + HourNumberOfTempMinute = TempMinute / 60; + if(TempMinute < 0) { + HourNumberOfTempMinute --; + } + TempHour = Time->Hour + HourNumberOfTempMinute; + Time->Minute = (UINT8)(TempMinute - 60 * HourNumberOfTempMinute); + + // + // Calculate Time->Hour + // TempDay will be used to calculate Time->Day + // + DayNumberOfTempHour = TempHour / 24 ; + if(TempHour < 0){ + DayNumberOfTempHour--; + } + TempDay = Time->Day + DayNumberOfTempHour; + Time->Hour = (UINT8)(TempHour - 24 * DayNumberOfTempHour); + + // + // Calculate Time->Day + // TempMonth will be used to calculate Time->Month + // + MonthNumberOfTempDay = (TempDay - 1) / (INTN)mDayOfMonth[Time->Month - 1]; + MonthRecord = (INTN)(Time->Month) ; + if(TempDay - 1 < 0){ + MonthNumberOfTempDay -- ; + MonthRecord -- ; + } + TempMonth = Time->Month + MonthNumberOfTempDay; + Time->Day = (UINT8)(TempDay - (INTN)mDayOfMonth[(MonthRecord - 1 + 12) % 12] * MonthNumberOfTempDay); + + // + // Calculate Time->Month, Time->Year + // + YearNumberOfTempMonth = (TempMonth - 1) / 12; + if(TempMonth - 1 < 0){ + YearNumberOfTempMonth --; + } + Time->Month = (UINT8)(TempMonth - 12 * (YearNumberOfTempMonth)); + Time->Year = (UINT16)(Time->Year + YearNumberOfTempMonth); +} + /** print out the list of files and directories from the LS command @@ -339,7 +427,6 @@ PrintNonSfoFooter( @retval SHELL_SUCCESS the printing was sucessful. **/ SHELL_STATUS -EFIAPI PrintLsOutput( IN CONST BOOLEAN Rec, IN CONST UINT64 Attribs, @@ -362,6 +449,7 @@ PrintLsOutput( CHAR16 *CorrectedPath; BOOLEAN FoundOne; BOOLEAN HeaderPrinted; + EFI_TIME LocalTime; HeaderPrinted = FALSE; FileCount = 0; @@ -408,7 +496,34 @@ PrintLsOutput( ; !IsNull(&ListHead->Link, &Node->Link) ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&ListHead->Link, &Node->Link) ){ + if (ShellGetExecutionBreakFlag ()) { + ShellStatus = SHELL_ABORTED; + break; + } ASSERT(Node != NULL); + + // + // Change the file time to local time. + // + Status = gRT->GetTime(&LocalTime, NULL); + if (!EFI_ERROR (Status)) { + if ((Node->Info->CreateTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) && + (Node->Info->CreateTime.Month >= 1 && Node->Info->CreateTime.Month <= 12)) { + // + // FileTimeToLocalTime () requires Month is in a valid range, other buffer out-of-band access happens. + // + FileTimeToLocalTime (&Node->Info->CreateTime, LocalTime.TimeZone); + } + if ((Node->Info->LastAccessTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) && + (Node->Info->LastAccessTime.Month >= 1 && Node->Info->LastAccessTime.Month <= 12)) { + FileTimeToLocalTime (&Node->Info->LastAccessTime, LocalTime.TimeZone); + } + if ((Node->Info->ModificationTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) && + (Node->Info->ModificationTime.Month >= 1 && Node->Info->ModificationTime.Month <= 12)) { + FileTimeToLocalTime (&Node->Info->ModificationTime, LocalTime.TimeZone); + } + } + if (LongestPath < StrSize(Node->FullName)) { LongestPath = StrSize(Node->FullName); } @@ -438,6 +553,7 @@ PrintLsOutput( } if (!Sfo && !HeaderPrinted) { + PathRemoveLastItem (CorrectedPath); PrintNonSfoHeader(CorrectedPath); } PrintFileInformation(Sfo, Node, &FileCount, &FileSize, &DirCount); @@ -445,12 +561,12 @@ PrintLsOutput( HeaderPrinted = TRUE; } - if (!Sfo) { + if (!Sfo && ShellStatus != SHELL_ABORTED) { PrintNonSfoFooter(FileCount, FileSize, DirCount); } } - if (Rec) { + if (Rec && ShellStatus != SHELL_ABORTED) { // // Re-Open all the files under the starting path for directories that didnt necessarily match our file filter // @@ -493,6 +609,13 @@ PrintLsOutput( &FoundOne, Count, TimeZone); + + // + // Since it's running recursively, we have to break immediately when returned SHELL_ABORTED + // + if (ShellStatus == SHELL_ABORTED) { + break; + } } } } @@ -575,7 +698,7 @@ ShellCommandRunLs ( Status = ShellCommandLineParse (LsParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"ls", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { @@ -590,7 +713,7 @@ ShellCommandRunLs ( } if (ShellCommandLineGetCount(Package) > 2) { - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"ls"); ShellStatus = SHELL_INVALID_PARAMETER; } else { // @@ -628,7 +751,7 @@ ShellCommandRunLs ( Count++; continue; default: - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ATTRIBUTE), gShellLevel2HiiHandle, ShellCommandLineGetValue(Package, L"-a")); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ATTRIBUTE), gShellLevel2HiiHandle, L"ls", ShellCommandLineGetValue(Package, L"-a")); ShellStatus = SHELL_INVALID_PARAMETER; break; } // switch @@ -649,7 +772,7 @@ ShellCommandRunLs ( CurDir = gEfiShellProtocol->GetCurDir(NULL); if (CurDir == NULL) { ShellStatus = SHELL_NOT_FOUND; - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"ls"); } // // Copy to the 2 strings for starting path and file search string @@ -658,13 +781,15 @@ ShellCommandRunLs ( ASSERT(FullPath == NULL); StrnCatGrow(&SearchString, NULL, L"*", 0); StrnCatGrow(&FullPath, NULL, CurDir, 0); + Size = FullPath != NULL? StrSize(FullPath) : 0; + StrnCatGrow(&FullPath, &Size, L"\\", 0); } else { if (StrStr(PathName, L":") == NULL && gEfiShellProtocol->GetCurDir(NULL) == NULL) { // // If we got something and it doesnt have a fully qualified path, then we needed to have a CWD. // ShellStatus = SHELL_NOT_FOUND; - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"ls"); } else { // // We got a valid fully qualified path or we have a CWD @@ -676,6 +801,8 @@ ShellCommandRunLs ( ShellCommandLineFreeVarList (Package); return SHELL_OUT_OF_RESOURCES; } + Size = FullPath != NULL? StrSize(FullPath) : 0; + StrnCatGrow(&FullPath, &Size, L"\\", 0); } StrnCatGrow(&FullPath, &Size, PathName, 0); if (FullPath == NULL) { @@ -692,16 +819,20 @@ ShellCommandRunLs ( // // must split off the search part that applies to files from the end of the directory part // - for (StrnCatGrow(&SearchString, NULL, PathName, 0) - ; SearchString != NULL && StrStr(SearchString, L"\\") != NULL - ; CopyMem(SearchString, StrStr(SearchString, L"\\") + 1, 1 + StrSize(StrStr(SearchString, L"\\") + 1))) ; - FullPath[StrLen(FullPath) - StrLen(SearchString)] = CHAR_NULL; + StrnCatGrow(&SearchString, NULL, FullPath, 0); + if (SearchString == NULL) { + FreePool (FullPath); + ShellCommandLineFreeVarList (Package); + return SHELL_OUT_OF_RESOURCES; + } + PathRemoveLastItem (FullPath); + CopyMem (SearchString, SearchString + StrLen (FullPath), StrSize (SearchString + StrLen (FullPath))); } } } 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); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"ls", L"gRT->GetTime", Status); TheTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE; } @@ -714,18 +845,18 @@ ShellCommandRunLs ( SearchString, NULL, Count, - (INT16)(TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:TheTime.TimeZone) + TheTime.TimeZone ); if (ShellStatus == SHELL_NOT_FOUND) { - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LS_FILE_NOT_FOUND), gShellLevel2HiiHandle); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LS_FILE_NOT_FOUND), gShellLevel2HiiHandle, L"ls", FullPath); } else if (ShellStatus == SHELL_INVALID_PARAMETER) { - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"ls", FullPath); } else if (ShellStatus == SHELL_ABORTED) { // // Ignore aborting. // } else if (ShellStatus != SHELL_SUCCESS) { - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"ls", FullPath); } } }