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 #include "filemanager.h"
00027 #include <assert.h>
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include <stdlib.h>
00031
00032 FileManager *fileManagerPtr=0;
00033
00034
00035 #ifdef HAVE_CONFIG_H
00036 # include <config.h>
00037 #else
00038 # ifdef WIN32
00039 # define PACKAGE_DATA_DIR ".."
00040 # define PACKAGE_SOURCE_DIR "../.."
00041 # else
00042 # define PACKAGE_DATA_DIR ".."
00043 # define PACKAGE_SOURCE_DIR SRC_PATH
00044 # endif
00045 #endif
00046
00047
00048 #ifdef WIN32
00049 # include <windows.h>
00050 # include <io.h>
00051 #else
00052 # include <sys/types.h>
00053 #ifdef WITH_DIRECTORY_LISTING
00054 # include <dirent.h>
00055 #endif
00056 # include <sys/stat.h>
00057 #endif
00058
00059 FileManager::FileManager()
00060 {
00061 addDir(".");
00062 addDir(PACKAGE_DATA_DIR);
00063 addDir(PACKAGE_SOURCE_DIR);
00064 #ifdef WITH_DIRECTORY_LISTING
00065 fileListIndex=-1;
00066 #endif
00067 dirListIndexCache=-1;
00068
00069
00070
00071 }
00072
00073 FileManager::~FileManager()
00074 {
00075 clearDirList();
00076 #ifdef WITH_DIRECTORY_LISTING
00077 clearFileList();
00078 #endif
00079 }
00080
00081 void FileManager::clearDirList(void)
00082 {
00083 for (std::vector<const char *>::iterator dirListIterator=dirList.begin(); dirListIterator!=dirList.end(); ++dirListIterator)
00084 {
00085 delete[] const_cast<char*>(*dirListIterator);
00086 }
00087 dirList.clear();
00088 }
00089
00090 #ifdef WITH_DIRECTORY_LISTING
00091 void FileManager::clearFileList(void)
00092 {
00093 for (std::vector<const char *>::iterator fileListIterator=fileList.begin(); fileListIterator!=fileList.end(); ++fileListIterator)
00094 {
00095 delete[] const_cast<char*>(*fileListIterator);
00096 }
00097 fileList.clear();
00098 fileListIndex=-1;
00099 }
00100 #endif
00101
00102 void FileManager::addDir(const char *dir)
00103 {
00104 int len=strlen(dir);
00105 char *newDir=new char[len+1];
00106 strncpy(newDir, dir, len+1);
00107 dirList.push_back(newDir);
00108 dirListIndexCache=0;
00109 }
00110
00111 FILE *FileManager::openWithbackupFP(const char *filename, const char *mode)
00112 {
00113 if (strchr(mode, 'w'))
00114 {
00115 char backupText[512];
00116 snprintf(backupText, sizeof(backupText), "%s~", filename);
00117 rename(filename, backupText);
00118 }
00119 return fopen(filename, mode);
00120 }
00121
00122 FILE *FileManager::openFP(const char *filename, const char *mode, bool verboseIfNotFound)
00123 {
00124 std::vector<const char *>::iterator dirListIterator;
00125
00126 if (filename && (filename[0] == '/'))
00127 return fopen(filename, mode);
00128
00129
00130 if ((strchr(mode, 'w')==NULL) && (dirListIndexCache>=0))
00131 {
00132 int allocatedLength=strlen(filename) + strlen(dirList[dirListIndexCache]) + 2;
00133 char *fn = new char[allocatedLength];
00134 snprintf(fn, allocatedLength, "%s%c%s", dirList[dirListIndexCache], DIR_SEPARATOR ,filename);
00135 FILE *fp = openWithbackupFP(fn, mode);
00136 delete[] fn;
00137 if (fp)
00138 return fp;
00139 }
00140
00141
00142 int index=0;
00143 for (dirListIterator=dirList.begin(); dirListIterator!=dirList.end(); ++dirListIterator)
00144 {
00145 int allocatedLength=strlen(filename) + strlen(dirList[index]) + 2;
00146 char *fn = new char[allocatedLength];
00147 snprintf(fn, allocatedLength, "%s%c%s", *dirListIterator, DIR_SEPARATOR ,filename);
00148
00149 FILE *fp = openWithbackupFP(fn, mode);
00150
00151 delete[] fn;
00152 if (fp)
00153 {
00154 dirListIndexCache=index;
00155 return fp;
00156 }
00157 index++;
00158 }
00159
00160 if (verboseIfNotFound)
00161 {
00162 fprintf(stderr, "FILE %s not found in mode %s.\n", filename, mode);
00163 fprintf(stderr, "Searched path :\n");
00164 for (dirListIterator=dirList.begin(); dirListIterator!=dirList.end(); ++dirListIterator)
00165 {
00166 printf("%s\n", *dirListIterator);
00167 }
00168 }
00169
00170 return NULL;
00171 }
00172
00173 void FileManager::remove(const char *filename)
00174 {
00175 std::vector<const char *>::iterator dirListIterator;
00176
00177
00178 for (dirListIterator=dirList.begin(); dirListIterator!=dirList.end(); ++dirListIterator)
00179 {
00180 int allocatedLength=strlen(filename) + strlen(*dirListIterator) + 2;
00181 char *fn = new char[allocatedLength];
00182 snprintf(fn, allocatedLength, "%s%c%s", *dirListIterator, DIR_SEPARATOR ,filename);
00183 remove(fn);
00184 }
00185 }
00186
00187 #ifdef WITH_DIRECTORY_LISTING
00188 bool FileManager::addListingForDir(const char *realDir, const char *extension)
00189 {
00190 #ifdef WIN32
00191 WIN32_FIND_DATA wfd;
00192 HANDLE hFind = NULL;
00193 BOOL b = TRUE;
00194
00195 char temp[MAX_PATH];
00196 char real[MAX_PATH];
00197 memset(real, 0, MAX_PATH);
00198
00199 if (!realDir)
00200 return false;
00201
00202 if (!strncmp(realDir, "../", 3))
00203 return true;
00204
00205 if (!strcmp(realDir, "./.") || !strcmp(realDir, "./"))
00206 memcpy(real, ".", 1);
00207 else
00208 memcpy(real, realDir, strlen(realDir) + 1);
00209
00210
00211 memset(temp, 0, MAX_PATH);
00212 sprintf(temp, "%s%c*", real, DIR_SEPARATOR);
00213 hFind = FindFirstFile(temp, &wfd);
00214 while (b) {
00215 if (!strncmp(wfd.cFileName, "..", 2))
00216 {
00217 b = FindNextFile(hFind, &wfd);
00218 continue;
00219 }
00220 if (!strncmp(wfd.cFileName, ".", 1))
00221 {
00222 b = FindNextFile(hFind, &wfd);
00223 continue;
00224 }
00225 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
00226 {
00227 memset(temp, 0, MAX_PATH);
00228 sprintf(temp, "%s%c%s", real, DIR_SEPARATOR, wfd.cFileName);
00229 addListingForDir(temp, extension);
00230 }
00231 b = FindNextFile(hFind, &wfd);
00232 }
00233
00234 b = TRUE;
00235
00236 memset(temp, 0, MAX_PATH);
00237 if (extension)
00238 sprintf(temp, "%s%c*.%s", real,DIR_SEPARATOR, extension);
00239 else
00240 sprintf(temp, "%s%c*", real, DIR_SEPARATOR);
00241 hFind = FindFirstFile(temp, &wfd);
00242 if (hFind == INVALID_HANDLE_VALUE) return true;
00243 while (b) {
00244 if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
00245 {
00246
00247 bool alreadyIn=false;
00248 for (std::vector<const char *>::iterator fileListIterator=fileList.begin(); (fileListIterator!=fileList.end())&&(alreadyIn==false); ++fileListIterator)
00249 {
00250 memset(temp, 0, MAX_PATH);
00251 sprintf(temp, "%s%c%s", real, DIR_SEPARATOR, wfd.cFileName);
00252 if (strcmp(temp, *fileListIterator)==0)
00253 alreadyIn=true;
00254 }
00255 if (!alreadyIn)
00256 {
00257 int len=strlen(wfd.cFileName) + strlen(real) + 2;
00258 char *fileName=new char[len];
00259 memset(fileName, 0, len);
00260 sprintf(fileName, "%s%c%s", real, DIR_SEPARATOR, wfd.cFileName);
00261 fileList.push_back(fileName);
00262 }
00263 }
00264 b = FindNextFile(hFind, &wfd);
00265 }
00266
00267 #else // angel > plus Win32 (system primate)
00268 DIR *dir=opendir(realDir);
00269 struct dirent *dirEntry;
00270
00271 if (!dir)
00272 {
00273 #ifdef DBG_VPATH_LIST
00274 fprintf(stderr, "Open dir failed for dir %s\n", realDir);
00275 #endif
00276 return false;
00277 }
00278
00279 while ((dirEntry=readdir(dir))!=NULL)
00280 {
00281 #ifdef DBG_VPATH_LIST
00282 fprintf(stderr, "%s\n", dirEntry->d_name);
00283 #endif
00284 int l, nl;
00285 l=strlen(extension);
00286 nl=strlen(dirEntry->d_name);
00287 if ((nl>l) &&
00288 (dirEntry->d_name[nl-l-1]=='.') &&
00289 (strcmp(extension,dirEntry->d_name+(nl-l))==0))
00290 {
00291
00292 bool alreadyIn=false;
00293 for (std::vector<const char *>::iterator fileListIterator=fileList.begin(); (fileListIterator!=fileList.end())&&(alreadyIn==false); ++fileListIterator)
00294 {
00295 if (strcmp(dirEntry->d_name, *fileListIterator)==0)
00296 alreadyIn=true;
00297 }
00298 if (!alreadyIn)
00299 {
00300 int len=strlen(dirEntry->d_name)+1;
00301 char *fileName=new char[len];
00302 strncpy(fileName, dirEntry->d_name, len);
00303 fileList.push_back(fileName);
00304 }
00305 }
00306 }
00307
00308 closedir(dir);
00309 #endif // angel > end of comentaire primate
00310 return true;
00311 }
00312
00313 bool FileManager::initDirectoryListing(const char *virtualDir, const char *extension)
00314 {
00315 bool result=false;
00316 clearFileList();
00317 for (std::vector<const char *>::iterator dirListIterator=dirList.begin(); dirListIterator!=dirList.end(); ++dirListIterator)
00318 {
00319 int allocatedLength=strlen(virtualDir) + strlen(*dirListIterator) + 2;
00320 char *dn = new char[allocatedLength];
00321 snprintf(dn, allocatedLength, "%s%c%s", *dirListIterator, DIR_SEPARATOR ,virtualDir);
00322 #ifdef DBG_VPATH_LIST
00323 fprintf(stderr, "Listing from dir %s :\n", dn);
00324 #endif
00325 result=addListingForDir(dn, extension) || result;
00326 delete[] dn;
00327 }
00328 if (result)
00329 fileListIndex=0;
00330 else
00331 fileListIndex=-1;
00332 return result;
00333 }
00334
00335 const char *FileManager::getNextDirectoryEntry(void)
00336 {
00337 if ((fileListIndex>=0) && (fileListIndex<(signed)fileList.size()))
00338 {
00339 return fileList[fileListIndex++];
00340 }
00341 return NULL;
00342 }
00343 #endif
00344