+ return true;
+#endif
+}
+ /*}}}*/
+// DisplayRecord - Displays the complete record for the package /*{{{*/
+// ---------------------------------------------------------------------
+/* This displays the package record from the proper package index file.
+ It is not used by DumpAvail for performance reasons. */
+bool DisplayRecord(pkgCache::VerIterator V)
+{
+ // Find an appropriate file
+ pkgCache::VerFileIterator Vf = V.FileList();
+ for (; Vf.end() == false; Vf++)
+ if ((Vf.File()->Flags & pkgCache::Flag::NotSource) == 0)
+ break;
+ if (Vf.end() == true)
+ Vf = V.FileList();
+
+ // Check and load the package list file
+ pkgCache::PkgFileIterator I = Vf.File();
+ if (I.IsOk() == false)
+ return _error->Error(_("Package file %s is out of sync."),I.FileName());
+
+ FileFd PkgF(I.FileName(),FileFd::ReadOnly);
+ if (_error->PendingError() == true)
+ return false;
+
+ // Read the record and then write it out again.
+ unsigned char *Buffer = new unsigned char[GCache->HeaderP->MaxVerFileSize+1];
+ Buffer[V.FileList()->Size] = '\n';
+ if (PkgF.Seek(V.FileList()->Offset) == false ||
+ PkgF.Read(Buffer,V.FileList()->Size) == false ||
+ write(STDOUT_FILENO,Buffer,V.FileList()->Size+1) != V.FileList()->Size+1)
+ {
+ delete [] Buffer;
+ return false;
+ }
+
+ delete [] Buffer;
+
+ return true;
+}
+ /*}}}*/
+// Search - Perform a search /*{{{*/
+// ---------------------------------------------------------------------
+/* This searches the package names and pacakge descriptions for a pattern */
+struct ExVerFile
+{
+ pkgCache::VerFile *Vf;
+ bool NameMatch;
+};
+
+bool Search(CommandLine &CmdL)
+{
+ pkgCache &Cache = *GCache;
+ bool ShowFull = _config->FindB("APT::Cache::ShowFull",false);
+ bool NamesOnly = _config->FindB("APT::Cache::NamesOnly",false);
+ unsigned NumPatterns = CmdL.FileSize() -1;
+
+ pkgDepCache::Policy Plcy;
+
+ // Make sure there is at least one argument
+ if (NumPatterns < 1)
+ return _error->Error(_("You must give exactly one pattern"));
+
+ // Compile the regex pattern
+ regex_t *Patterns = new regex_t[NumPatterns];
+ memset(Patterns,0,sizeof(*Patterns)*NumPatterns);
+ for (unsigned I = 0; I != NumPatterns; I++)
+ {
+ if (regcomp(&Patterns[I],CmdL.FileList[I+1],REG_EXTENDED | REG_ICASE |
+ REG_NOSUB) != 0)
+ {
+ for (; I != 0; I--)
+ regfree(&Patterns[I]);
+ return _error->Error("Regex compilation error");
+ }
+ }
+
+ // Create the text record parser
+ pkgRecords Recs(Cache);
+ if (_error->PendingError() == true)
+ {
+ for (unsigned I = 0; I != NumPatterns; I++)
+ regfree(&Patterns[I]);
+ return false;
+ }
+
+ ExVerFile *VFList = new ExVerFile[Cache.HeaderP->PackageCount+1];
+ memset(VFList,0,sizeof(*VFList)*Cache.HeaderP->PackageCount+1);
+
+ // Map versions that we want to write out onto the VerList array.
+ for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
+ {
+ VFList[P->ID].NameMatch = NumPatterns != 0;
+ for (unsigned I = 0; I != NumPatterns; I++)
+ {
+ if (regexec(&Patterns[I],P.Name(),0,0,0) == 0)
+ VFList[P->ID].NameMatch &= true;
+ else
+ VFList[P->ID].NameMatch = false;
+ }
+
+ // Doing names only, drop any that dont match..
+ if (NamesOnly == true && VFList[P->ID].NameMatch == false)
+ continue;
+
+ // Find the proper version to use.
+ pkgCache::VerIterator V = Plcy.GetCandidateVer(P);
+ if (V.end() == false)
+ VFList[P->ID].Vf = V.FileList();
+ }
+
+ // Include all the packages that provide matching names too
+ for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
+ {
+ if (VFList[P->ID].NameMatch == false)
+ continue;
+
+ for (pkgCache::PrvIterator Prv = P.ProvidesList() ; Prv.end() == false; Prv++)
+ {
+ pkgCache::VerIterator V = Plcy.GetCandidateVer(Prv.OwnerPkg());
+ if (V.end() == false)
+ {
+ VFList[Prv.OwnerPkg()->ID].Vf = V.FileList();
+ VFList[Prv.OwnerPkg()->ID].NameMatch = true;
+ }
+ }
+ }
+
+ LocalitySort(&VFList->Vf,Cache.HeaderP->PackageCount,sizeof(*VFList));
+
+ // Iterate over all the version records and check them
+ for (ExVerFile *J = VFList; J->Vf != 0; J++)
+ {
+ pkgRecords::Parser &P = Recs.Lookup(pkgCache::VerFileIterator(Cache,J->Vf));
+
+ bool Match = true;
+ if (J->NameMatch == false)
+ {
+ string LongDesc = P.LongDesc();
+ Match = NumPatterns != 0;
+ for (unsigned I = 0; I != NumPatterns; I++)
+ {
+ if (regexec(&Patterns[I],LongDesc.c_str(),0,0,0) == 0)
+ Match &= true;
+ else
+ Match = false;
+ }
+ }
+
+ if (Match == true)
+ {
+ if (ShowFull == true)
+ {
+ const char *Start;
+ const char *End;
+ P.GetRec(Start,End);
+ fwrite(Start,End-Start,1,stdout);
+ putc('\n',stdout);
+ }
+ else
+ printf("%s - %s\n",P.Name().c_str(),P.ShortDesc().c_str());
+ }
+ }
+
+ delete [] VFList;
+ for (unsigned I = 0; I != NumPatterns; I++)
+ regfree(&Patterns[I]);
+ if (ferror(stdout))
+ return _error->Error("Write to stdout failed");
+ return true;
+}
+ /*}}}*/
+// ShowPackage - Dump the package record to the screen /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool ShowPackage(CommandLine &CmdL)
+{
+ pkgCache &Cache = *GCache;
+ pkgDepCache::Policy Plcy;
+
+ for (const char **I = CmdL.FileList + 1; *I != 0; I++)
+ {
+ pkgCache::PkgIterator Pkg = Cache.FindPkg(*I);
+ if (Pkg.end() == true)
+ {
+ _error->Warning(_("Unable to locate package %s"),*I);
+ continue;
+ }
+
+ // Find the proper version to use.
+ if (_config->FindB("APT::Cache::AllVersions","true") == true)
+ {
+ pkgCache::VerIterator V;
+ for (V = Pkg.VersionList(); V.end() == false; V++)
+ {
+ if (DisplayRecord(V) == false)
+ return false;
+ }
+ }
+ else
+ {
+ pkgCache::VerIterator V = Plcy.GetCandidateVer(Pkg);
+ if (V.end() == true || V.FileList().end() == true)
+ continue;
+ if (DisplayRecord(V) == false)
+ return false;
+ }
+ }
+ return true;
+}
+ /*}}}*/
+// ShowPkgNames - Show package names /*{{{*/
+// ---------------------------------------------------------------------
+/* This does a prefix match on the first argument */
+bool ShowPkgNames(CommandLine &CmdL)
+{
+ pkgCache &Cache = *GCache;
+ pkgCache::PkgIterator I = Cache.PkgBegin();
+ bool All = _config->FindB("APT::Cache::AllNames","false");
+
+ if (CmdL.FileList[1] != 0)
+ {
+ for (;I.end() != true; I++)
+ {
+ if (All == false && I->VersionList == 0)
+ continue;
+
+ if (strncmp(I.Name(),CmdL.FileList[1],strlen(CmdL.FileList[1])) == 0)
+ cout << I.Name() << endl;
+ }
+
+ return true;
+ }
+
+ // Show all pkgs
+ for (;I.end() != true; I++)
+ {
+ if (All == false && I->VersionList == 0)
+ continue;
+ cout << I.Name() << endl;
+ }
+
+ return true;
+}
+ /*}}}*/
+// ShowSrcPackage - Show source package records /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool ShowSrcPackage(CommandLine &CmdL)
+{
+ pkgSourceList List;
+ List.ReadMainList();
+
+ // Create the text record parsers
+ pkgSrcRecords SrcRecs(List);
+ if (_error->PendingError() == true)
+ return false;
+
+ for (const char **I = CmdL.FileList + 1; *I != 0; I++)
+ {
+ SrcRecs.Restart();
+
+ pkgSrcRecords::Parser *Parse;
+ while ((Parse = SrcRecs.Find(*I,false)) != 0)
+ cout << Parse->AsStr() << endl;;
+ }
+ return true;
+}
+ /*}}}*/
+// Policy - Show the results of the preferences file /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool Policy(CommandLine &CmdL)
+{
+ if (SrcList == 0)
+ return _error->Error("Generate must be enabled for this function");
+
+ pkgCache &Cache = *GCache;
+ pkgPolicy Plcy(&Cache);
+ if (ReadPinFile(Plcy) == false)
+ return false;
+
+ // Print out all of the package files
+ if (CmdL.FileList[1] == 0)
+ {
+ cout << _("Package Files:") << endl;
+ for (pkgCache::PkgFileIterator F = Cache.FileBegin(); F.end() == false; F++)
+ {
+ // Locate the associated index files so we can derive a description
+ pkgIndexFile *Indx;
+ if (SrcList->FindIndex(F,Indx) == false &&
+ _system->FindIndex(F,Indx) == false)
+ return _error->Error(_("Cache is out of sync, can't x-ref a package file"));
+ printf(_("%4i %s\n"),
+ Plcy.GetPriority(F),Indx->Describe(true).c_str());
+
+ // Print the reference information for the package
+ string Str = F.RelStr();
+ if (Str.empty() == false)
+ printf(" release %s\n",F.RelStr().c_str());
+ if (F.Site() != 0 && F.Site()[0] != 0)
+ printf(" origin %s\n",F.Site());
+ }
+
+ // Show any packages have explicit pins
+ cout << _("Pinned Packages:") << endl;
+ pkgCache::PkgIterator I = Cache.PkgBegin();
+ for (;I.end() != true; I++)
+ {
+ if (Plcy.GetPriority(I) == 0)
+ continue;
+
+ // Print the package name and the version we are forcing to
+ cout << " " << I.Name() << " -> ";
+
+ pkgCache::VerIterator V = Plcy.GetMatch(I);
+ if (V.end() == true)
+ cout << _("(not found)") << endl;
+ else
+ cout << V.VerStr() << endl;
+ }
+
+ return true;
+ }
+
+ // Print out detailed information for each package
+ for (const char **I = CmdL.FileList + 1; *I != 0; I++)
+ {
+ pkgCache::PkgIterator Pkg = Cache.FindPkg(*I);
+ if (Pkg.end() == true)
+ {
+ _error->Warning(_("Unable to locate package %s"),*I);
+ continue;
+ }
+
+ cout << Pkg.Name() << ":" << endl;
+
+ // Installed version
+ cout << _(" Installed: ");
+ if (Pkg->CurrentVer == 0)
+ cout << _("(none)") << endl;
+ else
+ cout << Pkg.CurrentVer().VerStr() << endl;
+
+ // Candidate Version
+ cout << _(" Candidate: ");
+ pkgCache::VerIterator V = Plcy.GetCandidateVer(Pkg);
+ if (V.end() == true)
+ cout << _("(none)") << endl;
+ else
+ cout << V.VerStr() << endl;
+
+ // Pinned version
+ if (Plcy.GetPriority(Pkg) != 0)
+ {
+ cout << _(" Package Pin: ");
+ V = Plcy.GetMatch(Pkg);
+ if (V.end() == true)
+ cout << _("(not found)") << endl;
+ else
+ cout << V.VerStr() << endl;
+ }
+
+ // Show the priority tables
+ cout << _(" Version Table:") << endl;
+ for (V = Pkg.VersionList(); V.end() == false; V++)
+ {
+ if (Pkg.CurrentVer() == V)
+ cout << " *** " << V.VerStr();
+ else
+ cout << " " << V.VerStr();
+ cout << " " << Plcy.GetPriority(Pkg) << endl;
+ for (pkgCache::VerFileIterator VF = V.FileList(); VF.end() == false; VF++)
+ {
+ // Locate the associated index files so we can derive a description
+ pkgIndexFile *Indx;
+ if (SrcList->FindIndex(VF.File(),Indx) == false &&
+ _system->FindIndex(VF.File(),Indx) == false)
+ return _error->Error(_("Cache is out of sync, can't x-ref a package file"));
+ printf(_(" %4i %s\n"),Plcy.GetPriority(VF.File()),
+ Indx->Describe(true).c_str());
+ }
+ }
+ }
+