1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/target/rpm/RpmHeader.cc
19 #include "zypp/base/Logger.h"
20 #include "zypp/PathInfo.h"
22 #include "zypp/target/rpm/RpmHeader.h"
23 #include "zypp/CapFactory.h"
25 #include "zypp/Package.h"
33 ///////////////////////////////////////////////////////////////////
35 ///////////////////////////////////////////////////////////////////
38 // METHOD NAME : RpmHeader::RpmHeader
39 // METHOD TYPE : Constructor
43 RpmHeader::RpmHeader( Header h_r )
48 ///////////////////////////////////////////////////////////////////
51 // METHOD NAME : RpmHeader::RpmHeader
52 // METHOD TYPE : Constructor
54 RpmHeader::RpmHeader( BinHeader::Ptr & rhs )
59 ///////////////////////////////////////////////////////////////////
62 // METHOD NAME : RpmHeader::~RpmHeader
63 // METHOD TYPE : Destructor
67 RpmHeader::~RpmHeader()
71 ///////////////////////////////////////////////////////////////////
74 // METHOD NAME : RpmHeader::readPackage
75 // METHOD TYPE : constRpmHeaderPtr
77 RpmHeader::constPtr RpmHeader::readPackage( const Pathname & path_r,
78 VERIFICATION verification_r )
80 PathInfo file( path_r );
81 if ( ! file.isFile() ) {
82 ERR << "Not a file: " << file << endl;
86 FD_t fd = ::Fopen( file.asString().c_str(), "r.ufdio" );
87 if ( fd == 0 || ::Ferror(fd) ) {
88 ERR << "Can't open file for reading: " << file << " (" << ::Fstrerror(fd) << ")" << endl;
94 rpmts ts = ::rpmtsCreate();
95 unsigned vsflag = RPMVSF_DEFAULT;
96 if ( verification_r & NODIGEST )
97 vsflag |= _RPMVSF_NODIGESTS;
98 if ( verification_r & NOSIGNATURE )
99 vsflag |= _RPMVSF_NOSIGNATURES;
100 ::rpmtsSetVSFlags( ts, rpmVSFlags(vsflag) );
103 int res = ::rpmReadPackageFile( ts, fd, path_r.asString().c_str(), &nh );
105 ts = ::rpmtsFree(ts);
110 WAR << "Error reading header from " << path_r << " error(" << res << ")" << endl;
111 return (RpmHeader*)0;
114 RpmHeader::constPtr h( new RpmHeader( nh ) );
115 headerFree( nh ); // clear the reference set in ReadPackageFile
117 MIL << h << " from " << path_r << endl;
121 ///////////////////////////////////////////////////////////////////
124 // METHOD NAME : RpmHeader::dumpOn
125 // METHOD TYPE : ostream &
129 ostream & RpmHeader::dumpOn( ostream & str ) const
131 return BinHeader::dumpOn( str ) << '{' << tag_name() << "-" << tag_edition() << ( isSrc() ? ".src}" : "}");
135 ///////////////////////////////////////////////////////////////////
138 // METHOD NAME : RpmHeader::isSrc
139 // METHOD TYPE : bool
141 bool RpmHeader::isSrc() const
143 return has_tag( RPMTAG_SOURCEPACKAGE );
146 ///////////////////////////////////////////////////////////////////
149 // METHOD NAME : RpmHeader::tag_name
150 // METHOD TYPE : string
154 string RpmHeader::tag_name() const
156 return string( string_val( RPMTAG_NAME ) );
159 ///////////////////////////////////////////////////////////////////
162 // METHOD NAME : RpmHeader::tag_edition
163 // METHOD TYPE : Edition
167 Edition RpmHeader::tag_edition() const
169 return Edition( string_val( RPMTAG_VERSION ),
170 string_val( RPMTAG_RELEASE ),
171 string_val ( RPMTAG_EPOCH ));
174 ///////////////////////////////////////////////////////////////////
177 // METHOD NAME : RpmHeader::tag_arch
178 // METHOD TYPE : Arch
182 Arch RpmHeader::tag_arch() const
184 return Arch( string_val( RPMTAG_ARCH ) );
187 ///////////////////////////////////////////////////////////////////
190 // METHOD NAME : RpmHeader::tag_installtime
191 // METHOD TYPE : Date
195 Date RpmHeader::tag_installtime() const
197 return int_val( RPMTAG_INSTALLTIME );
200 ///////////////////////////////////////////////////////////////////
203 // METHOD NAME : RpmHeader::tag_buildtime
204 // METHOD TYPE : Date
208 Date RpmHeader::tag_buildtime() const
210 return int_val( RPMTAG_BUILDTIME );
213 ///////////////////////////////////////////////////////////////////
216 // METHOD NAME : RpmHeader::PkgRelList_val
217 // METHOD TYPE : unsigned
221 CapSet RpmHeader::PkgRelList_val( tag tag_r, bool pre, set<string> * freq_r ) const
225 int_32 kindFlags = 0;
226 int_32 kindVersion = 0;
229 case RPMTAG_REQUIRENAME:
230 kindFlags = RPMTAG_REQUIREFLAGS;
231 kindVersion = RPMTAG_REQUIREVERSION;
233 case RPMTAG_PROVIDENAME:
234 kindFlags = RPMTAG_PROVIDEFLAGS;
235 kindVersion = RPMTAG_PROVIDEVERSION;
237 case RPMTAG_OBSOLETENAME:
238 kindFlags = RPMTAG_OBSOLETEFLAGS;
239 kindVersion = RPMTAG_OBSOLETEVERSION;
241 case RPMTAG_CONFLICTNAME:
242 kindFlags = RPMTAG_CONFLICTFLAGS;
243 kindVersion = RPMTAG_CONFLICTVERSION;
246 INT << "Illegal RPMTAG_dependencyNAME " << tag_r << endl;
252 unsigned count = string_list( tag_r, names );
257 int_list( kindFlags, flags );
260 string_list( kindVersion, versions );
262 for ( unsigned i = 0; i < count; ++i ) {
264 string n( names[i] );
268 string v = versions[i];
276 switch ( f & RPMSENSE_SENSEMASK ) {
280 case RPMSENSE_LESS|RPMSENSE_EQUAL:
283 case RPMSENSE_GREATER:
286 case RPMSENSE_GREATER|RPMSENSE_EQUAL:
295 if ((pre && (f & RPMSENSE_PREREQ))
296 || ((! pre) && !(f & RPMSENSE_PREREQ)))
299 Capability cap = _f.parse(
300 ResTraits<Package>::kind,
312 ///////////////////////////////////////////////////////////////////
315 // METHOD NAME : RpmHeader::tag_provides
316 // METHOD TYPE : CapSet
320 CapSet RpmHeader::tag_provides( set<string> * freq_r ) const
322 return PkgRelList_val( RPMTAG_PROVIDENAME, false, freq_r );
325 ///////////////////////////////////////////////////////////////////
328 // METHOD NAME : RpmHeader::tag_requires
329 // METHOD TYPE : CapSet
333 CapSet RpmHeader::tag_requires( set<string> * freq_r ) const
335 return PkgRelList_val( RPMTAG_REQUIRENAME, false, freq_r );
338 ///////////////////////////////////////////////////////////////////
341 // METHOD NAME : RpmHeader::tag_requires
342 // METHOD TYPE : CapSet
346 CapSet RpmHeader::tag_prerequires( set<string> * freq_r ) const
348 return PkgRelList_val( RPMTAG_REQUIRENAME, true, freq_r );
351 ///////////////////////////////////////////////////////////////////
354 // METHOD NAME : RpmHeader::tag_conflicts
355 // METHOD TYPE : CapSet
359 CapSet RpmHeader::tag_conflicts( set<string> * freq_r ) const
361 return PkgRelList_val( RPMTAG_CONFLICTNAME, false, freq_r );
364 ///////////////////////////////////////////////////////////////////
367 // METHOD NAME : RpmHeader::tag_obsoletes
368 // METHOD TYPE : CapSet
372 CapSet RpmHeader::tag_obsoletes( set<string> * freq_r ) const
374 return PkgRelList_val( RPMTAG_OBSOLETENAME, false, freq_r );
377 ///////////////////////////////////////////////////////////////////
380 // METHOD NAME : RpmHeader::tag_size
381 // METHOD TYPE : ByteCount
385 ByteCount RpmHeader::tag_size() const
387 return int_val( RPMTAG_SIZE );
390 ///////////////////////////////////////////////////////////////////
393 // METHOD NAME : RpmHeader::tag_archivesize
394 // METHOD TYPE : ByteCount
398 ByteCount RpmHeader::tag_archivesize() const
400 return int_val( RPMTAG_ARCHIVESIZE );
403 ///////////////////////////////////////////////////////////////////
406 // METHOD NAME : RpmHeader::tag_summary
407 // METHOD TYPE : std::string
411 std::string RpmHeader::tag_summary() const
413 return string_val( RPMTAG_SUMMARY );
416 ///////////////////////////////////////////////////////////////////
419 // METHOD NAME : RpmHeader::tag_description
420 // METHOD TYPE : std::string
424 std::string RpmHeader::tag_description() const
426 return string_val( RPMTAG_DESCRIPTION );
429 ///////////////////////////////////////////////////////////////////
432 // METHOD NAME : RpmHeader::tag_group
433 // METHOD TYPE : std::string
437 std::string RpmHeader::tag_group() const
439 return string_val( RPMTAG_GROUP );
442 ///////////////////////////////////////////////////////////////////
445 // METHOD NAME : RpmHeader::tag_vendor
446 // METHOD TYPE : std::string
450 std::string RpmHeader::tag_vendor() const
452 return string_val( RPMTAG_VENDOR );
455 ///////////////////////////////////////////////////////////////////
458 // METHOD NAME : RpmHeader::tag_distribution
459 // METHOD TYPE : std::string
463 std::string RpmHeader::tag_distribution() const
465 return string_val( RPMTAG_DISTRIBUTION );
468 ///////////////////////////////////////////////////////////////////
471 // METHOD NAME : RpmHeader::tag_license
472 // METHOD TYPE : std::string
476 std::string RpmHeader::tag_license() const
478 return string_val( RPMTAG_LICENSE );
481 ///////////////////////////////////////////////////////////////////
484 // METHOD NAME : RpmHeader::tag_buildhost
485 // METHOD TYPE : std::string
489 std::string RpmHeader::tag_buildhost() const
491 return string_val( RPMTAG_BUILDHOST );
494 ///////////////////////////////////////////////////////////////////
497 // METHOD NAME : RpmHeader::tag_packager
498 // METHOD TYPE : std::string
502 std::string RpmHeader::tag_packager() const
504 return string_val( RPMTAG_PACKAGER );
507 ///////////////////////////////////////////////////////////////////
510 // METHOD NAME : RpmHeader::tag_url
511 // METHOD TYPE : std::string
515 std::string RpmHeader::tag_url() const
517 return string_val( RPMTAG_URL );
520 ///////////////////////////////////////////////////////////////////
523 // METHOD NAME : RpmHeader::tag_os
524 // METHOD TYPE : std::string
528 std::string RpmHeader::tag_os() const
530 return string_val( RPMTAG_OS );
533 ///////////////////////////////////////////////////////////////////
536 // METHOD NAME : RpmHeader::tag_prein
537 // METHOD TYPE : std::string
541 std::string RpmHeader::tag_prein() const
543 return string_val( RPMTAG_PREIN );
546 ///////////////////////////////////////////////////////////////////
549 // METHOD NAME : RpmHeader::tag_postin
550 // METHOD TYPE : std::string
554 std::string RpmHeader::tag_postin() const
556 return string_val( RPMTAG_POSTIN );
559 ///////////////////////////////////////////////////////////////////
562 // METHOD NAME : RpmHeader::tag_preun
563 // METHOD TYPE : std::string
567 std::string RpmHeader::tag_preun() const
569 return string_val( RPMTAG_PREUN );
572 ///////////////////////////////////////////////////////////////////
575 // METHOD NAME : RpmHeader::tag_postun
576 // METHOD TYPE : std::string
580 std::string RpmHeader::tag_postun() const
582 return string_val( RPMTAG_POSTUN );
585 ///////////////////////////////////////////////////////////////////
588 // METHOD NAME : RpmHeader::tag_sourcerpm
589 // METHOD TYPE : std::string
593 std::string RpmHeader::tag_sourcerpm() const
595 return string_val( RPMTAG_SOURCERPM );
598 ///////////////////////////////////////////////////////////////////
601 // METHOD NAME : RpmHeader::tag_filenames
602 // METHOD TYPE : std::list<std::string>
606 std::list<std::string> RpmHeader::tag_filenames() const
608 std::list<std::string> ret;
610 stringList basenames;
611 if ( string_list( RPMTAG_BASENAMES, basenames ) ) {
613 string_list( RPMTAG_DIRNAMES, dirnames );
615 int_list( RPMTAG_DIRINDEXES, dirindexes );
616 for ( unsigned i = 0; i < basenames.size(); ++ i ) {
617 ret.push_back( dirnames[dirindexes[i]] + basenames[i] );
624 ///////////////////////////////////////////////////////////////////
627 // METHOD NAME : RpmHeader::tag_changelog
628 // METHOD TYPE : Changelog
632 Changelog RpmHeader::tag_changelog() const
637 if ( int_list( RPMTAG_CHANGELOGTIME, times ) ) {
639 string_list( RPMTAG_CHANGELOGNAME, names );
641 string_list( RPMTAG_CHANGELOGTEXT, texts );
642 for ( unsigned i = 0; i < times.size(); ++ i ) {
643 ret.push_back( ChangelogEntry( times[i], names[i], texts[i] ) );
650 ///////////////////////////////////////////////////////////////////
653 // METHOD NAME : RpmHeader::tag_du
654 // METHOD TYPE : PkgDu &
658 DiskUsage & RpmHeader::tag_du( DiskUsage & dudata_r ) const
661 stringList basenames;
662 if ( string_list( RPMTAG_BASENAMES, basenames ) ) {
664 string_list( RPMTAG_DIRNAMES, dirnames );
666 int_list( RPMTAG_DIRINDEXES, dirindexes );
669 int_list( RPMTAG_FILEDEVICES, filedevices );
671 int_list( RPMTAG_FILEINODES, fileinodes );
673 int_list( RPMTAG_FILESIZES, filesizes );
675 int_list( RPMTAG_FILEMODES, filemodes );
677 ///////////////////////////////////////////////////////////////////
678 // Create and collect Entries by index. devino_cache is used to
679 // filter out hardliks ( different name but same device and inode ).
680 ///////////////////////////////////////////////////////////////////
681 filesystem::DevInoCache trace;
682 vector<DiskUsage::Entry> entries;
683 entries.resize( dirnames.size() );
684 for ( unsigned i = 0; i < dirnames.size(); ++i ) {
685 entries[i] = DiskUsage::Entry(dirnames[i]);
688 for ( unsigned i = 0; i < basenames.size(); ++ i ) {
689 filesystem::StatMode mode( filemodes[i] );
690 if ( mode.isFile() ) {
691 if ( trace.insert( filedevices[i], fileinodes[i] ) ) {
692 // Count full 1K blocks
693 entries[dirindexes[i]]._size += ByteCount( filesizes[i] ).fillBlock();
694 ++(entries[dirindexes[i]]._files);
696 // else: hardlink; already counted this device/inode
700 ///////////////////////////////////////////////////////////////////
701 // Crreate and collect by index Entries. DevInoTrace is used to
702 // filter out hardliks ( different name but same device and inode ).
703 ///////////////////////////////////////////////////////////////////
704 for ( unsigned i = 0; i < entries.size(); ++i ) {
705 if ( entries[i]._size ) {
706 dudata_r.add( entries[i] );
714 } // namespace target