0dffec5d59df91b336e6b2b95775ff04c5eec88d
[platform/upstream/libzypp.git] / zypp / target / rpm / RpmHeader.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/target/rpm/RpmHeader.cc
10  *
11 */
12 #include "librpm.h"
13 #ifdef _RPM_4_4
14 #include <rpm/ugid.h>
15 #else
16 ////////////////////////////////////////////////////////////////////
17 // unameToUid and gnameToGid are shamelessly stolen from rpm-4.4.
18 // (rpmio/ugid.c) Those functions were dropped in RPM_4_7
19 extern "C"
20 {
21 #include <pwd.h>
22 #include <grp.h>
23 }
24 /* unameToUid(), uidTouname() and the group variants are really poorly
25    implemented. They really ought to use hash tables. I just made the
26    guess that most files would be owned by root or the same person/group
27    who owned the last file. Those two values are cached, everything else
28    is looked up via getpw() and getgr() functions.  If this performs
29    too poorly I'll have to implement it properly :-( */
30
31 int unameToUid(const char * thisUname, uid_t * uid)
32 {
33 /*@only@*/ static char * lastUname = NULL;
34     static size_t lastUnameLen = 0;
35     static size_t lastUnameAlloced;
36     static uid_t lastUid;
37     struct passwd * pwent;
38     size_t thisUnameLen;
39
40     if (!thisUname) {
41         lastUnameLen = 0;
42         return -1;
43     } else if (strcmp(thisUname, "root") == 0) {
44 /*@-boundswrite@*/
45         *uid = 0;
46 /*@=boundswrite@*/
47         return 0;
48     }
49
50     thisUnameLen = strlen(thisUname);
51     if (lastUname == NULL || thisUnameLen != lastUnameLen ||
52         strcmp(thisUname, lastUname) != 0)
53     {
54         if (lastUnameAlloced < thisUnameLen + 1) {
55             lastUnameAlloced = thisUnameLen + 10;
56             lastUname = (char *)realloc(lastUname, lastUnameAlloced);   /* XXX memory leak */
57         }
58 /*@-boundswrite@*/
59         strcpy(lastUname, thisUname);
60 /*@=boundswrite@*/
61
62         pwent = getpwnam(thisUname);
63         if (pwent == NULL) {
64             /*@-internalglobs@*/ /* FIX: shrug */
65             endpwent();
66             /*@=internalglobs@*/
67             pwent = getpwnam(thisUname);
68             if (pwent == NULL) return -1;
69         }
70
71         lastUid = pwent->pw_uid;
72     }
73
74 /*@-boundswrite@*/
75     *uid = lastUid;
76 /*@=boundswrite@*/
77
78     return 0;
79 }
80
81 int gnameToGid(const char * thisGname, gid_t * gid)
82 {
83 /*@only@*/ static char * lastGname = NULL;
84     static size_t lastGnameLen = 0;
85     static size_t lastGnameAlloced;
86     static gid_t lastGid;
87     size_t thisGnameLen;
88     struct group * grent;
89
90     if (thisGname == NULL) {
91         lastGnameLen = 0;
92         return -1;
93     } else if (strcmp(thisGname, "root") == 0) {
94 /*@-boundswrite@*/
95         *gid = 0;
96 /*@=boundswrite@*/
97         return 0;
98     }
99
100     thisGnameLen = strlen(thisGname);
101     if (lastGname == NULL || thisGnameLen != lastGnameLen ||
102         strcmp(thisGname, lastGname) != 0)
103     {
104         if (lastGnameAlloced < thisGnameLen + 1) {
105             lastGnameAlloced = thisGnameLen + 10;
106             lastGname = (char *)realloc(lastGname, lastGnameAlloced);   /* XXX memory leak */
107         }
108 /*@-boundswrite@*/
109         strcpy(lastGname, thisGname);
110 /*@=boundswrite@*/
111
112         grent = getgrnam(thisGname);
113         if (grent == NULL) {
114             /*@-internalglobs@*/ /* FIX: shrug */
115             endgrent();
116             /*@=internalglobs@*/
117             grent = getgrnam(thisGname);
118             if (grent == NULL) {
119                 /* XXX The filesystem package needs group/lock w/o getgrnam. */
120                 if (strcmp(thisGname, "lock") == 0) {
121 /*@-boundswrite@*/
122                     *gid = lastGid = 54;
123 /*@=boundswrite@*/
124                     return 0;
125                 } else
126                 if (strcmp(thisGname, "mail") == 0) {
127 /*@-boundswrite@*/
128                     *gid = lastGid = 12;
129 /*@=boundswrite@*/
130                     return 0;
131                 } else
132                 return -1;
133             }
134         }
135         lastGid = grent->gr_gid;
136     }
137
138 /*@-boundswrite@*/
139     *gid = lastGid;
140 /*@=boundswrite@*/
141
142     return 0;
143 }
144 ////////////////////////////////////////////////////////////////////
145 #endif
146
147 #include <iostream>
148 #include <map>
149 #include <set>
150 #include <vector>
151
152 #include "zypp/base/Easy.h"
153 #include "zypp/base/Logger.h"
154 #include "zypp/base/Exception.h"
155
156 #include "zypp/target/rpm/librpmDb.h"
157 #include "zypp/target/rpm/RpmHeader.h"
158 #include "zypp/Package.h"
159 #include "zypp/PathInfo.h"
160
161 using std::endl;
162
163 namespace zypp
164 {
165 namespace target
166 {
167 namespace rpm
168 {
169
170 ///////////////////////////////////////////////////////////////////
171
172 ///////////////////////////////////////////////////////////////////
173 //
174 //
175 //        METHOD NAME : RpmHeader::RpmHeader
176 //        METHOD TYPE : Constructor
177 //
178 //        DESCRIPTION :
179 //
180 RpmHeader::RpmHeader( Header h_r )
181     : BinHeader( h_r )
182 {}
183
184 ///////////////////////////////////////////////////////////////////
185 //
186 //
187 //        METHOD NAME : RpmHeader::RpmHeader
188 //        METHOD TYPE : Constructor
189 //
190 RpmHeader::RpmHeader( BinHeader::Ptr & rhs )
191     : BinHeader( rhs )
192 {}
193
194 ///////////////////////////////////////////////////////////////////
195 //
196 //
197 //        METHOD NAME : RpmHeader::~RpmHeader
198 //        METHOD TYPE : Destructor
199 //
200 //        DESCRIPTION :
201 //
202 RpmHeader::~RpmHeader()
203 {}
204
205 ///////////////////////////////////////////////////////////////////
206 //
207 //
208 //        METHOD NAME : RpmHeader::readPackage
209 //        METHOD TYPE : constRpmHeaderPtr
210 //
211 RpmHeader::constPtr RpmHeader::readPackage( const Pathname & path_r,
212                                             VERIFICATION verification_r )
213 {
214   PathInfo file( path_r );
215   if ( ! file.isFile() )
216   {
217     ERR << "Not a file: " << file << endl;
218     return (RpmHeader*)0;
219   }
220
221   FD_t fd = ::Fopen( file.asString().c_str(), "r.ufdio" );
222   if ( fd == 0 || ::Ferror(fd) )
223   {
224     ERR << "Can't open file for reading: " << file << " (" << ::Fstrerror(fd) << ")" << endl;
225     if ( fd )
226       ::Fclose( fd );
227     return (RpmHeader*)0;
228   }
229
230   librpmDb::globalInit();
231   rpmts ts = ::rpmtsCreate();
232   unsigned vsflag = RPMVSF_DEFAULT;
233   if ( verification_r & NODIGEST )
234     vsflag |= _RPMVSF_NODIGESTS;
235   if ( verification_r & NOSIGNATURE )
236     vsflag |= _RPMVSF_NOSIGNATURES;
237   ::rpmtsSetVSFlags( ts, rpmVSFlags(vsflag) );
238
239   Header nh = 0;
240   int res = ::rpmReadPackageFile( ts, fd, path_r.asString().c_str(), &nh );
241
242   ts = rpmtsFree(ts);
243
244   ::Fclose( fd );
245
246   if ( ! nh )
247   {
248     WAR << "Error reading header from " << path_r << " error(" << res << ")" << endl;
249     return (RpmHeader*)0;
250   }
251
252   RpmHeader::constPtr h( new RpmHeader( nh ) );
253   headerFree( nh ); // clear the reference set in ReadPackageFile
254
255   MIL << h << " from " << path_r << endl;
256   return h;
257 }
258
259 ///////////////////////////////////////////////////////////////////
260 //
261 //
262 //        METHOD NAME : RpmHeader::dumpOn
263 //        METHOD TYPE : std::ostream &
264 //
265 //        DESCRIPTION :
266 //
267 std::ostream & RpmHeader::dumpOn( std::ostream & str ) const
268 {
269   str << BinHeader::dumpOn( str ) << '{' << tag_name() << "-";
270   if ( tag_epoch() != 0 )
271     str << tag_epoch() << ":";
272   str << tag_version()
273       << (tag_release().empty()?"":(std::string("-")+tag_release()))
274       << ( isSrc() ? ".src}" : "}");
275   return str;
276 }
277
278
279 ///////////////////////////////////////////////////////////////////
280 //
281 //
282 //        METHOD NAME : RpmHeader::isSrc
283 //        METHOD TYPE : bool
284 //
285 bool RpmHeader::isSrc() const
286 {
287   return has_tag( RPMTAG_SOURCEPACKAGE );
288 }
289
290 bool RpmHeader::isNosrc() const
291 {
292   return has_tag( RPMTAG_SOURCEPACKAGE ) && ( has_tag( RPMTAG_NOSOURCE ) || has_tag( RPMTAG_NOPATCH ) );
293 }
294
295 ///////////////////////////////////////////////////////////////////
296 //
297 //
298 //        METHOD NAME : RpmHeader::tag_name
299 //        METHOD TYPE : std::string
300 //
301 //        DESCRIPTION :
302 //
303 std::string RpmHeader::tag_name() const
304 {
305   return string_val( RPMTAG_NAME );
306 }
307
308 ///////////////////////////////////////////////////////////////////
309 //
310 //
311 //        METHOD NAME : RpmHeader::tag_epoch
312 //        METHOD TYPE : Edition::epoch_t
313 //
314 //        DESCRIPTION :
315 //
316 Edition::epoch_t RpmHeader::tag_epoch() const
317 {
318   return int_val ( RPMTAG_EPOCH );
319 }
320
321 ///////////////////////////////////////////////////////////////////
322 //
323 //
324 //        METHOD NAME : RpmHeader::tag_version
325 //        METHOD TYPE : std::string
326 //
327 //        DESCRIPTION :
328 //
329 std::string RpmHeader::tag_version() const
330 {
331   return string_val ( RPMTAG_VERSION );
332 }
333
334 ///////////////////////////////////////////////////////////////////
335 //
336 //
337 //        METHOD NAME : RpmHeader::tag_release
338 //        METHOD TYPE : std::string
339 //
340 //        DESCRIPTION :
341 //
342 std::string RpmHeader::tag_release() const
343 {
344   return string_val( RPMTAG_RELEASE );
345 }
346
347 ///////////////////////////////////////////////////////////////////
348 //
349 //
350 //        METHOD NAME : RpmHeader::tag_edition
351 //        METHOD TYPE : Edition
352 //
353 //        DESCRIPTION :
354 //
355 Edition RpmHeader::tag_edition () const
356 {
357   return Edition( tag_version(), tag_release(), tag_epoch() );
358 }
359
360 ///////////////////////////////////////////////////////////////////
361 //
362 //
363 //        METHOD NAME : RpmHeader::tag_arch
364 //        METHOD TYPE : Arch
365 //
366 //        DESCRIPTION :
367 //
368 Arch RpmHeader::tag_arch() const
369 {
370   return Arch( string_val( RPMTAG_ARCH ) );
371 }
372
373 ///////////////////////////////////////////////////////////////////
374 //
375 //
376 //        METHOD NAME : RpmHeader::tag_installtime
377 //        METHOD TYPE : Date
378 //
379 //        DESCRIPTION :
380 //
381 Date RpmHeader::tag_installtime() const
382 {
383   return int_val( RPMTAG_INSTALLTIME );
384 }
385
386 ///////////////////////////////////////////////////////////////////
387 //
388 //
389 //        METHOD NAME : RpmHeader::tag_buildtime
390 //        METHOD TYPE : Date
391 //
392 //        DESCRIPTION :
393 //
394 Date RpmHeader::tag_buildtime() const
395 {
396   return int_val( RPMTAG_BUILDTIME );
397 }
398 #warning CHECK IF FILE REQUIRES HANDLING IS OBSOLETE
399 ///////////////////////////////////////////////////////////////////
400 //
401 //
402 //        METHOD NAME : RpmHeader::PkgRelList_val
403 //        METHOD TYPE : CapabilitySet
404 //
405 //        DESCRIPTION :
406 //
407 CapabilitySet RpmHeader::PkgRelList_val( tag tag_r, bool pre, std::set<std::string> * freq_r ) const
408   {
409     CapabilitySet ret;
410
411     rpmTag  kindFlags   = rpmTag(0);
412     rpmTag  kindVersion = rpmTag(0);
413
414     switch ( tag_r )
415     {
416     case RPMTAG_REQUIRENAME:
417       kindFlags   = RPMTAG_REQUIREFLAGS;
418       kindVersion = RPMTAG_REQUIREVERSION;
419       break;
420     case RPMTAG_PROVIDENAME:
421       kindFlags   = RPMTAG_PROVIDEFLAGS;
422       kindVersion = RPMTAG_PROVIDEVERSION;
423       break;
424     case RPMTAG_OBSOLETENAME:
425       kindFlags   = RPMTAG_OBSOLETEFLAGS;
426       kindVersion = RPMTAG_OBSOLETEVERSION;
427       break;
428     case RPMTAG_CONFLICTNAME:
429       kindFlags   = RPMTAG_CONFLICTFLAGS;
430       kindVersion = RPMTAG_CONFLICTVERSION;
431       break;
432 #ifdef RPMTAG_OLDSUGGESTS
433     case RPMTAG_OLDENHANCESNAME:
434       kindFlags   = RPMTAG_OLDENHANCESFLAGS;
435       kindVersion = RPMTAG_OLDENHANCESVERSION;
436       break;
437     case RPMTAG_OLDSUGGESTSNAME:
438       kindFlags   = RPMTAG_OLDSUGGESTSFLAGS;
439       kindVersion = RPMTAG_OLDSUGGESTSVERSION;
440       break;
441     case RPMTAG_RECOMMENDNAME:
442       kindFlags   = RPMTAG_RECOMMENDFLAGS;
443       kindVersion = RPMTAG_RECOMMENDVERSION;
444       break;
445     case RPMTAG_SUPPLEMENTNAME:
446       kindFlags   = RPMTAG_SUPPLEMENTFLAGS;
447       kindVersion = RPMTAG_SUPPLEMENTVERSION;
448       break;
449     case RPMTAG_SUGGESTNAME:
450       kindFlags   = RPMTAG_SUGGESTFLAGS;
451       kindVersion = RPMTAG_SUGGESTVERSION;
452       break;
453     case RPMTAG_ENHANCENAME:
454       kindFlags   = RPMTAG_ENHANCEFLAGS;
455       kindVersion = RPMTAG_ENHANCEVERSION;
456       break;
457 #else
458     case RPMTAG_ENHANCESNAME:
459       kindFlags   = RPMTAG_ENHANCESFLAGS;
460       kindVersion = RPMTAG_ENHANCESVERSION;
461       break;
462     case RPMTAG_SUGGESTSNAME:
463       kindFlags   = RPMTAG_SUGGESTSFLAGS;
464       kindVersion = RPMTAG_SUGGESTSVERSION;
465       break;
466 #endif
467     default:
468       INT << "Illegal RPMTAG_dependencyNAME " << tag_r << endl;
469       return ret;
470       break;
471     }
472
473     stringList names;
474     unsigned count = string_list( tag_r, names );
475     if ( !count )
476       return ret;
477
478     intList  flags;
479     int_list( kindFlags, flags );
480
481     stringList versions;
482     string_list( kindVersion, versions );
483
484     for ( unsigned i = 0; i < count; ++i )
485     {
486
487       std::string n( names[i] );
488
489       Rel op = Rel::ANY;
490       int32_t f = flags[i];
491       std::string v = versions[i];
492
493       if ( n[0] == '/' )
494       {
495         if ( freq_r )
496         {
497           freq_r->insert( n );
498         }
499       }
500       else
501       {
502         if ( v.size() )
503         {
504           switch ( f & RPMSENSE_SENSEMASK )
505           {
506           case RPMSENSE_LESS:
507             op = Rel::LT;
508             break;
509           case RPMSENSE_LESS|RPMSENSE_EQUAL:
510             op = Rel::LE;
511             break;
512           case RPMSENSE_GREATER:
513             op = Rel::GT;
514             break;
515           case RPMSENSE_GREATER|RPMSENSE_EQUAL:
516             op = Rel::GE;
517             break;
518           case RPMSENSE_EQUAL:
519             op = Rel::EQ;
520             break;
521           }
522         }
523       }
524       if ((pre && (f & RPMSENSE_PREREQ))
525           || ((! pre) && !(f & RPMSENSE_PREREQ)))
526       {
527         try
528         {
529           ret.insert( Capability( n, op, Edition(v) ) );
530         }
531         catch (Exception & excpt_r)
532         {
533           ZYPP_CAUGHT(excpt_r);
534           WAR << "Invalid capability: " << n << " " << op << " "
535           << v << endl;
536         }
537       }
538     }
539
540     return ret;
541   }
542
543 ///////////////////////////////////////////////////////////////////
544 //
545 //
546 //        METHOD NAME : RpmHeader::tag_provides
547 //        METHOD TYPE : CapabilitySet
548 //
549 //        DESCRIPTION :
550 //
551 CapabilitySet RpmHeader::tag_provides( std::set<std::string> * freq_r ) const
552   {
553     return PkgRelList_val( RPMTAG_PROVIDENAME, false, freq_r );
554   }
555
556 ///////////////////////////////////////////////////////////////////
557 //
558 //
559 //        METHOD NAME : RpmHeader::tag_requires
560 //        METHOD TYPE : CapabilitySet
561 //
562 //        DESCRIPTION :
563 //
564 CapabilitySet RpmHeader::tag_requires( std::set<std::string> * freq_r ) const
565   {
566     return PkgRelList_val( RPMTAG_REQUIRENAME, false, freq_r );
567   }
568
569 ///////////////////////////////////////////////////////////////////
570 //
571 //
572 //        METHOD NAME : RpmHeader::tag_requires
573 //        METHOD TYPE : CapabilitySet
574 //
575 //        DESCRIPTION :
576 //
577 CapabilitySet RpmHeader::tag_prerequires( std::set<std::string> * freq_r ) const
578   {
579     return PkgRelList_val( RPMTAG_REQUIRENAME, true, freq_r );
580   }
581
582 ///////////////////////////////////////////////////////////////////
583 //
584 //
585 //        METHOD NAME : RpmHeader::tag_conflicts
586 //        METHOD TYPE : CapabilitySet
587 //
588 //        DESCRIPTION :
589 //
590 CapabilitySet RpmHeader::tag_conflicts( std::set<std::string> * freq_r ) const
591   {
592     return PkgRelList_val( RPMTAG_CONFLICTNAME, false, freq_r );
593   }
594
595 ///////////////////////////////////////////////////////////////////
596 //
597 //
598 //        METHOD NAME : RpmHeader::tag_obsoletes
599 //        METHOD TYPE : CapabilitySet
600 //
601 //        DESCRIPTION :
602 //
603 CapabilitySet RpmHeader::tag_obsoletes( std::set<std::string> * freq_r ) const
604   {
605     return PkgRelList_val( RPMTAG_OBSOLETENAME, false, freq_r );
606   }
607
608 ///////////////////////////////////////////////////////////////////
609 //
610 //
611 //        METHOD NAME : RpmHeader::tag_enhances
612 //        METHOD TYPE : CapabilitySet
613 //
614 //        DESCRIPTION :
615 //
616 CapabilitySet RpmHeader::tag_enhances( std::set<std::string> * freq_r ) const
617   {
618 #ifdef RPMTAG_OLDSUGGESTS
619     return PkgRelList_val( RPMTAG_ENHANCENAME, false, freq_r );
620 #else
621     return PkgRelList_val( RPMTAG_ENHANCESNAME, false, freq_r );
622 #endif
623   }
624
625 ///////////////////////////////////////////////////////////////////
626 //
627 //
628 //        METHOD NAME : RpmHeader::tag_suggests
629 //        METHOD TYPE : CapabilitySet
630 //
631 //        DESCRIPTION :
632 //
633 CapabilitySet RpmHeader::tag_suggests( std::set<std::string> * freq_r ) const
634   {
635 #ifdef RPMTAG_OLDSUGGESTS
636     return PkgRelList_val( RPMTAG_SUGGESTNAME, false, freq_r );
637 #else
638     return PkgRelList_val( RPMTAG_SUGGESTSNAME, false, freq_r );
639 #endif
640   }
641
642 ///////////////////////////////////////////////////////////////////
643 //
644 //
645 //        METHOD NAME : RpmHeader::tag_supplements
646 //        METHOD TYPE : CapabilitySet
647 //
648 //        DESCRIPTION :
649 //
650 CapabilitySet RpmHeader::tag_supplements( std::set<std::string> * freq_r ) const
651   {
652 #ifdef RPMTAG_OLDSUGGESTS
653     return PkgRelList_val( RPMTAG_SUPPLEMENTNAME, false, freq_r );
654 #else
655     return CapabilitySet();
656 #endif
657   }
658
659 ///////////////////////////////////////////////////////////////////
660 //
661 //
662 //        METHOD NAME : RpmHeader::tag_recommends
663 //        METHOD TYPE : CapabilitySet
664 //
665 //        DESCRIPTION :
666 //
667 CapabilitySet RpmHeader::tag_recommends( std::set<std::string> * freq_r ) const
668   {
669 #ifdef RPMTAG_OLDSUGGESTS
670     return PkgRelList_val( RPMTAG_RECOMMENDNAME, false, freq_r );
671 #else
672     return CapabilitySet();
673 #endif
674   }
675
676 ///////////////////////////////////////////////////////////////////
677 //
678 //
679 //        METHOD NAME : RpmHeader::tag_size
680 //        METHOD TYPE : ByteCount
681 //
682 //        DESCRIPTION :
683 //
684 ByteCount RpmHeader::tag_size() const
685 {
686   return int_val( RPMTAG_SIZE );
687 }
688
689 ///////////////////////////////////////////////////////////////////
690 //
691 //
692 //        METHOD NAME : RpmHeader::tag_archivesize
693 //        METHOD TYPE : ByteCount
694 //
695 //        DESCRIPTION :
696 //
697 ByteCount RpmHeader::tag_archivesize() const
698 {
699   return int_val( RPMTAG_ARCHIVESIZE );
700 }
701
702 ///////////////////////////////////////////////////////////////////
703 //
704 //
705 //        METHOD NAME : RpmHeader::tag_summary
706 //        METHOD TYPE : std::string
707 //
708 //        DESCRIPTION :
709 //
710 std::string RpmHeader::tag_summary() const
711 {
712   return string_val( RPMTAG_SUMMARY );
713 }
714
715 ///////////////////////////////////////////////////////////////////
716 //
717 //
718 //        METHOD NAME : RpmHeader::tag_description
719 //        METHOD TYPE : std::string
720 //
721 //        DESCRIPTION :
722 //
723 std::string RpmHeader::tag_description() const
724 {
725   return string_val( RPMTAG_DESCRIPTION );
726 }
727
728 ///////////////////////////////////////////////////////////////////
729 //
730 //
731 //        METHOD NAME : RpmHeader::tag_group
732 //        METHOD TYPE : std::string
733 //
734 //        DESCRIPTION :
735 //
736 std::string RpmHeader::tag_group() const
737 {
738   return string_val( RPMTAG_GROUP );
739 }
740
741 ///////////////////////////////////////////////////////////////////
742 //
743 //
744 //        METHOD NAME : RpmHeader::tag_vendor
745 //        METHOD TYPE : std::string
746 //
747 //        DESCRIPTION :
748 //
749 std::string RpmHeader::tag_vendor() const
750 {
751   return string_val( RPMTAG_VENDOR );
752 }
753
754 ///////////////////////////////////////////////////////////////////
755 //
756 //
757 //        METHOD NAME : RpmHeader::tag_distribution
758 //        METHOD TYPE : std::string
759 //
760 //        DESCRIPTION :
761 //
762 std::string RpmHeader::tag_distribution() const
763 {
764   return string_val( RPMTAG_DISTRIBUTION );
765 }
766
767 ///////////////////////////////////////////////////////////////////
768 //
769 //
770 //        METHOD NAME : RpmHeader::tag_license
771 //        METHOD TYPE : std::string
772 //
773 //        DESCRIPTION :
774 //
775 std::string RpmHeader::tag_license() const
776 {
777   return string_val( RPMTAG_LICENSE );
778 }
779
780 ///////////////////////////////////////////////////////////////////
781 //
782 //
783 //        METHOD NAME : RpmHeader::tag_buildhost
784 //        METHOD TYPE : std::string
785 //
786 //        DESCRIPTION :
787 //
788 std::string RpmHeader::tag_buildhost() const
789 {
790   return string_val( RPMTAG_BUILDHOST );
791 }
792
793 ///////////////////////////////////////////////////////////////////
794 //
795 //
796 //        METHOD NAME : RpmHeader::tag_packager
797 //        METHOD TYPE : std::string
798 //
799 //        DESCRIPTION :
800 //
801 std::string RpmHeader::tag_packager() const
802 {
803   return string_val( RPMTAG_PACKAGER );
804 }
805
806 ///////////////////////////////////////////////////////////////////
807 //
808 //
809 //        METHOD NAME : RpmHeader::tag_url
810 //        METHOD TYPE : std::string
811 //
812 //        DESCRIPTION :
813 //
814 std::string RpmHeader::tag_url() const
815 {
816   return string_val( RPMTAG_URL );
817 }
818
819 ///////////////////////////////////////////////////////////////////
820 //
821 //
822 //        METHOD NAME : RpmHeader::tag_os
823 //        METHOD TYPE : std::string
824 //
825 //        DESCRIPTION :
826 //
827 std::string RpmHeader::tag_os() const
828 {
829   return string_val( RPMTAG_OS );
830
831 }
832
833 std::string RpmHeader::tag_prein() const
834 { return string_val( RPMTAG_PREIN ); }
835
836 std::string RpmHeader::tag_preinprog() const
837 { return string_val( RPMTAG_PREINPROG ); }
838
839 std::string RpmHeader::tag_postin() const
840 { return string_val( RPMTAG_POSTIN ); }
841
842 std::string RpmHeader::tag_postinprog() const
843 { return string_val( RPMTAG_POSTINPROG ); }
844
845 std::string RpmHeader::tag_preun() const
846 { return string_val( RPMTAG_PREUN ); }
847
848 std::string RpmHeader::tag_preunprog() const
849 { return string_val( RPMTAG_PREUNPROG ); }
850
851 std::string RpmHeader::tag_postun() const
852 { return string_val( RPMTAG_POSTUN ); }
853
854 std::string RpmHeader::tag_postunprog() const
855 { return string_val( RPMTAG_POSTUNPROG ); }
856
857 std::string RpmHeader::tag_pretrans() const
858 { return string_val( RPMTAG_PRETRANS ); }
859
860 std::string RpmHeader::tag_pretransprog() const
861 { return string_val( RPMTAG_PRETRANSPROG ); }
862
863 std::string RpmHeader::tag_posttrans() const
864 { return string_val( RPMTAG_POSTTRANS ); }
865
866 std::string RpmHeader::tag_posttransprog() const
867 { return string_val( RPMTAG_POSTTRANSPROG ); }
868
869 ///////////////////////////////////////////////////////////////////
870 //
871 //
872 //        METHOD NAME : RpmHeader::tag_sourcerpm
873 //        METHOD TYPE : std::string
874 //
875 //        DESCRIPTION :
876 //
877 std::string RpmHeader::tag_sourcerpm() const
878 {
879   return string_val( RPMTAG_SOURCERPM );
880 }
881
882 ///////////////////////////////////////////////////////////////////
883 //
884 //
885 //        METHOD NAME : RpmHeader::tag_filenames
886 //        METHOD TYPE : std::list<std::string>
887 //
888 //        DESCRIPTION :
889 //
890 std::list<std::string> RpmHeader::tag_filenames() const
891 {
892   std::list<std::string> ret;
893
894   stringList basenames;
895   if ( string_list( RPMTAG_BASENAMES, basenames ) )
896   {
897     stringList dirnames;
898     string_list( RPMTAG_DIRNAMES, dirnames );
899     intList  dirindexes;
900     int_list( RPMTAG_DIRINDEXES, dirindexes );
901     for ( unsigned i = 0; i < basenames.size(); ++ i )
902     {
903       ret.push_back( dirnames[dirindexes[i]] + basenames[i] );
904     }
905   }
906
907   return ret;
908 }
909
910 ///////////////////////////////////////////////////////////////////
911 //
912 //
913 //        METHOD NAME : RpmHeader::tag_fileinfos
914 //        METHOD TYPE : std::list<FileInfo>
915 //
916 //        DESCRIPTION :
917 //
918 std::list<FileInfo> RpmHeader::tag_fileinfos() const
919 {
920   std::list<FileInfo> ret;
921
922   stringList basenames;
923   if ( string_list( RPMTAG_BASENAMES, basenames ) )
924   {
925     stringList dirnames;
926     string_list( RPMTAG_DIRNAMES, dirnames );
927     intList  dirindexes;
928     int_list( RPMTAG_DIRINDEXES, dirindexes );
929     intList filesizes;
930     int_list( RPMTAG_FILESIZES, filesizes );
931     stringList md5sums;
932     string_list( RPMTAG_FILEMD5S, md5sums );
933     stringList usernames;
934     string_list( RPMTAG_FILEUSERNAME, usernames );
935     stringList groupnames;
936     string_list( RPMTAG_FILEGROUPNAME, groupnames );
937     intList uids;
938     int_list( RPMTAG_FILEUIDS, uids );
939     intList gids;
940     int_list( RPMTAG_FILEGIDS, gids );
941     intList filemodes;
942     int_list( RPMTAG_FILEMODES, filemodes );
943     intList filemtimes;
944     int_list( RPMTAG_FILEMTIMES, filemtimes );
945     intList fileflags;
946     int_list( RPMTAG_FILEFLAGS, fileflags );
947     stringList filelinks;
948     string_list( RPMTAG_FILELINKTOS, filelinks );
949
950     for ( unsigned i = 0; i < basenames.size(); ++ i )
951     {
952       uid_t uid;
953       if (uids.empty())
954       {
955         uid = unameToUid( usernames[i].c_str(), &uid );
956       }
957       else
958       {
959         uid =uids[i];
960       }
961
962       gid_t gid;
963       if (gids.empty())
964       {
965         gid = gnameToGid( groupnames[i].c_str(), &gid );
966       }
967       else
968       {
969         gid = gids[i];
970       }
971
972       FileInfo info = {
973                         dirnames[dirindexes[i]] + basenames[i],
974                         filesizes[i],
975                         md5sums[i],
976                         uid,
977                         gid,
978                         mode_t(filemodes[i]),
979                         filemtimes[i],
980                         bool(fileflags[i] & RPMFILE_GHOST),
981                         filelinks[i]
982                       };
983
984       ret.push_back( info );
985     }
986   }
987
988   return ret;
989 }
990
991 ///////////////////////////////////////////////////////////////////
992 //
993 //
994 //        METHOD NAME : RpmHeader::tag_changelog
995 //        METHOD TYPE : Changelog
996 //
997 //        DESCRIPTION :
998 //
999 Changelog RpmHeader::tag_changelog() const
1000 {
1001   Changelog ret;
1002
1003   intList times;
1004   if ( int_list( RPMTAG_CHANGELOGTIME, times ) )
1005   {
1006     stringList names;
1007     string_list( RPMTAG_CHANGELOGNAME, names );
1008     stringList texts;
1009     string_list( RPMTAG_CHANGELOGTEXT, texts );
1010     for ( unsigned i = 0; i < times.size(); ++ i )
1011     {
1012       ret.push_back( ChangelogEntry( times[i], names[i], texts[i] ) );
1013     }
1014   }
1015
1016   return ret;
1017 }
1018
1019 } // namespace rpm
1020 } // namespace target
1021 } // namespace zypp