libzypp  13.10.6
RpmHeader.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include "librpm.h"
13 #ifdef _RPM_4_4
14 #include <rpm/ugid.h>
15 #else
16 // 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 }
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 
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 
171 
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 
185 //
186 //
187 // METHOD NAME : RpmHeader::RpmHeader
188 // METHOD TYPE : Constructor
189 //
191  : BinHeader( rhs )
192 {}
193 
195 //
196 //
197 // METHOD NAME : RpmHeader::~RpmHeader
198 // METHOD TYPE : Destructor
199 //
200 // DESCRIPTION :
201 //
203 {}
204 
206 //
207 //
208 // METHOD NAME : RpmHeader::readPackage
209 // METHOD TYPE : constRpmHeaderPtr
210 //
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 
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 
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 
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 
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 
307 //
308 //
309 // METHOD NAME : RpmHeader::tag_epoch
310 // METHOD TYPE : Edition::epoch_t
311 //
312 // DESCRIPTION :
313 //
315 {
316  return int_val ( RPMTAG_EPOCH );
317 }
318 
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 
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 
346 //
347 //
348 // METHOD NAME : RpmHeader::tag_edition
349 // METHOD TYPE : Edition
350 //
351 // DESCRIPTION :
352 //
354 {
355  return Edition( tag_version(), tag_release(), tag_epoch() );
356 }
357 
359 //
360 //
361 // METHOD NAME : RpmHeader::tag_arch
362 // METHOD TYPE : Arch
363 //
364 // DESCRIPTION :
365 //
367 {
368  return Arch( string_val( RPMTAG_ARCH ) );
369 }
370 
372 //
373 //
374 // METHOD NAME : RpmHeader::tag_installtime
375 // METHOD TYPE : Date
376 //
377 // DESCRIPTION :
378 //
380 {
381  return int_val( RPMTAG_INSTALLTIME );
382 }
383 
385 //
386 //
387 // METHOD NAME : RpmHeader::tag_buildtime
388 // METHOD TYPE : Date
389 //
390 // DESCRIPTION :
391 //
393 {
394  return int_val( RPMTAG_BUILDTIME );
395 }
396 #warning CHECK IF FILE REQUIRES HANDLING IS OBSOLETE
397 //
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  case RPMTAG_ENHANCESNAME:
431  kindFlags = RPMTAG_ENHANCESFLAGS;
432  kindVersion = RPMTAG_ENHANCESVERSION;
433  break;
434  case RPMTAG_SUGGESTSNAME:
435  kindFlags = RPMTAG_SUGGESTSFLAGS;
436  kindVersion = RPMTAG_SUGGESTSVERSION;
437  break;
438  default:
439  INT << "Illegal RPMTAG_dependencyNAME " << tag_r << endl;
440  return ret;
441  break;
442  }
443 
444  stringList names;
445  unsigned count = string_list( tag_r, names );
446  if ( !count )
447  return ret;
448 
449  intList flags;
450  int_list( kindFlags, flags );
451 
452  stringList versions;
453  string_list( kindVersion, versions );
454 
455  for ( unsigned i = 0; i < count; ++i )
456  {
457 
458  std::string n( names[i] );
459 
460  Rel op = Rel::ANY;
461  int32_t f = flags[i];
462  std::string v = versions[i];
463 
464  if ( n[0] == '/' )
465  {
466  if ( freq_r )
467  {
468  freq_r->insert( n );
469  }
470  }
471  else
472  {
473  if ( v.size() )
474  {
475  switch ( f & RPMSENSE_SENSEMASK )
476  {
477  case RPMSENSE_LESS:
478  op = Rel::LT;
479  break;
480  case RPMSENSE_LESS|RPMSENSE_EQUAL:
481  op = Rel::LE;
482  break;
483  case RPMSENSE_GREATER:
484  op = Rel::GT;
485  break;
486  case RPMSENSE_GREATER|RPMSENSE_EQUAL:
487  op = Rel::GE;
488  break;
489  case RPMSENSE_EQUAL:
490  op = Rel::EQ;
491  break;
492  }
493  }
494  }
495  if ((pre && (f & RPMSENSE_PREREQ))
496  || ((! pre) && !(f & RPMSENSE_PREREQ)))
497  {
498  try
499  {
500  ret.insert( Capability( n, op, Edition(v) ) );
501  }
502  catch (Exception & excpt_r)
503  {
504  ZYPP_CAUGHT(excpt_r);
505  WAR << "Invalid capability: " << n << " " << op << " "
506  << v << endl;
507  }
508  }
509  }
510 
511  return ret;
512  }
513 
515 //
516 //
517 // METHOD NAME : RpmHeader::tag_provides
518 // METHOD TYPE : CapabilitySet
519 //
520 // DESCRIPTION :
521 //
522 CapabilitySet RpmHeader::tag_provides( std::set<std::string> * freq_r ) const
523  {
524  return PkgRelList_val( RPMTAG_PROVIDENAME, false, freq_r );
525  }
526 
528 //
529 //
530 // METHOD NAME : RpmHeader::tag_requires
531 // METHOD TYPE : CapabilitySet
532 //
533 // DESCRIPTION :
534 //
535 CapabilitySet RpmHeader::tag_requires( std::set<std::string> * freq_r ) const
536  {
537  return PkgRelList_val( RPMTAG_REQUIRENAME, false, freq_r );
538  }
539 
541 //
542 //
543 // METHOD NAME : RpmHeader::tag_requires
544 // METHOD TYPE : CapabilitySet
545 //
546 // DESCRIPTION :
547 //
548 CapabilitySet RpmHeader::tag_prerequires( std::set<std::string> * freq_r ) const
549  {
550  return PkgRelList_val( RPMTAG_REQUIRENAME, true, freq_r );
551  }
552 
554 //
555 //
556 // METHOD NAME : RpmHeader::tag_conflicts
557 // METHOD TYPE : CapabilitySet
558 //
559 // DESCRIPTION :
560 //
561 CapabilitySet RpmHeader::tag_conflicts( std::set<std::string> * freq_r ) const
562  {
563  return PkgRelList_val( RPMTAG_CONFLICTNAME, false, freq_r );
564  }
565 
567 //
568 //
569 // METHOD NAME : RpmHeader::tag_obsoletes
570 // METHOD TYPE : CapabilitySet
571 //
572 // DESCRIPTION :
573 //
574 CapabilitySet RpmHeader::tag_obsoletes( std::set<std::string> * freq_r ) const
575  {
576  return PkgRelList_val( RPMTAG_OBSOLETENAME, false, freq_r );
577  }
578 
580 //
581 //
582 // METHOD NAME : RpmHeader::tag_enhances
583 // METHOD TYPE : CapabilitySet
584 //
585 // DESCRIPTION :
586 //
587 CapabilitySet RpmHeader::tag_enhances( std::set<std::string> * freq_r ) const
588  {
589  return PkgRelList_val( RPMTAG_ENHANCESNAME, false, freq_r );
590  }
591 
593 //
594 //
595 // METHOD NAME : RpmHeader::tag_suggests
596 // METHOD TYPE : CapabilitySet
597 //
598 // DESCRIPTION :
599 //
600 CapabilitySet RpmHeader::tag_suggests( std::set<std::string> * freq_r ) const
601  {
602  return PkgRelList_val( RPMTAG_SUGGESTSNAME, false, freq_r );
603  }
604 
606 //
607 //
608 // METHOD NAME : RpmHeader::tag_size
609 // METHOD TYPE : ByteCount
610 //
611 // DESCRIPTION :
612 //
614 {
615  return int_val( RPMTAG_SIZE );
616 }
617 
619 //
620 //
621 // METHOD NAME : RpmHeader::tag_archivesize
622 // METHOD TYPE : ByteCount
623 //
624 // DESCRIPTION :
625 //
627 {
628  return int_val( RPMTAG_ARCHIVESIZE );
629 }
630 
632 //
633 //
634 // METHOD NAME : RpmHeader::tag_summary
635 // METHOD TYPE : std::string
636 //
637 // DESCRIPTION :
638 //
639 std::string RpmHeader::tag_summary() const
640 {
641  return string_val( RPMTAG_SUMMARY );
642 }
643 
645 //
646 //
647 // METHOD NAME : RpmHeader::tag_description
648 // METHOD TYPE : std::string
649 //
650 // DESCRIPTION :
651 //
652 std::string RpmHeader::tag_description() const
653 {
654  return string_val( RPMTAG_DESCRIPTION );
655 }
656 
658 //
659 //
660 // METHOD NAME : RpmHeader::tag_group
661 // METHOD TYPE : std::string
662 //
663 // DESCRIPTION :
664 //
665 std::string RpmHeader::tag_group() const
666 {
667  return string_val( RPMTAG_GROUP );
668 }
669 
671 //
672 //
673 // METHOD NAME : RpmHeader::tag_vendor
674 // METHOD TYPE : std::string
675 //
676 // DESCRIPTION :
677 //
678 std::string RpmHeader::tag_vendor() const
679 {
680  return string_val( RPMTAG_VENDOR );
681 }
682 
684 //
685 //
686 // METHOD NAME : RpmHeader::tag_distribution
687 // METHOD TYPE : std::string
688 //
689 // DESCRIPTION :
690 //
691 std::string RpmHeader::tag_distribution() const
692 {
693  return string_val( RPMTAG_DISTRIBUTION );
694 }
695 
697 //
698 //
699 // METHOD NAME : RpmHeader::tag_license
700 // METHOD TYPE : std::string
701 //
702 // DESCRIPTION :
703 //
704 std::string RpmHeader::tag_license() const
705 {
706  return string_val( RPMTAG_LICENSE );
707 }
708 
710 //
711 //
712 // METHOD NAME : RpmHeader::tag_buildhost
713 // METHOD TYPE : std::string
714 //
715 // DESCRIPTION :
716 //
717 std::string RpmHeader::tag_buildhost() const
718 {
719  return string_val( RPMTAG_BUILDHOST );
720 }
721 
723 //
724 //
725 // METHOD NAME : RpmHeader::tag_packager
726 // METHOD TYPE : std::string
727 //
728 // DESCRIPTION :
729 //
730 std::string RpmHeader::tag_packager() const
731 {
732  return string_val( RPMTAG_PACKAGER );
733 }
734 
736 //
737 //
738 // METHOD NAME : RpmHeader::tag_url
739 // METHOD TYPE : std::string
740 //
741 // DESCRIPTION :
742 //
743 std::string RpmHeader::tag_url() const
744 {
745  return string_val( RPMTAG_URL );
746 }
747 
749 //
750 //
751 // METHOD NAME : RpmHeader::tag_os
752 // METHOD TYPE : std::string
753 //
754 // DESCRIPTION :
755 //
756 std::string RpmHeader::tag_os() const
757 {
758  return string_val( RPMTAG_OS );
759 }
760 
762 //
763 //
764 // METHOD NAME : RpmHeader::tag_prein
765 // METHOD TYPE : std::string
766 //
767 // DESCRIPTION :
768 //
769 std::string RpmHeader::tag_prein() const
770 {
771  return string_val( RPMTAG_PREIN );
772 }
773 
775 //
776 //
777 // METHOD NAME : RpmHeader::tag_postin
778 // METHOD TYPE : std::string
779 //
780 // DESCRIPTION :
781 //
782 std::string RpmHeader::tag_postin() const
783 {
784  return string_val( RPMTAG_POSTIN );
785 }
786 
788 //
789 //
790 // METHOD NAME : RpmHeader::tag_preun
791 // METHOD TYPE : std::string
792 //
793 // DESCRIPTION :
794 //
795 std::string RpmHeader::tag_preun() const
796 {
797  return string_val( RPMTAG_PREUN );
798 }
799 
801 //
802 //
803 // METHOD NAME : RpmHeader::tag_postun
804 // METHOD TYPE : std::string
805 //
806 // DESCRIPTION :
807 //
808 std::string RpmHeader::tag_postun() const
809 {
810  return string_val( RPMTAG_POSTUN );
811 }
812 
814 //
815 //
816 // METHOD NAME : RpmHeader::tag_sourcerpm
817 // METHOD TYPE : std::string
818 //
819 // DESCRIPTION :
820 //
821 std::string RpmHeader::tag_sourcerpm() const
822 {
823  return string_val( RPMTAG_SOURCERPM );
824 }
825 
827 //
828 //
829 // METHOD NAME : RpmHeader::tag_filenames
830 // METHOD TYPE : std::list<std::string>
831 //
832 // DESCRIPTION :
833 //
834 std::list<std::string> RpmHeader::tag_filenames() const
835 {
836  std::list<std::string> ret;
837 
838  stringList basenames;
839  if ( string_list( RPMTAG_BASENAMES, basenames ) )
840  {
841  stringList dirnames;
842  string_list( RPMTAG_DIRNAMES, dirnames );
843  intList dirindexes;
844  int_list( RPMTAG_DIRINDEXES, dirindexes );
845  for ( unsigned i = 0; i < basenames.size(); ++ i )
846  {
847  ret.push_back( dirnames[dirindexes[i]] + basenames[i] );
848  }
849  }
850 
851  return ret;
852 }
853 
855 //
856 //
857 // METHOD NAME : RpmHeader::tag_fileinfos
858 // METHOD TYPE : std::list<FileInfo>
859 //
860 // DESCRIPTION :
861 //
862 std::list<FileInfo> RpmHeader::tag_fileinfos() const
863 {
864  std::list<FileInfo> ret;
865 
866  stringList basenames;
867  if ( string_list( RPMTAG_BASENAMES, basenames ) )
868  {
869  stringList dirnames;
870  string_list( RPMTAG_DIRNAMES, dirnames );
871  intList dirindexes;
872  int_list( RPMTAG_DIRINDEXES, dirindexes );
873  intList filesizes;
874  int_list( RPMTAG_FILESIZES, filesizes );
875  stringList md5sums;
876  string_list( RPMTAG_FILEMD5S, md5sums );
877  stringList usernames;
878  string_list( RPMTAG_FILEUSERNAME, usernames );
879  stringList groupnames;
880  string_list( RPMTAG_FILEGROUPNAME, groupnames );
881  intList uids;
882  int_list( RPMTAG_FILEUIDS, uids );
883  intList gids;
884  int_list( RPMTAG_FILEGIDS, gids );
885  intList filemodes;
886  int_list( RPMTAG_FILEMODES, filemodes );
887  intList filemtimes;
888  int_list( RPMTAG_FILEMTIMES, filemtimes );
889  intList fileflags;
890  int_list( RPMTAG_FILEFLAGS, fileflags );
891  stringList filelinks;
892  string_list( RPMTAG_FILELINKTOS, filelinks );
893 
894  for ( unsigned i = 0; i < basenames.size(); ++ i )
895  {
896  uid_t uid;
897  if (uids.empty())
898  {
899  uid = unameToUid( usernames[i].c_str(), &uid );
900  }
901  else
902  {
903  uid =uids[i];
904  }
905 
906  gid_t gid;
907  if (gids.empty())
908  {
909  gid = gnameToGid( groupnames[i].c_str(), &gid );
910  }
911  else
912  {
913  gid = gids[i];
914  }
915 
916  FileInfo info = {
917  dirnames[dirindexes[i]] + basenames[i],
918  filesizes[i],
919  md5sums[i],
920  uid,
921  gid,
922  mode_t(filemodes[i]),
923  filemtimes[i],
924  bool(fileflags[i] & RPMFILE_GHOST),
925  filelinks[i]
926  };
927 
928  ret.push_back( info );
929  }
930  }
931 
932  return ret;
933 }
934 
936 //
937 //
938 // METHOD NAME : RpmHeader::tag_changelog
939 // METHOD TYPE : Changelog
940 //
941 // DESCRIPTION :
942 //
944 {
945  Changelog ret;
946 
947  intList times;
948  if ( int_list( RPMTAG_CHANGELOGTIME, times ) )
949  {
950  stringList names;
951  string_list( RPMTAG_CHANGELOGNAME, names );
952  stringList texts;
953  string_list( RPMTAG_CHANGELOGTEXT, texts );
954  for ( unsigned i = 0; i < times.size(); ++ i )
955  {
956  ret.push_back( ChangelogEntry( times[i], names[i], texts[i] ) );
957  }
958  }
959 
960  return ret;
961 }
962 
964 //
965 //
966 // METHOD NAME : RpmHeader::tag_du
967 // METHOD TYPE : PkgDu &
968 //
969 // DESCRIPTION :
970 //
971 DiskUsage & RpmHeader::tag_du( DiskUsage & dudata_r ) const
972 {
973  dudata_r.clear();
974  stringList basenames;
975  if ( string_list( RPMTAG_BASENAMES, basenames ) )
976  {
977  stringList dirnames;
978  string_list( RPMTAG_DIRNAMES, dirnames );
979  intList dirindexes;
980  int_list( RPMTAG_DIRINDEXES, dirindexes );
981 
982  intList filedevices;
983  int_list( RPMTAG_FILEDEVICES, filedevices );
984  intList fileinodes;
985  int_list( RPMTAG_FILEINODES, fileinodes );
986  intList filesizes;
987  int_list( RPMTAG_FILESIZES, filesizes );
988  intList filemodes;
989  int_list( RPMTAG_FILEMODES, filemodes );
990 
992  // Create and collect Entries by index. devino_cache is used to
993  // filter out hardliks ( different name but same device and inode ).
996  std::vector<DiskUsage::Entry> entries;
997  entries.resize( dirnames.size() );
998  for ( unsigned i = 0; i < dirnames.size(); ++i )
999  {
1000  entries[i] = DiskUsage::Entry( dirnames[i] );
1001 
1002  // cut off deeper directory levels in DiskUsage::Entry
1003  unsigned level = 3; // number of '/' incl. a trailing one
1004  std::string::size_type pos = 0; // we know rpm stores absolute pathnames
1005  while ( --level && pos != std::string::npos )
1006  {
1007  pos = entries[i].path.find( "/", pos+1 );
1008  }
1009  if ( pos != std::string::npos )
1010  {
1011  entries[i].path.erase( pos+1 );
1012  }
1013  }
1014 
1015  for ( unsigned i = 0; i < basenames.size(); ++ i )
1016  {
1017  filesystem::StatMode mode( filemodes[i] );
1018  if ( mode.isFile() )
1019  {
1020  if ( trace.insert( filedevices[i], fileinodes[i] ) )
1021  {
1022  // Count full 1K blocks
1023  entries[dirindexes[i]]._size += ByteCount( filesizes[i] ).blocks( ByteCount::K );
1024  ++(entries[dirindexes[i]]._files);
1025  }
1026  // else: hardlink; already counted this device/inode
1027  }
1028  }
1029 
1031  // Collect all enties. We first unify the duplicate entries that
1032  // were created by cutting off deeper levels. Then the size of each
1033  // directory must also be added to each of it's parent directories.
1035  DiskUsage tmpdata;
1036  for ( unsigned i = 0; i < entries.size(); ++i )
1037  {
1038  if ( entries[i]._size )
1039  tmpdata.add( entries[i] );
1040  }
1041 
1042  for_( it, tmpdata.begin(), tmpdata.end() )
1043  {
1044  DiskUsage::Entry ent( *it );
1045 
1046  do {
1047  dudata_r.add( ent );
1048  if ( ent.path.size() <= 1 ) // "" or "/"
1049  break;
1050 
1051  // set path to parent dir. Note that DiskUsage::Entry
1052  // has leading and trailing '/' on pathnmes.
1053  std::string::size_type rstart = ent.path.size() - 2; // trailing '/' !
1054  std::string::size_type lpos = ent.path.rfind( '/', rstart ); // one but last '/'
1055  if ( lpos == std::string::npos )
1056  break;
1057 
1058  ent.path.erase( lpos + 1 );
1059  } while( true );
1060  }
1061  }
1062  return dudata_r;
1063 }
1064 
1065 } // namespace rpm
1066 } // namespace target
1067 } // namespace zypp
std::string tag_buildhost() const
Definition: RpmHeader.cc:717
std::string tag_license() const
Definition: RpmHeader.cc:704
static const Rel LT
Definition: Rel.h:52
#define MIL
Definition: Logger.h:47
bool has_tag(tag tag_r) const
Definition: BinHeader.cc:229
std::string tag_packager() const
Definition: RpmHeader.cc:730
std::string tag_release() const
Definition: RpmHeader.cc:340
static const Rel GT
Definition: Rel.h:54
intrusive_ptr< const RpmHeader > constPtr
Definition: RpmHeader.h:65
CapabilitySet tag_requires(std::set< std::string > *freq_r=0) const
Definition: RpmHeader.cc:535
ByteCount tag_size() const
Definition: RpmHeader.cc:613
virtual std::ostream & dumpOn(std::ostream &str) const
Overload to realize std::ostream &amp; operator&lt;&lt;.
Definition: BinHeader.cc:410
bool isFile() const
Definition: PathInfo.h:96
DiskUsage & tag_du(DiskUsage &dudata_r) const
Returns reference to arg dudata_r.
Definition: RpmHeader.cc:971
Architecture.
Definition: Arch.h:36
Relational operators.
Definition: Rel.h:43
Store and operate with byte count.
Definition: ByteCount.h:30
static const Rel EQ
Definition: Rel.h:50
VERIFICATION
Digest and signature verification flags.
Definition: RpmHeader.h:179
Single entry in a change log.
Definition: Changelog.h:30
std::list< ChangelogEntry > Changelog
List of ChangelogEntry.
Definition: Changelog.h:53
#define INT
Definition: Logger.h:51
std::string tag_url() const
Definition: RpmHeader.cc:743
CapabilitySet tag_conflicts(std::set< std::string > *freq_r=0) const
Definition: RpmHeader.cc:561
void clear()
Clear EntrySet.
Definition: DiskUsage.h:120
std::string tag_prein() const
Definition: RpmHeader.cc:769
Edition tag_edition() const
Definition: RpmHeader.cc:353
CapabilitySet tag_provides(std::set< std::string > *freq_r=0) const
If freq_r is not NULL, file dependencies found are inserted.
Definition: RpmHeader.cc:522
std::string tag_preun() const
Definition: RpmHeader.cc:795
static const Rel LE
Definition: Rel.h:53
Changelog tag_changelog() const
Definition: RpmHeader.cc:943
intrusive_ptr< BinHeader > Ptr
Definition: BinHeader.h:47
void add(const Entry &newent_r)
Add an entry.
Definition: DiskUsage.h:97
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:27
Edition represents [epoch:]version[-release]
Definition: Edition.h:60
static const Rel ANY
Definition: Rel.h:56
CapabilitySet tag_suggests(std::set< std::string > *freq_r=0) const
Definition: RpmHeader.cc:600
Edition::epoch_t tag_epoch() const
Definition: RpmHeader.cc:314
unsigned epoch_t
Type of an epoch.
Definition: Edition.h:64
std::list< FileInfo > tag_fileinfos() const
complete information about the files (extended version of tag_filenames())
Definition: RpmHeader.cc:862
std::tr1::unordered_set< Capability > CapabilitySet
Definition: Capability.h:33
CapabilitySet tag_enhances(std::set< std::string > *freq_r=0) const
Definition: RpmHeader.cc:587
Holds data about how much space will be needed per directory.
Definition: DiskUsage.h:27
#define ERR
Definition: Logger.h:49
std::string tag_os() const
Definition: RpmHeader.cc:756
iterator begin()
Forward iterator pointing to the first entry (if any)
Definition: DiskUsage.h:135
int int_val(tag tag_r) const
Definition: BinHeader.cc:312
std::string tag_version() const
Definition: RpmHeader.cc:327
std::string tag_postun() const
Definition: RpmHeader.cc:808
std::list< std::string > tag_filenames() const
just the list of names
Definition: RpmHeader.cc:834
Store and operate on date (time_t).
Definition: Date.h:31
std::string tag_group() const
Definition: RpmHeader.cc:665
int unameToUid(const char *thisUname, uid_t *uid)
Definition: RpmHeader.cc:31
Simple cache remembering device/inode to detect hardlinks.
Definition: PathInfo.h:187
std::string tag_description() const
Definition: RpmHeader.cc:652
unsigned string_list(tag tag_r, stringList &lst_r) const
Definition: BinHeader.cc:281
#define WAR
Definition: Logger.h:48
CapabilitySet tag_obsoletes(std::set< std::string > *freq_r=0) const
Definition: RpmHeader.cc:574
static const Rel GE
Definition: Rel.h:55
bool insert(const dev_t &dev_r, const ino_t &ino_r)
Remember dev/ino.
Definition: PathInfo.h:201
virtual std::ostream & dumpOn(std::ostream &str) const
Overload to realize std::ostream &amp; operator&lt;&lt;.
Definition: RpmHeader.cc:267
std::string tag_postin() const
Definition: RpmHeader.cc:782
static RpmHeader::constPtr readPackage(const Pathname &path, VERIFICATION verification=VERIFY)
Get an accessible packages data from disk.
Definition: RpmHeader.cc:211
std::string string_val(tag tag_r) const
Definition: BinHeader.cc:355
SolvableIdType size_type
Definition: PoolMember.h:99
iterator end()
Forward iterator pointing behind the last entry.
Definition: DiskUsage.h:139
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:324
ByteCount tag_archivesize() const
Definition: RpmHeader.cc:626
Wrapper class for mode_t values as derived from ::stat.
Definition: PathInfo.h:80
Base class for Exception.
Definition: Exception.h:143
A sat capability.
Definition: Capability.h:59
std::string tag_vendor() const
Definition: RpmHeader.cc:678
static bool globalInit()
Initialize lib librpm (read configfiles etc.).
Definition: librpmDb.cc:128
static const Unit K
1024 Byte
Definition: ByteCount.h:45
int gnameToGid(const char *thisGname, gid_t *gid)
Definition: RpmHeader.cc:81
Date tag_installtime() const
Definition: RpmHeader.cc:379
std::string tag_distribution() const
Definition: RpmHeader.cc:691
Wrapper class for rpm header struct.
Definition: RpmHeader.h:61
std::string tag_sourcerpm() const
Definition: RpmHeader.cc:821
std::string tag_summary() const
Definition: RpmHeader.cc:639
std::string tag_name() const
Definition: RpmHeader.cc:301
CapabilitySet PkgRelList_val(tag tag_r, bool pre, std::set< std::string > *freq_r=0) const
Definition: RpmHeader.cc:405
SizeType blocks(ByteCount blocksize_r=K) const
Return number of blocks of size blocksize_r (default 1K).
Definition: ByteCount.h:114
unsigned int_list(tag tag_r, intList &lst_r) const
Definition: BinHeader.cc:242
std::string path
Definition: DiskUsage.h:41
CapabilitySet tag_prerequires(std::set< std::string > *freq_r=0) const
Definition: RpmHeader.cc:548