Imported Upstream version 15.0.0
[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   return BinHeader::dumpOn( str ) << '{' << tag_name() << "-"
270          << (tag_epoch()==0?"":(tag_epoch()+":"))
271          << tag_version()
272          << (tag_release().empty()?"":(std::string("-")+tag_release()))
273          << ( isSrc() ? ".src}" : "}");
274 }
275
276
277 ///////////////////////////////////////////////////////////////////
278 //
279 //
280 //        METHOD NAME : RpmHeader::isSrc
281 //        METHOD TYPE : bool
282 //
283 bool RpmHeader::isSrc() const
284 {
285   return has_tag( RPMTAG_SOURCEPACKAGE );
286 }
287
288 bool RpmHeader::isNosrc() const
289 {
290   return has_tag( RPMTAG_SOURCEPACKAGE ) && ( has_tag( RPMTAG_NOSOURCE ) || has_tag( RPMTAG_NOPATCH ) );
291 }
292
293 ///////////////////////////////////////////////////////////////////
294 //
295 //
296 //        METHOD NAME : RpmHeader::tag_name
297 //        METHOD TYPE : std::string
298 //
299 //        DESCRIPTION :
300 //
301 std::string RpmHeader::tag_name() const
302 {
303   return string_val( RPMTAG_NAME );
304 }
305
306 ///////////////////////////////////////////////////////////////////
307 //
308 //
309 //        METHOD NAME : RpmHeader::tag_epoch
310 //        METHOD TYPE : Edition::epoch_t
311 //
312 //        DESCRIPTION :
313 //
314 Edition::epoch_t RpmHeader::tag_epoch() const
315 {
316   return int_val ( RPMTAG_EPOCH );
317 }
318
319 ///////////////////////////////////////////////////////////////////
320 //
321 //
322 //        METHOD NAME : RpmHeader::tag_version
323 //        METHOD TYPE : std::string
324 //
325 //        DESCRIPTION :
326 //
327 std::string RpmHeader::tag_version() const
328 {
329   return string_val ( RPMTAG_VERSION );
330 }
331
332 ///////////////////////////////////////////////////////////////////
333 //
334 //
335 //        METHOD NAME : RpmHeader::tag_release
336 //        METHOD TYPE : std::string
337 //
338 //        DESCRIPTION :
339 //
340 std::string RpmHeader::tag_release() const
341 {
342   return string_val( RPMTAG_RELEASE );
343 }
344
345 ///////////////////////////////////////////////////////////////////
346 //
347 //
348 //        METHOD NAME : RpmHeader::tag_edition
349 //        METHOD TYPE : Edition
350 //
351 //        DESCRIPTION :
352 //
353 Edition RpmHeader::tag_edition () const
354 {
355   return Edition( tag_version(), tag_release(), tag_epoch() );
356 }
357
358 ///////////////////////////////////////////////////////////////////
359 //
360 //
361 //        METHOD NAME : RpmHeader::tag_arch
362 //        METHOD TYPE : Arch
363 //
364 //        DESCRIPTION :
365 //
366 Arch RpmHeader::tag_arch() const
367 {
368   return Arch( string_val( RPMTAG_ARCH ) );
369 }
370
371 ///////////////////////////////////////////////////////////////////
372 //
373 //
374 //        METHOD NAME : RpmHeader::tag_installtime
375 //        METHOD TYPE : Date
376 //
377 //        DESCRIPTION :
378 //
379 Date RpmHeader::tag_installtime() const
380 {
381   return int_val( RPMTAG_INSTALLTIME );
382 }
383
384 ///////////////////////////////////////////////////////////////////
385 //
386 //
387 //        METHOD NAME : RpmHeader::tag_buildtime
388 //        METHOD TYPE : Date
389 //
390 //        DESCRIPTION :
391 //
392 Date RpmHeader::tag_buildtime() const
393 {
394   return int_val( RPMTAG_BUILDTIME );
395 }
396 #warning CHECK IF FILE REQUIRES HANDLING IS OBSOLETE
397 ///////////////////////////////////////////////////////////////////
398 //
399 //
400 //        METHOD NAME : RpmHeader::PkgRelList_val
401 //        METHOD TYPE : CapabilitySet
402 //
403 //        DESCRIPTION :
404 //
405 CapabilitySet RpmHeader::PkgRelList_val( tag tag_r, bool pre, std::set<std::string> * freq_r ) const
406   {
407     CapabilitySet ret;
408
409     rpmTag  kindFlags   = rpmTag(0);
410     rpmTag  kindVersion = rpmTag(0);
411
412     switch ( tag_r )
413     {
414     case RPMTAG_REQUIRENAME:
415       kindFlags   = RPMTAG_REQUIREFLAGS;
416       kindVersion = RPMTAG_REQUIREVERSION;
417       break;
418     case RPMTAG_PROVIDENAME:
419       kindFlags   = RPMTAG_PROVIDEFLAGS;
420       kindVersion = RPMTAG_PROVIDEVERSION;
421       break;
422     case RPMTAG_OBSOLETENAME:
423       kindFlags   = RPMTAG_OBSOLETEFLAGS;
424       kindVersion = RPMTAG_OBSOLETEVERSION;
425       break;
426     case RPMTAG_CONFLICTNAME:
427       kindFlags   = RPMTAG_CONFLICTFLAGS;
428       kindVersion = RPMTAG_CONFLICTVERSION;
429       break;
430 #ifdef RPMTAG_OLDSUGGESTS
431     case RPMTAG_OLDENHANCESNAME:
432       kindFlags   = RPMTAG_OLDENHANCESFLAGS;
433       kindVersion = RPMTAG_OLDENHANCESVERSION;
434       break;
435     case RPMTAG_OLDSUGGESTSNAME:
436       kindFlags   = RPMTAG_OLDSUGGESTSFLAGS;
437       kindVersion = RPMTAG_OLDSUGGESTSVERSION;
438       break;
439     case RPMTAG_RECOMMENDNAME:
440       kindFlags   = RPMTAG_RECOMMENDFLAGS;
441       kindVersion = RPMTAG_RECOMMENDVERSION;
442       break;
443     case RPMTAG_SUPPLEMENTNAME:
444       kindFlags   = RPMTAG_SUPPLEMENTFLAGS;
445       kindVersion = RPMTAG_SUPPLEMENTVERSION;
446       break;
447     case RPMTAG_SUGGESTNAME:
448       kindFlags   = RPMTAG_SUGGESTFLAGS;
449       kindVersion = RPMTAG_SUGGESTVERSION;
450       break;
451     case RPMTAG_ENHANCENAME:
452       kindFlags   = RPMTAG_ENHANCEFLAGS;
453       kindVersion = RPMTAG_ENHANCEVERSION;
454       break;
455 #else
456     case RPMTAG_ENHANCESNAME:
457       kindFlags   = RPMTAG_ENHANCESFLAGS;
458       kindVersion = RPMTAG_ENHANCESVERSION;
459       break;
460     case RPMTAG_SUGGESTSNAME:
461       kindFlags   = RPMTAG_SUGGESTSFLAGS;
462       kindVersion = RPMTAG_SUGGESTSVERSION;
463       break;
464 #endif
465     default:
466       INT << "Illegal RPMTAG_dependencyNAME " << tag_r << endl;
467       return ret;
468       break;
469     }
470
471     stringList names;
472     unsigned count = string_list( tag_r, names );
473     if ( !count )
474       return ret;
475
476     intList  flags;
477     int_list( kindFlags, flags );
478
479     stringList versions;
480     string_list( kindVersion, versions );
481
482     for ( unsigned i = 0; i < count; ++i )
483     {
484
485       std::string n( names[i] );
486
487       Rel op = Rel::ANY;
488       int32_t f = flags[i];
489       std::string v = versions[i];
490
491       if ( n[0] == '/' )
492       {
493         if ( freq_r )
494         {
495           freq_r->insert( n );
496         }
497       }
498       else
499       {
500         if ( v.size() )
501         {
502           switch ( f & RPMSENSE_SENSEMASK )
503           {
504           case RPMSENSE_LESS:
505             op = Rel::LT;
506             break;
507           case RPMSENSE_LESS|RPMSENSE_EQUAL:
508             op = Rel::LE;
509             break;
510           case RPMSENSE_GREATER:
511             op = Rel::GT;
512             break;
513           case RPMSENSE_GREATER|RPMSENSE_EQUAL:
514             op = Rel::GE;
515             break;
516           case RPMSENSE_EQUAL:
517             op = Rel::EQ;
518             break;
519           }
520         }
521       }
522       if ((pre && (f & RPMSENSE_PREREQ))
523           || ((! pre) && !(f & RPMSENSE_PREREQ)))
524       {
525         try
526         {
527           ret.insert( Capability( n, op, Edition(v) ) );
528         }
529         catch (Exception & excpt_r)
530         {
531           ZYPP_CAUGHT(excpt_r);
532           WAR << "Invalid capability: " << n << " " << op << " "
533           << v << endl;
534         }
535       }
536     }
537
538     return ret;
539   }
540
541 ///////////////////////////////////////////////////////////////////
542 //
543 //
544 //        METHOD NAME : RpmHeader::tag_provides
545 //        METHOD TYPE : CapabilitySet
546 //
547 //        DESCRIPTION :
548 //
549 CapabilitySet RpmHeader::tag_provides( std::set<std::string> * freq_r ) const
550   {
551     return PkgRelList_val( RPMTAG_PROVIDENAME, false, freq_r );
552   }
553
554 ///////////////////////////////////////////////////////////////////
555 //
556 //
557 //        METHOD NAME : RpmHeader::tag_requires
558 //        METHOD TYPE : CapabilitySet
559 //
560 //        DESCRIPTION :
561 //
562 CapabilitySet RpmHeader::tag_requires( std::set<std::string> * freq_r ) const
563   {
564     return PkgRelList_val( RPMTAG_REQUIRENAME, false, freq_r );
565   }
566
567 ///////////////////////////////////////////////////////////////////
568 //
569 //
570 //        METHOD NAME : RpmHeader::tag_requires
571 //        METHOD TYPE : CapabilitySet
572 //
573 //        DESCRIPTION :
574 //
575 CapabilitySet RpmHeader::tag_prerequires( std::set<std::string> * freq_r ) const
576   {
577     return PkgRelList_val( RPMTAG_REQUIRENAME, true, freq_r );
578   }
579
580 ///////////////////////////////////////////////////////////////////
581 //
582 //
583 //        METHOD NAME : RpmHeader::tag_conflicts
584 //        METHOD TYPE : CapabilitySet
585 //
586 //        DESCRIPTION :
587 //
588 CapabilitySet RpmHeader::tag_conflicts( std::set<std::string> * freq_r ) const
589   {
590     return PkgRelList_val( RPMTAG_CONFLICTNAME, false, freq_r );
591   }
592
593 ///////////////////////////////////////////////////////////////////
594 //
595 //
596 //        METHOD NAME : RpmHeader::tag_obsoletes
597 //        METHOD TYPE : CapabilitySet
598 //
599 //        DESCRIPTION :
600 //
601 CapabilitySet RpmHeader::tag_obsoletes( std::set<std::string> * freq_r ) const
602   {
603     return PkgRelList_val( RPMTAG_OBSOLETENAME, false, freq_r );
604   }
605
606 ///////////////////////////////////////////////////////////////////
607 //
608 //
609 //        METHOD NAME : RpmHeader::tag_enhances
610 //        METHOD TYPE : CapabilitySet
611 //
612 //        DESCRIPTION :
613 //
614 CapabilitySet RpmHeader::tag_enhances( std::set<std::string> * freq_r ) const
615   {
616 #ifdef RPMTAG_OLDSUGGESTS
617     return PkgRelList_val( RPMTAG_ENHANCENAME, false, freq_r );
618 #else
619     return PkgRelList_val( RPMTAG_ENHANCESNAME, false, freq_r );
620 #endif
621   }
622
623 ///////////////////////////////////////////////////////////////////
624 //
625 //
626 //        METHOD NAME : RpmHeader::tag_suggests
627 //        METHOD TYPE : CapabilitySet
628 //
629 //        DESCRIPTION :
630 //
631 CapabilitySet RpmHeader::tag_suggests( std::set<std::string> * freq_r ) const
632   {
633 #ifdef RPMTAG_OLDSUGGESTS
634     return PkgRelList_val( RPMTAG_SUGGESTNAME, false, freq_r );
635 #else
636     return PkgRelList_val( RPMTAG_SUGGESTSNAME, false, freq_r );
637 #endif
638   }
639
640 ///////////////////////////////////////////////////////////////////
641 //
642 //
643 //        METHOD NAME : RpmHeader::tag_supplements
644 //        METHOD TYPE : CapabilitySet
645 //
646 //        DESCRIPTION :
647 //
648 CapabilitySet RpmHeader::tag_supplements( std::set<std::string> * freq_r ) const
649   {
650 #ifdef RPMTAG_OLDSUGGESTS
651     return PkgRelList_val( RPMTAG_SUPPLEMENTNAME, false, freq_r );
652 #else
653     return CapabilitySet();
654 #endif
655   }
656
657 ///////////////////////////////////////////////////////////////////
658 //
659 //
660 //        METHOD NAME : RpmHeader::tag_recommends
661 //        METHOD TYPE : CapabilitySet
662 //
663 //        DESCRIPTION :
664 //
665 CapabilitySet RpmHeader::tag_recommends( std::set<std::string> * freq_r ) const
666   {
667 #ifdef RPMTAG_OLDSUGGESTS
668     return PkgRelList_val( RPMTAG_RECOMMENDNAME, false, freq_r );
669 #else
670     return CapabilitySet();
671 #endif
672   }
673
674 ///////////////////////////////////////////////////////////////////
675 //
676 //
677 //        METHOD NAME : RpmHeader::tag_size
678 //        METHOD TYPE : ByteCount
679 //
680 //        DESCRIPTION :
681 //
682 ByteCount RpmHeader::tag_size() const
683 {
684   return int_val( RPMTAG_SIZE );
685 }
686
687 ///////////////////////////////////////////////////////////////////
688 //
689 //
690 //        METHOD NAME : RpmHeader::tag_archivesize
691 //        METHOD TYPE : ByteCount
692 //
693 //        DESCRIPTION :
694 //
695 ByteCount RpmHeader::tag_archivesize() const
696 {
697   return int_val( RPMTAG_ARCHIVESIZE );
698 }
699
700 ///////////////////////////////////////////////////////////////////
701 //
702 //
703 //        METHOD NAME : RpmHeader::tag_summary
704 //        METHOD TYPE : std::string
705 //
706 //        DESCRIPTION :
707 //
708 std::string RpmHeader::tag_summary() const
709 {
710   return string_val( RPMTAG_SUMMARY );
711 }
712
713 ///////////////////////////////////////////////////////////////////
714 //
715 //
716 //        METHOD NAME : RpmHeader::tag_description
717 //        METHOD TYPE : std::string
718 //
719 //        DESCRIPTION :
720 //
721 std::string RpmHeader::tag_description() const
722 {
723   return string_val( RPMTAG_DESCRIPTION );
724 }
725
726 ///////////////////////////////////////////////////////////////////
727 //
728 //
729 //        METHOD NAME : RpmHeader::tag_group
730 //        METHOD TYPE : std::string
731 //
732 //        DESCRIPTION :
733 //
734 std::string RpmHeader::tag_group() const
735 {
736   return string_val( RPMTAG_GROUP );
737 }
738
739 ///////////////////////////////////////////////////////////////////
740 //
741 //
742 //        METHOD NAME : RpmHeader::tag_vendor
743 //        METHOD TYPE : std::string
744 //
745 //        DESCRIPTION :
746 //
747 std::string RpmHeader::tag_vendor() const
748 {
749   return string_val( RPMTAG_VENDOR );
750 }
751
752 ///////////////////////////////////////////////////////////////////
753 //
754 //
755 //        METHOD NAME : RpmHeader::tag_distribution
756 //        METHOD TYPE : std::string
757 //
758 //        DESCRIPTION :
759 //
760 std::string RpmHeader::tag_distribution() const
761 {
762   return string_val( RPMTAG_DISTRIBUTION );
763 }
764
765 ///////////////////////////////////////////////////////////////////
766 //
767 //
768 //        METHOD NAME : RpmHeader::tag_license
769 //        METHOD TYPE : std::string
770 //
771 //        DESCRIPTION :
772 //
773 std::string RpmHeader::tag_license() const
774 {
775   return string_val( RPMTAG_LICENSE );
776 }
777
778 ///////////////////////////////////////////////////////////////////
779 //
780 //
781 //        METHOD NAME : RpmHeader::tag_buildhost
782 //        METHOD TYPE : std::string
783 //
784 //        DESCRIPTION :
785 //
786 std::string RpmHeader::tag_buildhost() const
787 {
788   return string_val( RPMTAG_BUILDHOST );
789 }
790
791 ///////////////////////////////////////////////////////////////////
792 //
793 //
794 //        METHOD NAME : RpmHeader::tag_packager
795 //        METHOD TYPE : std::string
796 //
797 //        DESCRIPTION :
798 //
799 std::string RpmHeader::tag_packager() const
800 {
801   return string_val( RPMTAG_PACKAGER );
802 }
803
804 ///////////////////////////////////////////////////////////////////
805 //
806 //
807 //        METHOD NAME : RpmHeader::tag_url
808 //        METHOD TYPE : std::string
809 //
810 //        DESCRIPTION :
811 //
812 std::string RpmHeader::tag_url() const
813 {
814   return string_val( RPMTAG_URL );
815 }
816
817 ///////////////////////////////////////////////////////////////////
818 //
819 //
820 //        METHOD NAME : RpmHeader::tag_os
821 //        METHOD TYPE : std::string
822 //
823 //        DESCRIPTION :
824 //
825 std::string RpmHeader::tag_os() const
826 {
827   return string_val( RPMTAG_OS );
828
829 }
830
831 std::string RpmHeader::tag_prein() const
832 { return string_val( RPMTAG_PREIN ); }
833
834 std::string RpmHeader::tag_preinprog() const
835 { return string_val( RPMTAG_PREINPROG ); }
836
837 std::string RpmHeader::tag_postin() const
838 { return string_val( RPMTAG_POSTIN ); }
839
840 std::string RpmHeader::tag_postinprog() const
841 { return string_val( RPMTAG_POSTINPROG ); }
842
843 std::string RpmHeader::tag_preun() const
844 { return string_val( RPMTAG_PREUN ); }
845
846 std::string RpmHeader::tag_preunprog() const
847 { return string_val( RPMTAG_PREUNPROG ); }
848
849 std::string RpmHeader::tag_postun() const
850 { return string_val( RPMTAG_POSTUN ); }
851
852 std::string RpmHeader::tag_postunprog() const
853 { return string_val( RPMTAG_POSTUNPROG ); }
854
855 std::string RpmHeader::tag_pretrans() const
856 { return string_val( RPMTAG_PRETRANS ); }
857
858 std::string RpmHeader::tag_pretransprog() const
859 { return string_val( RPMTAG_PRETRANSPROG ); }
860
861 std::string RpmHeader::tag_posttrans() const
862 { return string_val( RPMTAG_POSTTRANS ); }
863
864 std::string RpmHeader::tag_posttransprog() const
865 { return string_val( RPMTAG_POSTTRANSPROG ); }
866
867 ///////////////////////////////////////////////////////////////////
868 //
869 //
870 //        METHOD NAME : RpmHeader::tag_sourcerpm
871 //        METHOD TYPE : std::string
872 //
873 //        DESCRIPTION :
874 //
875 std::string RpmHeader::tag_sourcerpm() const
876 {
877   return string_val( RPMTAG_SOURCERPM );
878 }
879
880 ///////////////////////////////////////////////////////////////////
881 //
882 //
883 //        METHOD NAME : RpmHeader::tag_filenames
884 //        METHOD TYPE : std::list<std::string>
885 //
886 //        DESCRIPTION :
887 //
888 std::list<std::string> RpmHeader::tag_filenames() const
889 {
890   std::list<std::string> ret;
891
892   stringList basenames;
893   if ( string_list( RPMTAG_BASENAMES, basenames ) )
894   {
895     stringList dirnames;
896     string_list( RPMTAG_DIRNAMES, dirnames );
897     intList  dirindexes;
898     int_list( RPMTAG_DIRINDEXES, dirindexes );
899     for ( unsigned i = 0; i < basenames.size(); ++ i )
900     {
901       ret.push_back( dirnames[dirindexes[i]] + basenames[i] );
902     }
903   }
904
905   return ret;
906 }
907
908 ///////////////////////////////////////////////////////////////////
909 //
910 //
911 //        METHOD NAME : RpmHeader::tag_fileinfos
912 //        METHOD TYPE : std::list<FileInfo>
913 //
914 //        DESCRIPTION :
915 //
916 std::list<FileInfo> RpmHeader::tag_fileinfos() const
917 {
918   std::list<FileInfo> ret;
919
920   stringList basenames;
921   if ( string_list( RPMTAG_BASENAMES, basenames ) )
922   {
923     stringList dirnames;
924     string_list( RPMTAG_DIRNAMES, dirnames );
925     intList  dirindexes;
926     int_list( RPMTAG_DIRINDEXES, dirindexes );
927     intList filesizes;
928     int_list( RPMTAG_FILESIZES, filesizes );
929     stringList md5sums;
930     string_list( RPMTAG_FILEMD5S, md5sums );
931     stringList usernames;
932     string_list( RPMTAG_FILEUSERNAME, usernames );
933     stringList groupnames;
934     string_list( RPMTAG_FILEGROUPNAME, groupnames );
935     intList uids;
936     int_list( RPMTAG_FILEUIDS, uids );
937     intList gids;
938     int_list( RPMTAG_FILEGIDS, gids );
939     intList filemodes;
940     int_list( RPMTAG_FILEMODES, filemodes );
941     intList filemtimes;
942     int_list( RPMTAG_FILEMTIMES, filemtimes );
943     intList fileflags;
944     int_list( RPMTAG_FILEFLAGS, fileflags );
945     stringList filelinks;
946     string_list( RPMTAG_FILELINKTOS, filelinks );
947
948     for ( unsigned i = 0; i < basenames.size(); ++ i )
949     {
950       uid_t uid;
951       if (uids.empty())
952       {
953         uid = unameToUid( usernames[i].c_str(), &uid );
954       }
955       else
956       {
957         uid =uids[i];
958       }
959
960       gid_t gid;
961       if (gids.empty())
962       {
963         gid = gnameToGid( groupnames[i].c_str(), &gid );
964       }
965       else
966       {
967         gid = gids[i];
968       }
969
970       FileInfo info = {
971                         dirnames[dirindexes[i]] + basenames[i],
972                         filesizes[i],
973                         md5sums[i],
974                         uid,
975                         gid,
976                         mode_t(filemodes[i]),
977                         filemtimes[i],
978                         bool(fileflags[i] & RPMFILE_GHOST),
979                         filelinks[i]
980                       };
981
982       ret.push_back( info );
983     }
984   }
985
986   return ret;
987 }
988
989 ///////////////////////////////////////////////////////////////////
990 //
991 //
992 //        METHOD NAME : RpmHeader::tag_changelog
993 //        METHOD TYPE : Changelog
994 //
995 //        DESCRIPTION :
996 //
997 Changelog RpmHeader::tag_changelog() const
998 {
999   Changelog ret;
1000
1001   intList times;
1002   if ( int_list( RPMTAG_CHANGELOGTIME, times ) )
1003   {
1004     stringList names;
1005     string_list( RPMTAG_CHANGELOGNAME, names );
1006     stringList texts;
1007     string_list( RPMTAG_CHANGELOGTEXT, texts );
1008     for ( unsigned i = 0; i < times.size(); ++ i )
1009     {
1010       ret.push_back( ChangelogEntry( times[i], names[i], texts[i] ) );
1011     }
1012   }
1013
1014   return ret;
1015 }
1016
1017 } // namespace rpm
1018 } // namespace target
1019 } // namespace zypp