libzypp 9.41.1

RpmHeader.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include "librpm.h"
00013 #ifdef _RPM_4_4
00014 #include <rpm/ugid.h>
00015 #else
00016 
00017 // unameToUid and gnameToGid are shamelessly stolen from rpm-4.4.
00018 // (rpmio/ugid.c) Those functions were dropped in RPM_4_7
00019 extern "C"
00020 {
00021 #include <pwd.h>
00022 #include <grp.h>
00023 }
00024 /* unameToUid(), uidTouname() and the group variants are really poorly
00025    implemented. They really ought to use hash tables. I just made the
00026    guess that most files would be owned by root or the same person/group
00027    who owned the last file. Those two values are cached, everything else
00028    is looked up via getpw() and getgr() functions.  If this performs
00029    too poorly I'll have to implement it properly :-( */
00030 
00031 int unameToUid(const char * thisUname, uid_t * uid)
00032 {
00033 /*@only@*/ static char * lastUname = NULL;
00034     static size_t lastUnameLen = 0;
00035     static size_t lastUnameAlloced;
00036     static uid_t lastUid;
00037     struct passwd * pwent;
00038     size_t thisUnameLen;
00039 
00040     if (!thisUname) {
00041         lastUnameLen = 0;
00042         return -1;
00043     } else if (strcmp(thisUname, "root") == 0) {
00044 /*@-boundswrite@*/
00045         *uid = 0;
00046 /*@=boundswrite@*/
00047         return 0;
00048     }
00049 
00050     thisUnameLen = strlen(thisUname);
00051     if (lastUname == NULL || thisUnameLen != lastUnameLen ||
00052         strcmp(thisUname, lastUname) != 0)
00053     {
00054         if (lastUnameAlloced < thisUnameLen + 1) {
00055             lastUnameAlloced = thisUnameLen + 10;
00056             lastUname = (char *)realloc(lastUname, lastUnameAlloced);   /* XXX memory leak */
00057         }
00058 /*@-boundswrite@*/
00059         strcpy(lastUname, thisUname);
00060 /*@=boundswrite@*/
00061 
00062         pwent = getpwnam(thisUname);
00063         if (pwent == NULL) {
00064             /*@-internalglobs@*/ /* FIX: shrug */
00065             endpwent();
00066             /*@=internalglobs@*/
00067             pwent = getpwnam(thisUname);
00068             if (pwent == NULL) return -1;
00069         }
00070 
00071         lastUid = pwent->pw_uid;
00072     }
00073 
00074 /*@-boundswrite@*/
00075     *uid = lastUid;
00076 /*@=boundswrite@*/
00077 
00078     return 0;
00079 }
00080 
00081 int gnameToGid(const char * thisGname, gid_t * gid)
00082 {
00083 /*@only@*/ static char * lastGname = NULL;
00084     static size_t lastGnameLen = 0;
00085     static size_t lastGnameAlloced;
00086     static gid_t lastGid;
00087     size_t thisGnameLen;
00088     struct group * grent;
00089 
00090     if (thisGname == NULL) {
00091         lastGnameLen = 0;
00092         return -1;
00093     } else if (strcmp(thisGname, "root") == 0) {
00094 /*@-boundswrite@*/
00095         *gid = 0;
00096 /*@=boundswrite@*/
00097         return 0;
00098     }
00099 
00100     thisGnameLen = strlen(thisGname);
00101     if (lastGname == NULL || thisGnameLen != lastGnameLen ||
00102         strcmp(thisGname, lastGname) != 0)
00103     {
00104         if (lastGnameAlloced < thisGnameLen + 1) {
00105             lastGnameAlloced = thisGnameLen + 10;
00106             lastGname = (char *)realloc(lastGname, lastGnameAlloced);   /* XXX memory leak */
00107         }
00108 /*@-boundswrite@*/
00109         strcpy(lastGname, thisGname);
00110 /*@=boundswrite@*/
00111 
00112         grent = getgrnam(thisGname);
00113         if (grent == NULL) {
00114             /*@-internalglobs@*/ /* FIX: shrug */
00115             endgrent();
00116             /*@=internalglobs@*/
00117             grent = getgrnam(thisGname);
00118             if (grent == NULL) {
00119                 /* XXX The filesystem package needs group/lock w/o getgrnam. */
00120                 if (strcmp(thisGname, "lock") == 0) {
00121 /*@-boundswrite@*/
00122                     *gid = lastGid = 54;
00123 /*@=boundswrite@*/
00124                     return 0;
00125                 } else
00126                 if (strcmp(thisGname, "mail") == 0) {
00127 /*@-boundswrite@*/
00128                     *gid = lastGid = 12;
00129 /*@=boundswrite@*/
00130                     return 0;
00131                 } else
00132                 return -1;
00133             }
00134         }
00135         lastGid = grent->gr_gid;
00136     }
00137 
00138 /*@-boundswrite@*/
00139     *gid = lastGid;
00140 /*@=boundswrite@*/
00141 
00142     return 0;
00143 }
00145 #endif
00146 
00147 #include <iostream>
00148 #include <map>
00149 #include <set>
00150 #include <vector>
00151 
00152 #include "zypp/base/Easy.h"
00153 #include "zypp/base/Logger.h"
00154 #include "zypp/base/Exception.h"
00155 
00156 #include "zypp/target/rpm/librpmDb.h"
00157 #include "zypp/target/rpm/RpmHeader.h"
00158 #include "zypp/Package.h"
00159 #include "zypp/PathInfo.h"
00160 
00161 using std::endl;
00162 
00163 namespace zypp
00164 {
00165 namespace target
00166 {
00167 namespace rpm
00168 {
00169 
00171 
00173 //
00174 //
00175 //        METHOD NAME : RpmHeader::RpmHeader
00176 //        METHOD TYPE : Constructor
00177 //
00178 //        DESCRIPTION :
00179 //
00180 RpmHeader::RpmHeader( Header h_r )
00181     : BinHeader( h_r )
00182 {}
00183 
00185 //
00186 //
00187 //        METHOD NAME : RpmHeader::RpmHeader
00188 //        METHOD TYPE : Constructor
00189 //
00190 RpmHeader::RpmHeader( BinHeader::Ptr & rhs )
00191     : BinHeader( rhs )
00192 {}
00193 
00195 //
00196 //
00197 //        METHOD NAME : RpmHeader::~RpmHeader
00198 //        METHOD TYPE : Destructor
00199 //
00200 //        DESCRIPTION :
00201 //
00202 RpmHeader::~RpmHeader()
00203 {}
00204 
00206 //
00207 //
00208 //        METHOD NAME : RpmHeader::readPackage
00209 //        METHOD TYPE : constRpmHeaderPtr
00210 //
00211 RpmHeader::constPtr RpmHeader::readPackage( const Pathname & path_r,
00212                                             VERIFICATION verification_r )
00213 {
00214   PathInfo file( path_r );
00215   if ( ! file.isFile() )
00216   {
00217     ERR << "Not a file: " << file << endl;
00218     return (RpmHeader*)0;
00219   }
00220 
00221   FD_t fd = ::Fopen( file.asString().c_str(), "r.ufdio" );
00222   if ( fd == 0 || ::Ferror(fd) )
00223   {
00224     ERR << "Can't open file for reading: " << file << " (" << ::Fstrerror(fd) << ")" << endl;
00225     if ( fd )
00226       ::Fclose( fd );
00227     return (RpmHeader*)0;
00228   }
00229 
00230   librpmDb::globalInit();
00231   rpmts ts = ::rpmtsCreate();
00232   unsigned vsflag = RPMVSF_DEFAULT;
00233   if ( verification_r & NODIGEST )
00234     vsflag |= _RPMVSF_NODIGESTS;
00235   if ( verification_r & NOSIGNATURE )
00236     vsflag |= _RPMVSF_NOSIGNATURES;
00237   ::rpmtsSetVSFlags( ts, rpmVSFlags(vsflag) );
00238 
00239   Header nh = 0;
00240   int res = ::rpmReadPackageFile( ts, fd, path_r.asString().c_str(), &nh );
00241 
00242   ts = rpmtsFree(ts);
00243 
00244   ::Fclose( fd );
00245 
00246   if ( ! nh )
00247   {
00248     WAR << "Error reading header from " << path_r << " error(" << res << ")" << endl;
00249     return (RpmHeader*)0;
00250   }
00251 
00252   RpmHeader::constPtr h( new RpmHeader( nh ) );
00253   headerFree( nh ); // clear the reference set in ReadPackageFile
00254 
00255   MIL << h << " from " << path_r << endl;
00256   return h;
00257 }
00258 
00260 //
00261 //
00262 //        METHOD NAME : RpmHeader::dumpOn
00263 //        METHOD TYPE : std::ostream &
00264 //
00265 //        DESCRIPTION :
00266 //
00267 std::ostream & RpmHeader::dumpOn( std::ostream & str ) const
00268 {
00269   str << BinHeader::dumpOn( str ) << '{' << tag_name() << "-";
00270   if ( tag_epoch() != 0 )
00271     str << tag_epoch() << ":";
00272   str << tag_version()
00273       << (tag_release().empty()?"":(std::string("-")+tag_release()))
00274       << ( isSrc() ? ".src}" : "}");
00275   return str;
00276 }
00277 
00278 
00280 //
00281 //
00282 //        METHOD NAME : RpmHeader::isSrc
00283 //        METHOD TYPE : bool
00284 //
00285 bool RpmHeader::isSrc() const
00286 {
00287   return has_tag( RPMTAG_SOURCEPACKAGE );
00288 }
00289 
00290 bool RpmHeader::isNosrc() const
00291 {
00292   return has_tag( RPMTAG_SOURCEPACKAGE ) && ( has_tag( RPMTAG_NOSOURCE ) || has_tag( RPMTAG_NOPATCH ) );
00293 }
00294 
00296 //
00297 //
00298 //        METHOD NAME : RpmHeader::tag_name
00299 //        METHOD TYPE : std::string
00300 //
00301 //        DESCRIPTION :
00302 //
00303 std::string RpmHeader::tag_name() const
00304 {
00305   return string_val( RPMTAG_NAME );
00306 }
00307 
00309 //
00310 //
00311 //        METHOD NAME : RpmHeader::tag_epoch
00312 //        METHOD TYPE : Edition::epoch_t
00313 //
00314 //        DESCRIPTION :
00315 //
00316 Edition::epoch_t RpmHeader::tag_epoch() const
00317 {
00318   return int_val ( RPMTAG_EPOCH );
00319 }
00320 
00322 //
00323 //
00324 //        METHOD NAME : RpmHeader::tag_version
00325 //        METHOD TYPE : std::string
00326 //
00327 //        DESCRIPTION :
00328 //
00329 std::string RpmHeader::tag_version() const
00330 {
00331   return string_val ( RPMTAG_VERSION );
00332 }
00333 
00335 //
00336 //
00337 //        METHOD NAME : RpmHeader::tag_release
00338 //        METHOD TYPE : std::string
00339 //
00340 //        DESCRIPTION :
00341 //
00342 std::string RpmHeader::tag_release() const
00343 {
00344   return string_val( RPMTAG_RELEASE );
00345 }
00346 
00348 //
00349 //
00350 //        METHOD NAME : RpmHeader::tag_edition
00351 //        METHOD TYPE : Edition
00352 //
00353 //        DESCRIPTION :
00354 //
00355 Edition RpmHeader::tag_edition () const
00356 {
00357   return Edition( tag_version(), tag_release(), tag_epoch() );
00358 }
00359 
00361 //
00362 //
00363 //        METHOD NAME : RpmHeader::tag_arch
00364 //        METHOD TYPE : Arch
00365 //
00366 //        DESCRIPTION :
00367 //
00368 Arch RpmHeader::tag_arch() const
00369 {
00370   return Arch( string_val( RPMTAG_ARCH ) );
00371 }
00372 
00374 //
00375 //
00376 //        METHOD NAME : RpmHeader::tag_installtime
00377 //        METHOD TYPE : Date
00378 //
00379 //        DESCRIPTION :
00380 //
00381 Date RpmHeader::tag_installtime() const
00382 {
00383   return int_val( RPMTAG_INSTALLTIME );
00384 }
00385 
00387 //
00388 //
00389 //        METHOD NAME : RpmHeader::tag_buildtime
00390 //        METHOD TYPE : Date
00391 //
00392 //        DESCRIPTION :
00393 //
00394 Date RpmHeader::tag_buildtime() const
00395 {
00396   return int_val( RPMTAG_BUILDTIME );
00397 }
00398 #warning CHECK IF FILE REQUIRES HANDLING IS OBSOLETE
00399 
00400 //
00401 //
00402 //        METHOD NAME : RpmHeader::PkgRelList_val
00403 //        METHOD TYPE : CapabilitySet
00404 //
00405 //        DESCRIPTION :
00406 //
00407 CapabilitySet RpmHeader::PkgRelList_val( tag tag_r, bool pre, std::set<std::string> * freq_r ) const
00408   {
00409     CapabilitySet ret;
00410 
00411     rpmTag  kindFlags   = rpmTag(0);
00412     rpmTag  kindVersion = rpmTag(0);
00413 
00414     switch ( tag_r )
00415     {
00416     case RPMTAG_REQUIRENAME:
00417       kindFlags   = RPMTAG_REQUIREFLAGS;
00418       kindVersion = RPMTAG_REQUIREVERSION;
00419       break;
00420     case RPMTAG_PROVIDENAME:
00421       kindFlags   = RPMTAG_PROVIDEFLAGS;
00422       kindVersion = RPMTAG_PROVIDEVERSION;
00423       break;
00424     case RPMTAG_OBSOLETENAME:
00425       kindFlags   = RPMTAG_OBSOLETEFLAGS;
00426       kindVersion = RPMTAG_OBSOLETEVERSION;
00427       break;
00428     case RPMTAG_CONFLICTNAME:
00429       kindFlags   = RPMTAG_CONFLICTFLAGS;
00430       kindVersion = RPMTAG_CONFLICTVERSION;
00431       break;
00432     case RPMTAG_ENHANCESNAME:
00433       kindFlags   = RPMTAG_ENHANCESFLAGS;
00434       kindVersion = RPMTAG_ENHANCESVERSION;
00435       break;
00436     case RPMTAG_SUGGESTSNAME:
00437       kindFlags   = RPMTAG_SUGGESTSFLAGS;
00438       kindVersion = RPMTAG_SUGGESTSVERSION;
00439       break;
00440     default:
00441       INT << "Illegal RPMTAG_dependencyNAME " << tag_r << endl;
00442       return ret;
00443       break;
00444     }
00445 
00446     stringList names;
00447     unsigned count = string_list( tag_r, names );
00448     if ( !count )
00449       return ret;
00450 
00451     intList  flags;
00452     int_list( kindFlags, flags );
00453 
00454     stringList versions;
00455     string_list( kindVersion, versions );
00456 
00457     for ( unsigned i = 0; i < count; ++i )
00458     {
00459 
00460       std::string n( names[i] );
00461 
00462       Rel op = Rel::ANY;
00463       int32_t f = flags[i];
00464       std::string v = versions[i];
00465 
00466       if ( n[0] == '/' )
00467       {
00468         if ( freq_r )
00469         {
00470           freq_r->insert( n );
00471         }
00472       }
00473       else
00474       {
00475         if ( v.size() )
00476         {
00477           switch ( f & RPMSENSE_SENSEMASK )
00478           {
00479           case RPMSENSE_LESS:
00480             op = Rel::LT;
00481             break;
00482           case RPMSENSE_LESS|RPMSENSE_EQUAL:
00483             op = Rel::LE;
00484             break;
00485           case RPMSENSE_GREATER:
00486             op = Rel::GT;
00487             break;
00488           case RPMSENSE_GREATER|RPMSENSE_EQUAL:
00489             op = Rel::GE;
00490             break;
00491           case RPMSENSE_EQUAL:
00492             op = Rel::EQ;
00493             break;
00494           }
00495         }
00496       }
00497       if ((pre && (f & RPMSENSE_PREREQ))
00498           || ((! pre) && !(f & RPMSENSE_PREREQ)))
00499       {
00500         try
00501         {
00502           ret.insert( Capability( n, op, Edition(v) ) );
00503         }
00504         catch (Exception & excpt_r)
00505         {
00506           ZYPP_CAUGHT(excpt_r);
00507           WAR << "Invalid capability: " << n << " " << op << " "
00508           << v << endl;
00509         }
00510       }
00511     }
00512 
00513     return ret;
00514   }
00515 
00517 //
00518 //
00519 //        METHOD NAME : RpmHeader::tag_provides
00520 //        METHOD TYPE : CapabilitySet
00521 //
00522 //        DESCRIPTION :
00523 //
00524 CapabilitySet RpmHeader::tag_provides( std::set<std::string> * freq_r ) const
00525   {
00526     return PkgRelList_val( RPMTAG_PROVIDENAME, false, freq_r );
00527   }
00528 
00530 //
00531 //
00532 //        METHOD NAME : RpmHeader::tag_requires
00533 //        METHOD TYPE : CapabilitySet
00534 //
00535 //        DESCRIPTION :
00536 //
00537 CapabilitySet RpmHeader::tag_requires( std::set<std::string> * freq_r ) const
00538   {
00539     return PkgRelList_val( RPMTAG_REQUIRENAME, false, freq_r );
00540   }
00541 
00543 //
00544 //
00545 //        METHOD NAME : RpmHeader::tag_requires
00546 //        METHOD TYPE : CapabilitySet
00547 //
00548 //        DESCRIPTION :
00549 //
00550 CapabilitySet RpmHeader::tag_prerequires( std::set<std::string> * freq_r ) const
00551   {
00552     return PkgRelList_val( RPMTAG_REQUIRENAME, true, freq_r );
00553   }
00554 
00556 //
00557 //
00558 //        METHOD NAME : RpmHeader::tag_conflicts
00559 //        METHOD TYPE : CapabilitySet
00560 //
00561 //        DESCRIPTION :
00562 //
00563 CapabilitySet RpmHeader::tag_conflicts( std::set<std::string> * freq_r ) const
00564   {
00565     return PkgRelList_val( RPMTAG_CONFLICTNAME, false, freq_r );
00566   }
00567 
00569 //
00570 //
00571 //        METHOD NAME : RpmHeader::tag_obsoletes
00572 //        METHOD TYPE : CapabilitySet
00573 //
00574 //        DESCRIPTION :
00575 //
00576 CapabilitySet RpmHeader::tag_obsoletes( std::set<std::string> * freq_r ) const
00577   {
00578     return PkgRelList_val( RPMTAG_OBSOLETENAME, false, freq_r );
00579   }
00580 
00582 //
00583 //
00584 //        METHOD NAME : RpmHeader::tag_enhances
00585 //        METHOD TYPE : CapabilitySet
00586 //
00587 //        DESCRIPTION :
00588 //
00589 CapabilitySet RpmHeader::tag_enhances( std::set<std::string> * freq_r ) const
00590   {
00591     return PkgRelList_val( RPMTAG_ENHANCESNAME, false, freq_r );
00592   }
00593 
00595 //
00596 //
00597 //        METHOD NAME : RpmHeader::tag_suggests
00598 //        METHOD TYPE : CapabilitySet
00599 //
00600 //        DESCRIPTION :
00601 //
00602 CapabilitySet RpmHeader::tag_suggests( std::set<std::string> * freq_r ) const
00603   {
00604     return PkgRelList_val( RPMTAG_SUGGESTSNAME, false, freq_r );
00605   }
00606 
00608 //
00609 //
00610 //        METHOD NAME : RpmHeader::tag_size
00611 //        METHOD TYPE : ByteCount
00612 //
00613 //        DESCRIPTION :
00614 //
00615 ByteCount RpmHeader::tag_size() const
00616 {
00617   return int_val( RPMTAG_SIZE );
00618 }
00619 
00621 //
00622 //
00623 //        METHOD NAME : RpmHeader::tag_archivesize
00624 //        METHOD TYPE : ByteCount
00625 //
00626 //        DESCRIPTION :
00627 //
00628 ByteCount RpmHeader::tag_archivesize() const
00629 {
00630   return int_val( RPMTAG_ARCHIVESIZE );
00631 }
00632 
00634 //
00635 //
00636 //        METHOD NAME : RpmHeader::tag_summary
00637 //        METHOD TYPE : std::string
00638 //
00639 //        DESCRIPTION :
00640 //
00641 std::string RpmHeader::tag_summary() const
00642 {
00643   return string_val( RPMTAG_SUMMARY );
00644 }
00645 
00647 //
00648 //
00649 //        METHOD NAME : RpmHeader::tag_description
00650 //        METHOD TYPE : std::string
00651 //
00652 //        DESCRIPTION :
00653 //
00654 std::string RpmHeader::tag_description() const
00655 {
00656   return string_val( RPMTAG_DESCRIPTION );
00657 }
00658 
00660 //
00661 //
00662 //        METHOD NAME : RpmHeader::tag_group
00663 //        METHOD TYPE : std::string
00664 //
00665 //        DESCRIPTION :
00666 //
00667 std::string RpmHeader::tag_group() const
00668 {
00669   return string_val( RPMTAG_GROUP );
00670 }
00671 
00673 //
00674 //
00675 //        METHOD NAME : RpmHeader::tag_vendor
00676 //        METHOD TYPE : std::string
00677 //
00678 //        DESCRIPTION :
00679 //
00680 std::string RpmHeader::tag_vendor() const
00681 {
00682   return string_val( RPMTAG_VENDOR );
00683 }
00684 
00686 //
00687 //
00688 //        METHOD NAME : RpmHeader::tag_distribution
00689 //        METHOD TYPE : std::string
00690 //
00691 //        DESCRIPTION :
00692 //
00693 std::string RpmHeader::tag_distribution() const
00694 {
00695   return string_val( RPMTAG_DISTRIBUTION );
00696 }
00697 
00699 //
00700 //
00701 //        METHOD NAME : RpmHeader::tag_license
00702 //        METHOD TYPE : std::string
00703 //
00704 //        DESCRIPTION :
00705 //
00706 std::string RpmHeader::tag_license() const
00707 {
00708   return string_val( RPMTAG_LICENSE );
00709 }
00710 
00712 //
00713 //
00714 //        METHOD NAME : RpmHeader::tag_buildhost
00715 //        METHOD TYPE : std::string
00716 //
00717 //        DESCRIPTION :
00718 //
00719 std::string RpmHeader::tag_buildhost() const
00720 {
00721   return string_val( RPMTAG_BUILDHOST );
00722 }
00723 
00725 //
00726 //
00727 //        METHOD NAME : RpmHeader::tag_packager
00728 //        METHOD TYPE : std::string
00729 //
00730 //        DESCRIPTION :
00731 //
00732 std::string RpmHeader::tag_packager() const
00733 {
00734   return string_val( RPMTAG_PACKAGER );
00735 }
00736 
00738 //
00739 //
00740 //        METHOD NAME : RpmHeader::tag_url
00741 //        METHOD TYPE : std::string
00742 //
00743 //        DESCRIPTION :
00744 //
00745 std::string RpmHeader::tag_url() const
00746 {
00747   return string_val( RPMTAG_URL );
00748 }
00749 
00751 //
00752 //
00753 //        METHOD NAME : RpmHeader::tag_os
00754 //        METHOD TYPE : std::string
00755 //
00756 //        DESCRIPTION :
00757 //
00758 std::string RpmHeader::tag_os() const
00759 {
00760   return string_val( RPMTAG_OS );
00761 }
00762 
00764 //
00765 //
00766 //        METHOD NAME : RpmHeader::tag_prein
00767 //        METHOD TYPE : std::string
00768 //
00769 //        DESCRIPTION :
00770 //
00771 std::string RpmHeader::tag_prein() const
00772 {
00773   return string_val( RPMTAG_PREIN );
00774 }
00775 
00777 //
00778 //
00779 //        METHOD NAME : RpmHeader::tag_postin
00780 //        METHOD TYPE : std::string
00781 //
00782 //        DESCRIPTION :
00783 //
00784 std::string RpmHeader::tag_postin() const
00785 {
00786   return string_val( RPMTAG_POSTIN );
00787 }
00788 
00790 //
00791 //
00792 //        METHOD NAME : RpmHeader::tag_preun
00793 //        METHOD TYPE : std::string
00794 //
00795 //        DESCRIPTION :
00796 //
00797 std::string RpmHeader::tag_preun() const
00798 {
00799   return string_val( RPMTAG_PREUN );
00800 }
00801 
00803 //
00804 //
00805 //        METHOD NAME : RpmHeader::tag_postun
00806 //        METHOD TYPE : std::string
00807 //
00808 //        DESCRIPTION :
00809 //
00810 std::string RpmHeader::tag_postun() const
00811 {
00812   return string_val( RPMTAG_POSTUN );
00813 }
00814 
00816 //
00817 //
00818 //        METHOD NAME : RpmHeader::tag_sourcerpm
00819 //        METHOD TYPE : std::string
00820 //
00821 //        DESCRIPTION :
00822 //
00823 std::string RpmHeader::tag_sourcerpm() const
00824 {
00825   return string_val( RPMTAG_SOURCERPM );
00826 }
00827 
00829 //
00830 //
00831 //        METHOD NAME : RpmHeader::tag_filenames
00832 //        METHOD TYPE : std::list<std::string>
00833 //
00834 //        DESCRIPTION :
00835 //
00836 std::list<std::string> RpmHeader::tag_filenames() const
00837 {
00838   std::list<std::string> ret;
00839 
00840   stringList basenames;
00841   if ( string_list( RPMTAG_BASENAMES, basenames ) )
00842   {
00843     stringList dirnames;
00844     string_list( RPMTAG_DIRNAMES, dirnames );
00845     intList  dirindexes;
00846     int_list( RPMTAG_DIRINDEXES, dirindexes );
00847     for ( unsigned i = 0; i < basenames.size(); ++ i )
00848     {
00849       ret.push_back( dirnames[dirindexes[i]] + basenames[i] );
00850     }
00851   }
00852 
00853   return ret;
00854 }
00855 
00857 //
00858 //
00859 //        METHOD NAME : RpmHeader::tag_fileinfos
00860 //        METHOD TYPE : std::list<FileInfo>
00861 //
00862 //        DESCRIPTION :
00863 //
00864 std::list<FileInfo> RpmHeader::tag_fileinfos() const
00865 {
00866   std::list<FileInfo> ret;
00867 
00868   stringList basenames;
00869   if ( string_list( RPMTAG_BASENAMES, basenames ) )
00870   {
00871     stringList dirnames;
00872     string_list( RPMTAG_DIRNAMES, dirnames );
00873     intList  dirindexes;
00874     int_list( RPMTAG_DIRINDEXES, dirindexes );
00875     intList filesizes;
00876     int_list( RPMTAG_FILESIZES, filesizes );
00877     stringList md5sums;
00878     string_list( RPMTAG_FILEMD5S, md5sums );
00879     stringList usernames;
00880     string_list( RPMTAG_FILEUSERNAME, usernames );
00881     stringList groupnames;
00882     string_list( RPMTAG_FILEGROUPNAME, groupnames );
00883     intList uids;
00884     int_list( RPMTAG_FILEUIDS, uids );
00885     intList gids;
00886     int_list( RPMTAG_FILEGIDS, gids );
00887     intList filemodes;
00888     int_list( RPMTAG_FILEMODES, filemodes );
00889     intList filemtimes;
00890     int_list( RPMTAG_FILEMTIMES, filemtimes );
00891     intList fileflags;
00892     int_list( RPMTAG_FILEFLAGS, fileflags );
00893     stringList filelinks;
00894     string_list( RPMTAG_FILELINKTOS, filelinks );
00895 
00896     for ( unsigned i = 0; i < basenames.size(); ++ i )
00897     {
00898       uid_t uid;
00899       if (uids.empty())
00900       {
00901         uid = unameToUid( usernames[i].c_str(), &uid );
00902       }
00903       else
00904       {
00905         uid =uids[i];
00906       }
00907 
00908       gid_t gid;
00909       if (gids.empty())
00910       {
00911         gid = gnameToGid( groupnames[i].c_str(), &gid );
00912       }
00913       else
00914       {
00915         gid = gids[i];
00916       }
00917 
00918       FileInfo info = {
00919                         dirnames[dirindexes[i]] + basenames[i],
00920                         filesizes[i],
00921                         md5sums[i],
00922                         uid,
00923                         gid,
00924                         filemodes[i],
00925                         filemtimes[i],
00926                         fileflags[i] & RPMFILE_GHOST,
00927                         filelinks[i]
00928                       };
00929 
00930       ret.push_back( info );
00931     }
00932   }
00933 
00934   return ret;
00935 }
00936 
00938 //
00939 //
00940 //        METHOD NAME : RpmHeader::tag_changelog
00941 //        METHOD TYPE : Changelog
00942 //
00943 //        DESCRIPTION :
00944 //
00945 Changelog RpmHeader::tag_changelog() const
00946 {
00947   Changelog ret;
00948 
00949   intList times;
00950   if ( int_list( RPMTAG_CHANGELOGTIME, times ) )
00951   {
00952     stringList names;
00953     string_list( RPMTAG_CHANGELOGNAME, names );
00954     stringList texts;
00955     string_list( RPMTAG_CHANGELOGTEXT, texts );
00956     for ( unsigned i = 0; i < times.size(); ++ i )
00957     {
00958       ret.push_back( ChangelogEntry( times[i], names[i], texts[i] ) );
00959     }
00960   }
00961 
00962   return ret;
00963 }
00964 
00966 //
00967 //
00968 //        METHOD NAME : RpmHeader::tag_du
00969 //        METHOD TYPE : PkgDu &
00970 //
00971 //        DESCRIPTION :
00972 //
00973 DiskUsage & RpmHeader::tag_du( DiskUsage & dudata_r ) const
00974 {
00975   dudata_r.clear();
00976   stringList basenames;
00977   if ( string_list( RPMTAG_BASENAMES, basenames ) )
00978   {
00979     stringList dirnames;
00980     string_list( RPMTAG_DIRNAMES, dirnames );
00981     intList dirindexes;
00982     int_list( RPMTAG_DIRINDEXES, dirindexes );
00983 
00984     intList filedevices;
00985     int_list( RPMTAG_FILEDEVICES, filedevices );
00986     intList fileinodes;
00987     int_list( RPMTAG_FILEINODES, fileinodes );
00988     intList filesizes;
00989     int_list( RPMTAG_FILESIZES, filesizes );
00990     intList filemodes;
00991     int_list( RPMTAG_FILEMODES, filemodes );
00992 
00994     // Create and collect Entries by index. devino_cache is used to
00995     // filter out hardliks ( different name but same device and inode ).
00997     filesystem::DevInoCache trace;
00998     std::vector<DiskUsage::Entry> entries;
00999     entries.resize( dirnames.size() );
01000     for ( unsigned i = 0; i < dirnames.size(); ++i )
01001     {
01002       entries[i] = DiskUsage::Entry( dirnames[i] );
01003 
01004       // cut off deeper directory levels in DiskUsage::Entry
01005       unsigned level             = 3; // number of '/' incl. a trailing one
01006       std::string::size_type pos = 0; // we know rpm stores absolute pathnames
01007       while ( --level && pos != std::string::npos )
01008       {
01009         pos = entries[i].path.find( "/", pos+1 );
01010       }
01011       if ( pos != std::string::npos )
01012       {
01013         entries[i].path.erase( pos+1 );
01014       }
01015     }
01016 
01017     for ( unsigned i = 0; i < basenames.size(); ++ i )
01018     {
01019       filesystem::StatMode mode( filemodes[i] );
01020       if ( mode.isFile() )
01021       {
01022         if ( trace.insert( filedevices[i], fileinodes[i] ) )
01023         {
01024           // Count full 1K blocks
01025           entries[dirindexes[i]]._size += ByteCount( filesizes[i] ).blocks( ByteCount::K );
01026           ++(entries[dirindexes[i]]._files);
01027         }
01028         // else: hardlink; already counted this device/inode
01029       }
01030     }
01031 
01033     // Collect all enties. We first unify the duplicate entries that
01034     // were created by cutting off deeper levels. Then the size of each
01035     // directory must also be added to each of it's parent directories.
01037     DiskUsage tmpdata;
01038     for ( unsigned i = 0; i < entries.size(); ++i )
01039     {
01040       if ( entries[i]._size )
01041         tmpdata.add( entries[i] );
01042     }
01043 
01044     for_( it, tmpdata.begin(), tmpdata.end() )
01045     {
01046       DiskUsage::Entry ent( *it );
01047 
01048       do {
01049         dudata_r.add( ent );
01050         if ( ent.path.size() <= 1 ) // "" or "/"
01051           break;
01052 
01053         // set path to parent dir. Note that DiskUsage::Entry
01054         // has leading and trailing '/' on pathnmes.
01055         std::string::size_type rstart = ent.path.size() - 2;           // trailing '/' !
01056         std::string::size_type lpos   = ent.path.rfind( '/', rstart ); // one but last '/'
01057         if ( lpos == std::string::npos )
01058           break;
01059 
01060         ent.path.erase( lpos + 1 );
01061       } while( true );
01062     }
01063   }
01064   return dudata_r;
01065 }
01066 
01067 } // namespace rpm
01068 } // namespace target
01069 } // namespace zypp