private-show.cc 6.1 KB

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