private-show.cc 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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. pkgDepCache *depCache = CacheFile.GetDepCache();
  37. if (unlikely(depCache == NULL))
  38. return false;
  39. // Find an appropriate file
  40. pkgCache::VerFileIterator Vf = V.FileList();
  41. for (; Vf.end() == false; ++Vf)
  42. if ((Vf.File()->Flags & pkgCache::Flag::NotSource) == 0)
  43. break;
  44. if (Vf.end() == true)
  45. Vf = V.FileList();
  46. // Check and load the package list file
  47. pkgCache::PkgFileIterator I = Vf.File();
  48. if (I.IsOk() == false)
  49. return _error->Error(_("Package file %s is out of sync."),I.FileName());
  50. // find matching sources.list metaindex
  51. pkgSourceList *SrcList = CacheFile.GetSourceList();
  52. pkgIndexFile *Index;
  53. if (SrcList->FindIndex(I, Index) == false &&
  54. _system->FindIndex(I, Index) == false)
  55. return _error->Error("Can not find indexfile for Package %s (%s)",
  56. V.ParentPkg().Name(), V.VerStr());
  57. std::string source_index_file = Index->Describe(true);
  58. // Read the record
  59. FileFd PkgF;
  60. if (PkgF.Open(I.FileName(), FileFd::ReadOnly, FileFd::Extension) == false)
  61. return false;
  62. pkgTagSection Tags;
  63. pkgTagFile TagF(&PkgF);
  64. if (TagF.Jump(Tags, V.FileList()->Offset) == false)
  65. return _error->Error("Internal Error, Unable to parse a package record");
  66. // make size nice
  67. std::string installed_size;
  68. if (Tags.FindI("Installed-Size") > 0)
  69. strprintf(installed_size, "%sB", SizeToStr(Tags.FindI("Installed-Size")*1024).c_str());
  70. else
  71. installed_size = _("unknown");
  72. std::string package_size;
  73. if (Tags.FindI("Size") > 0)
  74. strprintf(package_size, "%sB", SizeToStr(Tags.FindI("Size")).c_str());
  75. else
  76. package_size = _("unknown");
  77. pkgDepCache::StateCache &state = (*depCache)[V.ParentPkg()];
  78. bool is_installed = V.ParentPkg().CurrentVer() == V;
  79. const char *manual_installed;
  80. if (is_installed)
  81. manual_installed = !(state.Flags & pkgCache::Flag::Auto) ? "yes" : "no";
  82. else
  83. manual_installed = 0;
  84. // FIXME: add verbose that does not do the removal of the tags?
  85. TFRewriteData RW[] = {
  86. // delete, apt-cache show has this info and most users do not care
  87. {"MD5sum", 0},
  88. {"SHA1", 0},
  89. {"SHA256", 0},
  90. {"Filename", 0},
  91. {"Multi-Arch", 0},
  92. {"Architecture", 0},
  93. {"Conffiles",0},
  94. // we use the translated description
  95. {"Description",0},
  96. {"Description-md5",0},
  97. // improve
  98. {"Installed-Size", installed_size.c_str(), 0},
  99. {"Size", package_size.c_str(), "Download-Size"},
  100. // add
  101. {"APT-Manual-Installed", manual_installed, 0},
  102. {"APT-Sources", source_index_file.c_str(), 0},
  103. {}
  104. };
  105. if(TFRewrite(stdout, Tags, NULL, RW) == false)
  106. return _error->Error("Internal Error, Unable to parse a package record");
  107. // write the description
  108. pkgRecords Recs(*Cache);
  109. // FIXME: show (optionally) all available translations(?)
  110. pkgCache::DescIterator Desc = V.TranslatedDescription();
  111. if (Desc.end() == false)
  112. {
  113. pkgRecords::Parser &P = Recs.Lookup(Desc.FileList());
  114. out << "Description: " << P.LongDesc();
  115. }
  116. // write a final newline (after the description)
  117. out << std::endl << std::endl;
  118. return true;
  119. }
  120. /*}}}*/
  121. bool ShowPackage(CommandLine &CmdL) /*{{{*/
  122. {
  123. pkgCacheFile CacheFile;
  124. CacheSetHelperVirtuals helper(true, GlobalError::NOTICE);
  125. APT::VersionList::Version const select = _config->FindB("APT::Cache::AllVersions", false) ?
  126. APT::VersionList::ALL : APT::VersionList::CANDIDATE;
  127. APT::VersionList const verset = APT::VersionList::FromCommandLine(CacheFile, CmdL.FileList + 1, select, helper);
  128. for (APT::VersionList::const_iterator Ver = verset.begin(); Ver != verset.end(); ++Ver)
  129. if (DisplayRecord(CacheFile, Ver, c1out) == false)
  130. return false;
  131. if (select == APT::VersionList::CANDIDATE)
  132. {
  133. APT::VersionList const verset_all = APT::VersionList::FromCommandLine(CacheFile, CmdL.FileList + 1, APT::VersionList::ALL, helper);
  134. if (verset_all.size() > verset.size())
  135. _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());
  136. }
  137. for (APT::PackageSet::const_iterator Pkg = helper.virtualPkgs.begin();
  138. Pkg != helper.virtualPkgs.end(); ++Pkg)
  139. {
  140. c1out << "Package: " << Pkg.FullName(true) << std::endl;
  141. c1out << "State: " << _("not a real package (virtual)") << std::endl;
  142. // FIXME: show providers, see private-cacheset.h
  143. // CacheSetHelperAPTGet::showVirtualPackageErrors()
  144. }
  145. if (verset.empty() == true)
  146. {
  147. if (helper.virtualPkgs.empty() == true)
  148. return _error->Error(_("No packages found"));
  149. else
  150. _error->Notice(_("No packages found"));
  151. }
  152. return true;
  153. }
  154. /*}}}*/
  155. } // namespace Cmd
  156. } // namespace APT