|
|
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
rm.c Abstract:
Shell app "rm"
Revision History
--*/
#include "shell.h"
/*
* */
#define FILE_INFO_SIZE (SIZE_OF_EFI_FILE_INFO + 1024)
EFI_FILE_INFO *RmInfo;
/*
* */
EFI_STATUS InitializeRM ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable );
VOID RemoveRM ( IN SHELL_FILE_ARG *Arg, IN BOOLEAN Quite );
/*
* */
EFI_DRIVER_ENTRY_POINT(InitializeRM)
EFI_STATUS InitializeRM ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { CHAR16 **Argv; UINTN Argc; UINTN Index; LIST_ENTRY FileList; LIST_ENTRY *Link; SHELL_FILE_ARG *Arg;
/*
* Check to see if the app is to install as a "internal command" * to the shell */
InstallInternalShellCommand ( ImageHandle, SystemTable, InitializeRM, L"rm", /* command */ L"rm file/dir [file/dir]", /* command syntax */ L"Remove file/directories", /* 1 line descriptor */ NULL /* command help page */ );
/*
* We are no being installed as an internal command driver, initialize * as an nshell app and run */
InitializeShellApplication (ImageHandle, SystemTable); Argv = SI->Argv; Argc = SI->Argc; InitializeListHead (&FileList);
RmInfo = AllocatePool (FILE_INFO_SIZE); if (!RmInfo) { Print (L"rm: out of memory\n"); goto Done; }
/*
* Expand each arg */
for (Index = 1; Index < Argc; Index += 1) { ShellFileMetaArg (Argv[Index], &FileList); }
if (IsListEmpty(&FileList)) { Print (L"rm: no file specified\n"); goto Done; }
/*
* Remove each file */
for (Link=FileList.Flink; Link!=&FileList; Link=Link->Flink) { Arg = CR(Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE); RemoveRM (Arg, 0); }
Done: ShellFreeFileList (&FileList); if (RmInfo) { FreePool (RmInfo); RmInfo = NULL; }
return EFI_SUCCESS; }
SHELL_FILE_ARG * RmCreateChild ( IN SHELL_FILE_ARG *Parent, IN CHAR16 *FileName, IN OUT LIST_ENTRY *ListHead ) { SHELL_FILE_ARG *Arg; UINTN Len;
Arg = AllocateZeroPool (sizeof(SHELL_FILE_ARG)); if (!Arg) { return NULL; }
Arg->Signature = SHELL_FILE_ARG_SIGNATURE; Parent->Parent->Open (Parent->Handle, &Arg->Parent, L".", EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0); Arg->ParentName = StrDuplicate(Parent->FullName); Arg->FileName = StrDuplicate(FileName);
/* append filename to parent's name to get the file's full name */ Len = StrLen(Arg->ParentName); if (Len && Arg->ParentName[Len-1] == '\\') { Len -= 1; }
Arg->FullName = PoolPrint(L"%.*s\\%s", Len, Arg->ParentName, FileName);
/* open it */ Arg->Status = Parent->Handle->Open ( Parent->Handle, &Arg->Handle, Arg->FileName, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0 );
InsertTailList (ListHead, &Arg->Link); return Arg; }
VOID RemoveRM ( IN SHELL_FILE_ARG *Arg, IN BOOLEAN Quite ) { EFI_STATUS Status; SHELL_FILE_ARG *Child; LIST_ENTRY Cleanup; UINTN Size; CHAR16 Str[2];
Status = Arg->Status; InitializeListHead (&Cleanup);
if (EFI_ERROR(Status)) { goto Done; }
/*
* If the file is a directory check it */
Size = FILE_INFO_SIZE; Status = Arg->Handle->GetInfo(Arg->Handle, &GenericFileInfo, &Size, RmInfo); if (EFI_ERROR(Status)) { Print(L"rm: can not get info of %hs\n", Arg->FullName); goto Done; }
if (RmInfo->Attribute & EFI_FILE_DIRECTORY) {
/*
* Remove all child entries from the directory */
Arg->Handle->SetPosition (Arg->Handle, 0); for (; ;) { Size = FILE_INFO_SIZE; Status = Arg->Handle->Read (Arg->Handle, &Size, RmInfo); if (EFI_ERROR(Status) || Size == 0) { break; }
/*
* Skip "." and ".." */
if (StriCmp(RmInfo->FileName, L".") == 0 || StriCmp(RmInfo->FileName, L"..") == 0) { continue; }
/*
* Build a shell_file_arg for the sub-entry */
Child = RmCreateChild (Arg, RmInfo->FileName, &Cleanup);
/*
* Remove it */
if (!Quite) { Print (L"rm: remove subtree '%hs' [y/n]? ", Arg->FullName); Input (NULL, Str, 2); Print (L"\n");
Status = (Str[0] == 'y' || Str[0] == 'Y') ? EFI_SUCCESS : EFI_ACCESS_DENIED;
if (EFI_ERROR(Status)) { goto Done; } }
Quite = TRUE; RemoveRM (Child, TRUE);
/*
* Close the handles */
ShellFreeFileList (&Cleanup); } }
/*
* Remove the file */
Status = Arg->Handle->Delete(Arg->Handle); Arg->Handle = NULL;
Done: if (EFI_ERROR(Status)) { Print (L"rm %s : %hr\n", Arg->FullName, Status); } else { Print (L"rm %s [ok]\n", Arg->FullName); } }
|