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         case RPMTAG_ENHANCESNAME:
00295           kindFlags   = RPMTAG_ENHANCESFLAGS;
00296           kindVersion = RPMTAG_ENHANCESVERSION;
00297           break;
00298 #warning NEEDS RPMTAG_SUPPLEMENTSNAME
00299 #if 0
00300         case RPMTAG_SUPPLEMENTSNAME:
00301           kindFlags   = RPMTAG_SUPPLEMENTSFLAGS;
00302           kindVersion = RPMTAG_SUPPLEMENTSVERSION;
00303           break;
00304 #endif
00305         default:
00306           INT << "Illegal RPMTAG_dependencyNAME " << tag_r << endl;
00307           return ret;
00308           break;
00309         }
00310 
00311         stringList names;
00312         unsigned count = string_list( tag_r, names );
00313         if ( !count )
00314           return ret;
00315 
00316         intList  flags;
00317         int_list( kindFlags, flags );
00318 
00319         stringList versions;
00320         string_list( kindVersion, versions );
00321 
00322         for ( unsigned i = 0; i < count; ++i ) {
00323 
00324           string n( names[i] );
00325 
00326           Rel op = Rel::ANY;
00327           int_32 f  = flags[i];
00328           string v  = versions[i];
00329 
00330           if ( n[0] == '/' ) {
00331             if ( freq_r ) {
00332               freq_r->insert( n );
00333             }
00334           } else {
00335             if ( v.size() ) {
00336               switch ( f & RPMSENSE_SENSEMASK ) {
00337               case RPMSENSE_LESS:
00338                 op = Rel::LT;
00339                 break;
00340               case RPMSENSE_LESS|RPMSENSE_EQUAL:
00341                 op = Rel::LE;
00342                 break;
00343               case RPMSENSE_GREATER:
00344                 op = Rel::GT;
00345                 break;
00346               case RPMSENSE_GREATER|RPMSENSE_EQUAL:
00347                 op = Rel::GE;
00348                 break;
00349               case RPMSENSE_EQUAL:
00350                 op = Rel::EQ;
00351                 break;
00352               }
00353             }
00354           }
00355           if ((pre && (f & RPMSENSE_PREREQ))
00356             || ((! pre) && !(f & RPMSENSE_PREREQ)))
00357           {
00358             CapFactory _f;
00359             try {
00360               Capability cap = _f.parse(
00361                 ResTraits<Package>::kind,
00362                 n,
00363                 op,
00364                 Edition(v)
00365               );
00366               ret.insert(cap);
00367             }
00368             catch (Exception & excpt_r)
00369             {
00370               ZYPP_CAUGHT(excpt_r);
00371               WAR << "Invalid capability: " << n << " " << op << " "
00372                 << v << endl;
00373             }
00374           }
00375         }
00376 
00377         return ret;
00378       }
00379 
00381       //
00382       //
00383       //        METHOD NAME : RpmHeader::tag_provides
00384       //        METHOD TYPE : CapSet
00385       //
00386       //        DESCRIPTION :
00387       //
00388       CapSet RpmHeader::tag_provides( set<string> * freq_r ) const
00389       {
00390         return PkgRelList_val( RPMTAG_PROVIDENAME, false, freq_r );
00391       }
00392 
00394       //
00395       //
00396       //        METHOD NAME : RpmHeader::tag_requires
00397       //        METHOD TYPE : CapSet
00398       //
00399       //        DESCRIPTION :
00400       //
00401       CapSet RpmHeader::tag_requires( set<string> * freq_r ) const
00402       {
00403         return PkgRelList_val( RPMTAG_REQUIRENAME, false, freq_r );
00404       }
00405 
00407       //
00408       //
00409       //        METHOD NAME : RpmHeader::tag_requires
00410       //        METHOD TYPE : CapSet
00411       //
00412       //        DESCRIPTION :
00413       //
00414       CapSet RpmHeader::tag_prerequires( set<string> * freq_r ) const
00415       {
00416         return PkgRelList_val( RPMTAG_REQUIRENAME, true, freq_r );
00417       }
00418 
00420       //
00421       //
00422       //        METHOD NAME : RpmHeader::tag_conflicts
00423       //        METHOD TYPE : CapSet
00424       //
00425       //        DESCRIPTION :
00426       //
00427       CapSet RpmHeader::tag_conflicts( set<string> * freq_r ) const
00428       {
00429         return PkgRelList_val( RPMTAG_CONFLICTNAME, false, freq_r );
00430       }
00431 
00433       //
00434       //
00435       //        METHOD NAME : RpmHeader::tag_obsoletes
00436       //        METHOD TYPE : CapSet
00437       //
00438       //        DESCRIPTION :
00439       //
00440       CapSet RpmHeader::tag_obsoletes( set<string> * freq_r ) const
00441       {
00442         return PkgRelList_val( RPMTAG_OBSOLETENAME, false, freq_r );
00443       }
00444 
00446       //
00447       //
00448       //        METHOD NAME : RpmHeader::tag_enhances
00449       //        METHOD TYPE : CapSet
00450       //
00451       //        DESCRIPTION :
00452       //
00453       CapSet RpmHeader::tag_enhances( set<string> * freq_r ) const
00454       {
00455         return PkgRelList_val( RPMTAG_ENHANCESNAME, false, freq_r );
00456       }
00457 
00459       //
00460       //
00461       //        METHOD NAME : RpmHeader::tag_supplements
00462       //        METHOD TYPE : CapSet
00463       //
00464       //        DESCRIPTION :
00465       //
00466       CapSet RpmHeader::tag_supplements( set<string> * freq_r ) const
00467       {
00468         return CapSet();
00469 #warning NEEDS RPMTAG_SUPPLEMENTSNAME
00470 #if 0
00471         return PkgRelList_val( RPMTAG_SUPPLEMENTSNAME, false, freq_r );
00472 #endif
00473       }
00474 
00476       //
00477       //
00478       //        METHOD NAME : RpmHeader::tag_size
00479       //        METHOD TYPE : ByteCount
00480       //
00481       //        DESCRIPTION :
00482       //
00483       ByteCount RpmHeader::tag_size() const
00484       {
00485         return int_val( RPMTAG_SIZE );
00486       }
00487 
00489       //
00490       //
00491       //        METHOD NAME : RpmHeader::tag_archivesize
00492       //        METHOD TYPE : ByteCount
00493       //
00494       //        DESCRIPTION :
00495       //
00496       ByteCount RpmHeader::tag_archivesize() const
00497       {
00498         return int_val( RPMTAG_ARCHIVESIZE );
00499       }
00500 
00502       //
00503       //
00504       //        METHOD NAME : RpmHeader::tag_summary
00505       //        METHOD TYPE : std::string
00506       //
00507       //        DESCRIPTION :
00508       //
00509       std::string RpmHeader::tag_summary() const
00510       {
00511         return string_val( RPMTAG_SUMMARY );
00512       }
00513 
00515       //
00516       //
00517       //        METHOD NAME : RpmHeader::tag_description
00518       //        METHOD TYPE : std::string
00519       //
00520       //        DESCRIPTION :
00521       //
00522       std::string RpmHeader::tag_description() const
00523       {
00524         return string_val( RPMTAG_DESCRIPTION );
00525       }
00526 
00528       //
00529       //
00530       //        METHOD NAME : RpmHeader::tag_group
00531       //        METHOD TYPE : std::string
00532       //
00533       //        DESCRIPTION :
00534       //
00535       std::string RpmHeader::tag_group() const
00536       {
00537         return string_val( RPMTAG_GROUP );
00538       }
00539 
00541       //
00542       //
00543       //        METHOD NAME : RpmHeader::tag_vendor
00544       //        METHOD TYPE : std::string
00545       //
00546       //        DESCRIPTION :
00547       //
00548       std::string RpmHeader::tag_vendor() const
00549       {
00550         return string_val( RPMTAG_VENDOR );
00551       }
00552 
00554       //
00555       //
00556       //        METHOD NAME : RpmHeader::tag_distribution
00557       //        METHOD TYPE : std::string
00558       //
00559       //        DESCRIPTION :
00560       //
00561       std::string RpmHeader::tag_distribution() const
00562       {
00563         return string_val( RPMTAG_DISTRIBUTION );
00564       }
00565 
00567       //
00568       //
00569       //        METHOD NAME : RpmHeader::tag_license
00570       //        METHOD TYPE : std::string
00571       //
00572       //        DESCRIPTION :
00573       //
00574       std::string RpmHeader::tag_license() const
00575       {
00576         return string_val( RPMTAG_LICENSE );
00577       }
00578 
00580       //
00581       //
00582       //        METHOD NAME : RpmHeader::tag_buildhost
00583       //        METHOD TYPE : std::string
00584       //
00585       //        DESCRIPTION :
00586       //
00587       std::string RpmHeader::tag_buildhost() const
00588       {
00589         return string_val( RPMTAG_BUILDHOST );
00590       }
00591 
00593       //
00594       //
00595       //        METHOD NAME : RpmHeader::tag_packager
00596       //        METHOD TYPE : std::string
00597       //
00598       //        DESCRIPTION :
00599       //
00600       std::string RpmHeader::tag_packager() const
00601       {
00602         return string_val( RPMTAG_PACKAGER );
00603       }
00604 
00606       //
00607       //
00608       //        METHOD NAME : RpmHeader::tag_url
00609       //        METHOD TYPE : std::string
00610       //
00611       //        DESCRIPTION :
00612       //
00613       std::string RpmHeader::tag_url() const
00614       {
00615         return string_val( RPMTAG_URL );
00616       }
00617 
00619       //
00620       //
00621       //        METHOD NAME : RpmHeader::tag_os
00622       //        METHOD TYPE : std::string
00623       //
00624       //        DESCRIPTION :
00625       //
00626       std::string RpmHeader::tag_os() const
00627       {
00628         return string_val( RPMTAG_OS );
00629       }
00630 
00632       //
00633       //
00634       //        METHOD NAME : RpmHeader::tag_prein
00635       //        METHOD TYPE : std::string
00636       //
00637       //        DESCRIPTION :
00638       //
00639       std::string RpmHeader::tag_prein() const
00640       {
00641         return string_val( RPMTAG_PREIN );
00642       }
00643 
00645       //
00646       //
00647       //        METHOD NAME : RpmHeader::tag_postin
00648       //        METHOD TYPE : std::string
00649       //
00650       //        DESCRIPTION :
00651       //
00652       std::string RpmHeader::tag_postin() const
00653       {
00654         return string_val( RPMTAG_POSTIN );
00655       }
00656 
00658       //
00659       //
00660       //        METHOD NAME : RpmHeader::tag_preun
00661       //        METHOD TYPE : std::string
00662       //
00663       //        DESCRIPTION :
00664       //
00665       std::string RpmHeader::tag_preun() const
00666       {
00667         return string_val( RPMTAG_PREUN );
00668       }
00669 
00671       //
00672       //
00673       //        METHOD NAME : RpmHeader::tag_postun
00674       //        METHOD TYPE : std::string
00675       //
00676       //        DESCRIPTION :
00677       //
00678       std::string RpmHeader::tag_postun() const
00679       {
00680         return string_val( RPMTAG_POSTUN );
00681       }
00682 
00684       //
00685       //
00686       //        METHOD NAME : RpmHeader::tag_sourcerpm
00687       //        METHOD TYPE : std::string
00688       //
00689       //        DESCRIPTION :
00690       //
00691       std::string RpmHeader::tag_sourcerpm() const
00692       {
00693         return string_val( RPMTAG_SOURCERPM );
00694       }
00695 
00697       //
00698       //
00699       //        METHOD NAME : RpmHeader::tag_filenames
00700       //        METHOD TYPE : std::list<std::string>
00701       //
00702       //        DESCRIPTION :
00703       //
00704       std::list<std::string> RpmHeader::tag_filenames() const
00705       {
00706         std::list<std::string> ret;
00707 
00708         stringList basenames;
00709         if ( string_list( RPMTAG_BASENAMES, basenames ) ) {
00710           stringList dirnames;
00711           string_list( RPMTAG_DIRNAMES, dirnames );
00712           intList  dirindexes;
00713           int_list( RPMTAG_DIRINDEXES, dirindexes );
00714           for ( unsigned i = 0; i < basenames.size(); ++ i ) {
00715             ret.push_back( dirnames[dirindexes[i]] + basenames[i] );
00716           }
00717         }
00718 
00719         return ret;
00720       }
00721 
00723       //
00724       //
00725       //        METHOD NAME : RpmHeader::tag_fileinfos
00726       //        METHOD TYPE : std::list<FileInfo>
00727       //
00728       //        DESCRIPTION :
00729       //
00730       std::list<FileInfo> RpmHeader::tag_fileinfos() const
00731       {
00732         std::list<FileInfo> ret;
00733 
00734         stringList basenames;
00735         if ( string_list( RPMTAG_BASENAMES, basenames ) ) {
00736           stringList dirnames;
00737           string_list( RPMTAG_DIRNAMES, dirnames );
00738           intList  dirindexes;
00739           int_list( RPMTAG_DIRINDEXES, dirindexes );
00740           intList filesizes;
00741           int_list( RPMTAG_FILESIZES, filesizes );
00742           stringList md5sums;
00743           string_list( RPMTAG_FILEMD5S, md5sums );
00744           stringList usernames;
00745           string_list( RPMTAG_FILEUSERNAME, usernames );
00746           stringList groupnames;
00747           string_list( RPMTAG_FILEGROUPNAME, groupnames );
00748           intList uids;
00749           int_list( RPMTAG_FILEUIDS, uids );
00750           intList gids;
00751           int_list( RPMTAG_FILEGIDS, gids );
00752           intList filemodes;
00753           int_list( RPMTAG_FILEMODES, filemodes );
00754           intList filemtimes;
00755           int_list( RPMTAG_FILEMTIMES, filemtimes );
00756           intList fileflags;
00757           int_list( RPMTAG_FILEFLAGS, fileflags );
00758           stringList filelinks;
00759           string_list( RPMTAG_FILELINKTOS, filelinks );
00760 
00761           for ( unsigned i = 0; i < basenames.size(); ++ i ) {
00762             uid_t uid;
00763             if (uids.empty()) {
00764               uid = unameToUid( usernames[i].c_str(), &uid );
00765             }
00766             else {
00767               uid =uids[i];
00768             }
00769 
00770             gid_t gid;
00771             if (gids.empty()) {
00772               gid = gnameToGid( groupnames[i].c_str(), &gid );
00773             }
00774             else {
00775               gid = gids[i];
00776             }
00777 
00778             FileInfo info = {
00779               dirnames[dirindexes[i]] + basenames[i],
00780               filesizes[i],
00781               md5sums[i],
00782               uid,
00783               gid,
00784               filemodes[i],
00785               filemtimes[i],
00786               fileflags[i] & RPMFILE_GHOST,
00787               filelinks[i]
00788             };
00789 
00790             ret.push_back( info );
00791           }
00792         }
00793 
00794         return ret;
00795       }
00796 
00798       //
00799       //
00800       //        METHOD NAME : RpmHeader::tag_changelog
00801       //        METHOD TYPE : Changelog
00802       //
00803       //        DESCRIPTION :
00804       //
00805       Changelog RpmHeader::tag_changelog() const
00806       {
00807         Changelog ret;
00808 
00809         intList times;
00810         if ( int_list( RPMTAG_CHANGELOGTIME, times ) ) {
00811           stringList names;
00812           string_list( RPMTAG_CHANGELOGNAME, names );
00813           stringList texts;
00814           string_list( RPMTAG_CHANGELOGTEXT, texts );
00815           for ( unsigned i = 0; i < times.size(); ++ i ) {
00816             ret.push_back( ChangelogEntry( times[i], names[i], texts[i] ) );
00817           }
00818         }
00819 
00820         return ret;
00821       }
00822 
00824       //
00825       //
00826       //        METHOD NAME : RpmHeader::tag_du
00827       //        METHOD TYPE : PkgDu &
00828       //
00829       //        DESCRIPTION :
00830       //
00831       DiskUsage & RpmHeader::tag_du( DiskUsage & dudata_r ) const
00832       {
00833         dudata_r.clear();
00834         stringList basenames;
00835         if ( string_list( RPMTAG_BASENAMES, basenames ) ) {
00836           stringList dirnames;
00837           string_list( RPMTAG_DIRNAMES, dirnames );
00838           intList dirindexes;
00839           int_list( RPMTAG_DIRINDEXES, dirindexes );
00840 
00841           intList filedevices;
00842           int_list( RPMTAG_FILEDEVICES, filedevices );
00843           intList fileinodes;
00844           int_list( RPMTAG_FILEINODES, fileinodes );
00845           intList filesizes;
00846           int_list( RPMTAG_FILESIZES, filesizes );
00847           intList filemodes;
00848           int_list( RPMTAG_FILEMODES, filemodes );
00849 
00851           // Create and collect Entries by index. devino_cache is used to
00852           // filter out hardliks ( different name but same device and inode ).
00854           filesystem::DevInoCache trace;
00855           vector<DiskUsage::Entry> entries;
00856           entries.resize( dirnames.size() );
00857           for ( unsigned i = 0; i < dirnames.size(); ++i ) {
00858             entries[i] = DiskUsage::Entry(dirnames[i]);
00859           }
00860 
00861           for ( unsigned i = 0; i < basenames.size(); ++ i ) {
00862             filesystem::StatMode mode( filemodes[i] );
00863             if ( mode.isFile() ) {
00864               if ( trace.insert( filedevices[i], fileinodes[i] ) ) {
00865                 // Count full 1K blocks
00866                 entries[dirindexes[i]]._size += ByteCount( filesizes[i] ).fillBlock();
00867                 ++(entries[dirindexes[i]]._files);
00868               }
00869               // else: hardlink; already counted this device/inode
00870             }
00871           }
00872 
00874           // Crreate and collect by index Entries. DevInoTrace is used to
00875           // filter out hardliks ( different name but same device and inode ).
00877           for ( unsigned i = 0; i < entries.size(); ++i ) {
00878             if ( entries[i]._size ) {
00879               dudata_r.add( entries[i] );
00880             }
00881           }
00882         }
00883         return dudata_r;
00884       }
00885 
00886     } // namespace rpm
00887   } // namespace target
00888 } // namespace zypp

Generated on Thu Jul 6 00:07:26 2006 for zypp by  doxygen 1.4.6