• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

_FindFirst.cpp

Go to the documentation of this file.
00001 
00005 #if (defined(__GNUC__)  || defined(__GCCXML__)) && !defined(__WIN32)
00006 #include "_FindFirst.h"
00007 #include "DS_List.h"
00008 
00009 #include <sys/stat.h>
00010 #if !defined(_PS3) && !defined(__PS3__) && !defined(SN_TARGET_PS3)
00011 #include <fnmatch.h>
00012 #endif
00013 
00014 static DataStructures::List< _findinfo_t* > fileInfo;
00015         
00016 #include "RakMemoryOverride.h"
00017 #include "RakAssert.h"
00018 
00022 long _findfirst(const char *name, _finddata_t *f)
00023 {
00024         RakNet::RakString nameCopy = name;
00025         RakNet::RakString filter;
00026 
00027         // This is linux only, so don't bother with '\'
00028         const char* lastSep = strrchr(name,'/');
00029         if(!lastSep)
00030         {
00031             // filter pattern only is given, search current directory.
00032             filter = nameCopy;
00033             nameCopy = ".";
00034         } else
00035         {
00036             // strip filter pattern from directory name, leave
00037             // trailing '/' intact.
00038             filter = lastSep+1;
00039             unsigned sepIndex = lastSep - name;
00040             nameCopy.Erase(sepIndex+1, nameCopy.GetLength() - sepIndex-1);
00041         }
00042 
00043         DIR* dir = opendir(nameCopy);
00044         
00045         if(!dir) return -1;
00046 
00047         _findinfo_t* fi = RakNet::OP_NEW<_findinfo_t>( __FILE__, __LINE__ );
00048         fi->filter    = filter;
00049         fi->dirName   = nameCopy;  // we need to remember this for stat()
00050         fi->openedDir = dir;
00051         fileInfo.Insert(fi, __FILE__, __LINE__);
00052 
00053         long ret = fileInfo.Size()-1;
00054 
00055         // Retrieve the first file. We cannot rely on the first item
00056         // being '.'
00057         if (_findnext(ret, f) == -1) return -1;
00058         else return ret;
00059 }
00060 
00061 #if defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3)
00062                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
00063 #else
00064 int _findnext(long h, _finddata_t *f)
00065 {
00066         RakAssert(h >= 0 && h < (long)fileInfo.Size());
00067         if (h < 0 || h >= (long)fileInfo.Size()) return -1;
00068         
00069         _findinfo_t* fi = fileInfo[h];
00070 
00071         while(true)
00072         {
00073                 dirent* entry = readdir(fi->openedDir);
00074                 if(entry == 0) return -1;
00075 
00076                 // Only report stuff matching our filter
00077                 if (fnmatch(fi->filter, entry->d_name, FNM_PATHNAME) != 0) continue;
00078 
00079                 // To reliably determine the entry's type, we must do
00080                 // a stat...  don't rely on entry->d_type, as this
00081                 // might be unavailable!
00082                 struct stat filestat;
00083                 RakNet::RakString fullPath = fi->dirName + entry->d_name;             
00084                 if (stat(fullPath, &filestat) != 0)
00085                 {
00086                     RAKNET_DEBUG_PRINTF("Cannot stat %s\n", fullPath.C_String());
00087                     continue;
00088                 }
00089 
00090                 if (S_ISREG(filestat.st_mode))
00091                 {
00092                     f->attrib = _A_NORMAL;
00093                 } else if (S_ISDIR(filestat.st_mode))
00094                 {
00095                     f->attrib = _A_SUBDIR;                    
00096                 } else continue; // We are interested in files and
00097                                  // directories only. Links currently
00098                                  // are not supported.
00099 
00100                 f->size = filestat.st_size;
00101                 strncpy(f->name, entry->d_name, STRING_BUFFER_SIZE);
00102                 
00103                 return 0;
00104         }
00105 
00106         return -1;
00107 }
00108 #endif
00109 
00110 
00111 
00112 
00116 int _findclose(long h)
00117 {
00118     if (h==-1) return 0;
00119    
00120     if (h < 0 || h >= (long)fileInfo.Size())
00121     {
00122         RakAssert(false);
00123         return -1;
00124     }
00125 
00126     _findinfo_t* fi = fileInfo[h];
00127     closedir(fi->openedDir);
00128     fileInfo.RemoveAtIndex(h);
00129     RakNet::OP_DELETE(fi, __FILE__, __LINE__);
00130     return 0;   
00131 }
00132 #endif

Generated on Thu Sep 30 2010 01:27:21 for RakNet by  doxygen 1.7.1