+ unsigned long Count = Cache->HeaderP->PackageCount+1;
+ pkgCache::VerFile **VFList = new pkgCache::VerFile *[Count];
+ memset(VFList,0,sizeof(*VFList)*Count);
+
+ // Map versions that we want to write out onto the VerList array.
+ for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
+ {
+ if (P->VersionList == 0)
+ continue;
+
+ /* Find the proper version to use. If the policy says there are no
+ possible selections we return the installed version, if available..
+ This prevents dselect from making it obsolete. */
+ pkgCache::VerIterator V = CacheFile.GetPolicy()->GetCandidateVer(P);
+ if (V.end() == true)
+ {
+ if (P->CurrentVer == 0)
+ continue;
+ V = P.CurrentVer();
+ }
+
+ pkgCache::VerFileIterator VF = V.FileList();
+ for (; VF.end() == false ; ++VF)
+ if ((VF.File()->Flags & pkgCache::Flag::NotSource) == 0)
+ break;
+
+ /* Okay, here we have a bit of a problem.. The policy has selected the
+ currently installed package - however it only exists in the
+ status file.. We need to write out something or dselect will mark
+ the package as obsolete! Thus we emit the status file entry, but
+ below we remove the status line to make it valid for the
+ available file. However! We only do this if their do exist *any*
+ non-source versions of the package - that way the dselect obsolete
+ handling works OK. */
+ if (VF.end() == true)
+ {
+ for (pkgCache::VerIterator Cur = P.VersionList(); Cur.end() != true; ++Cur)
+ {
+ for (VF = Cur.FileList(); VF.end() == false; ++VF)
+ {
+ if ((VF.File()->Flags & pkgCache::Flag::NotSource) == 0)
+ {
+ VF = V.FileList();
+ break;
+ }
+ }
+
+ if (VF.end() == false)
+ break;
+ }
+ }
+
+ VFList[P->ID] = VF;
+ }
+
+ LocalitySort(VFList,Count,sizeof(*VFList));
+
+ // Iterate over all the package files and write them out.
+ char *Buffer = new char[Cache->HeaderP->MaxVerFileSize+10];
+ for (pkgCache::VerFile **J = VFList; *J != 0;)
+ {
+ pkgCache::PkgFileIterator File(*Cache,(*J)->File + Cache->PkgFileP);
+ if (File.IsOk() == false)
+ {
+ _error->Error(_("Package file %s is out of sync."),File.FileName());
+ break;
+ }
+
+ FileFd PkgF(File.FileName(),FileFd::ReadOnly);
+ if (_error->PendingError() == true)
+ break;
+
+ /* Write all of the records from this package file, since we
+ already did locality sorting we can now just seek through the
+ file in read order. We apply 1 more optimization here, since often
+ there will be < 1 byte gaps between records (for the \n) we read that
+ into the next buffer and offset a bit.. */
+ unsigned long Pos = 0;
+ for (; *J != 0; J++)
+ {
+ if ((*J)->File + Cache->PkgFileP != File)
+ break;
+
+ const pkgCache::VerFile &VF = **J;
+
+ // Read the record and then write it out again.
+ unsigned long Jitter = VF.Offset - Pos;
+ if (Jitter > 8)
+ {
+ if (PkgF.Seek(VF.Offset) == false)
+ break;
+ Jitter = 0;
+ }
+
+ if (PkgF.Read(Buffer,VF.Size + Jitter) == false)
+ break;
+ Buffer[VF.Size + Jitter] = '\n';
+
+ // See above..
+ if ((File->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource)
+ {
+ pkgTagSection Tags;
+ TFRewriteData RW[] = {{"Status",0},{"Config-Version",0},{}};
+ const char *Zero = 0;
+ if (Tags.Scan(Buffer+Jitter,VF.Size+1) == false ||
+ TFRewrite(stdout,Tags,&Zero,RW) == false)
+ {
+ _error->Error("Internal Error, Unable to parse a package record");
+ break;
+ }
+ fputc('\n',stdout);
+ }
+ else
+ {
+ if (fwrite(Buffer+Jitter,VF.Size+1,1,stdout) != 1)
+ break;
+ }
+
+ Pos = VF.Offset + VF.Size;
+ }
+
+ fflush(stdout);
+ if (_error->PendingError() == true)
+ break;
+ }
+
+ delete [] Buffer;
+ delete [] VFList;
+ return !_error->PendingError();
+}
+ /*}}}*/
+// ShowDepends - Helper for printing out a dependency tree /*{{{*/
+bool ShowDepends(CommandLine &CmdL, bool const RevDepends)
+{
+ pkgCacheFile CacheFile;
+ pkgCache *Cache = CacheFile.GetPkgCache();
+ if (unlikely(Cache == NULL))
+ return false;
+
+ CacheSetHelperVirtuals helper(false);
+ APT::VersionList verset = APT::VersionList::FromCommandLine(CacheFile, CmdL.FileList + 1, APT::VersionList::CANDIDATE, helper);
+ if (verset.empty() == true && helper.virtualPkgs.empty() == true)
+ return _error->Error(_("No packages found"));
+ std::vector<bool> Shown(Cache->Head().PackageCount);
+
+ bool const Recurse = _config->FindB("APT::Cache::RecurseDepends", false);
+ bool const Installed = _config->FindB("APT::Cache::Installed", false);
+ bool const Important = _config->FindB("APT::Cache::Important", false);
+ bool const ShowDepType = _config->FindB("APT::Cache::ShowDependencyType", RevDepends == false);
+ bool const ShowVersion = _config->FindB("APT::Cache::ShowVersion", false);
+ bool const ShowPreDepends = _config->FindB("APT::Cache::ShowPre-Depends", true);
+ bool const ShowDepends = _config->FindB("APT::Cache::ShowDepends", true);
+ bool const ShowRecommends = _config->FindB("APT::Cache::ShowRecommends", Important == false);
+ bool const ShowSuggests = _config->FindB("APT::Cache::ShowSuggests", Important == false);
+ bool const ShowReplaces = _config->FindB("APT::Cache::ShowReplaces", Important == false);
+ bool const ShowConflicts = _config->FindB("APT::Cache::ShowConflicts", Important == false);
+ bool const ShowBreaks = _config->FindB("APT::Cache::ShowBreaks", Important == false);
+ bool const ShowEnhances = _config->FindB("APT::Cache::ShowEnhances", Important == false);
+ bool const ShowOnlyFirstOr = _config->FindB("APT::Cache::ShowOnlyFirstOr", false);
+
+ while (verset.empty() != true)
+ {
+ pkgCache::VerIterator Ver = *verset.begin();
+ verset.erase(verset.begin());
+ pkgCache::PkgIterator Pkg = Ver.ParentPkg();
+ Shown[Pkg->ID] = true;
+
+ cout << Pkg.FullName(true) << endl;
+
+ if (RevDepends == true)
+ cout << "Reverse Depends:" << endl;
+ for (pkgCache::DepIterator D = RevDepends ? Pkg.RevDependsList() : Ver.DependsList();
+ D.end() == false; ++D)
+ {
+ switch (D->Type) {
+ case pkgCache::Dep::PreDepends: if (!ShowPreDepends) continue; break;
+ case pkgCache::Dep::Depends: if (!ShowDepends) continue; break;
+ case pkgCache::Dep::Recommends: if (!ShowRecommends) continue; break;
+ case pkgCache::Dep::Suggests: if (!ShowSuggests) continue; break;
+ case pkgCache::Dep::Replaces: if (!ShowReplaces) continue; break; case pkgCache::Dep::Conflicts: if (!ShowConflicts) continue; break;
+ case pkgCache::Dep::DpkgBreaks: if (!ShowBreaks) continue; break;
+ case pkgCache::Dep::Enhances: if (!ShowEnhances) continue; break;
+ }
+
+ pkgCache::PkgIterator Trg = RevDepends ? D.ParentPkg() : D.TargetPkg();
+
+ if((Installed && Trg->CurrentVer != 0) || !Installed)
+ {
+
+ if ((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or && ShowOnlyFirstOr == false)
+ cout << " |";
+ else
+ cout << " ";
+
+ // Show the package
+ if (ShowDepType == true)
+ cout << D.DepType() << ": ";
+ if (Trg->VersionList == 0)
+ cout << "<" << Trg.FullName(true) << ">";
+ else
+ cout << Trg.FullName(true);
+ if (ShowVersion == true && D->Version != 0)
+ cout << " (" << pkgCache::CompTypeDeb(D->CompareOp) << ' ' << D.TargetVer() << ')';
+ cout << std::endl;
+
+ if (Recurse == true && Shown[Trg->ID] == false)
+ {
+ Shown[Trg->ID] = true;
+ verset.insert(APT::VersionSet::FromPackage(CacheFile, Trg, APT::VersionSet::CANDIDATE, helper));
+ }
+
+ }
+
+ // Display all solutions
+ SPtrArray<pkgCache::Version *> List = D.AllTargets();
+ pkgPrioSortList(*Cache,List);
+ for (pkgCache::Version **I = List; *I != 0; I++)
+ {
+ pkgCache::VerIterator V(*Cache,*I);
+ if (V != Cache->VerP + V.ParentPkg()->VersionList ||
+ V->ParentPkg == D->Package)
+ continue;
+ cout << " " << V.ParentPkg().FullName(true) << endl;
+
+ if (Recurse == true && Shown[V.ParentPkg()->ID] == false)
+ {
+ Shown[V.ParentPkg()->ID] = true;
+ verset.insert(APT::VersionSet::FromPackage(CacheFile, V.ParentPkg(), APT::VersionSet::CANDIDATE, helper));
+ }
+ }
+
+ if (ShowOnlyFirstOr == true)
+ while ((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or) ++D;
+ }
+ }
+
+ for (APT::PackageSet::const_iterator Pkg = helper.virtualPkgs.begin();
+ Pkg != helper.virtualPkgs.end(); ++Pkg)
+ cout << '<' << Pkg.FullName(true) << '>' << endl;
+
+ return true;
+}
+ /*}}}*/
+// Depends - Print out a dependency tree /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool Depends(CommandLine &CmdL)
+{
+ return ShowDepends(CmdL, false);
+}
+ /*}}}*/
+// RDepends - Print out a reverse dependency tree /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool RDepends(CommandLine &CmdL)
+{
+ return ShowDepends(CmdL, true);
+}
+ /*}}}*/
+// xvcg - Generate a graph for xvcg /*{{{*/
+// ---------------------------------------------------------------------
+// Code contributed from Junichi Uekawa <dancer@debian.org> on 20 June 2002.
+
+bool XVcg(CommandLine &CmdL)
+{
+ pkgCacheFile CacheFile;
+ pkgCache *Cache = CacheFile.GetPkgCache();
+ if (unlikely(Cache == NULL))