1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/PathInfo.h
11 * \todo replace by Blocxx
14 #ifndef ZYPP_PATHINFO_H
15 #define ZYPP_PATHINFO_H
19 #include <sys/types.h>
32 #include "zypp/Pathname.h"
36 ///////////////////////////////////////////////////////////////////
38 // CLASS NAME : PathInfo
40 * @short Wrapper class for ::stat/::lstat and other file/directory related operations.
44 friend std::ostream & operator<<( std::ostream & str, const PathInfo & obj );
48 enum Mode { STAT, LSTAT };
51 NOT_AVAIL = 0x00, // no typeinfo available
52 NOT_EXIST = 0x01, // file does not exist
61 friend std::ostream & operator<<( std::ostream & str, file_type obj );
64 * Wrapper class for mode_t values as derived from ::stat
69 * Simple cache remembering device/inode to detect hardlinks.
77 struct stat statbuf_C;
83 PathInfo( const Pathname & path = "", Mode initial = STAT );
84 PathInfo( const std::string & path, Mode initial = STAT );
85 PathInfo( const char * path, Mode initial = STAT );
88 const Pathname & path() const { return path_t; }
89 const std::string & asString() const { return path_t.asString(); }
90 Mode mode() const { return mode_e; }
91 int error() const { return error_i; }
93 void setPath( const Pathname & path ) { if ( path != path_t ) error_i = -1; path_t = path; }
94 void setMode( Mode mode ) { if ( mode != mode_e ) error_i = -1; mode_e = mode; }
96 bool stat ( const Pathname & path ) { setPath( path ); setMode( STAT ); return operator()(); }
97 bool lstat ( const Pathname & path ) { setPath( path ); setMode( LSTAT ); return operator()(); }
98 bool operator()( const Pathname & path ) { setPath( path ); return operator()(); }
100 bool stat() { setMode( STAT ); return operator()(); }
101 bool lstat() { setMode( LSTAT ); return operator()(); }
106 bool isExist() const { return !error_i; }
109 file_type fileType() const;
111 bool isFile() const { return isExist() && S_ISREG( statbuf_C.st_mode ); }
112 bool isDir () const { return isExist() && S_ISDIR( statbuf_C.st_mode ); }
113 bool isLink() const { return isExist() && S_ISLNK( statbuf_C.st_mode ); }
114 bool isChr() const { return isExist() && S_ISCHR( statbuf_C.st_mode ); }
115 bool isBlk() const { return isExist() && S_ISBLK( statbuf_C.st_mode ); }
116 bool isFifo() const { return isExist() && S_ISFIFO( statbuf_C.st_mode ); }
117 bool isSock() const { return isExist() && S_ISSOCK( statbuf_C.st_mode ); }
119 nlink_t nlink() const { return isExist() ? statbuf_C.st_nlink : 0; }
122 uid_t owner() const { return isExist() ? statbuf_C.st_uid : 0; }
123 gid_t group() const { return isExist() ? statbuf_C.st_gid : 0; }
126 bool isRUsr() const { return isExist() && (statbuf_C.st_mode & S_IRUSR); }
127 bool isWUsr() const { return isExist() && (statbuf_C.st_mode & S_IWUSR); }
128 bool isXUsr() const { return isExist() && (statbuf_C.st_mode & S_IXUSR); }
130 bool isR() const { return isRUsr(); }
131 bool isW() const { return isWUsr(); }
132 bool isX() const { return isXUsr(); }
134 bool isRGrp() const { return isExist() && (statbuf_C.st_mode & S_IRGRP); }
135 bool isWGrp() const { return isExist() && (statbuf_C.st_mode & S_IWGRP); }
136 bool isXGrp() const { return isExist() && (statbuf_C.st_mode & S_IXGRP); }
138 bool isROth() const { return isExist() && (statbuf_C.st_mode & S_IROTH); }
139 bool isWOth() const { return isExist() && (statbuf_C.st_mode & S_IWOTH); }
140 bool isXOth() const { return isExist() && (statbuf_C.st_mode & S_IXOTH); }
142 bool isUid() const { return isExist() && (statbuf_C.st_mode & S_ISUID); }
143 bool isGid() const { return isExist() && (statbuf_C.st_mode & S_ISGID); }
144 bool isVtx() const { return isExist() && (statbuf_C.st_mode & S_ISVTX); }
146 mode_t uperm() const { return isExist() ? (statbuf_C.st_mode & S_IRWXU) : 0; }
147 mode_t gperm() const { return isExist() ? (statbuf_C.st_mode & S_IRWXG) : 0; }
148 mode_t operm() const { return isExist() ? (statbuf_C.st_mode & S_IRWXO) : 0; }
149 mode_t perm() const { return isExist() ? (statbuf_C.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO|S_ISUID|S_ISGID|S_ISVTX)) : 0; }
151 bool isPerm ( mode_t m ) const { return (m == perm()); }
152 bool hasPerm( mode_t m ) const { return (m == (m & perm())); }
154 mode_t st_mode() const { return isExist() ? statbuf_C.st_mode : 0; }
156 // permission according to current uid/gid (returns [0-7])
157 mode_t userMay() const;
159 bool userMayR() const { return( userMay() & 01 ); }
160 bool userMayW() const { return( userMay() & 02 ); }
161 bool userMayX() const { return( userMay() & 04 ); }
163 bool userMayRW() const { return( (userMay() & 03) == 03 ); }
164 bool userMayRX() const { return( (userMay() & 05) == 05 ); }
165 bool userMayWX() const { return( (userMay() & 06) == 06 ); }
167 bool userMayRWX() const { return( userMay() == 07 ); }
170 dev_t dev() const { return isExist() ? statbuf_C.st_dev : 0; }
171 dev_t rdev() const { return isExist() ? statbuf_C.st_rdev : 0; }
172 ino_t ino() const { return isExist() ? statbuf_C.st_ino : 0; }
175 off_t size() const { return isExist() ? statbuf_C.st_size : 0; }
176 unsigned long blksize() const { return isExist() ? statbuf_C.st_blksize : 0; }
177 unsigned long blocks() const { return isExist() ? statbuf_C.st_blocks : 0; }
180 time_t atime() const { return isExist() ? statbuf_C.st_atime : 0; } /* time of last access */
181 time_t mtime() const { return isExist() ? statbuf_C.st_mtime : 0; } /* time of last modification */
182 time_t ctime() const { return isExist() ? statbuf_C.st_ctime : 0; }
186 ///////////////////////////////////////////////////////////////////
188 ///////////////////////////////////////////////////////////////////
189 // static functions as they may or may not invalidate any stat info
190 // stored by a PathiInfo.
191 ///////////////////////////////////////////////////////////////////
193 ///////////////////////////////////////////////////////////////////
195 ///////////////////////////////////////////////////////////////////
198 * Like '::mkdir'. Attempt to create a new directory named path. mode
199 * specifies the permissions to use. It is modified by the process's
200 * umask in the usual way.
202 * @return 0 on success, errno on failure
204 static int mkdir( const Pathname & path, unsigned mode = 0755 );
207 * Like 'mkdir -p'. No error if directory exists. Make parent directories
208 * as needed. mode specifies the permissions to use, if directories have to
209 * be created. It is modified by the process's umask in the usual way.
211 * @return 0 on success, errno on failure
213 static int assert_dir( const Pathname & path, unsigned mode = 0755 );
216 * Like '::rmdir'. Delete a directory, which must be empty.
218 * @return 0 on success, errno on failure
220 static int rmdir( const Pathname & path );
223 * Like 'rm -r DIR'. Delete a directory, recursively removing its contents.
225 * @return 0 on success, ENOTDIR if path is not a directory, otherwise the
226 * commands return value.
228 static int recursive_rmdir( const Pathname & path );
231 * Like 'rm -r DIR/ *'. Delete directory contents, but keep the directory itself.
233 * @return 0 on success, ENOTDIR if path is not a directory, otherwise the
234 * commands return value.
236 static int clean_dir( const Pathname & path );
239 * Like 'cp -a srcpath destpath'. Copy directory tree. srcpath/destpath must be
240 * directories. 'basename srcpath' must not exist in destpath.
242 * @return 0 on success, ENOTDIR if srcpath/destpath is not a directory, EEXIST if
243 * 'basename srcpath' exists in destpath, otherwise the commands return value.
245 static int copy_dir( const Pathname & srcpath, const Pathname & destpath );
248 * Return content of directory via retlist. If dots is false
249 * entries starting with '.' are not reported. "." and ".."
250 * are never reported.
252 * @return 0 on success, errno on failure.
254 static int readdir( std::list<std::string> & retlist,
255 const Pathname & path, bool dots = true );
260 direntry( const std::string & name_r = std::string(), file_type type_r = NOT_AVAIL )
266 typedef std::list<direntry> dircontent;
269 * Return content of directory via retlist. If dots is false
270 * entries starting with '.' are not reported. "." and ".."
271 * are never reported.
273 * The type of individual directory entries is determined accoding to
274 * statmode (i.e. via stat or lstat).
276 * @return 0 on success, errno on failure.
278 static int readdir( dircontent & retlist, const Pathname & path,
279 bool dots = true, Mode statmode = STAT );
281 ///////////////////////////////////////////////////////////////////
283 ///////////////////////////////////////////////////////////////////
286 * Like '::unlink'. Delete a file (symbolic link, socket, fifo or device).
288 * @return 0 on success, errno on failure
290 static int unlink( const Pathname & path );
293 * Like '::rename'. Renames a file, moving it between directories if required.
295 * @return 0 on success, errno on failure
297 static int rename( const Pathname & oldpath, const Pathname & newpath );
300 * Like 'cp file dest'. Copy file to destination file.
302 * @return 0 on success, EINVAL if file is not a file, EISDIR if
303 * destiantion is a directory, otherwise the commands return value.
305 static int copy( const Pathname & file, const Pathname & dest );
308 * Like '::symlink'. Creates a symbolic link named newpath which contains
309 * the string oldpath. If newpath exists it will not be overwritten.
311 * @return 0 on success, errno on failure.
313 static int symlink( const Pathname & oldpath, const Pathname & newpath );
316 * Like '::link'. Creates a hard link named newpath to an existing file
317 * oldpath. If newpath exists it will not be overwritten.
319 * @return 0 on success, errno on failure.
321 static int hardlink( const Pathname & oldpath, const Pathname & newpath );
324 * Like 'cp file dest'. Copy file to dest dir.
326 * @return 0 on success, EINVAL if file is not a file, ENOTDIR if dest
327 * is no directory, otherwise the commands return value.
329 static int copy_file2dir( const Pathname & file, const Pathname & dest );
332 * Compute a files md5sum.
334 * @return the files md5sum on success, otherwise an empty string..
336 static std::string md5sum( const Pathname & file );
339 * Compute a files sha1sum.
341 * @return the files sha1sum on success, otherwise an empty string..
343 static std::string sha1sum( const Pathname & file );
345 ///////////////////////////////////////////////////////////////////
347 ///////////////////////////////////////////////////////////////////
350 * Erase whatever happens to be located at path (file or directory).
352 * @return 0 on success.
354 static int erase( const Pathname & path );
356 ///////////////////////////////////////////////////////////////////
358 ///////////////////////////////////////////////////////////////////
361 * Like '::chmod'. The mode of the file given by path is changed.
363 * @return 0 on success, errno on failure
365 static int chmod( const Pathname & path, mode_t mode );
367 ///////////////////////////////////////////////////////////////////
369 ///////////////////////////////////////////////////////////////////
372 * Test whether a file is compressed (gzip/bzip2).
374 * @return ZT_GZ, ZT_BZ2 if file is compressed, otherwise ZT_NONE.
376 enum ZIP_TYPE { ZT_NONE, ZT_GZ, ZT_BZ2 };
378 static ZIP_TYPE zipType( const Pathname & file );
381 ///////////////////////////////////////////////////////////////////
383 ///////////////////////////////////////////////////////////////////
385 // CLASS NAME : PathInfo::stat_mode
387 * @short Wrapper class for mode_t values as derived from ::stat
389 class PathInfo::stat_mode {
390 friend std::ostream & operator<<( std::ostream & str, const stat_mode & obj );
394 stat_mode( const mode_t & mode_r = 0 ) : _mode( mode_r ) {}
397 file_type fileType() const;
399 bool isFile() const { return S_ISREG( _mode ); }
400 bool isDir () const { return S_ISDIR( _mode ); }
401 bool isLink() const { return S_ISLNK( _mode ); }
402 bool isChr() const { return S_ISCHR( _mode ); }
403 bool isBlk() const { return S_ISBLK( _mode ); }
404 bool isFifo() const { return S_ISFIFO( _mode ); }
405 bool isSock() const { return S_ISSOCK( _mode ); }
408 bool isRUsr() const { return (_mode & S_IRUSR); }
409 bool isWUsr() const { return (_mode & S_IWUSR); }
410 bool isXUsr() const { return (_mode & S_IXUSR); }
412 bool isR() const { return isRUsr(); }
413 bool isW() const { return isWUsr(); }
414 bool isX() const { return isXUsr(); }
416 bool isRGrp() const { return (_mode & S_IRGRP); }
417 bool isWGrp() const { return (_mode & S_IWGRP); }
418 bool isXGrp() const { return (_mode & S_IXGRP); }
420 bool isROth() const { return (_mode & S_IROTH); }
421 bool isWOth() const { return (_mode & S_IWOTH); }
422 bool isXOth() const { return (_mode & S_IXOTH); }
424 bool isUid() const { return (_mode & S_ISUID); }
425 bool isGid() const { return (_mode & S_ISGID); }
426 bool isVtx() const { return (_mode & S_ISVTX); }
428 mode_t uperm() const { return (_mode & S_IRWXU); }
429 mode_t gperm() const { return (_mode & S_IRWXG); }
430 mode_t operm() const { return (_mode & S_IRWXO); }
431 mode_t perm() const { return (_mode & (S_IRWXU|S_IRWXG|S_IRWXO|S_ISUID|S_ISGID|S_ISVTX)); }
433 bool isPerm ( mode_t m ) const { return (m == perm()); }
434 bool hasPerm( mode_t m ) const { return (m == (m & perm())); }
436 mode_t st_mode() const { return _mode; }
439 ///////////////////////////////////////////////////////////////////
441 ///////////////////////////////////////////////////////////////////
443 // CLASS NAME : PathInfo::devino_cache
445 * @short Simple cache remembering device/inode to detect hardlinks.
447 * PathInfo::devino_cache trace;
448 * for ( all files ) {
449 * if ( trace.insert( file.device, file.inode ) ) {
450 * // 1st occurance of file
452 * // else: hardlink; already counted this device/inode
457 class PathInfo::devino_cache {
461 std::map<dev_t,std::set<ino_t> > _devino;
472 void clear() { _devino.clear(); }
475 * Remember dev/ino. Return <code>true</code> if it's inserted the first
476 * time, <code>false</code> if alredy present in cache (a hardlink to a
477 * previously remembered file.
479 bool insert( const dev_t & dev_r, const ino_t & ino_r ) {
480 return _devino[dev_r].insert( ino_r ).second;
484 ///////////////////////////////////////////////////////////////////
486 ///////////////////////////////////////////////////////////////////
489 #endif // ZYPP_PATHINFO_H