00001 
00002 
00003 
00004 
00005 #include <unistd.h>
00006 #include <sys/stat.h>
00007 #include <vector>
00008 #include <cerrno>
00009 #include <cstring>
00010 #include "utils.h"
00011 
00013 bool
00014 utils::mkdir( const std::string& filename )
00015 {
00016         if( !(::mkdir( filename.c_str( ), 0755 ) == 0) ) {
00017                 set_error( ::strerror( errno ) );
00018                 return false;
00019         }
00020         clear_error( );
00021         return true;
00022 }
00023 
00025 bool
00026 utils::exists( const std::string& filename )
00027 {
00028         struct stat tmp;
00029         if( !(stat (filename.c_str( ), &tmp) >= 0)) {
00030                 set_error( ::strerror( errno ) );
00031                 return false;
00032         }
00033         clear_error( );
00034         return true;
00035 }
00036 
00038 bool
00039 utils::can_read( const std::string& filename )
00040 {
00041         if( !(access( filename.c_str( ), R_OK ) == 0) ) {
00042                 set_error( ::strerror( errno ) );
00043                 return false;
00044         }
00045         clear_error( );
00046         return true;
00047 }
00048 
00050 bool
00051 utils::is_dir( const std::string& filename )
00052 {
00053         struct stat tmp;
00054         if( lstat( filename.c_str( ), &tmp ) == 0 ) {
00055                 if( S_ISDIR( tmp.st_mode ) ) {
00056                         clear_error( );
00057                         return true;
00058                 }
00059         }
00060         set_error( ::strerror( errno ) );
00061         return false;
00062 }
00063 
00065 bool
00066 utils::is_link( const std::string& filename )
00067 {
00068         struct stat tmp;
00069         if( lstat( filename.c_str( ), &tmp ) == 0 ) {
00070                 if( S_ISLNK( tmp.st_mode ) ) {
00071                         clear_error( );
00072                         return true;
00073                 }
00074         }
00075         set_error( ::strerror( errno ) );
00076         return false;
00077 }
00078 
00080 bool
00081 utils::chdir( const std::string& filename )
00082 {
00083         if( !(::chdir( filename.c_str( ) ) == 0) ) {
00084                 set_error( ::strerror( errno ) );
00085                 return false;
00086         }
00087         clear_error( );
00088         return true;
00089 }
00090 
00092 std::string
00093 utils::get_valid_absolute_dir( const std::string& file )
00094 {
00095         
00096         std::string filename = file;
00097         filename = utils::trim( utils::rtrim( filename ) );
00098 
00099         
00100         if( filename.length( ) < 1 ) return "";
00101         
00102         
00103         if( filename[ 0 ] != '/' ) {
00104                 
00105                 char cwd[ 1024 ]; 
00106                 getcwd( cwd, 1024 );
00107 
00108                 
00109                 filename = std::string( cwd ) + "/" + filename;
00110         }
00111 
00112         
00113         std::vector<std::string> stack;
00114 
00115         
00116         std::string::size_type start = 0;
00117         std::string::size_type pos = 0;
00118         std::string token;
00119 
00120         
00121         while( (pos = filename.find_first_of( "/", start )) != std::string::npos ) {
00122                 token = filename.substr( start, pos - start );
00123                 if( token == ".." ) {
00124                         
00125                         if( stack.size( ) > 0 ) {
00126                                 stack.pop_back( );
00127                         }
00128                 } else if( (token.length( ) > 0) && (token != ".") ) {
00129                         
00130                         stack.push_back( token );
00131                 }
00132 
00133                 
00134                 start = pos + 1;
00135         }
00136 
00137         
00138         if( start < filename.length( ) ) {
00139                 token = filename.substr( start, filename.length( ) - start );
00140                 if( token == ".." ) {
00141                         
00142                         if( stack.size( ) > 0 ) {
00143                                 stack.pop_back( );
00144                         }
00145                 } else if( (token.length( ) > 0) && (token != ".") ) {
00146                         
00147                         stack.push_back( token );
00148                 }
00149         }
00150 
00151         
00152         filename = "";
00153         if( stack.size( ) > 1 ) {
00154                 std::string old;
00155                 for( unsigned int i = 0; i < stack.size( ); ++i ) {
00156                         old = filename;
00157                         filename += "/" + stack[ i ];
00158                         if( !(utils::is_dir( filename.c_str( ) )) ) {
00159                                 
00160                                 if( old.length( ) < 1 ) {
00161                                         return "/";
00162                                 } else {
00163                                         return old;
00164                                 }
00165                         }
00166                 }
00167                 
00168                 
00169                 return filename;
00170         } else if( stack.size( ) == 1 ) {
00171                 
00172                 filename += "/" + stack[ 0 ];
00173                 if( utils::is_dir( filename.c_str( ) ) ) {
00174                         return filename;
00175                 } else {
00176                         return "/";
00177                 }
00178         } else {
00179                 
00180                 return "";
00181         }
00182 }
00183 
00185 std::string
00186 utils::get_absolute_dir( const std::string& file )
00187 {
00188         
00189         std::string filename = file;
00190         filename = utils::trim( utils::rtrim( filename ) );
00191 
00192         
00193         if( filename.length( ) < 1 ) return "";
00194         
00195         
00196         if( filename[ 0 ] != '/' ) {
00197                 
00198                 char cwd[ 1024 ]; 
00199                 getcwd( cwd, 1024 );
00200 
00201                 
00202                 filename = std::string( cwd ) + "/" +  filename;
00203         }
00204 
00205         
00206         std::vector<std::string> stack;
00207 
00208         
00209         std::string::size_type start = 0;
00210         std::string::size_type pos = 0;
00211         std::string token;
00212 
00213         
00214         while( (pos = filename.find_first_of( "/", start )) != std::string::npos ) {
00215                 token = filename.substr( start, pos - start );
00216                 if( token == ".." ) {
00217                         
00218                         if( stack.size( ) > 0 ) {
00219                                 stack.pop_back( );
00220                         }
00221                 } else if( (token.length( ) > 0) && (token != ".") ) {
00222                         
00223                         stack.push_back( token );
00224                 }
00225 
00226                 
00227                 start = pos + 1;
00228         }
00229 
00230         
00231         if( start < filename.length( ) ) {
00232                 token = filename.substr( start, filename.length( ) - start );
00233                 if( token == ".." ) {
00234                         
00235                         if( stack.size( ) > 0 ) {
00236                                 stack.pop_back( );
00237                         }
00238                 } else if( (token.length( ) > 0) && (token != ".") ) {
00239                         
00240                         stack.push_back( token );
00241                 }
00242         }
00243 
00244         filename = "";
00245         if( stack.size( ) > 1 ) {
00246                 for( unsigned int i = 0; i < stack.size( ) - 1; ++i ) {
00247                         filename += "/" + stack[ i ];
00248                 }
00249                 return filename;
00250         } else {
00251                 return "/";
00252         }
00253 }
00254 
00256 std::string
00257 utils::get_filename( const std::string& file )
00258 {
00259         std::string::size_type pos = file.find_last_of( "/", file.length( ) );
00260         if( pos == std::string::npos ) {
00261                 
00262                 return file;
00263         } else {
00264                 return file.substr( pos + 1, file.length( ) - (pos + 1) );
00265         }
00266 }