Logo
  • Main Page
  • Related Pages
  • Modules
  • Classes
  • Files

mmsfilesearch.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider,             *
00003  *                           Matthias Hardt, Guido Madaus                  *
00004  *                                                                         *
00005  *   Copyright (C) 2007-2008 BerLinux Solutions GbR                        *
00006  *                           Stefan Schwarzer & Guido Madaus               *
00007  *                                                                         *
00008  *   Copyright (C) 2009-2013 BerLinux Solutions GmbH                       *
00009  *                                                                         *
00010  *   Authors:                                                              *
00011  *      Stefan Schwarzer   <stefan.schwarzer@diskohq.org>,                 *
00012  *      Matthias Hardt     <matthias.hardt@diskohq.org>,                   *
00013  *      Jens Schneider     <jens.schneider@diskohq.org>,                   *
00014  *      Guido Madaus       <guido.madaus@diskohq.org>,                     *
00015  *      Patrick Helterhoff <patrick.helterhoff@diskohq.org>,               *
00016  *      René Bählkow       <rene.baehlkow@diskohq.org>                     *
00017  *                                                                         *
00018  *   This library is free software; you can redistribute it and/or         *
00019  *   modify it under the terms of the GNU Lesser General Public            *
00020  *   License version 2.1 as published by the Free Software Foundation.     *
00021  *                                                                         *
00022  *   This library is distributed in the hope that it will be useful,       *
00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00025  *   Lesser General Public License for more details.                       *
00026  *                                                                         *
00027  *   You should have received a copy of the GNU Lesser General Public      *
00028  *   License along with this library; if not, write to the                 *
00029  *   Free Software Foundation, Inc.,                                       *
00030  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
00031  **************************************************************************/
00032 
00033 /**
00034  * @file mmsfilesearch.cpp
00035  *
00036  * Implementation of MMSFileSearch class.
00037  *
00038  * @ingroup mmstools
00039  */
00040 
00041 #include "mmstools/mmsfilesearch.h"
00042 #include <sys/types.h>
00043 #include <sys/stat.h>
00044 #include <unistd.h>
00045 #include <errno.h>
00046 #include <fnmatch.h>
00047 #include <string.h>
00048 
00049 
00050 MMSFileSearch::MMSFileSearch(string directory, string mask, bool recursive, bool caseinsensitive, bool getdirs) :
00051     recursive(recursive),
00052     caseinsensitive(caseinsensitive),
00053     getdirs(getdirs),
00054     mask(mask),
00055     dirhandle(NULL),
00056     option(MMSFILESEARCH_NONE) {
00057     setDirectory(directory);
00058     separateMask();
00059 }
00060 
00061 bool MMSFileSearch::match(char *entry) {
00062     for(vector<string>::iterator i = this->singlemask.begin(); i != this->singlemask.end(); ++i) {
00063         int flags = FNM_PATHNAME;
00064         if(this->caseinsensitive) {
00065             flags |= FNM_CASEFOLD;
00066         }
00067         if(fnmatch((*i).c_str(),entry,flags) == 0) {
00068             return true;
00069         }
00070     }
00071     return false;
00072 }
00073 
00074 void MMSFileSearch::setRecursive(bool recursive) {
00075     this->recursive = recursive;
00076 }
00077 
00078 void MMSFileSearch::setDirectory(string directory) {
00079     if(directory.empty()) {
00080         this->directory = "/";
00081     } else {
00082         this->directory = directory;
00083     }
00084 }
00085 
00086 void MMSFileSearch::setString(string mask) {
00087     this->mask = mask;
00088     this->singlemask.clear();
00089     separateMask();
00090 }
00091 
00092 
00093 void MMSFileSearch::setCaseInsensitive(bool caseinsensitive) {
00094     this->caseinsensitive = caseinsensitive;
00095 }
00096 
00097 void MMSFileSearch::separateMask() {
00098     int pos = 0;
00099     int tmppos = 0;
00100 
00101     while(pos!=-1) {
00102         pos = this->mask.find_first_of(";",tmppos);
00103         if(pos != -1) {
00104             string tmpstring = this->mask.substr(tmppos,pos-tmppos);
00105             this->singlemask.push_back(tmpstring);
00106         }
00107         else {
00108             string tmpstring = this->mask.substr(tmppos,mask.size()-tmppos);
00109             this->singlemask.push_back(tmpstring);
00110         }
00111         tmppos = pos +1;
00112     }
00113     if(strncmp(this->singlemask.at(0).c_str(),MMSFILESEARCH_DEEPESTDIRENTRY,strlen(MMSFILESEARCH_DEEPESTDIRENTRY)-1)==0) {
00114         this->option = MMSFILESEARCH_DEEPESTDIR;
00115     } else if(strncmp(this->singlemask.at(0).c_str(),MMSFILESEARCH_DEEPESTDIRENTRY_OF_FILE,strlen(MMSFILESEARCH_DEEPESTDIRENTRY_OF_FILE)-1)==0) {
00116         this->option = MMSFILESEARCH_DEEPESTDIR_OF_FILE;
00117     }
00118 
00119 }
00120 
00121 
00122 list<MMSFILE_ENTRY *> MMSFileSearch::execute() {
00123     list<MMSFILE_ENTRY *> result;
00124 
00125     this->dirhandle = opendir(this->directory.c_str());
00126     scanDir(&result,this->dirhandle,(this->directory!="/")?this->directory:"");
00127     closedir(this->dirhandle);
00128     return result;
00129 }
00130 
00131 void MMSFileSearch::scanDir(list<MMSFILE_ENTRY *> *result,DIR *dirhandle, string cwd) {
00132     if(!dirhandle)
00133         return;
00134 
00135     struct dirent *entry = readdir(dirhandle);
00136     bool filefound = false;
00137     bool dirfound = false;
00138     int  pos;
00139     while(entry != NULL) {
00140 
00141         if(strcmp(entry->d_name,".")==0) {
00142             entry = readdir(dirhandle);
00143             continue;
00144         }
00145         if(strcmp(entry->d_name,"..")==0) {
00146             entry = readdir(dirhandle);
00147             continue;
00148         }
00149 
00150         if(entry->d_type == DT_DIR) {
00151             if (this->getdirs) {
00152                 // put name of directory to the list
00153                 if((this->option == MMSFILESEARCH_NONE)||(this->option == MMSFILESEARCH_DEEPESTDIR_OF_FILE)) {
00154                     // we have a regular file -> and want to check it
00155                     if(match(entry->d_name) == true) {
00156                         filefound = true;
00157 
00158                         // we have found sth;
00159                         if((this->option != MMSFILESEARCH_DEEPESTDIR_OF_FILE)&&(this->option != MMSFILESEARCH_DEEPESTDIR)) {
00160 
00161                             //we really really want it
00162                             MMSFILE_ENTRY *file = new MMSFILE_ENTRY;
00163                             file->isdir = true;
00164                             file->name = cwd + "/" + entry->d_name;
00165                             file->basename = entry->d_name;
00166                             file->path = cwd;
00167                             result->push_back(file);
00168                         }
00169                     }
00170                 }
00171 
00172             }
00173             if(this->recursive == true) {
00174                 // we have a directory -> recurse
00175                 string newcwd = cwd + "/" + entry->d_name;
00176                 DIR *directory = opendir(newcwd.c_str());
00177                 if(directory != NULL) {
00178                     dirfound = true;
00179                     scanDir(result,directory,newcwd);
00180                     closedir(directory);
00181                 }
00182             }
00183         }
00184 
00185         if(entry->d_type == DT_REG) {
00186             if((this->option == MMSFILESEARCH_NONE)||(this->option == MMSFILESEARCH_DEEPESTDIR_OF_FILE)) {
00187 
00188                 // we have a regular file -> and want to check it
00189                 if(match(entry->d_name) == true) {
00190                     filefound = true;
00191 
00192                     // we have found sth;
00193                     if((this->option != MMSFILESEARCH_DEEPESTDIR_OF_FILE)&&(this->option != MMSFILESEARCH_DEEPESTDIR)) {
00194 
00195                         //we really really want it
00196                         MMSFILE_ENTRY *file = new MMSFILE_ENTRY;
00197                         file->isdir = false;
00198                         file->name = cwd + "/" + entry->d_name;
00199                         file->basename = entry->d_name;
00200                         file->path = cwd;
00201                         result->push_back(file);
00202                     }
00203                 }
00204             }
00205         }
00206         /* if DT_UNKNOWN it is possible to check stat */
00207         else if(entry->d_type == DT_UNKNOWN) {
00208             struct stat sBuf;
00209             string fname = cwd + "/" + entry->d_name;
00210             if((stat(fname.c_str(), &sBuf) == 0) && (S_ISREG(sBuf.st_mode))) {
00211                 if((this->option == MMSFILESEARCH_NONE)||(this->option == MMSFILESEARCH_DEEPESTDIR_OF_FILE)) {
00212                     // we have a regular file -> and want to check it
00213                     if(match(entry->d_name) == true) {
00214                         filefound = true;
00215 
00216                         // we have found sth;
00217                         if((this->option != MMSFILESEARCH_DEEPESTDIR_OF_FILE)&&(this->option != MMSFILESEARCH_DEEPESTDIR)) {
00218 
00219                             //we really really want it
00220                             MMSFILE_ENTRY *file = new MMSFILE_ENTRY;
00221                             file->isdir = false;
00222                             file->name = cwd + "/" + entry->d_name;
00223                             file->basename = entry->d_name;
00224                             file->path = cwd;
00225                             result->push_back(file);
00226                         }
00227                     }
00228                 }
00229             }
00230             else if(S_ISDIR(sBuf.st_mode)) {
00231                 if(this->recursive == true) {
00232                     // we have a directory -> recurse
00233                     string newcwd = cwd + "/" + entry->d_name;
00234                     DIR *directory = opendir(newcwd.c_str());
00235                     if(directory != NULL) {
00236                         dirfound = true;
00237                         scanDir(result,directory,newcwd);
00238                         closedir(directory);
00239                     }
00240                 }
00241             }
00242         }
00243         entry = readdir(dirhandle);
00244     }
00245 
00246     if((this->option == MMSFILESEARCH_DEEPESTDIR)&&(dirfound == false)) {
00247 
00248         // we have no dirs in here and should return the deepest directory entry
00249         MMSFILE_ENTRY *file = new MMSFILE_ENTRY;
00250         file->isdir = false;
00251         file->name = cwd;
00252         pos = cwd.find_last_of('/');
00253         file->basename = cwd.substr(pos+1);
00254         file->path = cwd.substr(0,pos+1);
00255         result->push_back(file);
00256 
00257     } else if((this->option == MMSFILESEARCH_DEEPESTDIR_OF_FILE)&&(filefound == true)) {
00258 
00259         //we should have at least one file until we really want it
00260         MMSFILE_ENTRY *file = new MMSFILE_ENTRY;
00261         file->isdir = false;
00262         file->name = cwd;
00263         pos = cwd.find_last_of('/');
00264         file->basename = cwd.substr(pos+1);
00265         file->path = cwd.substr(0,pos+1);
00266         result->push_back(file);
00267 
00268     }
00269 }

Generated by doxygen