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