//------------------------------------------------------------------------------
// File: com_protorm.cc
// Author: Jozsef Makai - CERN
//------------------------------------------------------------------------------
/************************************************************************
* EOS - the CERN Disk Storage System *
* Copyright (C) 2018 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
#include "common/StringTokenizer.hh"
#include "common/Path.hh"
#include "console/ConsoleMain.hh"
#include "console/commands/ICmdHelper.hh"
extern int com_rm(char*);
void com_rm_help();
//------------------------------------------------------------------------------
//! Class RmHelper
//------------------------------------------------------------------------------
class RmHelper: public ICmdHelper
{
public:
//----------------------------------------------------------------------------
//! Constructor
//!
//! @param opts global options
//----------------------------------------------------------------------------
RmHelper(const GlobalOptions& opts):
ICmdHelper(opts)
{
mIsAdmin = false;
}
//----------------------------------------------------------------------------
//! Destructor
//----------------------------------------------------------------------------
~RmHelper() override = default;
//----------------------------------------------------------------------------
//! Parse command line input
//!
//! @param arg input
//!
//! @return true if successful, otherwise false
//----------------------------------------------------------------------------
bool ParseCommand(const char* arg) override;
};
bool
RmHelper::ParseCommand(const char* arg)
{
XrdOucString option;
eos::console::RmProto* rm = mReq.mutable_rm();
eos::common::StringTokenizer tokenizer(arg);
bool noconfirmation = false;
tokenizer.GetLine();
while ((option = tokenizer.GetToken(false)).length() > 0 &&
(option.beginswith("-"))) {
if ((option == "-r") || (option == "-rf") || (option == "-fr")) {
rm->set_recursive(true);
} else if ((option == "-F") || (option == "--no-recycle-bin")) {
rm->set_bypassrecycle(true);
} else if (option == "-rF" || option == "-Fr") {
rm->set_recursive(true);
rm->set_bypassrecycle(true);
} else if (option == "--no-confirmation") {
noconfirmation = true;
} else if ( option== "--no-workflow" || option == "-n" ) {
rm->set_noworkflow(true);
} else {
return false;
}
}
auto path = option;
do {
XrdOucString param = tokenizer.GetToken();
if (param.length()) {
path += " ";
path += param;
} else {
break;
}
} while (true);
// remove escaped blanks
while (path.replace("\\ ", " "));
if (path.length() == 0) {
return false;
}
auto id = 0ull;
if (Path2FileDenominator(path, id)) {
rm->set_fileid(id);
rm->set_recursive(false); // disable recursive option for files
path = "";
} else {
if (Path2ContainerDenominator(path, id)) {
rm->set_containerid(id);
path = "";
} else {
path = abspath(path.c_str());
rm->set_path(path.c_str());
}
}
eos::common::Path cPath(path.c_str());
if (path.length()) {
mNeedsConfirmation = rm->recursive() && (cPath.GetSubPathSize() < 4) && !noconfirmation;
}
return true;
}
//------------------------------------------------------------------------------
// Rm command entry point
//------------------------------------------------------------------------------
int com_protorm(char* arg)
{
if (wants_help(arg)) {
com_rm_help();
global_retc = EINVAL;
return EINVAL;
}
RmHelper rm(gGlobalOpts);
if (!rm.ParseCommand(arg)) {
com_rm_help();
global_retc = EINVAL;
return EINVAL;
}
if (rm.NeedsConfirmation() && !rm.ConfirmOperation()) {
global_retc = EINTR;
return EINTR;
}
global_retc = rm.Execute(true, true);
return global_retc;
}
void com_rm_help()
{
std::ostringstream oss;
oss << "Usage: rm [-r|-rf|-rF|-n] [--no-recycle-bin|-F] [--no-confirmation] [--no-workflow] [|fid:|fxid:|cid:|cxid:]"
<< std::endl
<< " -r | -rf : remove files/directories recursively" << std::endl
<< " - the 'f' option is a convenience option with no additional functionality!"
<< std::endl
<< " - the recursive flag is automatically removed it the target is a file!"
<< std::endl << std::endl
<< " --no-recycle-bin|-F : remove bypassing recycling policies" << std::endl
<< " - you have to take the root role to use this flag!"
<< std::endl << std::endl
<< " -rF | Fr : remove files/directories recursively bypassing recycling policies"
<< std::endl
<< " - you have to take the root role to use this flag!" <<
std::endl
<< " - the recursive flag is automatically removed it the target is a file!"
<< std::endl
<< " --no-workflow | -n : don't run a workflow when deleting!"
<< std::endl
<< " --no-confirmation : don't ask for confirmation if recursive deletions is running in directory level < 4" << std::endl;
std::cerr << oss.str() << std::endl;
}