RpmHeader.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include "librpm.h"
00013 
00014 #include <iostream>
00015 #include <map>
00016 #include <set>
00017 #include <vector>
00018 
00019 #include "zypp/base/Logger.h"
00020 #include "zypp/PathInfo.h"
00021 
00022 #include "zypp/target/rpm/RpmHeader.h"
00023 #include "zypp/CapFactory.h"
00024 #include "zypp/Rel.h"
00025 #include "zypp/Package.h"
00026 #include "zypp/base/Exception.h"
00027 
00028 using namespace std;
00029 
00030 namespace zypp {
00031   namespace target {
00032     namespace rpm {
00033 
00035 
00037       //
00038       //
00039       //        METHOD NAME : RpmHeader::RpmHeader
00040       //        METHOD TYPE : Constructor
00041       //
00042       //        DESCRIPTION :
00043       //
00044       RpmHeader::RpmHeader( Header h_r )
00045           : BinHeader( h_r )
00046       {
00047       }
00048 
00050       //
00051       //
00052       //        METHOD NAME : RpmHeader::RpmHeader
00053       //        METHOD TYPE : Constructor
00054       //
00055       RpmHeader::RpmHeader( BinHeader::Ptr & rhs )
00056           : BinHeader( rhs )
00057       {
00058       }
00059 
00061       //
00062       //
00063       //        METHOD NAME : RpmHeader::~RpmHeader
00064       //        METHOD TYPE : Destructor
00065       //
00066       //        DESCRIPTION :
00067       //
00068       RpmHeader::~RpmHeader()
00069       {
00070       }
00071 
00073       //
00074       //
00075       //        METHOD NAME : RpmHeader::readPackage
00076       //        METHOD TYPE : constRpmHeaderPtr
00077       //
00078       RpmHeader::constPtr RpmHeader::readPackage( const Pathname & path_r,
00079                                           VERIFICATION verification_r )
00080       {
00081         PathInfo file( path_r );
00082         if ( ! file.isFile() ) {
00083           ERR << "Not a file: " << file << endl;
00084           return (RpmHeader*)0;
00085         }
00086 
00087         FD_t fd = ::Fopen( file.asString().c_str(), "r.ufdio" );
00088         if ( fd == 0 || ::Ferror(fd) ) {
00089           ERR << "Can't open file for reading: " << file << " (" << ::Fstrerror(fd) << ")" << endl;
00090           if ( fd )
00091             ::Fclose( fd );
00092           return (RpmHeader*)0;
00093         }
00094 
00095         rpmts ts = ::rpmtsCreate();
00096         unsigned vsflag = RPMVSF_DEFAULT;
00097         if ( verification_r & NODIGEST )
00098           vsflag |= _RPMVSF_NODIGESTS;
00099         if ( verification_r & NOSIGNATURE )
00100           vsflag |= _RPMVSF_NOSIGNATURES;
00101         ::rpmtsSetVSFlags( ts, rpmVSFlags(vsflag) );
00102 
00103         Header nh = 0;
00104         int res = ::rpmReadPackageFile( ts, fd, path_r.asString().c_str(), &nh );
00105 
00106         ts = ::rpmtsFree(ts);
00107 
00108         ::Fclose( fd );
00109 
00110         if ( ! nh ) {
00111           WAR << "Error reading header from " << path_r << " error(" << res << ")" << endl;
00112           return (RpmHeader*)0;
00113         }
00114 
00115         RpmHeader::constPtr h( new RpmHeader( nh ) );
00116         headerFree( nh ); // clear the reference set in ReadPackageFile
00117 
00118         MIL << h << " from " << path_r << endl;
00119         return h;
00120       }
00121 
00123       //
00124       //
00125       //        METHOD NAME : RpmHeader::dumpOn
00126       //        METHOD TYPE : ostream &
00127       //
00128       //        DESCRIPTION :
00129       //
00130       ostream & RpmHeader::dumpOn( ostream & str ) const
00131       {
00132         return BinHeader::dumpOn( str ) << '{' << tag_name() << "-"
00133                 << (tag_epoch().empty()?"":(tag_epoch()+":"))
00134                 << tag_version()
00135                 << (tag_release().empty()?"":(string("-")+tag_release()))
00136                 << ( isSrc() ? ".src}" : "}");
00137       }
00138 
00139 
00141       //
00142       //
00143       //        METHOD NAME : RpmHeader::isSrc
00144       //        METHOD TYPE : bool
00145       //
00146       bool RpmHeader::isSrc() const
00147       {
00148         return has_tag( RPMTAG_SOURCEPACKAGE );
00149       }
00150 
00152       //
00153       //
00154       //        METHOD NAME : RpmHeader::tag_name
00155       //        METHOD TYPE : string
00156       //
00157       //        DESCRIPTION :
00158       //
00159       string RpmHeader::tag_name() const
00160       {
00161         return string_val( RPMTAG_NAME );
00162       }
00163 
00165       //
00166       //
00167       //        METHOD NAME : RpmHeader::tag_epoch
00168       //        METHOD TYPE : string
00169       //
00170       //        DESCRIPTION :
00171       //
00172       string RpmHeader::tag_epoch() const
00173       {
00174         return string_val ( RPMTAG_EPOCH );
00175       }
00176 
00178       //
00179       //
00180       //        METHOD NAME : RpmHeader::tag_version
00181       //        METHOD TYPE : string
00182       //
00183       //        DESCRIPTION :
00184       //
00185       string RpmHeader::tag_version() const
00186       {
00187         return string_val ( RPMTAG_VERSION );
00188       }
00189 
00191       //
00192       //
00193       //        METHOD NAME : RpmHeader::tag_release
00194       //        METHOD TYPE : string
00195       //
00196       //        DESCRIPTION :
00197       //
00198       string RpmHeader::tag_release() const
00199       {
00200         return string_val( RPMTAG_RELEASE );
00201       }
00202 
00204       //
00205       //
00206       //        METHOD NAME : RpmHeader::tag_edition
00207       //        METHOD TYPE : Edition
00208       //
00209       //        DESCRIPTION :
00210       //
00211       Edition RpmHeader::tag_edition () const
00212       {
00213         try {
00214           return Edition( tag_version(), tag_release(), tag_epoch());
00215         }
00216         catch (Exception & excpt_r) {
00217           WAR << "Package " << tag_name() << "has an invalid edition";
00218           ZYPP_CAUGHT (excpt_r);
00219         }
00220         return Edition();
00221       }
00222 
00224       //
00225       //
00226       //        METHOD NAME : RpmHeader::tag_arch
00227       //        METHOD TYPE : string
00228       //
00229       //        DESCRIPTION :
00230       //
00231       string RpmHeader::tag_arch() const
00232       {
00233         return string_val( RPMTAG_ARCH );
00234       }
00235 
00237       //
00238       //
00239       //        METHOD NAME : RpmHeader::tag_installtime
00240       //        METHOD TYPE : Date
00241       //
00242       //        DESCRIPTION :
00243       //
00244       Date RpmHeader::tag_installtime() const
00245       {
00246         return int_val( RPMTAG_INSTALLTIME );
00247       }
00248 
00250       //
00251       //
00252       //        METHOD NAME : RpmHeader::tag_buildtime
00253       //        METHOD TYPE : Date
00254       //
00255       //        DESCRIPTION :
00256       //
00257       Date RpmHeader::tag_buildtime() const
00258       {
00259         return int_val( RPMTAG_BUILDTIME );
00260       }
00261 
00263       //
00264       //
00265       //        METHOD NAME : RpmHeader::PkgRelList_val
00266       //        METHOD TYPE : unsigned
00267       //
00268       //        DESCRIPTION :
00269       //
00270       CapSet RpmHeader::PkgRelList_val( tag tag_r, bool pre, set<string> * freq_r ) const
00271       {
00272         CapSet ret;
00273 
00274         int_32  kindFlags   = 0;
00275         int_32  kindVersion = 0;
00276 
00277         switch ( tag_r ) {
00278         case RPMTAG_REQUIRENAME:
00279           kindFlags   = RPMTAG_REQUIREFLAGS;
00280           kindVersion = RPMTAG_REQUIREVERSION;
00281           break;
00282         case RPMTAG_PROVIDENAME:
00283           kindFlags   = RPMTAG_PROVIDEFLAGS;
00284           kindVersion = RPMTAG_PROVIDEVERSION;
00285           break;
00286         case RPMTAG_OBSOLETENAME:
00287           kindFlags   = RPMTAG_OBSOLETEFLAGS;
00288           kindVersion = RPMTAG_OBSOLETEVERSION;
00289           break;
00290         case RPMTAG_CONFLICTNAME:
00291           kindFlags   = RPMTAG_CONFLICTFLAGS;
00292           kindVersion = RPMTAG_CONFLICTVERSION;
00293           break;
00294 #ifdef HAVE_RPM_ENHANCES
00295         case RPMTAG_ENHANCESNAME:
00296           kindFlags   = RPMTAG_ENHANCESFLAGS;
00297           kindVersion = RPMTAG_ENHANCESVERSION;
00298           break;
00299 #endif
00300 #warning NEEDS RPMTAG_SUPPLEMENTSNAME
00301 #if 0
00302         case RPMTAG_SUPPLEMENTSNAME:
00303           kindFlags   = RPMTAG_SUPPLEMENTSFLAGS;
00304           kindVersion = RPMTAG_SUPPLEMENTSVERSION;
00305           break;
00306 #endif
00307         default:
00308           INT << "Illegal RPMTAG_dependencyNAME " << tag_r << endl;
00309           return ret;
00310           break;
00311         }
00312 
00313         stringList names;
00314         unsigned count = string_list( tag_r, names );
00315         if ( !count )
00316           return ret;
00317 
00318         intList  flags;
00319         int_list( kindFlags, flags );
00320 
00321         stringList versions;
00322         string_list( kindVersion, versions );
00323 
00324         for ( unsigned i = 0; i < count; ++i ) {
00325 
00326           string n( names[i] );
00327 
00328           Rel op = Rel::ANY;
00329           int_32 f  = flags[i];
00330           string v  = versions[i];
00331 
00332           if ( n[0] == '/' ) {
00333             if ( freq_r ) {
00334               freq_r->insert( n );
00335             }
00336           } else {
00337             if ( v.size() ) {
00338               switch ( f & RPMSENSE_SENSEMASK ) {
00339               case RPMSENSE_LESS:
00340                 op = Rel::LT;
00341                 break;
00342               case RPMSENSE_LESS|RPMSENSE_EQUAL:
00343                 op = Rel::LE;
00344                 break;
00345               case RPMSENSE_GREATER:
00346                 op = Rel::GT;
00347                 break;
00348               case RPMSENSE_GREATER|RPMSENSE_EQUAL:
00349                 op = Rel::GE;
00350                 break;
00351               case RPMSENSE_EQUAL:
00352                 op = Rel::EQ;
00353                 break;
00354               }
00355             }
00356           }
00357           if ((pre && (f & RPMSENSE_PREREQ))
00358             || ((! pre) && !(f & RPMSENSE_PREREQ)))
00359           {
00360             CapFactory _f;
00361             try {
00362               Capability cap = _f.parse(
00363                 ResTraits<Package>::kind,
00364                 n,
00365                 op,
00366                 Edition(v)
00367               );
00368               ret.insert(cap);
00369             }
00370             catch (Exception & excpt_r)
00371             {
00372               ZYPP_CAUGHT(excpt_r);
00373               WAR << "Invalid capability: " << n << " " << op << " "
00374                 << v << endl;
00375             }
00376           }
00377         }
00378 
00379         return ret;
00380       }
00381 
00383       //
00384       //
00385       //        METHOD NAME : RpmHeader::tag_provides
00386       //        METHOD TYPE : CapSet
00387       //
00388       //        DESCRIPTION :
00389       //
00390       CapSet RpmHeader::tag_provides( set<string> * freq_r ) const
00391       {
00392         return PkgRelList_val( RPMTAG_PROVIDENAME, false, freq_r );
00393       }
00394 
00396       //
00397       //
00398       //        METHOD NAME : RpmHeader::tag_requires
00399       //        METHOD TYPE : CapSet
00400       //
00401       //        DESCRIPTION :
00402       //
00403       CapSet RpmHeader::tag_requires( set<string> * freq_r ) const
00404       {
00405         return PkgRelList_val( RPMTAG_REQUIRENAME, false, freq_r );
00406       }
00407 
00409       //
00410       //
00411       //        METHOD NAME : RpmHeader::tag_requires
00412       //        METHOD TYPE : CapSet
00413       //
00414       //        DESCRIPTION :
00415       //
00416       CapSet RpmHeader::tag_prerequires( set<string> * freq_r ) const
00417       {
00418         return PkgRelList_val( RPMTAG_REQUIRENAME, true, freq_r );
00419       }
00420 
00422       //
00423       //
00424       //        METHOD NAME : RpmHeader::tag_conflicts
00425       //        METHOD TYPE : CapSet
00426       //
00427       //        DESCRIPTION :
00428       //
00429       CapSet RpmHeader::tag_conflicts( set<string> * freq_r ) const
00430       {
00431         return PkgRelList_val( RPMTAG_CONFLICTNAME, false, freq_r );
00432       }
00433 
00435       //
00436       //
00437       //        METHOD NAME : RpmHeader::tag_obsoletes
00438       //        METHOD TYPE : CapSet
00439       //
00440       //        DESCRIPTION :
00441       //
00442       CapSet RpmHeader::tag_obsoletes( set<string> * freq_r ) const
00443       {
00444         return PkgRelList_val( RPMTAG_OBSOLETENAME, false, freq_r );
00445       }
00446 
00448       //
00449       //
00450       //        METHOD NAME : RpmHeader::tag_enhances
00451       //        METHOD TYPE : CapSet
00452       //
00453       //        DESCRIPTION :
00454       //
00455       CapSet RpmHeader::tag_enhances( set<string> * freq_r ) const
00456       {
00457 #ifdef HAVE_RPM_ENHANCES
00458         return PkgRelList_val( RPMTAG_ENHANCESNAME, false, freq_r );
00459 #else
00460         return CapSet();
00461 #endif
00462       }
00463 
00465       //
00466       //
00467       //        METHOD NAME : RpmHeader::tag_supplements
00468       //        METHOD TYPE : CapSet
00469       //
00470       //        DESCRIPTION :
00471       //
00472       CapSet RpmHeader::tag_supplements( set<string> * freq_r ) const
00473       {
00474         return CapSet();
00475 #warning NEEDS RPMTAG_SUPPLEMENTSNAME
00476 #if 0
00477         return PkgRelList_val( RPMTAG_SUPPLEMENTSNAME, false, freq_r );
00478 #endif
00479       }
00480 
00482       //
00483       //
00484       //        METHOD NAME : RpmHeader::tag_size
00485       //        METHOD TYPE : ByteCount
00486       //
00487       //        DESCRIPTION :
00488       //
00489       ByteCount RpmHeader::tag_size() const
00490       {
00491         return int_val( RPMTAG_SIZE );
00492       }
00493 
00495       //
00496       //
00497       //        METHOD NAME : RpmHeader::tag_archivesize
00498       //        METHOD TYPE : ByteCount
00499       //
00500       //        DESCRIPTION :
00501       //
00502       ByteCount RpmHeader::tag_archivesize() const
00503       {
00504         return int_val( RPMTAG_ARCHIVESIZE );
00505       }
00506 
00508       //
00509       //
00510       //        METHOD NAME : RpmHeader::tag_summary
00511       //        METHOD TYPE : std::string
00512       //
00513       //        DESCRIPTION :
00514       //
00515       std::string RpmHeader::tag_summary() const
00516       {
00517         return string_val( RPMTAG_SUMMARY );
00518       }
00519 
00521       //
00522       //
00523       //        METHOD NAME : RpmHeader::tag_description
00524       //        METHOD TYPE : std::string
00525       //
00526       //        DESCRIPTION :
00527       //
00528       std::string RpmHeader::tag_description() const
00529       {
00530         return string_val( RPMTAG_DESCRIPTION );
00531       }
00532 
00534       //
00535       //
00536       //        METHOD NAME : RpmHeader::tag_group
00537       //        METHOD TYPE : std::string
00538       //
00539       //        DESCRIPTION :
00540       //
00541       std::string RpmHeader::tag_group() const
00542       {
00543         return string_val( RPMTAG_GROUP );
00544       }
00545 
00547       //
00548       //
00549       //        METHOD NAME : RpmHeader::tag_vendor
00550       //        METHOD TYPE : std::string
00551       //
00552       //        DESCRIPTION :
00553       //
00554       std::string RpmHeader::tag_vendor() const
00555       {
00556         return string_val( RPMTAG_VENDOR );
00557       }
00558 
00560       //
00561       //
00562       //        METHOD NAME : RpmHeader::tag_distribution
00563       //        METHOD TYPE : std::string
00564       //
00565       //        DESCRIPTION :
00566       //
00567       std::string RpmHeader::tag_distribution() const
00568       {
00569         return string_val( RPMTAG_DISTRIBUTION );
00570       }
00571 
00573       //
00574       //
00575       //        METHOD NAME : RpmHeader::tag_license
00576       //        METHOD TYPE : std::string
00577       //
00578       //        DESCRIPTION :
00579       //
00580       std::string RpmHeader::tag_license() const
00581       {
00582         return string_val( RPMTAG_LICENSE );
00583       }
00584 
00586       //
00587       //
00588       //        METHOD NAME : RpmHeader::tag_buildhost
00589       //        METHOD TYPE : std::string
00590       //
00591       //        DESCRIPTION :
00592       //
00593       std::string RpmHeader::tag_buildhost() const
00594       {
00595         return string_val( RPMTAG_BUILDHOST );
00596       }
00597 
00599       //
00600       //
00601       //        METHOD NAME : RpmHeader::tag_packager
00602       //        METHOD TYPE : std::string
00603       //
00604       //        DESCRIPTION :
00605       //
00606       std::string RpmHeader::tag_packager() const
00607       {
00608         return string_val( RPMTAG_PACKAGER );
00609       }
00610 
00612       //
00613       //
00614       //        METHOD NAME : RpmHeader::tag_url
00615       //        METHOD TYPE : std::string
00616       //
00617       //        DESCRIPTION :
00618       //
00619       std::string RpmHeader::tag_url() const
00620       {
00621         return string_val( RPMTAG_URL );
00622       }
00623 
00625       //
00626       //
00627       //        METHOD NAME : RpmHeader::tag_os
00628       //        METHOD TYPE : std::string
00629       //
00630       //        DESCRIPTION :
00631       //
00632       std::string RpmHeader::tag_os() const
00633       {
00634         return string_val( RPMTAG_OS );
00635       }
00636 
00638       //
00639       //
00640       //        METHOD NAME : RpmHeader::tag_prein
00641       //        METHOD TYPE : std::string
00642       //
00643       //        DESCRIPTION :
00644       //
00645       std::string RpmHeader::tag_prein() const
00646       {
00647         return string_val( RPMTAG_PREIN );
00648       }
00649 
00651       //
00652       //
00653       //        METHOD NAME : RpmHeader::tag_postin
00654       //        METHOD TYPE : std::string
00655       //
00656       //        DESCRIPTION :
00657       //
00658       std::string RpmHeader::tag_postin() const
00659       {
00660         return string_val( RPMTAG_POSTIN );
00661       }
00662 
00664       //
00665       //
00666       //        METHOD NAME : RpmHeader::tag_preun
00667       //        METHOD TYPE : std::string
00668       //
00669       //        DESCRIPTION :
00670       //
00671       std::string RpmHeader::tag_preun() const
00672       {
00673         return string_val( RPMTAG_PREUN );
00674       }
00675 
00677       //
00678       //
00679       //        METHOD NAME : RpmHeader::tag_postun
00680       //        METHOD TYPE : std::string
00681       //
00682       //        DESCRIPTION :
00683       //
00684       std::string RpmHeader::tag_postun() const
00685       {
00686         return string_val( RPMTAG_POSTUN );
00687       }
00688 
00690       //
00691       //
00692       //        METHOD NAME : RpmHeader::tag_sourcerpm
00693       //        METHOD TYPE : std::string
00694       //
00695       //        DESCRIPTION :
00696       //
00697       std::string RpmHeader::tag_sourcerpm() const
00698       {
00699         return string_val( RPMTAG_SOURCERPM );
00700       }
00701 
00703       //
00704       //
00705       //        METHOD NAME : RpmHeader::tag_filenames
00706       //        METHOD TYPE : std::list<std::string>
00707       //
00708       //        DESCRIPTION :
00709       //
00710       std::list<std::string> RpmHeader::tag_filenames() const
00711       {
00712         std::list<std::string> ret;
00713 
00714         stringList basenames;
00715         if ( string_list( RPMTAG_BASENAMES, basenames ) ) {
00716           stringList dirnames;
00717           string_list( RPMTAG_DIRNAMES, dirnames );
00718           intList  dirindexes;
00719           int_list( RPMTAG_DIRINDEXES, dirindexes );
00720           for ( unsigned i = 0; i < basenames.size(); ++ i ) {
00721             ret.push_back( dirnames[dirindexes[i]] + basenames[i] );
00722           }
00723         }
00724 
00725         return ret;
00726       }
00727 
00729       //
00730       //
00731       //        METHOD NAME : RpmHeader::tag_fileinfos
00732       //        METHOD TYPE : std::list<FileInfo>
00733       //
00734       //        DESCRIPTION :
00735       //
00736       std::list<FileInfo> RpmHeader::tag_fileinfos() const
00737       {
00738         std::list<FileInfo> ret;
00739 
00740         stringList basenames;
00741         if ( string_list( RPMTAG_BASENAMES, basenames ) ) {
00742           stringList dirnames;
00743           string_list( RPMTAG_DIRNAMES, dirnames );
00744           intList  dirindexes;
00745           int_list( RPMTAG_DIRINDEXES, dirindexes );
00746           intList filesizes;
00747           int_list( RPMTAG_FILESIZES, filesizes );
00748           stringList md5sums;
00749           string_list( RPMTAG_FILEMD5S, md5sums );
00750           stringList usernames;
00751           string_list( RPMTAG_FILEUSERNAME, usernames );
00752           stringList groupnames;
00753           string_list( RPMTAG_FILEGROUPNAME, groupnames );
00754           intList uids;
00755           int_list( RPMTAG_FILEUIDS, uids );
00756           intList gids;
00757           int_list( RPMTAG_FILEGIDS, gids );
00758           intList filemodes;
00759           int_list( RPMTAG_FILEMODES, filemodes );
00760           intList filemtimes;
00761           int_list( RPMTAG_FILEMTIMES, filemtimes );
00762           intList fileflags;
00763           int_list( RPMTAG_FILEFLAGS, fileflags );
00764           stringList filelinks;
00765           string_list( RPMTAG_FILELINKTOS, filelinks );
00766 
00767           for ( unsigned i = 0; i < basenames.size(); ++ i ) {
00768             uid_t uid;
00769             if (uids.empty()) {
00770               uid = unameToUid( usernames[i].c_str(), &uid );
00771             }
00772             else {
00773               uid =uids[i];
00774             }
00775 
00776             gid_t gid;
00777             if (gids.empty()) {
00778               gid = gnameToGid( groupnames[i].c_str(), &gid );
00779             }
00780             else {
00781               gid = gids[i];
00782             }
00783 
00784             FileInfo info = {
00785               dirnames[dirindexes[i]] + basenames[i],
00786               filesizes[i],
00787               md5sums[i],
00788               uid,
00789               gid,
00790               filemodes[i],
00791               filemtimes[i],
00792               fileflags[i] & RPMFILE_GHOST,
00793               filelinks[i]
00794             };
00795 
00796             ret.push_back( info );
00797           }
00798         }
00799 
00800         return ret;
00801       }
00802 
00804       //
00805       //
00806       //        METHOD NAME : RpmHeader::tag_changelog
00807       //        METHOD TYPE : Changelog
00808       //
00809       //        DESCRIPTION :
00810       //
00811       Changelog RpmHeader::tag_changelog() const
00812       {
00813         Changelog ret;
00814 
00815         intList times;
00816         if ( int_list( RPMTAG_CHANGELOGTIME, times ) ) {
00817           stringList names;
00818           string_list( RPMTAG_CHANGELOGNAME, names );
00819           stringList texts;
00820           string_list( RPMTAG_CHANGELOGTEXT, texts );
00821           for ( unsigned i = 0; i < times.size(); ++ i ) {
00822             ret.push_back( ChangelogEntry( times[i], names[i], texts[i] ) );
00823           }
00824         }
00825 
00826         return ret;
00827       }
00828 
00830       //
00831       //
00832       //        METHOD NAME : RpmHeader::tag_du
00833       //        METHOD TYPE : PkgDu &
00834       //
00835       //        DESCRIPTION :
00836       //
00837       DiskUsage & RpmHeader::tag_du( DiskUsage & dudata_r ) const
00838       {
00839         dudata_r.clear();
00840         stringList basenames;
00841         if ( string_list( RPMTAG_BASENAMES, basenames ) ) {
00842           stringList dirnames;
00843           string_list( RPMTAG_DIRNAMES, dirnames );
00844           intList dirindexes;
00845           int_list( RPMTAG_DIRINDEXES, dirindexes );
00846 
00847           intList filedevices;
00848           int_list( RPMTAG_FILEDEVICES, filedevices );
00849           intList fileinodes;
00850           int_list( RPMTAG_FILEINODES, fileinodes );
00851           intList filesizes;
00852           int_list( RPMTAG_FILESIZES, filesizes );
00853           intList filemodes;
00854           int_list( RPMTAG_FILEMODES, filemodes );
00855 
00857           // Create and collect Entries by index. devino_cache is used to
00858           // filter out hardliks ( different name but same device and inode ).
00860           filesystem::DevInoCache trace;
00861           vector<DiskUsage::Entry> entries;
00862           entries.resize( dirnames.size() );
00863           for ( unsigned i = 0; i < dirnames.size(); ++i ) {
00864             entries[i] = DiskUsage::Entry(dirnames[i]);
00865           }
00866 
00867           for ( unsigned i = 0; i < basenames.size(); ++ i ) {
00868             filesystem::StatMode mode( filemodes[i] );
00869             if ( mode.isFile() ) {
00870               if ( trace.insert( filedevices[i], fileinodes[i] ) ) {
00871                 // Count full 1K blocks
00872                 entries[dirindexes[i]]._size += ByteCount( filesizes[i] ).fillBlock();
00873                 ++(entries[dirindexes[i]]._files);
00874               }
00875               // else: hardlink; already counted this device/inode
00876             }
00877           }
00878 
00880           // Crreate and collect by index Entries. DevInoTrace is used to
00881           // filter out hardliks ( different name but same device and inode ).
00883           for ( unsigned i = 0; i < entries.size(); ++i ) {
00884             if ( entries[i]._size ) {
00885               dudata_r.add( entries[i] );
00886             }
00887           }
00888         }
00889         return dudata_r;
00890       }
00891 
00892     } // namespace rpm
00893   } // namespace target
00894 } // namespace zypp

Generated on Tue Nov 28 16:49:33 2006 for zypp by  doxygen 1.5.0