Added filesystem::getUmask and filesystem::applyUmaskTo (in PathInfo.h) and
[platform/upstream/libzypp.git] / zypp / PathInfo.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/PathInfo.cc
10  *
11 */
12
13 #include <sys/types.h> // for ::minor, ::major macros
14 #include <sys/statvfs.h>
15
16 #include <iostream>
17 #include <fstream>
18 #include <iomanip>
19
20 #include <boost/filesystem/operations.hpp>
21 #include <boost/filesystem/exception.hpp>
22
23 #include "zypp/base/Logger.h"
24 #include "zypp/base/String.h"
25 #include "zypp/base/IOStream.h"
26
27 #include "zypp/ExternalProgram.h"
28 #include "zypp/PathInfo.h"
29 #include "zypp/Digest.h"
30
31
32 using std::string;
33
34 ///////////////////////////////////////////////////////////////////
35 namespace zypp
36 { /////////////////////////////////////////////////////////////////
37   ///////////////////////////////////////////////////////////////////
38   namespace filesystem
39   { /////////////////////////////////////////////////////////////////
40
41     /******************************************************************
42      **
43      ** FUNCTION NAME : operator<<
44      ** FUNCTION TYPE : std::ostream &
45     */
46     std::ostream & operator<<( std::ostream & str, FileType obj )
47     {
48       switch ( obj ) {
49 #define EMUMOUT(T) case T: return str << #T; break
50         EMUMOUT( FT_NOT_AVAIL );
51         EMUMOUT( FT_NOT_EXIST );
52         EMUMOUT( FT_FILE );
53         EMUMOUT( FT_DIR );
54         EMUMOUT( FT_CHARDEV );
55         EMUMOUT( FT_BLOCKDEV );
56         EMUMOUT( FT_FIFO );
57         EMUMOUT( FT_LINK );
58         EMUMOUT( FT_SOCKET );
59 #undef EMUMOUT
60       }
61       return str;
62     }
63
64     ///////////////////////////////////////////////////////////////////
65     //
66     //  METHOD NAME : StatMode::fileType
67     //  METHOD TYPE : FileType
68     //
69     FileType StatMode::fileType() const
70     {
71       if ( isFile() )
72         return FT_FILE;
73       if ( isDir() )
74         return FT_DIR;
75       if ( isLink() )
76         return FT_LINK;
77       if ( isChr() )
78         return FT_CHARDEV;
79       if ( isBlk() )
80         return FT_BLOCKDEV;
81       if ( isFifo() )
82         return FT_FIFO;
83       if ( isSock() )
84         return FT_SOCKET ;
85
86       return FT_NOT_AVAIL;
87     }
88
89     /******************************************************************
90      **
91      ** FUNCTION NAME : operator<<
92      ** FUNCTION TYPE : std::ostream &
93     */
94     std::ostream & operator<<( std::ostream & str, const StatMode & obj )
95     {
96       iostr::IosFmtFlagsSaver autoResoreState( str );
97
98       char t = '?';
99       if ( obj.isFile() )
100         t = '-';
101       else if ( obj.isDir() )
102         t = 'd';
103       else if ( obj.isLink() )
104         t = 'l';
105       else if ( obj.isChr() )
106         t = 'c';
107       else if ( obj.isBlk() )
108         t = 'b';
109       else if ( obj.isFifo() )
110         t = 'p';
111       else if ( obj.isSock() )
112         t = 's';
113
114       str << t << " " << std::setfill( '0' ) << std::setw( 4 ) << std::oct << obj.perm();
115       return str;
116     }
117
118     ///////////////////////////////////////////////////////////////////
119     //
120     //  Class : PathInfo
121     //
122     ///////////////////////////////////////////////////////////////////
123
124     ///////////////////////////////////////////////////////////////////
125     //
126     //  METHOD NAME : PathInfo::PathInfo
127     //  METHOD TYPE : Constructor
128     //
129     PathInfo::PathInfo()
130     : mode_e( STAT )
131     , error_i( -1 )
132     {}
133
134     ///////////////////////////////////////////////////////////////////
135     //
136     //  METHOD NAME : PathInfo::PathInfo
137     //  METHOD TYPE : Constructor
138     //
139     PathInfo::PathInfo( const Pathname & path, Mode initial )
140     : path_t( path )
141     , mode_e( initial )
142     , error_i( -1 )
143     {
144       operator()();
145     }
146
147     ///////////////////////////////////////////////////////////////////
148     //
149     //  METHOD NAME : PathInfo::PathInfo
150     //  METHOD TYPE : Constructor
151     //
152     PathInfo::PathInfo( const std::string & path, Mode initial )
153     : path_t( path )
154     , mode_e( initial )
155     , error_i( -1 )
156     {
157       operator()();
158     }
159
160     ///////////////////////////////////////////////////////////////////
161     //
162     //  METHOD NAME : PathInfo::PathInfo
163     //  METHOD TYPE : Constructor
164     //
165     PathInfo::PathInfo( const char * path, Mode initial )
166     : path_t( path )
167     , mode_e( initial )
168     , error_i( -1 )
169     {
170       operator()();
171     }
172
173     ///////////////////////////////////////////////////////////////////
174     //
175     //  METHOD NAME : PathInfo::~PathInfo
176     //  METHOD TYPE : Destructor
177     //
178     PathInfo::~PathInfo()
179     {
180     }
181
182     ///////////////////////////////////////////////////////////////////
183     //
184     //  METHOD NAME : PathInfo::operator()
185     //  METHOD TYPE : bool
186     //
187     bool PathInfo::operator()()
188     {
189       if ( path_t.empty() ) {
190         error_i = -1;
191       } else {
192         switch ( mode_e ) {
193         case STAT:
194           error_i = ::stat( path_t.asString().c_str(), &statbuf_C );
195           break;
196         case LSTAT:
197           error_i = ::lstat( path_t.asString().c_str(), &statbuf_C );
198           break;
199         }
200         if ( error_i == -1 )
201           error_i = errno;
202       }
203       return !error_i;
204     }
205
206     ///////////////////////////////////////////////////////////////////
207     //
208     //  METHOD NAME : PathInfo::fileType
209     //  METHOD TYPE : File_type
210     //
211     FileType PathInfo::fileType() const
212     {
213       if ( isExist() )
214         return asStatMode().fileType();
215       return FT_NOT_EXIST;
216     }
217
218     ///////////////////////////////////////////////////////////////////
219     //
220     //  METHOD NAME : PathInfo::userMay
221     //  METHOD TYPE : mode_t
222     //
223     mode_t PathInfo::userMay() const
224     {
225       if ( !isExist() )
226         return 0;
227       if ( owner() == getuid() ) {
228         return( uperm()/0100 );
229       } else if ( group() == getgid() ) {
230         return( gperm()/010 );
231       }
232       return operm();
233     }
234
235     /******************************************************************
236      **
237      ** FUNCTION NAME : PathInfo::major
238      ** FUNCTION TYPE : unsigned int
239      */
240     unsigned int PathInfo::major() const
241     {
242       return isBlk() || isChr() ? ::major(statbuf_C.st_rdev) : 0;
243     }
244
245     /******************************************************************
246      **
247      ** FUNCTION NAME : PathInfo::minor
248      ** FUNCTION TYPE : unsigned int
249      */
250     unsigned int PathInfo::minor() const
251     {
252       return isBlk() || isChr() ? ::minor(statbuf_C.st_rdev) : 0;
253     }
254
255     /******************************************************************
256      **
257      ** FUNCTION NAME : operator<<
258      ** FUNCTION TYPE :  std::ostream &
259     */
260     std::ostream & operator<<( std::ostream & str, const PathInfo & obj )
261     {
262       iostr::IosFmtFlagsSaver autoResoreState( str );
263
264       str << obj.asString() << "{";
265       if ( !obj.isExist() ) {
266         str << "does not exist}";
267       } else {
268         str << obj.asStatMode() << " " << std::dec << obj.owner() << "/" << obj.group();
269
270         if ( obj.isFile() )
271           str << " size " << obj.size();
272
273         str << "}";
274       }
275
276       return str;
277     }
278
279     ///////////////////////////////////////////////////////////////////
280     //
281     //  filesystem utilities
282     //
283     ///////////////////////////////////////////////////////////////////
284
285     /******************************************************************
286      **
287      ** FUNCTION NAME : _Log_Result
288      ** FUNCTION TYPE : int
289      **
290      ** DESCRIPTION : Helper function to log return values.
291     */
292     inline int _Log_Result( const int res, const char * rclass = "errno" )
293     {
294       if ( res )
295         WAR << " FAILED: " << rclass << " " << res << std::endl;
296       else
297         DBG << std::endl;
298       return res;
299     }
300
301     ///////////////////////////////////////////////////////////////////
302     //
303     //  METHOD NAME : PathInfo::mkdir
304     //  METHOD TYPE : int
305     //
306     int mkdir( const Pathname & path, unsigned mode )
307     {
308       DBG << "mkdir " << path << ' ' << str::octstring( mode );
309       if ( ::mkdir( path.asString().c_str(), mode ) == -1 ) {
310         return _Log_Result( errno );
311       }
312       return _Log_Result( 0 );
313     }
314
315     ///////////////////////////////////////////////////////////////////
316     //
317     //  METHOD NAME : assert_dir()
318     //  METHOD TYPE : int
319     //
320     int assert_dir( const Pathname & path, unsigned mode )
321     {
322       string::size_type pos, lastpos = 0;
323       string spath = path.asString()+"/";
324       int ret = 0;
325
326       if(path.empty())
327         return ENOENT;
328
329       // skip ./
330       if(path.relative())
331         lastpos=2;
332       // skip /
333       else
334         lastpos=1;
335
336       //    DBG << "about to create " << spath << endl;
337       while((pos = spath.find('/',lastpos)) != string::npos )
338         {
339           string dir = spath.substr(0,pos);
340           ret = ::mkdir(dir.c_str(), mode);
341           if(ret == -1)
342             {
343               // ignore errors about already existing directorys
344               if(errno == EEXIST)
345                 ret=0;
346               else
347                 ret=errno;
348             }
349           //    DBG << "creating directory " << dir << (ret?" failed":" succeeded") << endl;
350           lastpos = pos+1;
351         }
352       return ret;
353     }
354
355     ///////////////////////////////////////////////////////////////////
356     //
357     //  METHOD NAME : rmdir
358     //  METHOD TYPE : int
359     //
360     int rmdir( const Pathname & path )
361     {
362       DBG << "rmdir " << path;
363       if ( ::rmdir( path.asString().c_str() ) == -1 ) {
364         return _Log_Result( errno );
365       }
366       return _Log_Result( 0 );
367     }
368
369     ///////////////////////////////////////////////////////////////////
370     //
371     //  METHOD NAME : recursive_rmdir
372     //  METHOD TYPE : int
373     //
374     int recursive_rmdir( const Pathname & path )
375     {
376       DBG << "recursive_rmdir " << path << ' ';
377       PathInfo p( path );
378
379       if ( !p.isExist() ) {
380         return _Log_Result( 0 );
381       }
382
383       if ( !p.isDir() ) {
384         return _Log_Result( ENOTDIR );
385       }
386
387       try
388         {
389           boost::filesystem::path bp( path.asString(), boost::filesystem::native );
390           boost::filesystem::remove_all( bp );
391         }
392       catch ( boost::filesystem::filesystem_error & excpt )
393         {
394           WAR << " FAILED: " << excpt.what() << std::endl;
395           return -1;
396         }
397
398       return _Log_Result( 0 );
399     }
400
401     ///////////////////////////////////////////////////////////////////
402     //
403     //  METHOD NAME : clean_dir
404     //  METHOD TYPE : int
405     //
406     int clean_dir( const Pathname & path )
407     {
408       DBG << "clean_dir " << path << ' ';
409       PathInfo p( path );
410
411       if ( !p.isExist() ) {
412         return _Log_Result( 0 );
413       }
414
415       if ( !p.isDir() ) {
416         return _Log_Result( ENOTDIR );
417       }
418
419       string cmd( str::form( "cd '%s' && rm -rf --preserve-root -- *", path.asString().c_str() ) );
420       ExternalProgram prog( cmd, ExternalProgram::Stderr_To_Stdout );
421       for ( string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) {
422         DBG << "  " << output;
423       }
424       int ret = prog.close();
425       return _Log_Result( ret, "returned" );
426     }
427
428     ///////////////////////////////////////////////////////////////////
429     //
430     //  METHOD NAME : copy_dir
431     //  METHOD TYPE : int
432     //
433     int copy_dir( const Pathname & srcpath, const Pathname & destpath )
434     {
435       DBG << "copy_dir " << srcpath << " -> " << destpath << ' ';
436
437       PathInfo sp( srcpath );
438       if ( !sp.isDir() ) {
439         return _Log_Result( ENOTDIR );
440       }
441
442       PathInfo dp( destpath );
443       if ( !dp.isDir() ) {
444         return _Log_Result( ENOTDIR );
445       }
446
447       PathInfo tp( destpath + srcpath.basename() );
448       if ( tp.isExist() ) {
449         return _Log_Result( EEXIST );
450       }
451
452
453       const char *const argv[] = {
454         "/bin/cp",
455         "-dR",
456         "--",
457         srcpath.asString().c_str(),
458         destpath.asString().c_str(),
459         NULL
460       };
461       ExternalProgram prog( argv, ExternalProgram::Stderr_To_Stdout );
462       for ( string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) {
463         DBG << "  " << output;
464       }
465       int ret = prog.close();
466       return _Log_Result( ret, "returned" );
467     }
468
469     ///////////////////////////////////////////////////////////////////
470     //
471     //  METHOD NAME : copy_dir_content
472     //  METHOD TYPE : int
473     //
474     int copy_dir_content(const Pathname & srcpath, const Pathname & destpath)
475     {
476       DBG << "copy_dir " << srcpath << " -> " << destpath << ' ';
477
478       PathInfo sp( srcpath );
479       if ( !sp.isDir() ) {
480         return _Log_Result( ENOTDIR );
481       }
482
483       PathInfo dp( destpath );
484       if ( !dp.isDir() ) {
485         return _Log_Result( ENOTDIR );
486       }
487
488       if ( srcpath == destpath ) {
489         return _Log_Result( EEXIST );
490       }
491
492       std::string src( srcpath.asString());
493       src += "/.";
494       const char *const argv[] = {
495         "/bin/cp",
496         "-dR",
497         "--",
498         src.c_str(),
499         destpath.asString().c_str(),
500         NULL
501       };
502       ExternalProgram prog( argv, ExternalProgram::Stderr_To_Stdout );
503       for ( string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) {
504         DBG << "  " << output;
505       }
506       int ret = prog.close();
507       return _Log_Result( ret, "returned" );
508     }
509
510     ///////////////////////////////////////////////////////////////////
511     //
512     //  METHOD NAME : readdir
513     //  METHOD TYPE : int
514     //
515     int readdir( std::list<std::string> & retlist,
516                  const Pathname & path, bool dots )
517     {
518       retlist.clear();
519
520       DBG << "readdir " << path << ' ';
521
522       DIR * dir = ::opendir( path.asString().c_str() );
523       if ( ! dir ) {
524         return _Log_Result( errno );
525       }
526
527       struct dirent *entry;
528       while ( (entry = ::readdir( dir )) != 0 ) {
529
530         if ( entry->d_name[0] == '.' ) {
531           if ( !dots )
532             continue;
533           if ( entry->d_name[1] == '\0'
534                || (    entry->d_name[1] == '.'
535                     && entry->d_name[2] == '\0' ) )
536             continue;
537         }
538         retlist.push_back( entry->d_name );
539       }
540
541       ::closedir( dir );
542
543       return _Log_Result( 0 );
544     }
545
546
547     ///////////////////////////////////////////////////////////////////
548     //
549     //  METHOD NAME : readdir
550     //  METHOD TYPE : int
551     //
552     int readdir( std::list<Pathname> & retlist,
553                  const Pathname & path, bool dots )
554     {
555       retlist.clear();
556
557       std::list<string> content;
558       int res = readdir( content, path, dots );
559
560       if ( !res ) {
561         for ( std::list<string>::const_iterator it = content.begin(); it != content.end(); ++it ) {
562           retlist.push_back( path + *it );
563         }
564       }
565
566       return res;
567     }
568
569     ///////////////////////////////////////////////////////////////////
570     //
571     //  METHOD NAME : readdir
572     //  METHOD TYPE : int
573     //
574     int readdir( DirContent & retlist, const Pathname & path,
575                  bool dots, PathInfo::Mode statmode )
576     {
577       retlist.clear();
578
579       std::list<string> content;
580       int res = readdir( content, path, dots );
581
582       if ( !res ) {
583         for ( std::list<string>::const_iterator it = content.begin(); it != content.end(); ++it ) {
584           PathInfo p( path + *it, statmode );
585           retlist.push_back( DirEntry( *it, p.fileType() ) );
586         }
587       }
588
589       return res;
590     }
591
592     ///////////////////////////////////////////////////////////////////
593     //
594     //  METHOD NAME : is_empty_dir
595     //  METHOD TYPE : int
596     //
597     int is_empty_dir(const Pathname & path)
598     {
599       DIR * dir = ::opendir( path.asString().c_str() );
600       if ( ! dir ) {
601         return _Log_Result( errno );
602       }
603
604       struct dirent *entry;
605       while ( (entry = ::readdir( dir )) != NULL )
606       {
607         std::string name(entry->d_name);
608
609         if ( name == "." || name == "..")
610           continue;
611
612         break;
613       }
614       ::closedir( dir );
615
616       return entry != NULL ? -1 : 0;
617     }
618
619     ///////////////////////////////////////////////////////////////////
620     //
621     //  METHOD NAME : unlink
622     //  METHOD TYPE : int
623     //
624     int unlink( const Pathname & path )
625     {
626       DBG << "unlink " << path;
627       if ( ::unlink( path.asString().c_str() ) == -1 ) {
628         return _Log_Result( errno );
629       }
630       return _Log_Result( 0 );
631     }
632
633     ///////////////////////////////////////////////////////////////////
634     //
635     //  METHOD NAME : rename
636     //  METHOD TYPE : int
637     //
638     int rename( const Pathname & oldpath, const Pathname & newpath )
639     {
640       DBG << "rename " << oldpath << " -> " << newpath;
641       if ( ::rename( oldpath.asString().c_str(), newpath.asString().c_str() ) == -1 ) {
642         return _Log_Result( errno );
643       }
644       return _Log_Result( 0 );
645     }
646
647     ///////////////////////////////////////////////////////////////////
648     //
649     //  METHOD NAME : copy
650     //  METHOD TYPE : int
651     //
652     int copy( const Pathname & file, const Pathname & dest )
653     {
654       DBG << "copy " << file << " -> " << dest << ' ';
655
656       PathInfo sp( file );
657       if ( !sp.isFile() ) {
658         return _Log_Result( EINVAL );
659       }
660
661       PathInfo dp( dest );
662       if ( dp.isDir() ) {
663         return _Log_Result( EISDIR );
664       }
665
666       const char *const argv[] = {
667         "/bin/cp",
668         "--",
669         file.asString().c_str(),
670         dest.asString().c_str(),
671         NULL
672       };
673       ExternalProgram prog( argv, ExternalProgram::Stderr_To_Stdout );
674       for ( string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) {
675         DBG << "  " << output;
676       }
677       int ret = prog.close();
678       return _Log_Result( ret, "returned" );
679     }
680
681     ///////////////////////////////////////////////////////////////////
682     //
683     //  METHOD NAME : symlink
684     //  METHOD TYPE : int
685     //
686     int symlink( const Pathname & oldpath, const Pathname & newpath )
687     {
688       DBG << "symlink " << newpath << " -> " << oldpath;
689       if ( ::symlink( oldpath.asString().c_str(), newpath.asString().c_str() ) == -1 ) {
690         return _Log_Result( errno );
691       }
692       return _Log_Result( 0 );
693     }
694
695     ///////////////////////////////////////////////////////////////////
696     //
697     //  METHOD NAME : hardlink
698     //  METHOD TYPE : int
699     //
700     int hardlink( const Pathname & oldpath, const Pathname & newpath )
701     {
702       DBG << "hardlink " << newpath << " -> " << oldpath;
703       if ( ::link( oldpath.asString().c_str(), newpath.asString().c_str() ) == -1 ) {
704         return _Log_Result( errno );
705       }
706       return _Log_Result( 0 );
707     }
708
709     ///////////////////////////////////////////////////////////////////
710     //
711     //  METHOD NAME : copy_file2dir
712     //  METHOD TYPE : int
713     //
714     int copy_file2dir( const Pathname & file, const Pathname & dest )
715     {
716       DBG << "copy_file2dir " << file << " -> " << dest << ' ';
717
718       PathInfo sp( file );
719       if ( !sp.isFile() ) {
720         return _Log_Result( EINVAL );
721       }
722
723       PathInfo dp( dest );
724       if ( !dp.isDir() ) {
725         return _Log_Result( ENOTDIR );
726       }
727
728       const char *const argv[] = {
729         "/bin/cp",
730         "--",
731         file.asString().c_str(),
732         dest.asString().c_str(),
733         NULL
734       };
735       ExternalProgram prog( argv, ExternalProgram::Stderr_To_Stdout );
736       for ( string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) {
737         DBG << "  " << output;
738       }
739       int ret = prog.close();
740       return _Log_Result( ret, "returned" );
741     }
742
743     ///////////////////////////////////////////////////////////////////
744     //
745     //  METHOD NAME : md5sum
746     //  METHOD TYPE : std::string
747     //
748     std::string md5sum( const Pathname & file )
749     {
750       if ( ! PathInfo( file ).isFile() ) {
751         return string();
752       }
753       std::ifstream istr( file.asString().c_str() );
754       if ( ! istr ) {
755         return string();
756       }
757       return Digest::digest( "MD5", istr );
758     }
759
760     ///////////////////////////////////////////////////////////////////
761     //
762     //  METHOD NAME : sha1sum
763     //  METHOD TYPE : std::string
764     //
765     std::string sha1sum( const Pathname & file )
766     {
767       return checksum(file, "SHA1");
768     }
769
770     ///////////////////////////////////////////////////////////////////
771     //
772     //  METHOD NAME : checksum
773     //  METHOD TYPE : std::string
774     //
775     std::string checksum( const Pathname & file, const std::string &algorithm )
776     {
777       if ( ! PathInfo( file ).isFile() ) {
778         return string();
779       }
780       std::ifstream istr( file.asString().c_str() );
781       if ( ! istr ) {
782         return string();
783       }
784       return Digest::digest( algorithm, istr );
785     }
786
787     bool is_checksum( const Pathname & file, const CheckSum &checksum )
788     {
789       return ( filesystem::checksum(file,  checksum.type()) == checksum.checksum() );
790     }
791
792     ///////////////////////////////////////////////////////////////////
793     //
794     //  METHOD NAME : erase
795     //  METHOD TYPE : int
796     //
797     int erase( const Pathname & path )
798     {
799       int res = 0;
800       PathInfo p( path, PathInfo::LSTAT );
801       if ( p.isExist() )
802         {
803           if ( p.isDir() )
804             res = recursive_rmdir( path );
805           else
806             res = unlink( path );
807         }
808       return res;
809     }
810
811     ///////////////////////////////////////////////////////////////////
812     //
813     //  METHOD NAME : chmod
814     //  METHOD TYPE : int
815     //
816     int chmod( const Pathname & path, mode_t mode )
817     {
818       DBG << "chmod " << path << ' ' << str::octstring( mode );
819       if ( ::chmod( path.asString().c_str(), mode ) == -1 ) {
820         return _Log_Result( errno );
821       }
822       return _Log_Result( 0 );
823     }
824
825     ///////////////////////////////////////////////////////////////////
826     //
827     //  METHOD NAME : zipType
828     //  METHOD TYPE : ZIP_TYPE
829     //
830     ZIP_TYPE zipType( const Pathname & file )
831     {
832       ZIP_TYPE ret = ZT_NONE;
833
834       int fd = open( file.asString().c_str(), O_RDONLY );
835
836       if ( fd != -1 ) {
837         const int magicSize = 3;
838         unsigned char magic[magicSize];
839         memset( magic, 0, magicSize );
840         if ( read( fd, magic, magicSize ) == magicSize ) {
841           if ( magic[0] == 0037 && magic[1] == 0213 ) {
842             ret = ZT_GZ;
843           } else if ( magic[0] == 'B' && magic[1] == 'Z' && magic[2] == 'h' ) {
844             ret = ZT_BZ2;
845           }
846         }
847         close( fd );
848       }
849
850       return ret;
851     }
852
853     ///////////////////////////////////////////////////////////////////
854     //
855     //  METHOD NAME : df
856     //  METHOD TYPE : ByteCount
857     //
858     ByteCount df( const Pathname & path_r )
859     {
860       ByteCount ret( -1 );
861       struct statvfs sb;
862       if ( statvfs( path_r.c_str(), &sb ) == 0 )
863         {
864           ret = sb.f_bfree * sb.f_bsize;
865         }
866       return ret;
867     }
868
869     ///////////////////////////////////////////////////////////////////
870     //
871     //  METHOD NAME : getUmask
872     //  METHOD TYPE : mode_t
873     //
874     mode_t getUmask()
875     {
876       mode_t mask = ::umask( 0022 );
877       ::umask( mask );
878       return mask;
879     }
880
881     /////////////////////////////////////////////////////////////////
882   } // namespace filesystem
883   ///////////////////////////////////////////////////////////////////
884   /////////////////////////////////////////////////////////////////
885 } // namespace zypp
886 ///////////////////////////////////////////////////////////////////