Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GDAL 4 : * Purpose: gdal "vsi delete" subcommand 5 : * Author: Even Rouault <even dot rouault at spatialys.com> 6 : * 7 : ****************************************************************************** 8 : * Deleteright (c) 2025, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "gdalalg_vsi_delete.h" 14 : 15 : #include "cpl_conv.h" 16 : #include "cpl_string.h" 17 : #include "cpl_vsi.h" 18 : #include "cpl_vsi_error.h" 19 : 20 : #include <algorithm> 21 : 22 : //! @cond Doxygen_Suppress 23 : 24 : #ifndef _ 25 : #define _(x) (x) 26 : #endif 27 : 28 : /************************************************************************/ 29 : /* GDALVSIDeleteAlgorithm::GDALVSIDeleteAlgorithm() */ 30 : /************************************************************************/ 31 : 32 50 : GDALVSIDeleteAlgorithm::GDALVSIDeleteAlgorithm() 33 50 : : GDALAlgorithm(NAME, DESCRIPTION, HELP_URL) 34 : { 35 50 : AddProgressArg(/* hidden = */ true); 36 : 37 : { 38 : auto &arg = AddArg("filename", 0, _("File or directory name to delete"), 39 100 : &m_filename) 40 50 : .SetPositional() 41 50 : .SetMinCharCount(1) 42 50 : .SetRequired(); 43 50 : SetAutoCompleteFunctionForFilename(arg, 0); 44 : } 45 : 46 100 : AddArg("recursive", 'r', _("Delete directories recursively"), &m_recursive) 47 50 : .AddShortNameAlias('R'); 48 50 : } 49 : 50 : /************************************************************************/ 51 : /* GDALVSIDeleteAlgorithm::RunImpl() */ 52 : /************************************************************************/ 53 : 54 7 : bool GDALVSIDeleteAlgorithm::RunImpl(GDALProgressFunc, void *) 55 : { 56 7 : bool ret = false; 57 : VSIStatBufL sStat; 58 7 : VSIErrorReset(); 59 7 : const auto nOldErrorNum = VSIGetLastErrorNo(); 60 7 : if (VSIStatL(m_filename.c_str(), &sStat) != 0) 61 : { 62 2 : if (nOldErrorNum != VSIGetLastErrorNo()) 63 : { 64 1 : ReportError(CE_Failure, CPLE_FileIO, 65 : "'%s' cannot be accessed. %s: %s", m_filename.c_str(), 66 : VSIErrorNumToString(VSIGetLastErrorNo()), 67 : VSIGetLastErrorMsg()); 68 : } 69 : else 70 : { 71 1 : ReportError(CE_Failure, CPLE_FileIO, 72 : "'%s' does not exist or cannot be accessed", 73 : m_filename.c_str()); 74 : } 75 : } 76 : else 77 : { 78 5 : if (m_recursive) 79 : { 80 2 : ret = VSIRmdirRecursive(m_filename.c_str()) == 0; 81 : } 82 : else 83 : { 84 5 : ret = VSI_ISDIR(sStat.st_mode) ? VSIRmdir(m_filename.c_str()) == 0 85 2 : : VSIUnlink(m_filename.c_str()) == 0; 86 : } 87 5 : if (!ret) 88 : { 89 1 : ReportError(CE_Failure, CPLE_FileIO, "Cannot delete %s", 90 : m_filename.c_str()); 91 : } 92 : } 93 7 : return ret; 94 : } 95 : 96 : //! @endcond