AaronCameron.net
I care not for your petty politics.
Not a Member? - Login or Create an Account
Wednesday the 23rd of May 2012 @ 11:42pm
Front Page Journal Projects Your Profile About
[]

LibN2L-4 Library Code Reference

Classes
Compounds
Files
Members
Method Index
Full Reference

cVfsStat.cpp

Go to the documentation of this file.
00001 #include "cVfsStat.h"
00002 
00003 #include "vfsUtilities.h"
00004 #include "cVfsOpenException.h"
00005 
00006 #include <sys/stat.h>
00007 
00008 #include <errno.h>
00009 
00010 #ifdef WIN32
00011 #   ifndef S_ISDIR
00012 #       define S_ISDIR(mode)        (((mode) & _S_IFDIR) != 0)
00013 #   endif
00014 #   ifndef S_ISREG
00015 #       define S_ISREG(mode)        (((mode) & _S_IFREG) != 0)
00016 #   endif
00017 #endif
00018 
00019 namespace n2l
00020 {
00021     /*****************************************************************/
00022     cVfsStat::cVfsStat( const tFsNodeName &iName ) :
00023         mStat( 0 ),
00024         mPermissions( 0 )
00025     {
00026         doStat( iName );
00027     }
00028 
00029     /*****************************************************************/
00030     cVfsStat::~cVfsStat()
00031     {
00032         if (mStat) delete mStat;
00033     }
00034 
00035     /*****************************************************************/
00036     const tUint cVfsStat::permissions() const
00037     {
00038         return mPermissions;
00039     }
00040 
00041     /*****************************************************************/
00042     const tVfsFileSize cVfsStat::size() const
00043     {
00044         return tVfsFileSize(mStat->st_size);
00045     }
00046 
00047     const tVfsINode cVfsStat::inode() const
00048     {
00049         return tVfsINode(mStat->st_ino);
00050     }
00051 
00052     /*****************************************************************/
00053     const tBool cVfsStat::isFile() const
00054     {
00055         return S_ISREG(mStat->st_mode);
00056     }
00057 
00058     /*****************************************************************/
00059     const tBool cVfsStat::isDir() const
00060     {
00061         return S_ISDIR(mStat->st_mode);
00062     }
00063 
00064     /*****************************************************************/
00065     const tBool cVfsStat::isSymLink() const
00066     {
00067 #       ifdef WIN32 
00068             return false;
00069 #       else
00070             // Forgive me.  I'm stupid, not malicious.
00071             struct stat *tmpStat = new struct stat;
00072             tSint r = lstat(mName.c_str(), tmpStat);
00073             if (r!=0)
00074                 throw cVfsOpenException( "cVfsStat::isSymLink", 
00075                     tString("Stat failed with error: ") + asString(r),
00076                     mName );
00077             tBool isLink = S_ISLNK(tmpStat->st_mode);
00078             delete tmpStat;
00079             return isLink;
00080 #       endif
00081     }
00082 
00083     /*****************************************************************/
00084     const tFsNodeName cVfsStat::readLink() const
00085     {
00086         if (!isSymLink())
00087             throw cBadDataUseException( "cVfsStat::readLink",
00088                 "Not a symbolic link!" );
00089 #       ifndef WIN32
00090             tSint bufSize = 1024;
00091             for (;;) {
00092                 char *buf = new char[bufSize+1];
00093                 tSint size = readlink( mName.c_str(), buf, bufSize );
00094                 if (size==-1 || bufSize*2<bufSize) {
00095                     throw cVfsException( "cVfsStat::readLink",
00096                         "Error I do not know what to do with.  The "
00097                         "errono was: " + asString( errno ) );
00098                 } else if (size==bufSize) {
00099                     // May have worked may not.  There's apparently no
00100                     // way to find out.  Good job guys, quality work.
00101                     // The manual says to make the buffer bigger and
00102                     // try again.  F-ing retarded.
00103                 } else {
00104                     buf[size] = '\0';
00105                     tFsNodeName tmp = buf;
00106                     delete []buf;
00107                     return tmp;
00108                 }
00109                 delete []buf;
00110                 bufSize *= 2;
00111             }
00112 #       else
00113             // isSymlink will always return false for windows, so this
00114             // doesn't matter.
00115             return "";
00116 #       endif
00117     }
00118 
00119     /*****************************************************************/
00120     void cVfsStat::reload()
00121     {
00122         delete mStat;
00123         mStat = 0;
00124         doStat( mName );
00125     }
00126 
00127     /*****************************************************************/
00128     void cVfsStat::doStat( const tFsNodeName &iName )
00129     {
00130         mName = cleanVfsPath( iName );
00131         mStat = new struct stat;
00132         tSint r = stat(mName.c_str(), mStat);
00133         if (r!=0)
00134             throw cVfsOpenException( "cVfsStat::doStat", 
00135                 tString("Stat failed with error: ") + asString(r),
00136                 mName );
00137 
00138         // Calculate the effective permissions for this process
00139 
00140 #       ifdef WIN32
00141             if (mStat->st_mode&_S_IREAD)
00142                 mPermissions = mPermissions | VfsPermission_Readable;
00143 
00144             if (mStat->st_mode&_S_IWRITE)
00145                 mPermissions = mPermissions | VfsPermission_Writeable;
00146 
00147             if (mStat->st_mode&_S_IEXEC)
00148                 mPermissions = mPermissions | VfsPermission_Executable;
00149 
00150 #       else
00151             const tUID UID = n2lProcessUID();
00152             const tUID GID = n2lProcessGID();
00153 
00154             if ((UID==mStat->st_uid && mStat->st_mode&S_IRUSR) ||
00155                 (GID==mStat->st_gid && mStat->st_mode&S_IRGRP) ||
00156                 (mStat->st_mode&S_IROTH))
00157                 mPermissions = mPermissions | VfsPermission_Readable;
00158 
00159             if ((UID==mStat->st_uid && mStat->st_mode&S_IWUSR) ||
00160                 (GID==mStat->st_gid && mStat->st_mode&S_IWGRP) ||
00161                 (mStat->st_mode&S_IWOTH))
00162                 mPermissions = mPermissions | VfsPermission_Writeable;
00163 
00164             if ((UID==mStat->st_uid && mStat->st_mode&S_IXUSR) ||
00165                 (GID==mStat->st_gid && mStat->st_mode&S_IXGRP) ||
00166                 (mStat->st_mode&S_IXOTH))
00167                 mPermissions = mPermissions | VfsPermission_Executable;
00168 #       endif
00169 
00170     }
00171 
00172 
00173 }
©2012 Aaron Cameron