14 #include <sys/statvfs.h> 15 #include <sys/sysmacros.h> 21 #include <zypp-core/fs/PathInfo.h> 22 #include <zypp-core/base/LogTools.h> 23 #include <zypp-core/base/String.h> 24 #include <zypp-core/base/IOStream.h> 25 #include <zypp-core/base/Errno.h> 27 #include <zypp-core/AutoDispose.h> 28 #include <zypp-core/ExternalProgram.h> 29 #include <zypp-core/Digest.h> 30 #include <zypp-core/fs/TmpPath.h> 50 #define EMUMOUT(T) case T: return str << #T; break 102 else if ( obj.
isDir() )
106 else if ( obj.
isChr() )
108 else if ( obj.
isBlk() )
115 str << t <<
" " << std::setfill(
'0' ) << std::setw( 4 ) << std::oct << obj.
perm();
228 if (
owner() == geteuid() ) {
229 return(
uperm()/0100 );
230 }
else if (
group() == getegid() ) {
231 return(
gperm()/010 );
284 #define logResult MIL << endl, doLogResult 287 inline int doLogResult(
const int res,
const char * rclass = 0 )
292 WAR <<
" FAILED: " << rclass <<
" " << res << endl;
337 while ( (pos = spath.find(
'/',lastpos)) != std::string::npos )
339 string dir( spath.substr(0,pos) );
340 ret =
::mkdir( dir.c_str(), mode );
343 if ( errno == EEXIST )
348 WAR <<
" FAILED: mkdir " << dir <<
' ' <<
str::octstring( mode ) <<
" errno " << ret << endl;
368 MIL <<
"rmdir " << path;
369 if ( ::
rmdir( path.asString().c_str() ) == -1 ) {
385 if ( ! (dp = opendir( dir.
c_str() )) )
390 std::string direntry = d->d_name;
391 if ( direntry ==
"." || direntry ==
".." )
393 Pathname new_path( dir / d->d_name );
396 if ( ! lstat( new_path.
c_str(), &st ) )
398 if ( S_ISDIR( st.st_mode ) )
406 if ( removeDir && ::
rmdir( dir.
c_str() ) < 0 )
414 MIL <<
"recursive_rmdir " << path <<
' ';
427 MIL <<
"unlink symlink ";
428 if ( ::
unlink( path.asString().c_str() ) == -1 ) {
444 MIL <<
"clean_dir " << path <<
' ';
465 MIL <<
"copy_dir " << srcpath <<
" -> " << destpath <<
' ';
478 if ( tp.isExist() ) {
483 const char *
const argv[] = {
488 destpath.asString().c_str(),
493 MIL <<
" " << output;
495 int ret = prog.
close();
506 MIL <<
"copy_dir " << srcpath <<
" -> " << destpath <<
' ';
518 if ( srcpath == destpath ) {
522 std::string src( srcpath.
asString());
524 const char *
const argv[] = {
529 destpath.asString().c_str(),
534 MIL <<
" " << output;
536 int ret = prog.
close();
543 template <
class... T>
546 template <
typename F>
550 []( DIR * dir_r ) {
if ( dir_r ) ::closedir( dir_r ); } );
552 MIL <<
"readdir " << dir_r <<
' ';
558 for (
struct dirent * entry = ::
readdir( dir ); entry; entry =
::readdir( dir ) )
560 if ( entry->d_name[0] ==
'.' && ( entry->d_name[1] ==
'\0' || ( entry->d_name[1] ==
'.' && entry->d_name[2] ==
'\0' ) ) )
564 static_assert( !std::is_invocable_v<
function<
bool(
const Pathname &,
const char *
const)>,
const Pathname &,
const DirEntry &> ,
"Invoke detection broken" );
565 static_assert( !std::is_invocable_v<
function<
bool(
const Pathname &,
const DirEntry& )>,
const Pathname &,
const char *> ,
"Invoke detection broken" );
567 if constexpr ( std::is_invocable_v<F, const Pathname &, const char *const> ) {
568 if ( ! std::forward<F>(fnc_r)( dir_r, entry->d_name ) ) {
572 }
else if constexpr ( std::is_invocable_v<F, const Pathname &, const DirEntry&> ) {
573 if ( ! std::forward<F>(fnc_r)( dir_r,
DirEntry( entry ) ) ) {
578 static_assert( always_false<F>,
"Callback not supported" );
605 int readdir( std::list<std::string> & retlist_r,
const Pathname & path_r,
bool dots_r )
609 [&](
const Pathname & dir_r,
const char *
const name_r )->
bool 611 if ( dots_r || name_r[0] !=
'.' )
612 retlist_r.push_back( name_r );
622 [&](
const Pathname & dir_r,
const char *
const name_r )->
bool 624 if ( dots_r || name_r[0] !=
'.' )
625 retlist_r.push_back( dir_r/name_r );
633 switch( entry->d_type ) {
673 [&](
const Pathname & dir_r,
const char *
const name_r )->
bool 675 if ( dots_r || name_r[0] !=
'.' )
676 retlist_r.push_back(
DirEntry( name_r,
PathInfo( dir_r/name_r, statmode_r ).fileType() ) );
691 [&](
const Pathname & dir_r,
const char *
const name_r )->
bool 702 MIL <<
"unlink " << path;
703 if ( ::
unlink( path.asString().c_str() ) == -1 ) {
718 if ( ret == -1 && errno == EXDEV ) {
719 const char *
const argv[] = {
726 for (
string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) {
727 MIL <<
" " << output;
744 MIL <<
"rename " << oldpath <<
" -> " << newpath;
745 if ( safe_rename( oldpath.
asString().c_str(), newpath.asString().c_str() ) == -1 ) {
758 MIL <<
"exchange " << lpath <<
" <-> " << rpath;
759 if ( lpath.
empty() || rpath.empty() )
774 if ( safe_rename( rpath.c_str(), lpath.
c_str() ) == -1 ) {
787 if ( safe_rename( lpath.
c_str(), rpath.c_str() ) == -1 ) {
800 if ( safe_rename( lpath.
c_str(), tmp.c_str() ) == -1 ) {
803 if ( safe_rename( rpath.c_str(), lpath.
c_str() ) == -1 ) {
804 safe_rename( tmp.c_str(), lpath.
c_str() );
807 if ( safe_rename( tmp.c_str(), rpath.c_str() ) == -1 ) {
808 safe_rename( lpath.
c_str(), rpath.c_str() );
809 safe_rename( tmp.c_str(), lpath.
c_str() );
822 MIL <<
"copy " << file <<
" -> " << dest <<
' ';
834 const char *
const argv[] = {
836 "--remove-destination",
839 dest.asString().c_str(),
844 MIL <<
" " << output;
846 int ret = prog.
close();
857 MIL <<
"symlink " << newpath <<
" -> " << oldpath;
858 if ( ::
symlink( oldpath.asString().c_str(), newpath.
asString().c_str() ) == -1 ) {
871 MIL <<
"hardlink " << newpath <<
" -> " << oldpath;
872 if ( ::link( oldpath.asString().c_str(), newpath.
asString().c_str() ) == -1 ) {
885 MIL <<
"hardlinkCopy " << oldpath <<
" -> " << newpath;
891 MIL <<
" => copy" << endl;
892 return copy( oldpath, newpath );
898 int res =
unlink( newpath );
904 if ( ::link( oldpath.
asString().c_str(), newpath.asString().c_str() ) == -1 )
910 MIL <<
" => copy" << endl;
911 return copy( oldpath, newpath );
926 static const ssize_t bufsiz = 2047;
927 static char buf[bufsiz+1];
932 MIL <<
"readlink " << symlink_r;
947 static const unsigned int level_limit = 256;
948 static unsigned int count;
952 for (count = level_limit; info.
isLink() && count; count--)
954 DBG <<
"following symlink " << path;
956 DBG <<
"->" << path << std::endl;
963 ERR <<
"Expand level limit reached. Probably a cyclic symbolic link." << endl;
967 else if (count < level_limit)
975 ERR << path <<
" is broken (expanded from " << path_r <<
")" << endl;
981 DBG <<
"not a symlink" << endl;
992 MIL <<
"copy_file2dir " << file <<
" -> " << dest <<
' ';
1000 if ( !dp.
isDir() ) {
1004 const char *
const argv[] = {
1008 dest.asString().c_str(),
1013 MIL <<
" " << output;
1015 int ret = prog.
close();
1026 if ( !
PathInfo( file ).isFile() ) {
1029 std::ifstream istr( file.
asString().c_str() );
1053 if ( !
PathInfo( file ).isFile() ) {
1056 std::ifstream istr( file.
asString().c_str() );
1103 mode_t omode(
PathInfo( path ).st_mode() );
1104 mode_t tmode( omode | mode );
1105 if ( omode != mode )
1106 return chmod( path, tmode );
1112 mode_t omode(
PathInfo( path ).st_mode() );
1113 mode_t tmode( omode & ~mode );
1114 if ( omode != mode )
1115 return chmod( path, tmode );
1128 int fd = open( file.
asString().c_str(), O_RDONLY|O_CLOEXEC );
1131 const int magicSize = 5;
1132 unsigned char magic[magicSize];
1133 memset( magic, 0, magicSize );
1134 if (
read( fd, magic, magicSize ) == magicSize ) {
1135 if ( magic[0] == 0037 && magic[1] == 0213 ) {
1137 }
else if ( magic[0] ==
'B' && magic[1] ==
'Z' && magic[2] ==
'h' ) {
1139 }
else if ( magic[0] ==
'\0' && magic[1] ==
'Z' && magic[2] ==
'C' && magic[3] ==
'K' && magic[4] ==
'1') {
1159 if ( statvfs( path_r.
c_str(), &sb ) == 0 )
1161 ret = sb.f_bfree * sb.f_bsize;
1173 mode_t mask = ::umask( 0022 );
1194 int fd = ::creat( path.c_str(), mode );
1217 return chmod( path, mode );
1222 int fd = ::creat( path.c_str(), mode );
1236 MIL <<
"touch " << path;
1237 struct ::utimbuf times;
1238 times.actime = ::time( 0 );
1239 times.modtime = ::time( 0 );
1240 if ( ::utime( path.asString().c_str(), × ) == -1 ) {
std::string asString(const Patch::Category &obj)
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
int exchange(const Pathname &lpath, const Pathname &rpath)
Exchanges two files or directories.
ZIP_TYPE
Test whether a file is compressed (gzip/bzip2).
std::string digest()
get hex string representation of the digest
Listentry returned by readdir.
int assert_file(const Pathname &path, unsigned mode)
Create an empty file if it does not yet exist.
std::string octstring(char n, int w=4)
std::string sha1sum(const Pathname &file)
Compute a files sha1sum.
Convenience errno wrapper.
std::string md5sum(const Pathname &file)
Compute a files md5sum.
int readlink(const Pathname &symlink_r, Pathname &target_r)
Like 'readlink'.
bool lstat()
LSTAT current path.
Store and operate with byte count.
int mkdir(const Pathname &path, unsigned mode)
Like 'mkdir'.
bool operator==(const DirEntry &rhs) const
int hardlink(const Pathname &oldpath, const Pathname &newpath)
Like '::link'.
int chmod(const Pathname &path, mode_t mode)
Like 'chmod'.
std::ostream & dumpRange(std::ostream &str, TIterator begin, TIterator end, const std::string &intro="{", const std::string &pfx="\ ", const std::string &sep="\ ", const std::string &sfx="\, const std::string &extro="}")
Print range defined by iterators (multiline style).
int dirForEach(const Pathname &dir_r, const StrMatcher &matcher_r, function< bool(const Pathname &, const char *const)> fnc_r)
int clean_dir(const Pathname &path)
Like 'rm -r DIR/ *'.
const char * c_str() const
String representation.
boost::io::ios_base_all_saver IosFmtFlagsSaver
Save and restore streams width, precision and fmtflags.
String related utilities and Regular expression matching.
mode_t userMay() const
Returns current users permission ([0-7])
constexpr bool always_false
std::string receiveLine()
Read one line from the input stream.
bool stat()
STAT current path.
std::string basename() const
Return the last component of this path.
Provide a new empty temporary file and delete it when no longer needed.
unsigned int devMinor() const
std::map< std::string, std::string > read(const Pathname &_path)
Read sysconfig file path_r and return (key,valye) pairs.
int copy_file2dir(const Pathname &file, const Pathname &dest)
Like 'cp file dest'.
DirEntry(const std::string &name_r=std::string(), FileType type_r=FT_NOT_AVAIL)
int is_empty_dir(const Pathname &path_r)
Check if the specified directory is empty.
ZIP_TYPE zipType(const Pathname &file)
bool empty() const
Test for an empty path.
int addmod(const Pathname &path, mode_t mode)
Add the mode bits to the file given by path.
int assert_file_mode(const Pathname &path, unsigned mode)
Like assert_file but enforce mode even if the file already exists.
bool operator()()
Restat current path using current mode.
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
int unlink(const Pathname &path)
Like 'unlink'.
const std::string & asString() const
String representation.
int rename(const Pathname &oldpath, const Pathname &newpath)
Like 'rename'.
bool isExist() const
Return whether valid stat info exists.
Pathname dirname() const
Return all but the last component od this path.
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
int error() const
Return error returned from last stat/lstat call.
std::list< DirEntry > DirContent
Returned by readdir.
int hardlinkCopy(const Pathname &oldpath, const Pathname &newpath)
Create newpath as hardlink or copy of oldpath.
int symlink(const Pathname &oldpath, const Pathname &newpath)
Like 'symlink'.
const std::string & asString() const
Return current Pathname as String.
int touch(const Pathname &path)
Change file's modification and access times.
int close()
Wait for the progamm to complete.
int copy(const Pathname &file, const Pathname &dest)
Like 'cp file dest'.
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
int dirForEachImpl(const Pathname &dir_r, F &&fnc_r)
int rmdir(const Pathname &path)
Like 'rmdir'.
mode_t getUmask()
Get the current umask (file mode creation mask)
int copy_dir(const Pathname &srcpath, const Pathname &destpath)
Like 'cp -a srcpath destpath'.
Wrapper class for mode_t values as derived from ::stat.
FileType
File type information.
std::string checksum(const Pathname &file, const std::string &algorithm)
Compute a files checksum.
int erase(const Pathname &path)
Erase whatever happens to be located at path (file or directory).
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
bool relative() const
Test for a relative path.
int dirForEachExt(const Pathname &dir_r, const function< bool(const Pathname &, const DirEntry &)> &fnc_r)
Simiar to.
unsigned int devMajor() const
int copy_dir_content(const Pathname &srcpath, const Pathname &destpath)
Like 'cp -a srcpath/.
Wrapper class for ::stat/::lstat.
Pathname expandlink(const Pathname &path_r)
Recursively follows the symlink pointed to by path_r and returns the Pathname to the real file or dir...
static TmpFile makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
mode_t applyUmaskTo(mode_t mode_r)
Modify mode_r according to the current umask ( mode_r & ~getUmask() ).
FileType fileType() const
int delmod(const Pathname &path, mode_t mode)
Remove the mode bits from the file given by path.
std::string strerror(int errno_r)
Return string describing the error_r code.
std::ostream & operator<<(std::ostream &str, const Glob &obj)
Easy-to use interface to the ZYPP dependency resolver.
bool lstat(const Pathname &path)
LSTAT path.
static int recursive_rmdir_1(const Pathname &dir, bool removeDir=true)
bool is_checksum(const Pathname &file, const CheckSum &checksum)
check files checksum
FileType fileType() const
StatMode asStatMode() const
Return st_mode() as filesystem::StatMode.
ByteCount df(const Pathname &path_r)
Report free disk space on a mounted file system.