libzypp 9.41.1
|
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