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 : const auto nOldErrorNum = VSIGetLastErrorNo(); 57 7 : VSIErrorReset(); 58 : 59 7 : bool ret = false; 60 : VSIStatBufL sStat; 61 7 : if (VSIStatL(m_filename.c_str(), &sStat) != 0) 62 : { 63 2 : if (nOldErrorNum != VSIGetLastErrorNo()) 64 : { 65 1 : ReportError(CE_Failure, CPLE_FileIO, 66 : "'%s' cannot be accessed. %s: %s", m_filename.c_str(), 67 : VSIErrorNumToString(VSIGetLastErrorNo()), 68 : VSIGetLastErrorMsg()); 69 : } 70 : else 71 : { 72 1 : ReportError(CE_Failure, CPLE_FileIO, 73 : "'%s' does not exist or cannot be accessed", 74 : m_filename.c_str()); 75 : } 76 : } 77 : else 78 : { 79 5 : if (m_recursive) 80 : { 81 2 : ret = VSIRmdirRecursive(m_filename.c_str()) == 0; 82 : } 83 : else 84 : { 85 5 : ret = VSI_ISDIR(sStat.st_mode) ? VSIRmdir(m_filename.c_str()) == 0 86 2 : : VSIUnlink(m_filename.c_str()) == 0; 87 : } 88 5 : if (!ret) 89 : { 90 1 : ReportError(CE_Failure, CPLE_FileIO, "Cannot delete %s", 91 : m_filename.c_str()); 92 : } 93 : } 94 7 : return ret; 95 : } 96 : 97 : //! @endcond