1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
// Copyright (c) 2012-2014 Konstantin Isakov <ikm@zbackup.org> and ZBackup contributors, see CONTRIBUTORS
// Part of ZBackup. Licensed under GNU GPLv2 or later + OpenSSL, see LICENSE
#include <fcntl.h>
#include <libgen.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <vector>
#include "dir.hh"
DIR * dir;
namespace Dir {
bool exists( string const & name )
{
struct stat buf;
return stat( name.c_str(), &buf ) == 0 && S_ISDIR( buf.st_mode );
}
void create( string const & name )
{
if ( mkdir( name.c_str(), 0777 ) != 0 )
throw exCantCreate( name );
}
void remove( string const & name )
{
if ( rmdir( name.c_str() ) != 0 )
throw exCantRemove( name );
}
string addPath( string const & first, string const & second )
{
if ( first.empty() )
return second;
if ( second.empty() )
return first;
if ( first[ first.size() - 1 ] == separator() )
return first + second;
else
return first + separator() + second;
}
string getRealPath( string const & path )
{
if ( char * r = realpath( path.c_str(), NULL ) )
{
string result( r );
free( r );
return result;
}
else
throw exCantGetRealPath( path );
}
string getDirName( string const & path )
{
char const * c = path.c_str();
std::vector< char > copy( c, c + path.size() + 1 );
return dirname( copy.data() );
}
string getBaseName( string const & path )
{
char const * c = path.c_str();
std::vector< char > copy( c, c + path.size() + 1 );
return basename( copy.data() );
}
bool isDirEmpty( string const & path )
{
Listing lst(path);
Entry tmp;
return !lst.getNext(tmp);
}
Listing::Listing( string const & dirName ): dirName( dirName )
{
dir = opendir( dirName.c_str() );
if ( !dir )
throw exCantList( dirName );
}
Listing::~Listing()
{
closedir( dir );
}
bool Listing::getNext( Entry & result )
{
dirent entry;
dirent * entryPtr;
struct stat entryStats;
for ( ; ; )
{
if ( readdir_r( dir, &entry, &entryPtr ) != 0 )
throw exCantList( dirName );
if ( !entryPtr )
return false;
#ifndef __APPLE__
if ( fstatat( dirfd( dir ), entry.d_name, &entryStats,
AT_SYMLINK_NOFOLLOW ) != 0 )
#else
if ( lstat( addPath( dirName, entry.d_name ).c_str(),
&entryStats ) != 0)
#endif
throw exCantList( dirName );
bool isDir = S_ISDIR( entryStats.st_mode );
bool isSymLink = S_ISLNK( entryStats.st_mode );
if ( isDir &&
( entry.d_name[ 0 ] == '.' &&
( !entry.d_name[ 1 ] || entry.d_name[ 1 ] == '.' ) ) )
{
// Skip the . or .. entries
continue;
}
result = Entry( entry.d_name, isDir, isSymLink );
return true;
}
}
}
|