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