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

Generated on Tue Sep 25 19:23:09 2007 for libzypp by  doxygen 1.5.3