// ---------------------------------------------------------------------- // File: Glob.hh // Author: Andreas-Joachim Peters - CERN // ---------------------------------------------------------------------- /************************************************************************ * EOS - the CERN Disk Storage System * * Copyright (C) 2023 CERN/ASwitzerland * * * * 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 .* ************************************************************************/ //----------------------------------------------------------------------------- //! @brief Class applying bash pattern amtching //----------------------------------------------------------------------------- #ifndef __EOSCOMMON__GLOB__HH #define __EOSCOMMON__GLOBE__HH #include #include #include #include #include #include #include #include #include #include #include #include "common/Namespace.hh" #include "common/Path.hh" EOSCOMMONNAMESPACE_BEGIN //------------------------------------------------------------------------------ //! Static Class running bash pattern matching //! To use this static functions include this header file //! Example (call this for each entry in a listing) //! using eos::common::Glob; //! Glob glob; //! glob.Match("asdf*.txt", "asdf1.txt"; (true in this case, otherwise false) //------------------------------------------------------------------------------ class Glob { public: //---------------------------------------------------------------------------- //! //---------------------------------------------------------------------------- Glob() : mIt(0) {} virtual ~Glob() {} static void *opendir(const char *name) { return (DIR*) (gGlob); } static struct dirent *readdir(void *dirp) { Glob* thisglob = (Glob*) dirp; return thisglob->getEntry(); } static void closedir(void *dirp) {return;} static int stat(const char *pathname, struct stat *statbuf) { statbuf->st_mode = S_IFREG; return 0;} static int lstat(const char *pathname, struct stat *statbuf) { statbuf->st_mode = S_IFREG; return 0;} struct dirent* getEntry() { if (mIt < mNames.size()) { mEntry.d_ino = mIt+1; // 0 leads to NOMATCH with glibc 2-17!!! mEntry.d_off = mIt; mEntry.d_reclen = 255; mEntry.d_type = DT_REG;; snprintf(mEntry.d_name, mEntry.d_reclen, "%s",mNames[mIt++].c_str()); return &mEntry; } else { return nullptr; } } bool Match(const std::string& pattern, const std::string& path) { static std::mutex g_i_mutex; mIt=0; mNames.clear(); std::lock_guard lock(g_i_mutex); gGlob = this; bool result = false; eos::common::Path cPath(path.c_str()); mNames.resize(1); mNames[0] = cPath.GetName(); glob_t globbuf; memset(&globbuf,0, sizeof(globbuf)); // globbuf.gl_offs = 2; globbuf.gl_opendir=opendir; globbuf.gl_readdir=readdir; globbuf.gl_closedir=closedir; globbuf.gl_stat=stat; globbuf.gl_lstat=lstat; glob(pattern.c_str(), GLOB_ALTDIRFUNC, NULL, &globbuf); if (globbuf.gl_pathc) { result = true; } else { result = false; } globfree(&globbuf); return result; } static Glob* gGlob; private: std::vector mNames; uint64_t mIt; struct dirent mEntry; }; EOSCOMMONNAMESPACE_END #endif