gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
DirectoryScanner.H
Go to the documentation of this file.
1 /* Copyright 2000-2018 Matt Flax <flatmax@flatmax.org>
2  This file is part of GTK+ IOStream class set
3 
4  GTK+ IOStream is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  GTK+ IOStream is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You have received a copy of the GNU General Public License
15  along with GTK+ IOStream
16  */
17 #ifndef DIRECTORYSCANNER_H_
18 #define DIRECTORYSCANNER_H_
19 
20 #include <errno.h>
21 
22 #include <Debug.H>
23 #define DIRSCAN_OPENDIR_ERROR DIRSCAN_ERROR_OFFSET-1
24 #define DIRSCAN_CLOSEDIR_ERROR DIRSCAN_ERROR_OFFSET-2
25 #define DIRSCAN_NOTOPEN_ERROR DIRSCAN_ERROR_OFFSET-3
26 #define DIRSCAN_CREATEDIR_ERROR DIRSCAN_ERROR_OFFSET-4
27 #define DIRSCAN_DIRDOESNTEXIST_ERROR DIRSCAN_ERROR_OFFSET-5
28 
29 #include <vector>
30 
31 #if defined(_MSC_VER) || defined(__MINGW32__)
33 #include <direct.h>
34 #else
35 #include <sys/stat.h>
36 #include <dirent.h>
37 #include <pwd.h> // for getHomeDir
38 #include <unistd.h> // for getHomeDir
39 #endif
40 #include <string.h>
41 
44 class DirectoryScannerDebug : public Debug {
45 public:
49 #ifndef NDEBUG
50  errors[DIRSCAN_OPENDIR_ERROR]=std::string("Error when trying to open the directory ");
51  errors[DIRSCAN_CLOSEDIR_ERROR]=std::string("Error when trying to close the directory. ");
52  errors[DIRSCAN_NOTOPEN_ERROR]=std::string("You must open the directory first. ");
53  errors[DIRSCAN_CREATEDIR_ERROR]=std::string("Could not create the directory named : ");
54  errors[DIRSCAN_DIRDOESNTEXIST_ERROR]=std::string("Could not find that directory : ");
55 
56 #endif
57  }
58 };
59 
63 class DirectoryScanner : public std::vector<std::string> {
64  DIR *dir;
65  std::string path;
66 public:
70  dir=NULL;
71  }
72 
76  DirectoryScanner(std::string path) {
77  dir=NULL;
78  open(path);
79  }
80 
81  virtual ~DirectoryScanner() {
82  if (dir)
83  close();
84  }
85 
90  int open(std::string path) {
91  if (dir)
92  close();
93  dir = opendir(path.c_str()); // open the directory
94  if (!dir) {
95  char *errStr=strerror(errno);
96  return DirectoryScannerDebug().evaluateError(DIRSCAN_OPENDIR_ERROR, path+". "+*errStr);
97  }
98  return NO_ERROR;
99  }
100 
104  int close(void) {
105  int ret=closedir(dir); // close the directory
106  if (ret==-1) {
107  char *errStr=strerror(errno);
108  return DirectoryScannerDebug().evaluateError(DIRSCAN_CLOSEDIR_ERROR, std::string(errStr));
109  }
110  resize(0); // remove any previous entries
111  path="";
112  return NO_ERROR;
113  }
114 
119  int findAll(const std::vector<std::string> &dontInclude) {
120  if (!dir)
121  return DirectoryScannerDebug().evaluateError(DIRSCAN_NOTOPEN_ERROR);
122  const struct dirent *ent;
123  rewinddir(dir); // go to the beginning
124  while (ent = readdir(dir), ent != NULL) {
125  bool excluded=false;
126  //cout<<ent->d_name<<endl;
127  for (unsigned int i=0; i<dontInclude.size(); i++){
128  //cout<<"\t\t"<<dontInclude[i]<<'\t'<<strcmp(dontInclude[i].c_str(), ent->d_name)<<endl;
129  if (strcmp(dontInclude[i].c_str(), ent->d_name)==0) {
130  excluded=true;
131  break;
132  }
133  }
134  if (!excluded) // if not excluded then add to the list
135  push_back(std::string(ent->d_name));
136  }
137  /* discern for the following on d_type in future - although not supported by all systems
138  DT_BLK This is a block device.
139  DT_CHR This is a character device.
140  DT_DIR This is a directory.
141  DT_FIFO This is a named pipe (FIFO).
142  DT_LNK This is a symbolic link.
143  DT_REG This is a regular file.
144  DT_SOCK This is a UNIX domain socket.
145  DT_UNKNOWN The file type is unknown.
146  */
147  return NO_ERROR;
148  }
149 
153  void keepWithPattern(const std::string pattern){
154  for (int i=size()-1; i>=0; i--) // remove any elements which don't match the pattern
155  if (operator[](i).find(pattern)==std::string::npos)
156  erase(begin()+i);
157  }
158 
162  std::string getPath(){
163  return path;
164  }
165 
166  #if !defined(_MSC_VER) && !defined(__MINGW32__)
167 
170  static std::string getHomeDir(){
171  struct passwd *pw = getpwuid(getuid());
172  if (pw)
173  return std::string(pw->pw_dir);
174  else
175  return std::string();
176  }
177 #endif
178 
181 #if !defined(_MSC_VER) && !defined(__MINGW32__)
182  static int mkDir(const std::string &pathname, mode_t mode){
183  printf("hi2 \n");
184  std::string cmd("mkdir -p ");
185  cmd+=pathname;
186  printf("%s\n",cmd.c_str());
187  int ret=system(cmd.c_str());
188  printf("%d\n",ret);
189  if (ret!=0) { // onfailure try with mkdir
190  int res=mkdir(pathname.c_str(), mode);
191  if (res==EDQUOT)
192  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+". The user's quota of disk blocks or inodes on the filesystem has been exhausted.");
193  if (res==EFAULT)
194  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+" points outside your accessible address space.");
195  if (res==ELOOP)
196  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+". Too many symbolic links were encountered in resolving pathname.");
197  if (res==ELOOP)
198  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+". Too many symbolic links were encountered in resolving pathname.");
199  if (res==EMLINK)
200  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+". The number of links to the parent directory would exceed LINK_MAX.");
201  if (res==ENAMETOOLONG)
202  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+" was too long.");
203  if (res==ENOENT)
204  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+". A directory component in pathname does not exist or is a dangling symbolic link.");
205  if (res==ENOMEM)
206  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+". Insufficient kernel memory was available.");
207  if (res==ENOSPC)
208  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+". The device containing pathname has no room for the new directory.");
209 
210  if (res==ENOSPC)
211  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+". The new directory cannot be created because the user's disk quota is exhausted.");
212  if (res==ENOTDIR)
213  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+". A component used as a directory in pathname is not, in fact, a directory.");
214  if (res==EPERM )
215  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+". The filesystem containing pathname does not support the creation of directories.");
216  if (res==EROFS)
217  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+" refers to a file on a read-only filesystem.");
218  if (res==EACCES)
219  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+". The parent directory does not allow write permission to the process, or one of the directories in pathname did not allow search permission.");
220  if (res==EEXIST)
221  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+" already exists");
222  }
223 #else
224  static int mkDir(const std::string &pathname) {
225  printf("hi1 \n");
226  int res=_mkdir(pathname.c_str());
227  if (res==ENOENT)
228  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+" the path couldn't be found");
229  if (res==EEXIST)
230  return DirectoryScannerDebug().evaluateError(DIRSCAN_CREATEDIR_ERROR, pathname+" already exists");
231 #endif
232  return NO_ERROR;
233  }
234 };
235 
236 #endif // DIRECTORYSCANNER_H_
size(signal)
static std::string getHomeDir()
static DIR * opendir(const char *dirname)
Definition: dirent.h:591
std::string getPath()
#define DIRSCAN_NOTOPEN_ERROR
Error when the directory hasn&#39;t been open yet.
char d_name[PATH_MAX]
Definition: dirent.h:275
Definition: dirent.h:270
std::map< int, std::string > errors
This will contain a map between error numbers and descriptive std::strings for the errors...
Definition: Debug.H:115
#define NO_ERROR
There is no error.
Definition: Debug.H:33
Definition: dirent.h:279
DirectoryScanner(std::string path)
#define DIRSCAN_CREATEDIR_ERROR
Error when the directory hasn&#39;t been open yet.
int open(std::string path)
int findAll(const std::vector< std::string > &dontInclude)
virtual ~DirectoryScanner()
static struct dirent * readdir(DIR *dirp)
Definition: dirent.h:661
#define DIRSCAN_DIRDOESNTEXIST_ERROR
Error when the directory hasn&#39;t been open yet.
static void rewinddir(DIR *dirp)
Definition: dirent.h:771
Definition: Debug.H:112
#define DIRSCAN_CLOSEDIR_ERROR
Error when the specified dir doesn&#39;t close successfully.
void keepWithPattern(const std::string pattern)
static int closedir(DIR *dirp)
Definition: dirent.h:744
static int mkDir(const std::string &pathname, mode_t mode)
#define DIRSCAN_OPENDIR_ERROR
Error when the specified directory can&#39;t be found.
gtkIOStream: /tmp/gtkiostream/include/DirectoryScanner.H Source File
GTK+ IOStream  Beta