/** @file
  Main file for attrib shell level 2 function.

  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "UefiShellLevel2CommandsLib.h"

STATIC CONST SHELL_PARAM_ITEM  ParamList[] = {
  { L"-q", TypeFlag },
  { NULL,  TypeMax  }
};

/**
  Determine if a directory has no files in it.

  @param[in] FileHandle   The EFI_HANDLE to the directory.

  @retval TRUE  The directory has no files (or directories).
  @retval FALSE The directory has at least 1 file or directory in it.
**/
BOOLEAN
IsDirectoryEmpty (
  IN SHELL_FILE_HANDLE  FileHandle
  )
{
  EFI_STATUS     Status;
  EFI_FILE_INFO  *FileInfo;
  BOOLEAN        NoFile;
  BOOLEAN        RetVal;

  RetVal   = TRUE;
  NoFile   = FALSE;
  FileInfo = NULL;

  for (Status = FileHandleFindFirstFile (FileHandle, &FileInfo)
       ; !NoFile && !EFI_ERROR (Status)
       ; FileHandleFindNextFile (FileHandle, FileInfo, &NoFile)
       )
  {
    if (  (StrStr (FileInfo->FileName, L".") != FileInfo->FileName)
       && (StrStr (FileInfo->FileName, L"..") != FileInfo->FileName))
    {
      RetVal = FALSE;
    }
  }

  return (RetVal);
}

/**
  Delete a directory.

  @param[in] Node   The node to start deleting with.
  @param[in] Quiet  TRUE to print no messages.

  @retval SHELL_SUCCESS       The operation was successful.
  @retval SHELL_ACCESS_DENIED A file was read only.
  @retval SHELL_ABORTED       The abort message was received.
  @retval SHELL_DEVICE_ERROR  A device error occurred reading this Node.
**/
STATIC
SHELL_STATUS
DeleteDirectory (
  IN EFI_SHELL_FILE_INFO  *Node,
  IN CONST BOOLEAN        Quiet
  )
{
  SHELL_STATUS           ShellStatus;
  EFI_SHELL_FILE_INFO    *List;
  EFI_SHELL_FILE_INFO    *Node2;
  EFI_STATUS             Status;
  SHELL_PROMPT_RESPONSE  *Resp;
  CHAR16                 *TempName;
  UINTN                  NewSize;

  ASSERT ((Node->Info->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY);

  Resp        = NULL;
  ShellStatus = SHELL_SUCCESS;
  List        = NULL;

  if (IsDirectoryEmpty (Node->Handle)) {
    return ShellStatus;
  }

  if (!Quiet) {
    Status = ShellPrintHiiDefaultEx (STRING_TOKEN (STR_RM_LOG_DELETE_CONF), gShellLevel2HiiHandle, Node->FullName);
    Status = ShellPromptForResponse (ShellPromptResponseTypeYesNo, NULL, (VOID **)&Resp);
    ASSERT (Resp != NULL);
    if (EFI_ERROR (Status) || (*Resp != ShellPromptResponseYes)) {
      SHELL_FREE_NON_NULL (Resp);
      return (SHELL_ABORTED);
    }

    SHELL_FREE_NON_NULL (Resp);
  }

  //
  // empty out the directory
  //
  Status = gEfiShellProtocol->FindFilesInDir (Node->Handle, &List);
  if (EFI_ERROR (Status)) {
    if (List != NULL) {
      gEfiShellProtocol->FreeFileList (&List);
    }

    return (SHELL_DEVICE_ERROR);
  }

  for (Node2 = (EFI_SHELL_FILE_INFO   *)GetFirstNode (&List->Link)
       ; !IsNull (&List->Link, &Node2->Link)
       ; Node2 = (EFI_SHELL_FILE_INFO   *)GetNextNode (&List->Link, &Node2->Link)
       )
  {
    //
    // skip the directory traversing stuff...
    //
    if (IsDotOrDotDot (Node2->FileName)) {
      continue;
    }

    Node2->Status = gEfiShellProtocol->OpenFileByName (Node2->FullName, &Node2->Handle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE);
    if (EFI_ERROR (Node2->Status) && (StrStr (Node2->FileName, L":") == NULL)) {
      //
      // Update the node filename to have full path with file system identifier
      //
      NewSize  = StrSize (Node->FullName) + StrSize (Node2->FullName);
      TempName = AllocateZeroPool (NewSize);
      if (TempName == NULL) {
        ShellStatus = SHELL_OUT_OF_RESOURCES;
      } else {
        StrCpyS (TempName, NewSize/sizeof (CHAR16), Node->FullName);
        TempName[StrStr (TempName, L":")+1-TempName] = CHAR_NULL;
        StrCatS (TempName, NewSize/sizeof (CHAR16), Node2->FullName);
        FreePool ((VOID *)Node2->FullName);
        Node2->FullName = TempName;

        //
        // Now try again to open the file
        //
        Node2->Status = gEfiShellProtocol->OpenFileByName (Node2->FullName, &Node2->Handle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE);
      }
    }

    if (!EFI_ERROR (Node2->Status)) {
      ShellStatus = CascadeDelete (Node2, Quiet);
    } else if (ShellStatus == SHELL_SUCCESS) {
      ShellStatus = (SHELL_STATUS)(Node2->Status&(~0x80000000));
    }

    if (ShellStatus != SHELL_SUCCESS) {
      break;
    }
  }

  if (List != NULL) {
    gEfiShellProtocol->FreeFileList (&List);
  }

  return ShellStatus;
}

/**
  Delete a node and all nodes under it (including sub directories).

  @param[in] Node   The node to start deleting with.
  @param[in] Quiet  TRUE to print no messages.

  @retval SHELL_SUCCESS       The operation was successful.
  @retval SHELL_ACCESS_DENIED A file was read only.
  @retval SHELL_ABORTED       The abort message was received.
  @retval SHELL_DEVICE_ERROR  A device error occurred reading this Node.
**/
SHELL_STATUS
CascadeDelete (
  IN EFI_SHELL_FILE_INFO  *Node,
  IN CONST BOOLEAN        Quiet
  )
{
  SHELL_STATUS  ShellStatus;
  EFI_STATUS    Status;

  ShellStatus = SHELL_SUCCESS;
  Status      = EFI_SUCCESS;

  if ((Node->Info->Attribute & EFI_FILE_READ_ONLY) == EFI_FILE_READ_ONLY) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_RM_LOG_DETELE_RO), gShellLevel2HiiHandle, L"rm", Node->FullName);
    return (SHELL_ACCESS_DENIED);
  }

  if ((Node->Info->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {
    ShellStatus = DeleteDirectory (Node, Quiet);
    if (ShellStatus != SHELL_SUCCESS) {
      return ShellStatus;
    }
  }

  if (!IsDotOrDotDot (Node->FileName)) {
    //
    // now delete the current node...
    //
    if (!Quiet) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_RM_LOG_DELETE), gShellLevel2HiiHandle, Node->FullName);
    }

    Status       = gEfiShellProtocol->DeleteFile (Node->Handle);
    Node->Handle = NULL;
  }

  //
  // We cant allow for the warning here! (Dont use EFI_ERROR Macro).
  //
  if (Status != EFI_SUCCESS) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_RM_LOG_DELETE_ERR), gShellLevel2HiiHandle, Status);
    return (SHELL_ACCESS_DENIED);
  } else {
    if (!Quiet) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_RM_LOG_DELETE_COMP), gShellLevel2HiiHandle);
    }

    return (SHELL_SUCCESS);
  }
}

/**
  Determines if a Node is a valid delete target.  Will prevent deleting the root directory.

  @param[in] List       RESERVED.  Not used.
  @param[in] Node       The node to analyze.
  @param[in] Package    RESERVED.  Not used.
**/
BOOLEAN
IsValidDeleteTarget (
  IN CONST EFI_SHELL_FILE_INFO  *List,
  IN CONST EFI_SHELL_FILE_INFO  *Node,
  IN CONST LIST_ENTRY           *Package
  )
{
  CONST CHAR16  *TempLocation;
  BOOLEAN       RetVal;
  CHAR16        *SearchString;
  CHAR16        *Pattern;
  UINTN         Size;

  if ((Node == NULL) || (Node->FullName == NULL)) {
    return (FALSE);
  }

  TempLocation = StrStr (Node->FullName, L":");
  if ((TempLocation == NULL) || (StrLen (TempLocation) <= 2)) {
    //
    // Deleting the root directory is invalid.
    //
    return (FALSE);
  }

  TempLocation = ShellGetCurrentDir (NULL);
  if (TempLocation == NULL) {
    //
    // No working directory is specified so whatever is left is ok.
    //
    return (TRUE);
  }

  Pattern      = NULL;
  SearchString = NULL;
  Size         = 0;
  Pattern      = StrnCatGrow (&Pattern, &Size, TempLocation, 0);
  Pattern      = StrnCatGrow (&Pattern, &Size, L"\\", 0);
  Size         = 0;
  SearchString = StrnCatGrow (&SearchString, &Size, Node->FullName, 0);
  if (SearchString == NULL) {
    RetVal = FALSE;
    goto Done;
  }

  if (!EFI_ERROR (ShellIsDirectory (SearchString))) {
    SearchString = StrnCatGrow (&SearchString, &Size, L"\\", 0);
    SearchString = StrnCatGrow (&SearchString, &Size, L"*", 0);
  }

  if ((Pattern == NULL) || (SearchString == NULL)) {
    RetVal = FALSE;
  } else {
    RetVal = TRUE;
    if (gUnicodeCollation->MetaiMatch (gUnicodeCollation, Pattern, SearchString)) {
      RetVal = FALSE;
    }
  }

Done:
  SHELL_FREE_NON_NULL (Pattern);
  SHELL_FREE_NON_NULL (SearchString);

  return (RetVal);
}

/** Main function of the 'Rm' command.

  @param[in] Package    List of input parameter for the command.
**/
STATIC
SHELL_STATUS
MainCmdRm (
  LIST_ENTRY  *Package
  )
{
  EFI_STATUS           Status;
  CONST CHAR16         *Param;
  SHELL_STATUS         ShellStatus;
  UINTN                ParamCount;
  EFI_SHELL_FILE_INFO  *FileList;
  EFI_SHELL_FILE_INFO  *Node;

  ShellStatus = SHELL_SUCCESS;
  ParamCount  = 0;
  FileList    = NULL;

  if (ShellCommandLineGetRawValue (Package, 1) == NULL) {
    //
    // we insufficient parameters
    //
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"rm");
    return SHELL_INVALID_PARAMETER;
  }

  //
  // get a list with each file specified by parameters
  // if parameter is a directory then add all the files below it to the list
  //
  for ( ParamCount = 1, Param = ShellCommandLineGetRawValue (Package, ParamCount)
        ; Param != NULL
        ; ParamCount++, Param = ShellCommandLineGetRawValue (Package, ParamCount)
        )
  {
    Status = ShellOpenFileMetaArg ((CHAR16 *)Param, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);
    if (EFI_ERROR (Status) || (FileList == NULL) || IsListEmpty (&FileList->Link)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"rm", (CHAR16 *)Param);
      ShellStatus = SHELL_NOT_FOUND;
      break;
    }
  }

  if ((ShellStatus != SHELL_SUCCESS) || (FileList == NULL)) {
    goto Exit;
  }

  //
  // loop through the list and make sure we are not aborting...
  //
  for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link)
        ; !IsNull (&FileList->Link, &Node->Link) && !ShellGetExecutionBreakFlag ()
        ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link)
        )
  {
    //
    // skip the directory traversing stuff...
    //
    if (IsDotOrDotDot (Node->FileName)) {
      continue;
    }

    //
    // do the deleting of nodes
    //
    if (EFI_ERROR (Node->Status)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_RM_LOG_DELETE_ERR2), gShellLevel2HiiHandle, Node->Status);
      ShellStatus = SHELL_ACCESS_DENIED;
      break;
    }

    if (!IsValidDeleteTarget (FileList, Node, Package)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_RM_LOG_DELETE_ERR3), gShellLevel2HiiHandle, Node->FullName);
      ShellStatus = SHELL_INVALID_PARAMETER;
      break;
    }

    ShellStatus = CascadeDelete (Node, ShellCommandLineGetFlag (Package, L"-q"));
  }

Exit:
  //
  // Free the fileList
  //
  if (FileList != NULL) {
    Status = ShellCloseFileMetaArg (&FileList);
  }

  return ShellStatus;
}

/**
  Function for 'rm' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunRm (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS    Status;
  LIST_ENTRY    *Package;
  CHAR16        *ProblemParam;
  SHELL_STATUS  ShellStatus;

  ProblemParam = NULL;
  ShellStatus  = SHELL_SUCCESS;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize ();
  ASSERT_EFI_ERROR (Status);

  //
  // parse the command line
  //
  Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR (Status)) {
    if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"rm", ProblemParam);
      FreePool (ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT (FALSE);
    }

    return ShellStatus;
  }

  ShellStatus = MainCmdRm (Package);

  //
  // free the command line package
  //
  ShellCommandLineFreeVarList (Package);

  return (ShellStatus);
}
