private-show.cc 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // Includes /*{{{*/
  2. #include <apt-pkg/error.h>
  3. #include <apt-pkg/cachefile.h>
  4. #include <apt-pkg/cachefilter.h>
  5. #include <apt-pkg/cacheset.h>
  6. #include <apt-pkg/init.h>
  7. #include <apt-pkg/progress.h>
  8. #include <apt-pkg/sourcelist.h>
  9. #include <apt-pkg/cmndline.h>
  10. #include <apt-pkg/strutl.h>
  11. #include <apt-pkg/fileutl.h>
  12. #include <apt-pkg/pkgrecords.h>
  13. #include <apt-pkg/srcrecords.h>
  14. #include <apt-pkg/version.h>
  15. #include <apt-pkg/policy.h>
  16. #include <apt-pkg/tagfile.h>
  17. #include <apt-pkg/algorithms.h>
  18. #include <apt-pkg/sptr.h>
  19. #include <apt-pkg/pkgsystem.h>
  20. #include <apt-pkg/indexfile.h>
  21. #include <apt-pkg/metaindex.h>
  22. #include <apti18n.h>
  23. #include "private-output.h"
  24. #include "private-cacheset.h"
  25. /*}}}*/
  26. namespace APT {
  27. namespace Cmd {
  28. // DisplayRecord - Displays the complete record for the package /*{{{*/
  29. // ---------------------------------------------------------------------
  30. bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V,
  31. ostream &out)
  32. {
  33. pkgCache *Cache = CacheFile.GetPkgCache();
  34. if (unlikely(Cache == NULL))
  35. return false;
  36. // Find an appropriate file
  37. pkgCache::VerFileIterator Vf = V.FileList();
  38. for (; Vf.end() == false; ++Vf)
  39. if ((Vf.File()->Flags & pkgCache::Flag::NotSource) == 0)
  40. break;
  41. if (Vf.end() == true)
  42. Vf = V.FileList();
  43. // Check and load the package list file
  44. pkgCache::PkgFileIterator I = Vf.File();
  45. if (I.IsOk() == false)
  46. return _error->Error(_("Package file %s is out of sync."),I.FileName());
  47. // Read the record
  48. FileFd PkgF;
  49. if (PkgF.Open(I.FileName(), FileFd::ReadOnly, FileFd::Extension) == false)
  50. return false;
  51. pkgTagSection Tags;
  52. pkgTagFile TagF(&PkgF);
  53. if (TagF.Jump(Tags, V.FileList()->Offset) == false)
  54. return _error->Error("Internal Error, Unable to parse a package record");
  55. // make size nice
  56. std::string installed_size;
  57. if (Tags.FindI("Installed-Size") > 0)
  58. installed_size = SizeToStr(Tags.FindI("Installed-Size")*1024);
  59. else
  60. installed_size = _("unknown");
  61. std::string package_size;
  62. if (Tags.FindI("Size") > 0)
  63. package_size = SizeToStr(Tags.FindI("Size"));
  64. else
  65. package_size = _("unknown");
  66. TFRewriteData RW[] = {
  67. {"Conffiles",0},
  68. {"Description",0},
  69. {"Description-md5",0},
  70. {"Installed-Size", installed_size.c_str(), 0},
  71. {"Size", package_size.c_str(), "Download-Size"},
  72. {}
  73. };
  74. if(TFRewrite(stdout, Tags, NULL, RW) == false)
  75. return _error->Error("Internal Error, Unable to parse a package record");
  76. // write the description
  77. pkgRecords Recs(*Cache);
  78. // FIXME: show (optionally) all available translations(?)
  79. pkgCache::DescIterator Desc = V.TranslatedDescription();
  80. if (Desc.end() == false)
  81. {
  82. pkgRecords::Parser &P = Recs.Lookup(Desc.FileList());
  83. out << "Description: " << P.LongDesc();
  84. }
  85. // write a final newline (after the description)
  86. out << std::endl << std::endl;
  87. return true;
  88. }
  89. /*}}}*/
  90. bool ShowPackage(CommandLine &CmdL) /*{{{*/
  91. {
  92. pkgCacheFile CacheFile;
  93. CacheSetHelperVirtuals helper(true, GlobalError::NOTICE);
  94. APT::VersionList::Version const select = _config->FindB("APT::Cache::AllVersions", false) ?
  95. APT::VersionList::ALL : APT::VersionList::CANDIDATE;
  96. APT::VersionList const verset = APT::VersionList::FromCommandLine(CacheFile, CmdL.FileList + 1, select, helper);
  97. for (APT::VersionList::const_iterator Ver = verset.begin(); Ver != verset.end(); ++Ver)
  98. if (DisplayRecord(CacheFile, Ver, c1out) == false)
  99. return false;
  100. if (select == APT::VersionList::CANDIDATE)
  101. {
  102. APT::VersionList const verset_all = APT::VersionList::FromCommandLine(CacheFile, CmdL.FileList + 1, APT::VersionList::ALL, helper);
  103. if (verset_all.size() > verset.size())
  104. _error->Notice(ngettext("There is %lu additional record. Please use the '-a' switch to see it", "There are %lu additional records. Please use the '-a' switch to see them.", verset_all.size() - verset.size()), verset_all.size() - verset.size());
  105. }
  106. for (APT::PackageSet::const_iterator Pkg = helper.virtualPkgs.begin();
  107. Pkg != helper.virtualPkgs.end(); ++Pkg)
  108. {
  109. c1out << "Package: " << Pkg.FullName(true) << std::endl;
  110. c1out << "State: " << _("not a real package (virtual)") << std::endl;
  111. // FIXME: show providers, see private-cacheset.h
  112. // CacheSetHelperAPTGet::showVirtualPackageErrors()
  113. }
  114. if (verset.empty() == true)
  115. {
  116. if (helper.virtualPkgs.empty() == true)
  117. return _error->Error(_("No packages found"));
  118. else
  119. _error->Notice(_("No packages found"));
  120. }
  121. return true;
  122. }
  123. /*}}}*/
  124. } // namespace Cmd
  125. } // namespace APT