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

Generated on Tue May 5 14:43:20 2015 for libzypp by  doxygen 1.5.6