00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032 #ifdef HAVE_CONFIG_H
00033 #include "autoconfig.h"
00034 #endif
00035
00036 #include <sys/types.h>
00037 #include <sys/stat.h>
00038 #include <dirent.h>
00039
00040 #include "common.h"
00041 #include "config_manager.h"
00042 #include "content_manager.h"
00043 #include "filesystem.h"
00044 #include "mxml/mxml.h"
00045 #include "tools.h"
00046
00047 using namespace zmm;
00048 using namespace mxml;
00049
00050 int FsObjectComparator(void *arg1, void *arg2)
00051 {
00052 FsObject *o1 = (FsObject *)arg1;
00053 FsObject *o2 = (FsObject *)arg2;
00054 if (o1->isDirectory)
00055 {
00056 if (o2->isDirectory)
00057 return strcmp(o1->filename.c_str(), o2->filename.c_str());
00058 else
00059 return -1;
00060 }
00061 else
00062 {
00063 if (o2->isDirectory)
00064 return 1;
00065 else
00066 return strcmp(o1->filename.c_str(), o2->filename.c_str());
00067 }
00068 }
00069
00070 Filesystem::Filesystem() : Object()
00071 {
00072 includeRules = Ref<Array<RExp> >(new Array<RExp>());
00073 Ref<ConfigManager> cm = ConfigManager::getInstance();
00074
00075
00076
00077
00078
00079
00080
00081
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 }
00097
00098 Ref<Array<FsObject> > Filesystem::readDirectory(String path, int mask,
00099 int childMask)
00100 {
00101 if (path.charAt(0) != '/')
00102 {
00103 throw _Exception(_("Filesystem: relative paths not allowed: ") +
00104 path);
00105 }
00106 if (! fileAllowed(path))
00107 throw _Exception(_("Filesystem: file blocked: ") + path);
00108
00109 struct stat statbuf;
00110 int ret;
00111
00112 Ref<Array<FsObject> > files(new Array<FsObject>());
00113
00114 DIR *dir;
00115 struct dirent *dent;
00116
00117 dir = opendir(path.c_str());
00118 if (! dir)
00119 {
00120 throw _Exception(_("could not list directory ") +
00121 path + " : " + strerror(errno));
00122 }
00123
00124 while ((dent = readdir(dir)) != NULL)
00125 {
00126 char *name = dent->d_name;
00127 if (name[0] == '.')
00128 {
00129 if (name[1] == 0)
00130 {
00131 continue;
00132 }
00133 else if (name[1] == '.' && name[2] == 0)
00134 {
00135 continue;
00136 }
00137 else if (!(mask & FS_MASK_HIDDEN))
00138 continue;
00139 }
00140 String childPath;
00141 if (path == FS_ROOT_DIRECTORY)
00142 childPath = path + name;
00143 else
00144 childPath = path + "/" + name;
00145 if (fileAllowed(childPath))
00146 {
00147 bool isDirectory = false;
00148 bool hasContent = false;
00149 ret = stat(childPath.c_str(), &statbuf);
00150 if (ret != 0)
00151 continue;
00152 if (S_ISREG(statbuf.st_mode))
00153 {
00154 if (! (mask & FS_MASK_FILES))
00155 continue;
00156 }
00157 else if (S_ISDIR(statbuf.st_mode))
00158 {
00159 if (! (mask & FS_MASK_DIRECTORIES))
00160 continue;
00161 isDirectory = true;
00162 if (childMask)
00163 {
00164 try
00165 {
00166 hasContent = have(childPath, childMask);
00167 }
00168 catch (Exception e)
00169 {
00170
00171 }
00172 }
00173 }
00174 else
00175 continue;
00176
00177 Ref<FsObject> obj(new FsObject());
00178 obj->filename = name;
00179 obj->isDirectory = isDirectory;
00180 obj->hasContent = hasContent;
00181 files->append(obj);
00182 }
00183 }
00184 closedir(dir);
00185
00186 quicksort((COMPARABLE *)files->getObjectArray(), files->size(),
00187 FsObjectComparator);
00188
00189 return files;
00190 }
00191
00192 bool Filesystem::have(String path, int mask)
00193 {
00194
00195
00196
00197
00198
00199
00200
00201 if (! fileAllowed(path))
00202 return false;
00203
00204 struct stat statbuf;
00205 int ret;
00206
00207 Ref<Array<FsObject> > files(new Array<FsObject>());
00208
00209 DIR *dir;
00210 struct dirent *dent;
00211
00212 dir = opendir(path.c_str());
00213 if (! dir)
00214 {
00215 throw _Exception(_("could not list directory ")+
00216 path + " : " + strerror(errno));
00217 }
00218
00219 bool result = false;
00220 while ((dent = readdir(dir)) != NULL)
00221 {
00222 char *name = dent->d_name;
00223 if (name[0] == '.')
00224 {
00225 if (name[1] == 0)
00226 {
00227 continue;
00228 }
00229 else if (name[1] == '.' && name[2] == 0)
00230 {
00231 continue;
00232 }
00233 else if (!(mask & FS_MASK_HIDDEN))
00234 continue;
00235 }
00236 String childPath;
00237 if (path == FS_ROOT_DIRECTORY)
00238 childPath = path + name;
00239 else
00240 childPath = path + "/" + name;
00241 if (fileAllowed(childPath))
00242 {
00243 ret = stat(childPath.c_str(), &statbuf);
00244 if (ret != 0)
00245 continue;
00246 if (S_ISREG(statbuf.st_mode) && mask & FS_MASK_FILES)
00247 {
00248 result = true;
00249 break;
00250 }
00251 else if (S_ISDIR(statbuf.st_mode) && mask & FS_MASK_DIRECTORIES)
00252 {
00253 result = true;
00254 break;
00255 }
00256 else
00257 continue;
00258 }
00259 }
00260 closedir(dir);
00261 return result;
00262 }
00263
00264 bool Filesystem::haveFiles(String dir)
00265 {
00266 return have(dir, FS_MASK_FILES);
00267 }
00268 bool Filesystem::haveDirectories(String dir)
00269 {
00270 return have(dir, FS_MASK_DIRECTORIES);
00271 }
00272
00273 bool Filesystem::fileAllowed(String path)
00274 {
00275 if (path == ConfigManager::getInstance()->getConfigFilename())
00276 return false;
00277
00278 return true;
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 }