libzypp  10.5.0
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   return BinHeader::dumpOn( str ) << '{' << tag_name() << "-"
00270          << (tag_epoch()==0?"":(tag_epoch()+":"))
00271          << tag_version()
00272          << (tag_release().empty()?"":(std::string("-")+tag_release()))
00273          << ( isSrc() ? ".src}" : "}");
00274 }
00275 
00276 
00278 //
00279 //
00280 //        METHOD NAME : RpmHeader::isSrc
00281 //        METHOD TYPE : bool
00282 //
00283 bool RpmHeader::isSrc() const
00284 {
00285   return has_tag( RPMTAG_SOURCEPACKAGE );
00286 }
00287 
00289 //
00290 //
00291 //        METHOD NAME : RpmHeader::tag_name
00292 //        METHOD TYPE : std::string
00293 //
00294 //        DESCRIPTION :
00295 //
00296 std::string RpmHeader::tag_name() const
00297 {
00298   return string_val( RPMTAG_NAME );
00299 }
00300 
00302 //
00303 //
00304 //        METHOD NAME : RpmHeader::tag_epoch
00305 //        METHOD TYPE : Edition::epoch_t
00306 //
00307 //        DESCRIPTION :
00308 //
00309 Edition::epoch_t RpmHeader::tag_epoch() const
00310 {
00311   return int_val ( RPMTAG_EPOCH );
00312 }
00313 
00315 //
00316 //
00317 //        METHOD NAME : RpmHeader::tag_version
00318 //        METHOD TYPE : std::string
00319 //
00320 //        DESCRIPTION :
00321 //
00322 std::string RpmHeader::tag_version() const
00323 {
00324   return string_val ( RPMTAG_VERSION );
00325 }
00326 
00328 //
00329 //
00330 //        METHOD NAME : RpmHeader::tag_release
00331 //        METHOD TYPE : std::string
00332 //
00333 //        DESCRIPTION :
00334 //
00335 std::string RpmHeader::tag_release() const
00336 {
00337   return string_val( RPMTAG_RELEASE );
00338 }
00339 
00341 //
00342 //
00343 //        METHOD NAME : RpmHeader::tag_edition
00344 //        METHOD TYPE : Edition
00345 //
00346 //        DESCRIPTION :
00347 //
00348 Edition RpmHeader::tag_edition () const
00349 {
00350   return Edition( tag_version(), tag_release(), tag_epoch() );
00351 }
00352 
00354 //
00355 //
00356 //        METHOD NAME : RpmHeader::tag_arch
00357 //        METHOD TYPE : Arch
00358 //
00359 //        DESCRIPTION :
00360 //
00361 Arch RpmHeader::tag_arch() const
00362 {
00363   return Arch( string_val( RPMTAG_ARCH ) );
00364 }
00365 
00367 //
00368 //
00369 //        METHOD NAME : RpmHeader::tag_installtime
00370 //        METHOD TYPE : Date
00371 //
00372 //        DESCRIPTION :
00373 //
00374 Date RpmHeader::tag_installtime() const
00375 {
00376   return int_val( RPMTAG_INSTALLTIME );
00377 }
00378 
00380 //
00381 //
00382 //        METHOD NAME : RpmHeader::tag_buildtime
00383 //        METHOD TYPE : Date
00384 //
00385 //        DESCRIPTION :
00386 //
00387 Date RpmHeader::tag_buildtime() const
00388 {
00389   return int_val( RPMTAG_BUILDTIME );
00390 }
00391 #warning CHECK IF FILE REQUIRES HANDLING IS OBSOLETE
00392 
00393 //
00394 //
00395 //        METHOD NAME : RpmHeader::PkgRelList_val
00396 //        METHOD TYPE : CapabilitySet
00397 //
00398 //        DESCRIPTION :
00399 //
00400 CapabilitySet RpmHeader::PkgRelList_val( tag tag_r, bool pre, std::set<std::string> * freq_r ) const
00401   {
00402     CapabilitySet ret;
00403 
00404     rpmTag  kindFlags   = rpmTag(0);
00405     rpmTag  kindVersion = rpmTag(0);
00406 
00407     switch ( tag_r )
00408     {
00409     case RPMTAG_REQUIRENAME:
00410       kindFlags   = RPMTAG_REQUIREFLAGS;
00411       kindVersion = RPMTAG_REQUIREVERSION;
00412       break;
00413     case RPMTAG_PROVIDENAME:
00414       kindFlags   = RPMTAG_PROVIDEFLAGS;
00415       kindVersion = RPMTAG_PROVIDEVERSION;
00416       break;
00417     case RPMTAG_OBSOLETENAME:
00418       kindFlags   = RPMTAG_OBSOLETEFLAGS;
00419       kindVersion = RPMTAG_OBSOLETEVERSION;
00420       break;
00421     case RPMTAG_CONFLICTNAME:
00422       kindFlags   = RPMTAG_CONFLICTFLAGS;
00423       kindVersion = RPMTAG_CONFLICTVERSION;
00424       break;
00425     case RPMTAG_ENHANCESNAME:
00426       kindFlags   = RPMTAG_ENHANCESFLAGS;
00427       kindVersion = RPMTAG_ENHANCESVERSION;
00428       break;
00429     case RPMTAG_SUGGESTSNAME:
00430       kindFlags   = RPMTAG_SUGGESTSFLAGS;
00431       kindVersion = RPMTAG_SUGGESTSVERSION;
00432       break;
00433     default:
00434       INT << "Illegal RPMTAG_dependencyNAME " << tag_r << endl;
00435       return ret;
00436       break;
00437     }
00438 
00439     stringList names;
00440     unsigned count = string_list( tag_r, names );
00441     if ( !count )
00442       return ret;
00443 
00444     intList  flags;
00445     int_list( kindFlags, flags );
00446 
00447     stringList versions;
00448     string_list( kindVersion, versions );
00449 
00450     for ( unsigned i = 0; i < count; ++i )
00451     {
00452 
00453       std::string n( names[i] );
00454 
00455       Rel op = Rel::ANY;
00456       int32_t f = flags[i];
00457       std::string v = versions[i];
00458 
00459       if ( n[0] == '/' )
00460       {
00461         if ( freq_r )
00462         {
00463           freq_r->insert( n );
00464         }
00465       }
00466       else
00467       {
00468         if ( v.size() )
00469         {
00470           switch ( f & RPMSENSE_SENSEMASK )
00471           {
00472           case RPMSENSE_LESS:
00473             op = Rel::LT;
00474             break;
00475           case RPMSENSE_LESS|RPMSENSE_EQUAL:
00476             op = Rel::LE;
00477             break;
00478           case RPMSENSE_GREATER:
00479             op = Rel::GT;
00480             break;
00481           case RPMSENSE_GREATER|RPMSENSE_EQUAL:
00482             op = Rel::GE;
00483             break;
00484           case RPMSENSE_EQUAL:
00485             op = Rel::EQ;
00486             break;
00487           }
00488         }
00489       }
00490       if ((pre && (f & RPMSENSE_PREREQ))
00491           || ((! pre) && !(f & RPMSENSE_PREREQ)))
00492       {
00493         try
00494         {
00495           ret.insert( Capability( n, op, Edition(v) ) );
00496         }
00497         catch (Exception & excpt_r)
00498         {
00499           ZYPP_CAUGHT(excpt_r);
00500           WAR << "Invalid capability: " << n << " " << op << " "
00501           << v << endl;
00502         }
00503       }
00504     }
00505 
00506     return ret;
00507   }
00508 
00510 //
00511 //
00512 //        METHOD NAME : RpmHeader::tag_provides
00513 //        METHOD TYPE : CapabilitySet
00514 //
00515 //        DESCRIPTION :
00516 //
00517 CapabilitySet RpmHeader::tag_provides( std::set<std::string> * freq_r ) const
00518   {
00519     return PkgRelList_val( RPMTAG_PROVIDENAME, false, freq_r );
00520   }
00521 
00523 //
00524 //
00525 //        METHOD NAME : RpmHeader::tag_requires
00526 //        METHOD TYPE : CapabilitySet
00527 //
00528 //        DESCRIPTION :
00529 //
00530 CapabilitySet RpmHeader::tag_requires( std::set<std::string> * freq_r ) const
00531   {
00532     return PkgRelList_val( RPMTAG_REQUIRENAME, false, freq_r );
00533   }
00534 
00536 //
00537 //
00538 //        METHOD NAME : RpmHeader::tag_requires
00539 //        METHOD TYPE : CapabilitySet
00540 //
00541 //        DESCRIPTION :
00542 //
00543 CapabilitySet RpmHeader::tag_prerequires( std::set<std::string> * freq_r ) const
00544   {
00545     return PkgRelList_val( RPMTAG_REQUIRENAME, true, freq_r );
00546   }
00547 
00549 //
00550 //
00551 //        METHOD NAME : RpmHeader::tag_conflicts
00552 //        METHOD TYPE : CapabilitySet
00553 //
00554 //        DESCRIPTION :
00555 //
00556 CapabilitySet RpmHeader::tag_conflicts( std::set<std::string> * freq_r ) const
00557   {
00558     return PkgRelList_val( RPMTAG_CONFLICTNAME, false, freq_r );
00559   }
00560 
00562 //
00563 //
00564 //        METHOD NAME : RpmHeader::tag_obsoletes
00565 //        METHOD TYPE : CapabilitySet
00566 //
00567 //        DESCRIPTION :
00568 //
00569 CapabilitySet RpmHeader::tag_obsoletes( std::set<std::string> * freq_r ) const
00570   {
00571     return PkgRelList_val( RPMTAG_OBSOLETENAME, false, freq_r );
00572   }
00573 
00575 //
00576 //
00577 //        METHOD NAME : RpmHeader::tag_enhances
00578 //        METHOD TYPE : CapabilitySet
00579 //
00580 //        DESCRIPTION :
00581 //
00582 CapabilitySet RpmHeader::tag_enhances( std::set<std::string> * freq_r ) const
00583   {
00584     return PkgRelList_val( RPMTAG_ENHANCESNAME, false, freq_r );
00585   }
00586 
00588 //
00589 //
00590 //        METHOD NAME : RpmHeader::tag_suggests
00591 //        METHOD TYPE : CapabilitySet
00592 //
00593 //        DESCRIPTION :
00594 //
00595 CapabilitySet RpmHeader::tag_suggests( std::set<std::string> * freq_r ) const
00596   {
00597     return PkgRelList_val( RPMTAG_SUGGESTSNAME, false, freq_r );
00598   }
00599 
00601 //
00602 //
00603 //        METHOD NAME : RpmHeader::tag_size
00604 //        METHOD TYPE : ByteCount
00605 //
00606 //        DESCRIPTION :
00607 //
00608 ByteCount RpmHeader::tag_size() const
00609 {
00610   return int_val( RPMTAG_SIZE );
00611 }
00612 
00614 //
00615 //
00616 //        METHOD NAME : RpmHeader::tag_archivesize
00617 //        METHOD TYPE : ByteCount
00618 //
00619 //        DESCRIPTION :
00620 //
00621 ByteCount RpmHeader::tag_archivesize() const
00622 {
00623   return int_val( RPMTAG_ARCHIVESIZE );
00624 }
00625 
00627 //
00628 //
00629 //        METHOD NAME : RpmHeader::tag_summary
00630 //        METHOD TYPE : std::string
00631 //
00632 //        DESCRIPTION :
00633 //
00634 std::string RpmHeader::tag_summary() const
00635 {
00636   return string_val( RPMTAG_SUMMARY );
00637 }
00638 
00640 //
00641 //
00642 //        METHOD NAME : RpmHeader::tag_description
00643 //        METHOD TYPE : std::string
00644 //
00645 //        DESCRIPTION :
00646 //
00647 std::string RpmHeader::tag_description() const
00648 {
00649   return string_val( RPMTAG_DESCRIPTION );
00650 }
00651 
00653 //
00654 //
00655 //        METHOD NAME : RpmHeader::tag_group
00656 //        METHOD TYPE : std::string
00657 //
00658 //        DESCRIPTION :
00659 //
00660 std::string RpmHeader::tag_group() const
00661 {
00662   return string_val( RPMTAG_GROUP );
00663 }
00664 
00666 //
00667 //
00668 //        METHOD NAME : RpmHeader::tag_vendor
00669 //        METHOD TYPE : std::string
00670 //
00671 //        DESCRIPTION :
00672 //
00673 std::string RpmHeader::tag_vendor() const
00674 {
00675   return string_val( RPMTAG_VENDOR );
00676 }
00677 
00679 //
00680 //
00681 //        METHOD NAME : RpmHeader::tag_distribution
00682 //        METHOD TYPE : std::string
00683 //
00684 //        DESCRIPTION :
00685 //
00686 std::string RpmHeader::tag_distribution() const
00687 {
00688   return string_val( RPMTAG_DISTRIBUTION );
00689 }
00690 
00692 //
00693 //
00694 //        METHOD NAME : RpmHeader::tag_license
00695 //        METHOD TYPE : std::string
00696 //
00697 //        DESCRIPTION :
00698 //
00699 std::string RpmHeader::tag_license() const
00700 {
00701   return string_val( RPMTAG_LICENSE );
00702 }
00703 
00705 //
00706 //
00707 //        METHOD NAME : RpmHeader::tag_buildhost
00708 //        METHOD TYPE : std::string
00709 //
00710 //        DESCRIPTION :
00711 //
00712 std::string RpmHeader::tag_buildhost() const
00713 {
00714   return string_val( RPMTAG_BUILDHOST );
00715 }
00716 
00718 //
00719 //
00720 //        METHOD NAME : RpmHeader::tag_packager
00721 //        METHOD TYPE : std::string
00722 //
00723 //        DESCRIPTION :
00724 //
00725 std::string RpmHeader::tag_packager() const
00726 {
00727   return string_val( RPMTAG_PACKAGER );
00728 }
00729 
00731 //
00732 //
00733 //        METHOD NAME : RpmHeader::tag_url
00734 //        METHOD TYPE : std::string
00735 //
00736 //        DESCRIPTION :
00737 //
00738 std::string RpmHeader::tag_url() const
00739 {
00740   return string_val( RPMTAG_URL );
00741 }
00742 
00744 //
00745 //
00746 //        METHOD NAME : RpmHeader::tag_os
00747 //        METHOD TYPE : std::string
00748 //
00749 //        DESCRIPTION :
00750 //
00751 std::string RpmHeader::tag_os() const
00752 {
00753   return string_val( RPMTAG_OS );
00754 }
00755 
00757 //
00758 //
00759 //        METHOD NAME : RpmHeader::tag_prein
00760 //        METHOD TYPE : std::string
00761 //
00762 //        DESCRIPTION :
00763 //
00764 std::string RpmHeader::tag_prein() const
00765 {
00766   return string_val( RPMTAG_PREIN );
00767 }
00768 
00770 //
00771 //
00772 //        METHOD NAME : RpmHeader::tag_postin
00773 //        METHOD TYPE : std::string
00774 //
00775 //        DESCRIPTION :
00776 //
00777 std::string RpmHeader::tag_postin() const
00778 {
00779   return string_val( RPMTAG_POSTIN );
00780 }
00781 
00783 //
00784 //
00785 //        METHOD NAME : RpmHeader::tag_preun
00786 //        METHOD TYPE : std::string
00787 //
00788 //        DESCRIPTION :
00789 //
00790 std::string RpmHeader::tag_preun() const
00791 {
00792   return string_val( RPMTAG_PREUN );
00793 }
00794 
00796 //
00797 //
00798 //        METHOD NAME : RpmHeader::tag_postun
00799 //        METHOD TYPE : std::string
00800 //
00801 //        DESCRIPTION :
00802 //
00803 std::string RpmHeader::tag_postun() const
00804 {
00805   return string_val( RPMTAG_POSTUN );
00806 }
00807 
00809 //
00810 //
00811 //        METHOD NAME : RpmHeader::tag_sourcerpm
00812 //        METHOD TYPE : std::string
00813 //
00814 //        DESCRIPTION :
00815 //
00816 std::string RpmHeader::tag_sourcerpm() const
00817 {
00818   return string_val( RPMTAG_SOURCERPM );
00819 }
00820 
00822 //
00823 //
00824 //        METHOD NAME : RpmHeader::tag_filenames
00825 //        METHOD TYPE : std::list<std::string>
00826 //
00827 //        DESCRIPTION :
00828 //
00829 std::list<std::string> RpmHeader::tag_filenames() const
00830 {
00831   std::list<std::string> ret;
00832 
00833   stringList basenames;
00834   if ( string_list( RPMTAG_BASENAMES, basenames ) )
00835   {
00836     stringList dirnames;
00837     string_list( RPMTAG_DIRNAMES, dirnames );
00838     intList  dirindexes;
00839     int_list( RPMTAG_DIRINDEXES, dirindexes );
00840     for ( unsigned i = 0; i < basenames.size(); ++ i )
00841     {
00842       ret.push_back( dirnames[dirindexes[i]] + basenames[i] );
00843     }
00844   }
00845 
00846   return ret;
00847 }
00848 
00850 //
00851 //
00852 //        METHOD NAME : RpmHeader::tag_fileinfos
00853 //        METHOD TYPE : std::list<FileInfo>
00854 //
00855 //        DESCRIPTION :
00856 //
00857 std::list<FileInfo> RpmHeader::tag_fileinfos() const
00858 {
00859   std::list<FileInfo> ret;
00860 
00861   stringList basenames;
00862   if ( string_list( RPMTAG_BASENAMES, basenames ) )
00863   {
00864     stringList dirnames;
00865     string_list( RPMTAG_DIRNAMES, dirnames );
00866     intList  dirindexes;
00867     int_list( RPMTAG_DIRINDEXES, dirindexes );
00868     intList filesizes;
00869     int_list( RPMTAG_FILESIZES, filesizes );
00870     stringList md5sums;
00871     string_list( RPMTAG_FILEMD5S, md5sums );
00872     stringList usernames;
00873     string_list( RPMTAG_FILEUSERNAME, usernames );
00874     stringList groupnames;
00875     string_list( RPMTAG_FILEGROUPNAME, groupnames );
00876     intList uids;
00877     int_list( RPMTAG_FILEUIDS, uids );
00878     intList gids;
00879     int_list( RPMTAG_FILEGIDS, gids );
00880     intList filemodes;
00881     int_list( RPMTAG_FILEMODES, filemodes );
00882     intList filemtimes;
00883     int_list( RPMTAG_FILEMTIMES, filemtimes );
00884     intList fileflags;
00885     int_list( RPMTAG_FILEFLAGS, fileflags );
00886     stringList filelinks;
00887     string_list( RPMTAG_FILELINKTOS, filelinks );
00888 
00889     for ( unsigned i = 0; i < basenames.size(); ++ i )
00890     {
00891       uid_t uid;
00892       if (uids.empty())
00893       {
00894         uid = unameToUid( usernames[i].c_str(), &uid );
00895       }
00896       else
00897       {
00898         uid =uids[i];
00899       }
00900 
00901       gid_t gid;
00902       if (gids.empty())
00903       {
00904         gid = gnameToGid( groupnames[i].c_str(), &gid );
00905       }
00906       else
00907       {
00908         gid = gids[i];
00909       }
00910 
00911       FileInfo info = {
00912                         dirnames[dirindexes[i]] + basenames[i],
00913                         filesizes[i],
00914                         md5sums[i],
00915                         uid,
00916                         gid,
00917                         mode_t(filemodes[i]),
00918                         filemtimes[i],
00919                         bool(fileflags[i] & RPMFILE_GHOST),
00920                         filelinks[i]
00921                       };
00922 
00923       ret.push_back( info );
00924     }
00925   }
00926 
00927   return ret;
00928 }
00929 
00931 //
00932 //
00933 //        METHOD NAME : RpmHeader::tag_changelog
00934 //        METHOD TYPE : Changelog
00935 //
00936 //        DESCRIPTION :
00937 //
00938 Changelog RpmHeader::tag_changelog() const
00939 {
00940   Changelog ret;
00941 
00942   intList times;
00943   if ( int_list( RPMTAG_CHANGELOGTIME, times ) )
00944   {
00945     stringList names;
00946     string_list( RPMTAG_CHANGELOGNAME, names );
00947     stringList texts;
00948     string_list( RPMTAG_CHANGELOGTEXT, texts );
00949     for ( unsigned i = 0; i < times.size(); ++ i )
00950     {
00951       ret.push_back( ChangelogEntry( times[i], names[i], texts[i] ) );
00952     }
00953   }
00954 
00955   return ret;
00956 }
00957 
00959 //
00960 //
00961 //        METHOD NAME : RpmHeader::tag_du
00962 //        METHOD TYPE : PkgDu &
00963 //
00964 //        DESCRIPTION :
00965 //
00966 DiskUsage & RpmHeader::tag_du( DiskUsage & dudata_r ) const
00967 {
00968   dudata_r.clear();
00969   stringList basenames;
00970   if ( string_list( RPMTAG_BASENAMES, basenames ) )
00971   {
00972     stringList dirnames;
00973     string_list( RPMTAG_DIRNAMES, dirnames );
00974     intList dirindexes;
00975     int_list( RPMTAG_DIRINDEXES, dirindexes );
00976 
00977     intList filedevices;
00978     int_list( RPMTAG_FILEDEVICES, filedevices );
00979     intList fileinodes;
00980     int_list( RPMTAG_FILEINODES, fileinodes );
00981     intList filesizes;
00982     int_list( RPMTAG_FILESIZES, filesizes );
00983     intList filemodes;
00984     int_list( RPMTAG_FILEMODES, filemodes );
00985 
00987     // Create and collect Entries by index. devino_cache is used to
00988     // filter out hardliks ( different name but same device and inode ).
00990     filesystem::DevInoCache trace;
00991     std::vector<DiskUsage::Entry> entries;
00992     entries.resize( dirnames.size() );
00993     for ( unsigned i = 0; i < dirnames.size(); ++i )
00994     {
00995       entries[i] = DiskUsage::Entry( dirnames[i] );
00996 
00997       // cut off deeper directory levels in DiskUsage::Entry
00998       unsigned level             = 3; // number of '/' incl. a trailing one
00999       std::string::size_type pos = 0; // we know rpm stores absolute pathnames
01000       while ( --level && pos != std::string::npos )
01001       {
01002         pos = entries[i].path.find( "/", pos+1 );
01003       }
01004       if ( pos != std::string::npos )
01005       {
01006         entries[i].path.erase( pos+1 );
01007       }
01008     }
01009 
01010     for ( unsigned i = 0; i < basenames.size(); ++ i )
01011     {
01012       filesystem::StatMode mode( filemodes[i] );
01013       if ( mode.isFile() )
01014       {
01015         if ( trace.insert( filedevices[i], fileinodes[i] ) )
01016         {
01017           // Count full 1K blocks
01018           entries[dirindexes[i]]._size += ByteCount( filesizes[i] ).blocks( ByteCount::K );
01019           ++(entries[dirindexes[i]]._files);
01020         }
01021         // else: hardlink; already counted this device/inode
01022       }
01023     }
01024 
01026     // Collect all enties. We first unify the duplicate entries that
01027     // were created by cutting off deeper levels. Then the size of each
01028     // directory must also be added to each of it's parent directories.
01030     DiskUsage tmpdata;
01031     for ( unsigned i = 0; i < entries.size(); ++i )
01032     {
01033       if ( entries[i]._size )
01034         tmpdata.add( entries[i] );
01035     }
01036 
01037     for_( it, tmpdata.begin(), tmpdata.end() )
01038     {
01039       DiskUsage::Entry ent( *it );
01040 
01041       do {
01042         dudata_r.add( ent );
01043         if ( ent.path.size() <= 1 ) // "" or "/"
01044           break;
01045 
01046         // set path to parent dir. Note that DiskUsage::Entry
01047         // has leading and trailing '/' on pathnmes.
01048         std::string::size_type rstart = ent.path.size() - 2;           // trailing '/' !
01049         std::string::size_type lpos   = ent.path.rfind( '/', rstart ); // one but last '/'
01050         if ( lpos == std::string::npos )
01051           break;
01052 
01053         ent.path.erase( lpos + 1 );
01054       } while( true );
01055     }
01056   }
01057   return dudata_r;
01058 }
01059 
01060 } // namespace rpm
01061 } // namespace target
01062 } // namespace zypp