#include <set>
#include <map>
-#include "zypp/Pathname.h"
+#include <zypp/Pathname.h>
+#include <zypp/CheckSum.h>
+#include <zypp/ByteCount.h>
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
+ class StrMatcher;
+
///////////////////////////////////////////////////////////////////
/** Types and functions for filesystem operations.
* \todo move zypp::filesystem stuff into separate header
const Pathname & path() const { return path_t; }
/** Return current Pathname as String. */
const std::string & asString() const { return path_t.asString(); }
+ /** Return current Pathname as C-string. */
+ const char * c_str() const { return path_t.asString().c_str(); }
/** Return current stat Mode. */
Mode mode() const { return mode_e; }
/** Return error returned from last stat/lstat call. */
dev_t dev() const { return isExist() ? statbuf_C.st_dev : 0; }
dev_t rdev() const { return isExist() ? statbuf_C.st_rdev : 0; }
- unsigned int major() const;
- unsigned int minor() const;
+ unsigned int devMajor() const;
+ unsigned int devMinor() const;
//@}
/** \name Size info. */
int copy_dir_content( const Pathname & srcpath, const Pathname & destpath);
/**
+ * Convenience returning <tt>StrMatcher( "[^.]*", Match::GLOB )</tt>
+ * \see \ref dirForEach
+ */
+ const StrMatcher & matchNoDots();
+
+ /**
+ * Invoke callback function \a fnc_r for each entry in directory \a dir_r.
+ *
+ * If \a fnc_r is a \c NULL function \c 0 is returned immediately without even
+ * testing or accessing \a dir_r.
+ *
+ * Otherwise \c ::readdir is used to read the name of every entry in \a dir_r,
+ * omitting \c '.' and \c '..'. \a dir_r and the current entries name are passed
+ * as arguments to \a fnc_r. If \a fnc_r returns \c false processing is aborted.
+ *
+ * @return 0 on success, -1 if aborted by callback, errno > 0 on ::readdir failure.
+ */
+ int dirForEach( const Pathname & dir_r, function<bool(const Pathname &, const char *const)> fnc_r );
+
+ /**
+ * \overload taking a \ref StrMatcher to filter the entries for which \a fnc_r is invoked.
+ *
+ * For convenience a \ref StrMatcher \ref matchNoDots is provided in this namespace.</tt>
+ *
+ * \code
+ * bool cbfnc( const Pathname & dir_r, const char *const str_r )
+ * {
+ * D BG <*< " - " << dir_r/str_r << endl;
+ * return true;
+ * }
+ * // Print no-dot files in "/tmp" via callback
+ * filesystem::dirForEach( "/tmp", filesystem::matchNoDots(), cbfnc );
+ *
+ * // same via lambda
+ * filesystem::dirForEach( "/tmp", filesystem::matchNoDots(),
+ * [](const Pathname & dir_r, const std::string & str_r)->bool
+ * {
+ * DBG << " - " << dir_r/str_r << endl;
+ * return true;
+ * });
+ * \endcode
+ */
+ int dirForEach( const Pathname & dir_r, const StrMatcher & matcher_r, function<bool(const Pathname &, const char *const)> fnc_r );
+
+ /**
* Return content of directory via retlist. If dots is false
* entries starting with '.' are not reported. "." and ".."
* are never reported.
: name( name_r )
, type( type_r )
{}
+
+ bool operator==( const DirEntry &rhs ) const;
};
+ inline std::ostream & operator<<( std::ostream & str, const DirEntry & obj )
+ { return str << '[' << obj.type << "] " << obj.name; }
+
/** Returned by readdir. */
typedef std::list<DirEntry> DirContent;
+ std::ostream & operator<<( std::ostream & str, const DirContent & obj );
+
/**
* Return content of directory via retlist. If dots is false
* entries starting with '.' are not reported. "." and ".."
int readdir( DirContent & retlist, const Pathname & path,
bool dots = true, PathInfo::Mode statmode = PathInfo::STAT );
-
/**
* Check if the specified directory is empty.
* \param path The path of the directory to check.
/** \name File related functions. */
//@{
/**
+ * Create an empty file if it does not yet exist. Make parent directories
+ * as needed. mode specifies the permissions to use. It is modified by the
+ * process's umask in the usual way.
+ *
+ * @return 0 on success, errno on failure
+ **/
+ int assert_file( const Pathname & path, unsigned mode = 0644 );
+ /**
+ * Like \ref assert_file but enforce \a mode even if the file already exists.
+ */
+ int assert_file_mode( const Pathname & path, unsigned mode = 0644 );
+
+ /**
+ * Change file's modification and access times.
+ *
+ * \return 0 on success, errno on failure
+ * \see man utime
+ */
+ int touch (const Pathname & path);
+
+ /**
* Like '::unlink'. Delete a file (symbolic link, socket, fifo or device).
*
* @return 0 on success, errno on failure
int unlink( const Pathname & path );
/**
- * Like '::rename'. Renames a file, moving it between directories if required.
+ * Like '::rename'. Renames a file, moving it between directories if
+ * required. It falls back to using mv(1) in case errno is set to
+ * EXDEV, indicating a cross-device rename, which is likely to happen when
+ * oldpath and newpath are not on the same OverlayFS layer.
*
* @return 0 on success, errno on failure
**/
int rename( const Pathname & oldpath, const Pathname & newpath );
+ /** Exchanges two files or directories.
+ *
+ * Most common use is when building a new config file (or dir)
+ * in a tempfile. After the job is done, configfile and tempfile
+ * are exchanged. This includes moving away the configfile in case
+ * the tempfile does not exist. Parent directories are created as
+ * needed.
+ *
+ * \note Paths are exchanged using \c ::rename, so take care both paths
+ * are located on the same filesystem.
+ *
+ * \code
+ * Pathname configfile( "/etc/myconfig" );
+ * TmpFile newconfig( TmpFile::makeSibling( configfile ) );
+ * // now write the new config:
+ * std::ofstream o( newconfig.path().c_str() );
+ * o << "mew values << endl;
+ * o.close();
+ * // If everything is fine, exchange the files:
+ * exchange( newconfig.path(), configfile );
+ * // Now the old configfile is still available at newconfig.path()
+ * // until newconfig goes out of scope.
+ * \endcode
+ *
+ * @return 0 on success, errno on failure
+ */
+ int exchange( const Pathname & lpath, const Pathname & rpath );
+
/**
* Like 'cp file dest'. Copy file to destination file.
*
int hardlink( const Pathname & oldpath, const Pathname & newpath );
/**
+ * Create \a newpath as hardlink or copy of \a oldpath.
+ *
+ * @return 0 on success, errno on failure.
+ */
+ int hardlinkCopy( const Pathname & oldpath, const Pathname & newpath );
+
+ /**
+ * Like '::readlink'. Return the contents of the symbolic link
+ * \a symlink_r via \a target_r.
+ *
+ * @return 0 on success, errno on failure.
+ */
+ int readlink( const Pathname & symlink_r, Pathname & target_r );
+ /** \overload Return an empty Pathname on error. */
+ inline Pathname readlink( const Pathname & symlink_r )
+ {
+ Pathname target;
+ readlink( symlink_r, target );
+ return target;
+ }
+
+ /**
+ * Recursively follows the symlink pointed to by \a path_r and returns
+ * the Pathname to the real file or directory pointed to by the link.
+ *
+ * There is a recursion limit of 256 iterations to protect against a cyclic
+ * link.
+ *
+ * @return Pathname of the file or directory pointed to by the given link
+ * if it is a valid link. If \a path_r is not a link, an exact copy of
+ * it is returned. If \a path_r is a broken or a cyclic link, an empty
+ * Pathname is returned and the event logged.
+ */
+ Pathname expandlink( const Pathname & path_r );
+
+ /**
* Like 'cp file dest'. Copy file to dest dir.
*
* @return 0 on success, EINVAL if file is not a file, ENOTDIR if dest
std::string sha1sum( const Pathname & file );
//@}
+ /**
+ * Compute a files checksum
+ *
+ * @return the files checksum on success, otherwise an empty string..
+ **/
+ std::string checksum( const Pathname & file, const std::string &algorithm );
+
+ /**
+ * check files checksum
+ *
+ * @return true if the checksum matches (an empty Checksum always matches!)
+ **/
+ bool is_checksum( const Pathname & file, const CheckSum &checksum );
+
///////////////////////////////////////////////////////////////////
/** \name Changing permissions. */
//@{
* @return 0 on success, errno on failure
**/
int chmod( const Pathname & path, mode_t mode );
+
+ /**
+ * Add the \c mode bits to the file given by path.
+ *
+ * @return 0 on success, errno on failure
+ */
+ int addmod( const Pathname & path, mode_t mode );
+
+ /**
+ * Remove the \c mode bits from the file given by path.
+ *
+ * @return 0 on success, errno on failure
+ */
+ int delmod( const Pathname & path, mode_t mode );
//@}
///////////////////////////////////////////////////////////////////
*
* @return ZT_GZ, ZT_BZ2 if file is compressed, otherwise ZT_NONE.
**/
- enum ZIP_TYPE { ZT_NONE, ZT_GZ, ZT_BZ2 };
+ enum ZIP_TYPE { ZT_NONE, ZT_GZ, ZT_BZ2, ZT_ZCHNK };
ZIP_TYPE zipType( const Pathname & file );
* \todo check cooperation with zypp::TmpFile and zypp::TmpDir
**/
int erase( const Pathname & path );
+
+ /**
+ * Report free disk space on a mounted file system.
+ *
+ * path is the path name of any file within the mounted filesystem.
+ *
+ * @return Free disk space or -1 on error.
+ **/
+ ByteCount df( const Pathname & path );
+
+ /**
+ * Get the current umask (file mode creation mask)
+ *
+ * @return The current umask
+ **/
+ mode_t getUmask();
+
+ /**
+ * Modify \c mode_r according to the current umask
+ * <tt>( mode_r & ~getUmask() )</tt>.
+ * \see \ref getUmask.
+ * @return The resulting permissions.
+ **/
+ inline mode_t applyUmaskTo( mode_t mode_r )
+ { return mode_r & ~getUmask(); }
//@}
/////////////////////////////////////////////////////////////////