- move common code in apt-cache/shell to cmdline
[apt.git] / cmdline / apt-shell.cc
index 9cdc914..d91f5ca 100644 (file)
@@ -1817,32 +1817,6 @@ bool DoScript(CommandLine &CmdL)
 
 // --- Unchanged stuff from apt-cache.
 
-// LocalitySort - Sort a version list by package file locality         /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-int LocalityCompare(const void *a, const void *b)
-{
-   pkgCache::VerFile *A = *(pkgCache::VerFile **)a;
-   pkgCache::VerFile *B = *(pkgCache::VerFile **)b;
-   
-   if (A == 0 && B == 0)
-      return 0;
-   if (A == 0)
-      return 1;
-   if (B == 0)
-      return -1;
-   
-   if (A->File == B->File)
-      return A->Offset - B->Offset;
-   return A->File - B->File;
-}
-
-void LocalitySort(pkgCache::VerFile **begin,
-                 unsigned long Count,size_t Size)
-{   
-   qsort(begin,Count,Size,LocalityCompare);
-}
-                                                                       /*}}}*/
 
 // Depends - Print out a dependency tree                               /*{{{*/
 // ---------------------------------------------------------------------
@@ -1852,94 +1826,7 @@ bool Depends(CommandLine &CmdL)
    if (CheckHelp(CmdL) == true)
       return true;
 
-   pkgCache &Cache = *GCache;
-   SPtrArray<unsigned> Colours = new unsigned[Cache.Head().PackageCount];
-   memset(Colours,0,sizeof(*Colours)*Cache.Head().PackageCount);
-   
-   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;
-      }
-      Colours[Pkg->ID] = 1;
-   }
-   
-   bool Recurse = _config->FindB("APT::Cache::RecurseDepends",false);
-   bool Installed = _config->FindB("APT::Cache::Installed",false);
-   bool DidSomething;
-   do
-   {
-      DidSomething = false;
-      for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
-      {
-        if (Colours[Pkg->ID] != 1)
-           continue;
-        Colours[Pkg->ID] = 2;
-        DidSomething = true;
-        
-        pkgCache::VerIterator Ver = Pkg.VersionList();
-        if (Ver.end() == true)
-        {
-           cout << '<' << Pkg.Name() << '>' << endl;
-           continue;
-        }
-        
-        // CNC:2003-03-03
-        cout << Pkg.Name() << "-" << Ver.VerStr() << endl;
-        
-        for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++)
-        {
-
-           pkgCache::PkgIterator Trg = D.TargetPkg();
-
-           if((Installed && Trg->CurrentVer != 0) || !Installed)
-             {
-
-               if ((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)
-                 cout << " |";
-               else
-                 cout << "  ";
-           
-               // Show the package
-               if (Trg->VersionList == 0)
-                  cout << D.DepType() << ": <" << Trg.Name() << ">" << endl;
-               // CNC:2003-03-03
-               else if (D.TargetVer() == 0)
-                  cout << D.DepType() << ": " << Trg.Name() << endl;
-               else
-                  cout << D.DepType() << ": " << Trg.Name()
-                       << " " << D.CompType() << " " << D.TargetVer() << endl;
-           
-               if (Recurse == true)
-                 Colours[D.TargetPkg()->ID]++;
-
-             }
-           
-           // 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;
-              // CNC:2003-03-03
-              cout << "    " << V.ParentPkg().Name()
-                   << "-" << V.VerStr() << endl;
-              
-              if (Recurse == true)
-                 Colours[D.ParentPkg()->ID]++;
-           }
-        }
-      }      
-   }   
-   while (DidSomething == true);
-   
-   return true;
+   return cmdDepends(CmdL, *GCache);
 }
                                                                        /*}}}*/
 // RDepends - Print out a reverse dependency tree - mbc                        /*{{{*/
@@ -1950,87 +1837,7 @@ bool RDepends(CommandLine &CmdL)
    if (CheckHelp(CmdL) == true)
       return true;
 
-   pkgCache &Cache = *GCache;
-   SPtrArray<unsigned> Colours = new unsigned[Cache.Head().PackageCount];
-   memset(Colours,0,sizeof(*Colours)*Cache.Head().PackageCount);
-   
-   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;
-      }
-      Colours[Pkg->ID] = 1;
-   }
-   
-   bool Recurse = _config->FindB("APT::Cache::RecurseDepends",false);
-   bool Installed = _config->FindB("APT::Cache::Installed",false);
-   bool DidSomething;
-   do
-   {
-      DidSomething = false;
-      for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
-      {
-        if (Colours[Pkg->ID] != 1)
-           continue;
-        Colours[Pkg->ID] = 2;
-        DidSomething = true;
-        
-        pkgCache::VerIterator Ver = Pkg.VersionList();
-        if (Ver.end() == true)
-        {
-           cout << '<' << Pkg.Name() << '>' << endl;
-           continue;
-        }
-        
-        cout << Pkg.Name() << endl;
-        
-        cout << "Reverse Depends:" << endl;
-        for (pkgCache::DepIterator D = Pkg.RevDependsList(); D.end() == false; D++)
-        {          
-           // Show the package
-           pkgCache::PkgIterator Trg = D.ParentPkg();
-
-           if((Installed && Trg->CurrentVer != 0) || !Installed)
-             {
-
-               if ((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)
-                 cout << " |";
-               else
-                 cout << "  ";
-
-               if (Trg->VersionList == 0)
-                 cout << D.DepType() << ": <" << Trg.Name() << ">" << endl;
-               else
-                 cout << Trg.Name() << endl;
-
-               if (Recurse == true)
-                 Colours[D.ParentPkg()->ID]++;
-
-             }
-           
-           // 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().Name() << endl;
-              
-              if (Recurse == true)
-                 Colours[D.ParentPkg()->ID]++;
-           }
-        }
-      }      
-   }   
-   while (DidSomething == true);
-   
-   return true;
+   return cmdRDepends(CmdL, *GCache);
 }
 
                                                                        /*}}}*/
@@ -2043,207 +1850,15 @@ bool WhatDepends(CommandLine &CmdL)
    if (CheckHelp(CmdL) == true)
       return true;
 
-   pkgCache &Cache = *GCache;
-   SPtrArray<unsigned> Colours = new unsigned[Cache.Head().PackageCount];
-   memset(Colours,0,sizeof(*Colours)*Cache.Head().PackageCount);
-   
-   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;
-      }
-      Colours[Pkg->ID] = 1;
-   }
-   
-   bool Recurse = _config->FindB("APT::Cache::RecurseDepends",false);
-   bool DidSomething;
-   do
-   {
-      DidSomething = false;
-      for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
-      {
-        if (Colours[Pkg->ID] != 1)
-           continue;
-        Colours[Pkg->ID] = 2;
-        DidSomething = true;
-        
-        pkgCache::VerIterator Ver = Pkg.VersionList();
-        if (Ver.end() == true)
-           cout << '<' << Pkg.Name() << '>' << endl;
-        else
-           cout << Pkg.Name() << "-" << Ver.VerStr() << endl;
-
-        SPtrArray<unsigned> LocalColours = 
-                    new unsigned[Cache.Head().PackageCount];
-        memset(LocalColours,0,sizeof(*LocalColours)*Cache.Head().PackageCount);
-           
-        // Display all dependencies directly on the package.
-        for (pkgCache::DepIterator RD = Pkg.RevDependsList();
-             RD.end() == false; RD++)
-        {
-           pkgCache::PkgIterator Parent = RD.ParentPkg();
-
-           if (LocalColours[Parent->ID] == 1)
-              continue;
-           LocalColours[Parent->ID] = 1;
-              
-           if (Ver.end() == false && RD.TargetVer() &&
-               Cache.VS->CheckDep(Ver.VerStr(),RD) == false)
-              continue;
-
-           if (Recurse == true && Colours[Parent->ID] == 0)
-              Colours[Parent->ID] = 1;
-
-           pkgCache::VerIterator ParentVer = Parent.VersionList();
-
-           // Show the package
-           cout << "  " << Parent.Name()
-                << "-" << ParentVer.VerStr() << endl;
-
-           // Display all dependencies from that package that relate
-           // to the queried package.
-           for (pkgCache::DepIterator D = ParentVer.DependsList();
-                D.end() == false; D++)
-           {
-              // If this is a virtual package, there's no provides.
-              if (Ver.end() == true) {
-                 // If it's not the same package, and there's no provides
-                 // skip that package.
-                 if (D.TargetPkg() != Pkg)
-                    continue;
-              } else if (D.TargetPkg() != Pkg ||
-                         Cache.VS->CheckDep(Ver.VerStr(),D) == false) {
-                 // Oops. Either it's not the same package, or the
-                 // version didn't match. Check virtual provides from
-                 // the queried package version and verify if this
-                 // dependency matches one of those.
-                 bool Hit = false;
-                 for (pkgCache::PrvIterator Prv = Ver.ProvidesList();
-                      Prv.end() == false; Prv++) {
-                    if (Prv.ParentPkg() == D.TargetPkg() &&
-                        (Prv.ParentPkg()->VersionList == 0 ||
-                         Cache.VS->CheckDep(Prv.ProvideVersion(),D)==false)) {
-                       Hit = true;
-                       break;
-                    }
-                 }
-                 if (Hit == false)
-                    continue;
-              }
-
-              // Bingo!
-              pkgCache::PkgIterator Trg = D.TargetPkg();
-              if (Trg->VersionList == 0)
-                 cout << "    " << D.DepType()
-                                << ": <" << Trg.Name() << ">" << endl;
-              else if (D.TargetVer() == 0)
-                 cout << "    " << D.DepType()
-                                << ": " << Trg.Name() << endl;
-              else
-                 cout << "    " << D.DepType()
-                                << ": " << Trg.Name()
-                                << " " << D.CompType() << " "
-                                << D.TargetVer() << endl;
-
-              // 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().Name()
-                      << "-" << V.VerStr() << endl;
-                 
-                 if (Recurse == true)
-                    Colours[D.ParentPkg()->ID]++;
-              }
-           }
-        }
-
-        // Is this a virtual package the user queried directly?
-        if (Ver.end())
-           continue;
-
-        // Display all dependencies on virtual provides, which were not
-        // yet shown in the step above.
-        for (pkgCache::PrvIterator RDPrv = Ver.ProvidesList();
-             RDPrv.end() == false; RDPrv++) {
-           for (pkgCache::DepIterator RD = RDPrv.ParentPkg().RevDependsList();
-                RD.end() == false; RD++)
-           {
-              pkgCache::PkgIterator Parent = RD.ParentPkg();
-
-              if (LocalColours[Parent->ID] == 1)
-                 continue;
-              LocalColours[Parent->ID] = 1;
-                 
-              if (Ver.end() == false &&
-                  Cache.VS->CheckDep(Ver.VerStr(),RD) == false)
-                 continue;
-
-              if (Recurse == true && Colours[Parent->ID] == 0)
-                 Colours[Parent->ID] = 1;
-
-              pkgCache::VerIterator ParentVer = Parent.VersionList();
+   return cmdWhatDepends(CmdL, *GCache);
+}
 
-              // Show the package
-              cout << "  " << Parent.Name()
-                   << "-" << ParentVer.VerStr() << endl;
+bool WhatProvides(CommandLine &CmdL)
+{
+   if (CheckHelp(CmdL) == true)
+      return true;
 
-              for (pkgCache::DepIterator D = ParentVer.DependsList();
-                   D.end() == false; D++)
-              {
-                 // Go on if it's the same package and version or
-                 // if it's the same package and has no versions
-                 // (a virtual package).
-                 if (D.TargetPkg() != RDPrv.ParentPkg() ||
-                     (RDPrv.ProvideVersion() != 0 &&
-                      Cache.VS->CheckDep(RDPrv.ProvideVersion(),D) == false))
-                    continue;
-
-                 // Bingo!
-                 pkgCache::PkgIterator Trg = D.TargetPkg();
-                 if (Trg->VersionList == 0)
-                    cout << "    " << D.DepType()
-                                   << ": <" << Trg.Name() << ">" << endl;
-                 else if (D.TargetVer() == 0)
-                    cout << "    " << D.DepType()
-                                   << ": " << Trg.Name() << endl;
-                 else
-                    cout << "    " << D.DepType()
-                                   << ": " << Trg.Name()
-                                   << " " << D.CompType() << " "
-                                   << D.TargetVer() << endl;
-
-                 // 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().Name()
-                         << "-" << V.VerStr() << endl;
-                    
-                    if (Recurse == true)
-                       Colours[D.ParentPkg()->ID]++;
-                 }
-              }
-           }
-        }
-      } 
-   }
-   while (DidSomething == true);
-   
-   return true;
+   return cmdWhatProvides(CmdL, *GCache);
 }
                                                                        /*}}}*/
 // UnMet - Show unmet dependencies                                     /*{{{*/
@@ -2254,88 +1869,7 @@ bool UnMet(CommandLine &CmdL)
    if (CheckHelp(CmdL,0) == true)
       return true;
 
-   pkgCache &Cache = *GCache;
-   bool Important = _config->FindB("APT::Cache::Important",false);
-   
-   for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
-   {
-      for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++)
-      {
-        bool Header = false;
-        for (pkgCache::DepIterator D = V.DependsList(); D.end() == false;)
-        {
-           // Collect or groups
-           pkgCache::DepIterator Start;
-           pkgCache::DepIterator End;
-           D.GlobOr(Start,End);
-           
-           // Skip conflicts and replaces
-           if (End->Type != pkgCache::Dep::PreDepends &&
-               End->Type != pkgCache::Dep::Depends && 
-               End->Type != pkgCache::Dep::Suggests &&
-               End->Type != pkgCache::Dep::Recommends)
-              continue;
-
-           // Important deps only
-           if (Important == true)
-              if (End->Type != pkgCache::Dep::PreDepends &&
-                  End->Type != pkgCache::Dep::Depends)
-                 continue;
-           
-           // Verify the or group
-           bool OK = false;
-           pkgCache::DepIterator RealStart = Start;
-           do
-           {
-              // See if this dep is Ok
-              pkgCache::Version **VList = Start.AllTargets();
-              if (*VList != 0)
-              {
-                 OK = true;
-                 delete [] VList;
-                 break;
-              }
-              delete [] VList;
-              
-              if (Start == End)
-                 break;
-              Start++;
-           }
-           while (1);
-
-           // The group is OK
-           if (OK == true)
-              continue;
-           
-           // Oops, it failed..
-           if (Header == false)
-              ioprintf(cout,_("Package %s version %s has an unmet dep:\n"),
-                       P.Name(),V.VerStr());
-           Header = true;
-           
-           // Print out the dep type
-           cout << " " << End.DepType() << ": ";
-
-           // Show the group
-           Start = RealStart;
-           do
-           {
-              cout << Start.TargetPkg().Name();
-              if (Start.TargetVer() != 0)
-                 cout << " (" << Start.CompType() << " " << Start.TargetVer() <<
-                 ")";
-              if (Start == End)
-                 break;
-              cout << " | ";
-              Start++;
-           }
-           while (1);
-           
-           cout << endl;
-        }       
-      }
-   }   
-   return true;
+   return cmdUnMet(CmdL, *GCache);
 }
                                                                        /*}}}*/
 // DumpPackage - Show a dump of a package record                       /*{{{*/
@@ -2346,61 +1880,7 @@ bool DumpPackage(CommandLine &CmdL)
    if (CheckHelp(CmdL) == true)
       return true;
 
-   pkgCache &Cache = *GCache;
-   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 << "Package: " << Pkg.Name() << endl;
-      cout << "Versions: " << endl;
-      for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
-      {
-        cout << Cur.VerStr();
-        for (pkgCache::VerFileIterator Vf = Cur.FileList(); Vf.end() == false; Vf++)
-           cout << "(" << Vf.File().FileName() << ")";
-        cout << endl;
-      }
-      
-      cout << endl;
-      
-      cout << "Reverse Depends: " << endl;
-      for (pkgCache::DepIterator D = Pkg.RevDependsList(); D.end() != true; D++)
-      {
-        cout << "  " << D.ParentPkg().Name() << ',' << D.TargetPkg().Name();
-        if (D->Version != 0)
-           cout << ' ' << DeNull(D.TargetVer()) << endl;
-        else
-           cout << endl;
-      }
-      
-      cout << "Dependencies: " << endl;
-      for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
-      {
-        cout << Cur.VerStr() << " - ";
-        for (pkgCache::DepIterator Dep = Cur.DependsList(); Dep.end() != true; Dep++)
-           cout << Dep.TargetPkg().Name() << " (" << (int)Dep->CompareOp << " " << DeNull(Dep.TargetVer()) << ") ";
-        cout << endl;
-      }      
-
-      cout << "Provides: " << endl;
-      for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
-      {
-        cout << Cur.VerStr() << " - ";
-        for (pkgCache::PrvIterator Prv = Cur.ProvidesList(); Prv.end() != true; Prv++)
-           cout << Prv.ParentPkg().Name() << " ";
-        cout << endl;
-      }
-      cout << "Reverse Provides: " << endl;
-      for (pkgCache::PrvIterator Prv = Pkg.ProvidesList(); Prv.end() != true; Prv++)
-        cout << Prv.OwnerPkg().Name() << " " << Prv.OwnerVer().VerStr() << endl;            
-   }
-
-   return true;
+   return cmdDumpPackage(CmdL, *GCache);
 }
                                                                        /*}}}*/
 // DisplayRecord - Displays the complete record for the package                /*{{{*/
@@ -2409,183 +1889,23 @@ bool DumpPackage(CommandLine &CmdL)
    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();
-      
-// CNC:2002-07-24
-#if HAVE_RPM
-   pkgRecords Recs(*GCache);
-   pkgRecords::Parser &P = Recs.Lookup(Vf);
-   const char *Start;
-   const char *End;
-   P.GetRec(Start,End);
-   cout << string(Start,End-Start) << endl;
-#else
-   // 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 ||
-       fwrite(Buffer,1,V.FileList()->Size+1,stdout) < V.FileList()->Size+1)
-   {
-      delete [] Buffer;
-      return false;
-   }
-   
-   delete [] Buffer;
-#endif
-
-   return true;
+   return cmdDisplayRecord(V, *GCache);
 }
                                                                        /*}}}*/
-// 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)
 {
    if (CheckHelp(CmdL) == true)
       return true;
 
-   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));
+   return cmdSearch(CmdL, *GCache);
+}
 
-   // 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 SearchFile(CommandLine &CmdL)
+{
+   if (CheckHelp(CmdL) == true)
+      return true;
 
-      bool Match = true;
-      if (J->NameMatch == false)
-      {
-        string LongDesc = P.LongDesc();
-        // CNC 2004-2004-04-10
-        string ShortDesc = P.ShortDesc();
-        Match = NumPatterns != 0;
-        for (unsigned I = 0; I != NumPatterns; I++)
-        {
-           if (regexec(&Patterns[I],LongDesc.c_str(),0,0,0) == 0 ||
-               regexec(&Patterns[I],ShortDesc.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);
-           cout << string(Start,End-Start) << endl;
-        }       
-        else
-           cout << P.Name() << " - " << P.ShortDesc() << endl;
-      }
-   }
-   
-   delete [] VFList;
-   for (unsigned I = 0; I != NumPatterns; I++)
-      regfree(&Patterns[I]);
-   if (ferror(stdout))
-       return _error->Error("Write to stdout failed");
-   return true;
+   return cmdSearchFile(CmdL, *GCache);
 }
 
 // DoList - List packages.                                             /*{{{*/
@@ -2596,155 +1916,7 @@ bool DoList(CommandLine &CmdL)
    if (CheckHelp(CmdL) == true)
       return true;
 
-   CacheFile &Cache = *GCache;
-
-   bool MatchAll = (CmdL.FileSize() == 1);
-   bool ShowUpgradable = _config->FindB("APT::Cache::ShowUpgradable", false);
-   bool ShowInstalled = _config->FindB("APT::Cache::ShowInstalled", false);
-
-   const char **PatternList = &CmdL.FileList[1];
-   int NumPatterns = CmdL.FileSize()-1;
-
-   bool ShowVersion = _config->FindB("APT::Cache::ShowVersion", false);
-   bool ShowSummary = _config->FindB("APT::Cache::ShowSummary", false);
-
-   const char *PkgName;
-   vector<int> Matches(Cache->Head().PackageCount);
-   size_t NumMatches = 0;
-   size_t Len = 0, NameMaxLen = 0, VerMaxLen = 0;
-   bool Matched;
-   for (unsigned int J = 0; J < Cache->Head().PackageCount; J++)
-   {
-      Matched = false;
-      pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
-      if (Pkg->VersionList == 0)
-        continue;
-      if (ShowInstalled && Pkg->CurrentVer == 0)
-        continue;
-      if (ShowUpgradable &&
-         (Pkg->CurrentVer == 0 || Cache[Pkg].Upgradable() == false))
-        continue;
-      PkgName = Pkg.Name();
-      if (MatchAll == true)
-        Matched = true;
-      else for (int i=0; i != NumPatterns; i++) {
-        if (fnmatch(PatternList[i], PkgName, 0) == 0) {
-           Matched = true;
-           break;
-        }
-      }
-      if (Matched == true) {
-        Matches[NumMatches++] = J;
-        Len = strlen(PkgName);
-        if (Len > NameMaxLen)
-           NameMaxLen = Len;
-        if (ShowVersion == true && Pkg->CurrentVer != 0) {
-           Len = strlen(Pkg.CurrentVer().VerStr());
-           if (Len > VerMaxLen)
-              VerMaxLen = Len;
-        }
-      }
-   }
-
-   if (NumMatches == 0)
-      return true;
-
-   if (ShowVersion == true) {
-      const char *NameLabel = _("Name");
-      const char *InstalledLabel = _("Installed");
-      const char *CandidateLabel = _("Candidate");
-      size_t NameLen = strlen(NameLabel);
-      size_t InstalledLen = strlen(InstalledLabel);
-      size_t CandidateLen = strlen(CandidateLabel);
-
-      unsigned int FirstColumn = NameMaxLen+2;
-      if (FirstColumn < NameLen+2)
-        FirstColumn = NameLen+2;
-
-      unsigned int SecondColumn = VerMaxLen+2;
-      if (SecondColumn < InstalledLen+2)
-        SecondColumn = InstalledLen+2;
-
-      vector<char> BlankFirst(FirstColumn+1,' ');
-      BlankFirst[FirstColumn] = 0;
-
-      vector<char> BlankSecond(SecondColumn+1,' ');
-      BlankSecond[SecondColumn] = 0;
-
-      vector<char> Bar(ScreenWidth+1,'-');
-      Bar[ScreenWidth] = 0;
-
-      c2out << NameLabel << &BlankFirst[NameLen]
-           << InstalledLabel << &BlankSecond[InstalledLen]
-           << CandidateLabel << endl;
-      c2out << &Bar[ScreenWidth-NameLen] << &BlankFirst[NameLen]
-           << &Bar[ScreenWidth-InstalledLen] << &BlankSecond[InstalledLen]
-           << &Bar[ScreenWidth-CandidateLen] << endl;
-
-      const char *Str;
-      size_t StrLen;
-      for (unsigned int K = 0; K != NumMatches; K++) {
-        pkgCache::PkgIterator Pkg(Cache,Cache.List[Matches[K]]);
-        Str = Pkg.Name();
-        StrLen = strlen(Str);
-        c2out << Str << &BlankFirst[StrLen];
-        if (Pkg->CurrentVer != 0) {
-           Str = Pkg.CurrentVer().VerStr();
-           StrLen = strlen(Str);
-           if (Len < SecondColumn-1)
-              c2out << Str << &BlankSecond[StrLen];
-           else
-              c2out << Str << " ";
-        } else {
-           c2out << "-" << &BlankSecond[1];
-        }
-        Str = "-";
-        if (Cache[Pkg].CandidateVer != 0) {
-           Str = Cache[Pkg].CandidateVerIter(Cache).VerStr();
-           if (Pkg->CurrentVer != 0 &&
-               strcmp(Str, Pkg.CurrentVer().VerStr()) == 0)
-              Str = "-";
-        }
-        c2out << Str << endl;
-      }
-   } else if (ShowSummary == true) {
-      pkgRecords Recs(Cache);
-      if (_error->PendingError() == true)
-        return false;
-      for (unsigned int K = 0; K != NumMatches; K++) {
-        pkgCache::PkgIterator Pkg(Cache,Cache.List[Matches[K]]);
-        pkgRecords::Parser &Parse = Recs.Lookup(Pkg.VersionList().FileList());
-        c2out << Pkg.Name() << " - " << Parse.ShortDesc() << endl;
-      }
-   } else {
-      unsigned int PerLine = ScreenWidth/(NameMaxLen+2);
-      if (PerLine == 0) PerLine = 1;
-      unsigned int ColumnLen = ScreenWidth/PerLine;
-      unsigned int NumLines = (NumMatches+PerLine-1)/PerLine;
-      vector<char> Blank(ColumnLen+1,' ');
-      Blank[ColumnLen] = 0;
-
-      const char *Str;
-      size_t StrLen;
-      unsigned int K;
-      for (unsigned int Line = 0; Line != NumLines; Line++) {
-        for (unsigned int Entry = 0; Entry != PerLine; Entry++) {
-           K = Line+(Entry*NumLines);
-           if (K >= NumMatches)
-              break;
-           pkgCache::PkgIterator Pkg(Cache,Cache.List[Matches[K]]);
-           Str = Pkg.Name();
-           StrLen = strlen(Str);
-           if (Len < ColumnLen-1)
-              c2out << Str << &Blank[StrLen];
-           else
-              c2out << Str << " ";
-        }
-        c2out << endl;
-      }
-   }
-   
-   return true;
+   return cmdDoList(CmdL, *GCache);
 }
                                                                        /*}}}*/
 // ShowPackage - Dump the package record to the screen                 /*{{{*/
@@ -2755,47 +1927,8 @@ bool ShowPackage(CommandLine &CmdL)
    if (CheckHelp(CmdL) == true)
       return true;
 
-   pkgCache &Cache = *GCache;
-   pkgDepCache::Policy Plcy;
-
-   unsigned found = 0;
-   
-   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;
-      }
-
-      ++found;
-
-      // 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;
-      }      
-   }
-
-   if (found > 0)
-        return true;
-   return _error->Error(_("No packages found"));
+   return cmdShowPackage(CmdL, *GCache);
 }
-                                                                       /*}}}*/
 // --- End of stuff from apt-cache.
 
 
@@ -2865,7 +1998,7 @@ bool ShowHelp(CommandLine &CmdL)
       "   remove - Remove packages\n"
       "   keep - Keep packages\n"
       "   upgrade - Perform a global upgrade\n"
-      "   dist-upgrade - Perform a globla distribution upgrade\n"
+      "   dist-upgrade - Perform a global distribution upgrade\n"
       "   build-dep - Install build-dependencies for source packages\n"
 //      "   dselect-upgrade - Follow dselect selections\n"
       "   update - Retrieve new lists of packages\n"
@@ -2877,10 +2010,12 @@ bool ShowHelp(CommandLine &CmdL)
       "   showpkg - Show some general information for a single package\n"
       "   list/ls - List packages\n"
       "   search - Search the package list for a regex pattern\n"
+      "   searchfile - Search the packages for a file\n"
       "   script - Run scripts.\n"
       "   depends - Show raw dependency information for a package\n"
-      "   whatdepends - Show raw dependency information on a package\n"
+      "   whatdepends - Show packages depending on given capabilities\n"
       // "   rdepends - Show reverse dependency information for a package\n"
+      "   whatprovides - Show packages that provide given capabilities\n"
       "   check - Verify that there are no broken dependencies\n"
       "   unmet - Show unmet dependencies\n"
       "   clean - Erase downloaded archive files\n"
@@ -3466,10 +2601,12 @@ int main(int argc,const char *argv[])
                                   {"showpkg",&DumpPackage},
                                    {"unmet",&UnMet},
                                    {"search",&Search},
+                                   {"search",&SearchFile},
                                    {"list",&DoList},
                                    {"ls",&DoList},
                                    {"depends",&Depends},
                                    {"whatdepends",&WhatDepends},
+                                   {"whatprovides",&WhatProvides},
                                    {"rdepends",&RDepends},
                                    {"show",&ShowPackage},
                                    {0,0}};