/** @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;

  //
  // check for "-?"
  //
  if (ShellCommandLineGetFlag (Package, L"-?")) {
    ASSERT (FALSE);
  }

  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);
}
