Main Page   Class Hierarchy   File List  

ocFileSys.h

00001 #ifndef OC_FILE_SYS_H
00002 #define OC_FILE_SYS_H
00003 
00004 #include "ocString.h"
00005 #include <stdio.h>
00006 #include <sys/stat.h>
00007 #include <unistd.h>
00008 #include <sys/types.h>
00009 #include <dirent.h>
00010 #include <fstream>
00011 #include <vector>
00012 #include <string>
00013 /*
00014   make a directory entry class
00015   just complete enough
00016   class to work with STL
00017 */
00018 struct ocDirEntry
00019 {
00020   string name;
00021   ino_t fileno;
00022   unsigned char type;
00023     
00024   mode_t file_mode;
00025   uid_t file_uid;
00026   gid_t file_gid;
00027   off_t file_size;
00028   time_t last_access;
00029   time_t last_mod;
00030   time_t last_statchg;
00031 
00032   ocDirEntry():fileno(0),type(0),
00033   file_mode(0),file_uid(0),file_gid(0),file_size(0),last_access(0),last_mod(0),last_statchg(0)
00034   {;}
00035   ocDirEntry(dirent * pin, string path):fileno(0),type(0),
00036   file_mode(0),file_uid(0),file_gid(0),file_size(0),last_access(0),last_mod(0),last_statchg(0)  
00037   {
00038     if(pin)
00039     {
00040       name = pin->d_name;
00041       fileno = pin->d_fileno;
00042       type = pin->d_type;      
00043       struct stat buf;
00044       path +="/";
00045       path += name;
00046       int ret = stat(path.c_str(), &buf);
00047       if( ret==0 )
00048       {
00049         file_mode = buf.st_mode;    //mode of file (see below)
00050         file_uid = buf.st_uid;     //user ID of file
00051         file_gid = buf.st_gid;     //group ID of file
00052         file_size = buf.st_size;    //file size in bytes (if file is a regular file)
00053         last_access = buf.st_atime;   //time of last access
00054         last_mod = buf.st_mtime;   //time of last data modification
00055         last_statchg = buf.st_ctime;   //time of last status change
00056       }      
00057     }
00058   }
00059   ocDirEntry( const ocDirEntry & in )
00060   :name(in.name),fileno(in.fileno),type(in.type){;}
00061   ocDirEntry & operator = ( const ocDirEntry & in )
00062   {
00063     name = in.name;
00064     fileno = in.fileno;
00065     type = in.type;
00066     return * this;
00067   }
00068   virtual ~ocDirEntry(){;}
00069 };
00070 
00071 typedef vector<ocDirEntry> ocDirectory;
00072 
00073 class ocFileSys
00074 {
00075   DIR *dp;
00076   struct dirent *ep;
00077   mode_t mode;
00078   ocDirectory m_directory;
00079   int rc;
00080   string error;
00081 
00082 public:
00083   ocFileSys():dp(NULL),ep(NULL)
00084   {
00085     // default mode is 773
00086     mode = S_IRUSR | S_IWUSR | S_IXUSR |
00087            S_IRGRP | S_IWGRP | S_IXGRP |
00088            S_IROTH | S_IXOTH;
00089   }
00090   ~ocFileSys()
00091   {
00092 
00093   }
00094   /*
00095     mode is used to set file attribute 'rwx'
00096      for user group and public
00097   */
00098   void setMode( mode_t in )
00099   {
00100     mode = in;
00101   }
00102   // remove a file
00103   bool remove( string path )
00104   {
00105     rc = ::remove( path.c_str() );    
00106     return rc == 0;
00107   }      
00108   
00109   string check( void )
00110   {
00111     error = "";
00112     if(rc)
00113     {
00114       if( errno == EFAULT )
00115       {
00116         error = "EFAULT pathname points outside your accessible address space.";
00117       }  
00118       if( errno == EACCES )
00119       {
00120         error = "EACCES Write access to the directory containing pathname is not allowed "
00121         "     for the process's effective uid, or one of  the  directories  in"
00122         "     pathname did not allow search (execute) permission.";
00123       } 
00124       if( errno == EPERM )
00125       { 
00126         error = "EPERM The  directory  containing pathname has the sticky-bit (S_ISVTX) "
00127         "   set and the process's effective uid is neither the  uid  of  the "
00128         "   file to be deleted nor that of the directory containing it. ";
00129       }
00130       if( errno == ENAMETOOLONG ) 
00131       {
00132         error = "ENAMETOOLONG pathname was too long.";
00133       }
00134       if(  errno == ENOENT )
00135       {
00136         error = "ENOENT A  directory  component  in pathname does not exist or is a dangling symbolic link.";
00137       } 
00138       if(  errno == ENOTDIR)
00139       {
00140         error = "ENOTDIR A component used as a directory in pathname is not, in  fact,  a directory.";
00141       }
00142       if(  errno == ENOMEM )
00143       {
00144           error = "ENOMEM Insufficient kernel memory was available.";
00145       }
00146       if(  errno == EROFS )
00147       {
00148         error = "EROFS pathname refers to a file on a read-only filesystem.";
00149       } 
00150     }
00151     return error;
00152   }
00153   // rename a file
00154   bool rename( string path, string newpath )
00155   {
00156     rc = ::rename( path.c_str(), newpath.c_str() );
00157     return rc == 0;
00158   }
00159   bool copy( string path, string newpath )
00160   {
00161     bool isOK = false;    
00162     ifstream src(path.c_str(), ifstream::in | ifstream::binary);
00163     ofstream tgt(newpath.c_str(), ifstream::trunc | ifstream::binary);    
00164     if( src.good() && tgt.good() )
00165     {
00166       // get length of file:
00167       src.seekg (0, ios::end);
00168       int length = src.tellg();
00169       src.seekg (0, ios::beg);
00170       // allocate memory:
00171       char * buffer = new char [length];            
00172       if( length > 0 && buffer )
00173       {
00174         // read data as a block:
00175         src.read (buffer,length);
00176         tgt.write(buffer,length);
00177         delete [] buffer;  // free memory  
00178         src.close();  // close files
00179         tgt.close();
00180         isOK = true;
00181       }   
00182     }    
00183     return isOK;
00184   }
00185   bool is( string path )
00186   {
00187     rc = access(path.c_str(), F_OK);
00188     return rc == 0;
00189   }
00190   /*
00191     open the directory and get all of the directory entries.
00192   */
00193   bool openDir( string path )
00194   {
00195     bool bRet = false;
00196     dp = opendir( path.c_str() );
00197     if(dp)
00198     {
00199       while (ep = readdir (dp))
00200       {
00201         ocDirEntry temp(ep,path);
00202         m_directory.push_back(temp);
00203       }
00204       closedir (dp);
00205       bRet = true;
00206     }
00207     return bRet;
00208   }
00209   ocDirectory & getDirectoryEntries( void )
00210   {
00211     return m_directory;
00212   }
00213   bool isDir( string path )
00214   {
00215     bool bRet = false;
00216     struct stat buf;
00217     int ret = stat(path.c_str(), &buf);
00218     if( ret==0 && S_ISDIR(buf.st_mode) )
00219     {
00220       bRet = true;
00221     }
00222     return bRet;
00223   }
00224   off_t fileSize( string path )
00225   {
00226     off_t size = 0;
00227     struct stat buf;
00228     int ret = stat(path.c_str(), &buf);
00229     if( ret==0 )
00230     {
00231       size = buf.st_size;
00232     }
00233     return size;
00234   }
00235   bool makeDir( string dir )
00236   {
00237     bool bRet = false;
00238     bRet = (mkdir( dir.c_str(), mode) == 0);
00239     return bRet;
00240   }
00241 
00242   bool makePath( string path )
00243   {
00244     bool bRet = false;
00245     // make sure there is a path
00246     if( path.length() )
00247     {
00248       string buildpath("");
00249       // see if it is pathed from root
00250       if( path[0] == '/' ) buildpath = "/";
00251       ocString pathParts(path);
00252       while( !pathParts.endOfParse() )
00253       {
00254         buildpath += pathParts.parse("/");
00255         buildpath += "/";
00256         if( isDir( buildpath ) == false )
00257         {
00258            makeDir( buildpath );
00259         }
00260       }
00261       // break the path into sub elements
00262     }
00263     return bRet;
00264   }
00265 };
00266 
00267 #endif
00268 /*
00269 // example usage and testing
00270 int main( int ac, char * av[] )
00271 {
00272   if( ac == 2 )
00273   {
00274     cout << "Is " << av[1] << " a Dir?" << endl;
00275     ocFileSys ocFS;
00276     cout << (ocFS.isDir( av[1] )?"YES!":"NO!") << endl;
00277     cout << "Is " << av[1] << " There?" << endl;
00278     cout << (ocFS.is( av[1] )?"YES!":"NO!") << endl;
00279     cout << "in any case, make it a path..." << endl;
00280     ocFS.makePath( av[1] );
00281   }
00282   {
00283     ocFileSys fs;
00284     if( fs.openDir(av[1]) )
00285     {
00286       ocDirectory & entries = fs.getDirectoryEntries();
00287       for(int i = 0; i < entries.size(); i++ )
00288       {
00289         cout << " fNo: " << entries[i].fileno
00290              << " fType: " << (int)(entries[i].type)
00291              << " Name: " << entries[i].name << endl;
00292       }
00293       cout << entries.size() << endl;
00294     }
00295   }
00296   return 0;
00297 }
00298 */
00299 /*
00300    - Data Type: struct dirent
00301      This is a structure type used to return information about directory
00302      entries.  It contains the following fields:
00303 
00304     `char d_name[]'
00305           This is the null-terminated file name component.  This is the
00306           only field you can count on in all POSIX systems.
00307 
00308     `ino_t d_fileno'
00309           This is the file serial number.  For BSD compatibility, you
00310           can also refer to this member as `d_ino'.  In the GNU system
00311           and most POSIX systems, for most files this the same as the
00312           `st_ino' member that `stat' will return for the file.  *Note
00313           File Attributes::.
00314 
00315     `unsigned char d_namlen'
00316           This is the length of the file name, not including the
00317           terminating null character.  Its type is `unsigned char'
00318           because that is the integer type of the appropriate size
00319 
00320     `unsigned char d_type'
00321           This is the type of the file, possibly unknown.  The
00322           following constants are defined for its value:
00323 
00324          `DT_UNKNOWN'
00325                The type is unknown.  On some systems this is the only
00326                value returned.
00327 
00328          `DT_REG'
00329                A regular file.
00330 
00331          `DT_DIR'
00332                A directory.
00333 
00334          `DT_FIFO'
00335                A named pipe, or FIFO.  *Note FIFO Special Files::.
00336 
00337          `DT_SOCK'
00338                A local-domain socket.
00339          `DT_CHR'
00340                A character device.
00341 
00342          `DT_BLK'
00343                A block device.
00344 
00345           This member is a BSD extension.  The symbol
00346           `_DIRENT_HAVE_D_TYPE' is defined if this member is available.
00347           On systems where it is used, it corresponds to the file type
00348           bits in the `st_mode' member of `struct statbuf'.  If the
00349           value cannot be determine the member value is DT_UNKNOWN.
00350           These two macros convert between `d_type' values and
00351           `st_mode' values:
00352 
00353            - Function: int IFTODT (mode_t MODE)
00354                This returns the `d_type' value corresponding to MODE.
00355 
00356            - Function: mode_t DTTOIF (int DTYPE)
00357                This returns the `st_mode' value corresponding to DTYPE.
00358 
00359 
00360     mode_t bit field values:
00361     =========================
00362     S_ISUID           04000 set user ID on execution
00363     S_ISGID           02000 set group ID on execution
00364     S_ISVTX           01000 sticky bit
00365 
00366     S_IRUSR (S_IREAD) 00400 read by owner
00367     S_IWUSR (S_IWRITE)00200 write by owner
00368     S_IXUSR (S_IEXEC) 00100 execute/search by owner
00369 
00370     S_IRGRP           00040 read by group
00371     S_IWGRP           00020 write by group
00372     S_IXGRP           00010 execute/search by group
00373 
00374     S_IROTH           00004 read by others
00375     S_IWOTH           00002 write by others
00376     S_IXOTH           00001 execute/search by others
00377 */

Generated on Tue Jan 20 09:03:27 2004 for OpenTools by doxygen1.2.18