]> git.saurik.com Git - apt-legacy.git/commitdiff
Many fixes for Name, Section, and mDNSResponder.
authorJay Freeman (saurik) <saurik@saurik.com>
Sun, 3 Feb 2008 13:20:46 +0000 (13:20 +0000)
committerJay Freeman (saurik) <saurik@saurik.com>
Sun, 3 Feb 2008 13:20:46 +0000 (13:20 +0000)
A mdns.diff

git-svn-id: http://svn.telesphoreo.org/trunk@66 514c082c-b64e-11dc-b46d-3d985efe055d

22 files changed:
cmdline/apt-cache.cc
cmdline/apt-cache.cc.orig [new file with mode: 0644]
cmdline/apt-cdrom.cc
cmdline/apt-cdrom.cc.orig [new file with mode: 0644]
cmdline/apt-config.cc
cmdline/apt-config.cc.orig [new file with mode: 0644]
cmdline/apt-extracttemplates.cc
cmdline/apt-extracttemplates.cc.orig [new file with mode: 0644]
cmdline/apt-get.cc
cmdline/apt-get.cc.orig [new file with mode: 0644]
cmdline/apt-sortpkgs.cc
cmdline/apt-sortpkgs.cc.orig [new file with mode: 0644]
ftparchive/apt-ftparchive.cc
methods/cdrom.cc
methods/copy.cc
methods/file.cc
methods/ftp.cc
methods/gpgv.cc
methods/gzip.cc
methods/http.cc
methods/rred.cc
methods/rsh.cc

index b05d6b98d982e96e2319d6f123fa307a03d49886..c6a5a86f1bc1a198d7b2f5780d39f761141a7f06 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // $Id: apt-cache.cc,v 1.72 2004/04/30 04:34:03 mdz Exp $
@@ -1706,6 +1710,13 @@ void CacheInitialize()
 
 int main(int argc,const char *argv[])
 {
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
    CommandLine::Args Args[] = {
       {'h',"help","help",0},
       {'v',"version","version",0},
diff --git a/cmdline/apt-cache.cc.orig b/cmdline/apt-cache.cc.orig
new file mode 100644 (file)
index 0000000..13df621
--- /dev/null
@@ -0,0 +1,1824 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
+// -*- mode: cpp; mode: fold -*-
+// Description                                                         /*{{{*/
+// $Id: apt-cache.cc,v 1.72 2004/04/30 04:34:03 mdz Exp $
+/* ######################################################################
+   
+   apt-cache - Manages the cache files
+   
+   apt-cache provides some functions fo manipulating the cache files.
+   It uses the command line interface common to all the APT tools. 
+   
+   Returns 100 on failure, 0 on success.
+   
+   ##################################################################### */
+                                                                       /*}}}*/
+// Include Files                                                       /*{{{*/
+#include <apt-pkg/error.h>
+#include <apt-pkg/pkgcachegen.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/policy.h>
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/sptr.h>
+
+#include <config.h>
+#include <apti18n.h>
+
+#include <locale.h>
+#include <iostream>
+#include <unistd.h>
+#include <errno.h>
+#include <regex.h>
+#include <stdio.h>
+
+#include <iomanip>
+                                                                       /*}}}*/
+
+using namespace std;
+
+pkgCache *GCache = 0;
+pkgSourceList *SrcList = 0;
+
+// 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);
+}
+                                                                       /*}}}*/
+// UnMet - Show unmet dependencies                                     /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool UnMet(CommandLine &CmdL)
+{
+   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;
+}
+                                                                       /*}}}*/
+// DumpPackage - Show a dump of a package record                       /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DumpPackage(CommandLine &CmdL)
+{   
+   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;
+}
+                                                                       /*}}}*/
+// Stats - Dump some nice statistics                                   /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool Stats(CommandLine &Cmd)
+{
+   pkgCache &Cache = *GCache;
+   cout << _("Total package names : ") << Cache.Head().PackageCount << " (" <<
+      SizeToStr(Cache.Head().PackageCount*Cache.Head().PackageSz) << ')' << endl;
+
+   int Normal = 0;
+   int Virtual = 0;
+   int NVirt = 0;
+   int DVirt = 0;
+   int Missing = 0;
+   pkgCache::PkgIterator I = Cache.PkgBegin();
+   for (;I.end() != true; I++)
+   {
+      if (I->VersionList != 0 && I->ProvidesList == 0)
+      {
+        Normal++;
+        continue;
+      }
+
+      if (I->VersionList != 0 && I->ProvidesList != 0)
+      {
+        NVirt++;
+        continue;
+      }
+      
+      if (I->VersionList == 0 && I->ProvidesList != 0)
+      {
+        // Only 1 provides
+        if (I.ProvidesList()->NextProvides == 0)
+        {
+           DVirt++;
+        }
+        else
+           Virtual++;
+        continue;
+      }
+      if (I->VersionList == 0 && I->ProvidesList == 0)
+      {
+        Missing++;
+        continue;
+      }
+   }
+   cout << _("  Normal packages: ") << Normal << endl;
+   cout << _("  Pure virtual packages: ") << Virtual << endl;
+   cout << _("  Single virtual packages: ") << DVirt << endl;
+   cout << _("  Mixed virtual packages: ") << NVirt << endl;
+   cout << _("  Missing: ") << Missing << endl;
+   
+   cout << _("Total distinct versions: ") << Cache.Head().VersionCount << " (" <<
+      SizeToStr(Cache.Head().VersionCount*Cache.Head().VersionSz) << ')' << endl;
+   cout << _("Total dependencies: ") << Cache.Head().DependsCount << " (" << 
+      SizeToStr(Cache.Head().DependsCount*Cache.Head().DependencySz) << ')' << endl;
+   
+   cout << _("Total ver/file relations: ") << Cache.Head().VerFileCount << " (" <<
+      SizeToStr(Cache.Head().VerFileCount*Cache.Head().VerFileSz) << ')' << endl;
+   cout << _("Total Provides mappings: ") << Cache.Head().ProvidesCount << " (" <<
+      SizeToStr(Cache.Head().ProvidesCount*Cache.Head().ProvidesSz) << ')' << endl;
+   
+   // String list stats
+   unsigned long Size = 0;
+   unsigned long Count = 0;
+   for (pkgCache::StringItem *I = Cache.StringItemP + Cache.Head().StringList;
+        I!= Cache.StringItemP; I = Cache.StringItemP + I->NextItem)
+   {
+      Count++;
+      Size += strlen(Cache.StrP + I->String) + 1;
+   }
+   cout << _("Total globbed strings: ") << Count << " (" << SizeToStr(Size) << ')' << endl;
+
+   unsigned long DepVerSize = 0;
+   for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
+   {
+      for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++)
+      {
+        for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
+        {
+           if (D->Version != 0)
+              DepVerSize += strlen(D.TargetVer()) + 1;
+        }
+      }
+   }
+   cout << _("Total dependency version space: ") << SizeToStr(DepVerSize) << endl;
+   
+   unsigned long Slack = 0;
+   for (int I = 0; I != 7; I++)
+      Slack += Cache.Head().Pools[I].ItemSize*Cache.Head().Pools[I].Count;
+   cout << _("Total slack space: ") << SizeToStr(Slack) << endl;
+   
+   unsigned long Total = 0;
+   Total = Slack + Size + Cache.Head().DependsCount*Cache.Head().DependencySz + 
+           Cache.Head().VersionCount*Cache.Head().VersionSz +
+           Cache.Head().PackageCount*Cache.Head().PackageSz + 
+           Cache.Head().VerFileCount*Cache.Head().VerFileSz +
+           Cache.Head().ProvidesCount*Cache.Head().ProvidesSz;
+   cout << _("Total space accounted for: ") << SizeToStr(Total) << endl;
+   
+   return true;
+}
+                                                                       /*}}}*/
+// Dump - show everything                                              /*{{{*/
+// ---------------------------------------------------------------------
+/* This is worthless except fer debugging things */
+bool Dump(CommandLine &Cmd)
+{
+   pkgCache &Cache = *GCache;
+   cout << "Using Versioning System: " << Cache.VS->Label << endl;
+   
+   for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
+   {
+      cout << "Package: " << P.Name() << endl;
+      for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++)
+      {
+        cout << " Version: " << V.VerStr() << endl;
+        cout << "     File: " << V.FileList().File().FileName() << endl;
+        for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
+           cout << "  Depends: " << D.TargetPkg().Name() << ' ' << 
+                            DeNull(D.TargetVer()) << endl;
+      }      
+   }
+
+   for (pkgCache::PkgFileIterator F = Cache.FileBegin(); F.end() == false; F++)
+   {
+      cout << "File: " << F.FileName() << endl;
+      cout << " Type: " << F.IndexType() << endl;
+      cout << " Size: " << F->Size << endl;
+      cout << " ID: " << F->ID << endl;
+      cout << " Flags: " << F->Flags << endl;
+      cout << " Time: " << TimeRFC1123(F->mtime) << endl;
+      cout << " Archive: " << DeNull(F.Archive()) << endl;
+      cout << " Component: " << DeNull(F.Component()) << endl;
+      cout << " Version: " << DeNull(F.Version()) << endl;
+      cout << " Origin: " << DeNull(F.Origin()) << endl;
+      cout << " Site: " << DeNull(F.Site()) << endl;
+      cout << " Label: " << DeNull(F.Label()) << endl;
+      cout << " Architecture: " << DeNull(F.Architecture()) << endl;
+   }
+
+   return true;
+}
+                                                                       /*}}}*/
+// DumpAvail - Print out the available list                            /*{{{*/
+// ---------------------------------------------------------------------
+/* This is needed to make dpkg --merge happy.. I spent a bit of time to 
+   make this run really fast, perhaps I went a little overboard.. */
+bool DumpAvail(CommandLine &Cmd)
+{
+   pkgCache &Cache = *GCache;
+
+   pkgPolicy Plcy(&Cache);
+   if (ReadPinFile(Plcy) == false)
+      return false;
+   
+   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 = Plcy.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();
+}
+                                                                       /*}}}*/
+// Depends - Print out a dependency tree                               /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool Depends(CommandLine &CmdL)
+{
+   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;
+        
+        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;
+               else
+                 cout << D.DepType() << ": " << Trg.Name() << 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;
+              cout << "    " << V.ParentPkg().Name() << endl;
+              
+              if (Recurse == true)
+                 Colours[D.ParentPkg()->ID]++;
+           }
+        }
+      }      
+   }   
+   while (DidSomething == true);
+   
+   return true;
+}
+
+// RDepends - Print out a reverse dependency tree - mbc                        /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool RDepends(CommandLine &CmdL)
+{
+   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;
+}
+
+                                                                       /*}}}*/
+
+
+// xvcg - Generate a graph for xvcg                                    /*{{{*/
+// ---------------------------------------------------------------------
+// Code contributed from Junichi Uekawa <dancer@debian.org> on 20 June 2002.
+
+bool XVcg(CommandLine &CmdL)
+{
+   pkgCache &Cache = *GCache;
+   bool GivenOnly = _config->FindB("APT::Cache::GivenOnly",false);
+   
+   /* Normal packages are boxes
+      Pure Provides are triangles
+      Mixed are diamonds
+      rhomb are missing packages*/
+   const char *Shapes[] = {"ellipse","triangle","box","rhomb"};
+   
+   /* Initialize the list of packages to show.
+      1 = To Show
+      2 = To Show no recurse
+      3 = Emitted no recurse
+      4 = Emitted
+      0 = None */
+   enum States {None=0, ToShow, ToShowNR, DoneNR, Done};
+   enum TheFlags {ForceNR=(1<<0)};
+   unsigned char *Show = new unsigned char[Cache.Head().PackageCount];
+   unsigned char *Flags = new unsigned char[Cache.Head().PackageCount];
+   unsigned char *ShapeMap = new unsigned char[Cache.Head().PackageCount];
+   
+   // Show everything if no arguments given
+   if (CmdL.FileList[1] == 0)
+      for (unsigned long I = 0; I != Cache.Head().PackageCount; I++)
+        Show[I] = ToShow;
+   else
+      for (unsigned long I = 0; I != Cache.Head().PackageCount; I++)
+        Show[I] = None;
+   memset(Flags,0,sizeof(*Flags)*Cache.Head().PackageCount);
+   
+   // Map the shapes
+   for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
+   {   
+      if (Pkg->VersionList == 0)
+      {
+        // Missing
+        if (Pkg->ProvidesList == 0)
+           ShapeMap[Pkg->ID] = 0;
+        else
+           ShapeMap[Pkg->ID] = 1;
+      }
+      else
+      {
+        // Normal
+        if (Pkg->ProvidesList == 0)
+           ShapeMap[Pkg->ID] = 2;
+        else
+           ShapeMap[Pkg->ID] = 3;
+      }
+   }
+   
+   // Load the list of packages from the command line into the show list
+   for (const char **I = CmdL.FileList + 1; *I != 0; I++)
+   {
+      // Process per-package flags
+      string P = *I;
+      bool Force = false;
+      if (P.length() > 3)
+      {
+        if (P.end()[-1] == '^')
+        {
+           Force = true;
+           P.erase(P.end()-1);
+        }
+        
+        if (P.end()[-1] == ',')
+           P.erase(P.end()-1);
+      }
+      
+      // Locate the package
+      pkgCache::PkgIterator Pkg = Cache.FindPkg(P);
+      if (Pkg.end() == true)
+      {
+        _error->Warning(_("Unable to locate package %s"),*I);
+        continue;
+      }
+      Show[Pkg->ID] = ToShow;
+      
+      if (Force == true)
+        Flags[Pkg->ID] |= ForceNR;
+   }
+   
+   // Little header
+   cout << "graph: { title: \"packages\"" << endl <<
+     "xmax: 700 ymax: 700 x: 30 y: 30" << endl <<
+     "layout_downfactor: 8" << endl;
+
+   bool Act = true;
+   while (Act == true)
+   {
+      Act = false;
+      for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
+      {
+        // See we need to show this package
+        if (Show[Pkg->ID] == None || Show[Pkg->ID] >= DoneNR)
+           continue;
+
+        //printf ("node: { title: \"%s\" label: \"%s\" }\n", Pkg.Name(), Pkg.Name());
+        
+        // Colour as done
+        if (Show[Pkg->ID] == ToShowNR || (Flags[Pkg->ID] & ForceNR) == ForceNR)
+        {
+           // Pure Provides and missing packages have no deps!
+           if (ShapeMap[Pkg->ID] == 0 || ShapeMap[Pkg->ID] == 1)
+              Show[Pkg->ID] = Done;
+           else
+              Show[Pkg->ID] = DoneNR;
+        }       
+        else
+           Show[Pkg->ID] = Done;
+        Act = true;
+
+        // No deps to map out
+        if (Pkg->VersionList == 0 || Show[Pkg->ID] == DoneNR)
+           continue;
+        
+        pkgCache::VerIterator Ver = Pkg.VersionList();
+        for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++)
+        {
+           // See if anything can meet this dep
+           // Walk along the actual package providing versions
+           bool Hit = false;
+           pkgCache::PkgIterator DPkg = D.TargetPkg();
+           for (pkgCache::VerIterator I = DPkg.VersionList();
+                     I.end() == false && Hit == false; I++)
+           {
+              if (Cache.VS->CheckDep(I.VerStr(),D->CompareOp,D.TargetVer()) == true)
+                 Hit = true;
+           }
+           
+           // Follow all provides
+           for (pkgCache::PrvIterator I = DPkg.ProvidesList(); 
+                     I.end() == false && Hit == false; I++)
+           {
+              if (Cache.VS->CheckDep(I.ProvideVersion(),D->CompareOp,D.TargetVer()) == false)
+                 Hit = true;
+           }
+           
+
+           // Only graph critical deps     
+           if (D.IsCritical() == true)
+           {
+              printf ("edge: { sourcename: \"%s\" targetname: \"%s\" class: 2 ",Pkg.Name(), D.TargetPkg().Name() );
+              
+              // Colour the node for recursion
+              if (Show[D.TargetPkg()->ID] <= DoneNR)
+              {
+                 /* If a conflicts does not meet anything in the database
+                    then show the relation but do not recurse */
+                 if (Hit == false && 
+                     (D->Type == pkgCache::Dep::Conflicts ||
+                      D->Type == pkgCache::Dep::Obsoletes))
+                 {
+                    if (Show[D.TargetPkg()->ID] == None && 
+                        Show[D.TargetPkg()->ID] != ToShow)
+                       Show[D.TargetPkg()->ID] = ToShowNR;
+                 }               
+                 else
+                 {
+                    if (GivenOnly == true && Show[D.TargetPkg()->ID] != ToShow)
+                       Show[D.TargetPkg()->ID] = ToShowNR;
+                    else
+                       Show[D.TargetPkg()->ID] = ToShow;
+                 }
+              }
+              
+              // Edge colour
+              switch(D->Type)
+              {
+                 case pkgCache::Dep::Conflicts:
+                   printf("label: \"conflicts\" color: lightgreen }\n");
+                   break;
+                 case pkgCache::Dep::Obsoletes:
+                   printf("label: \"obsoletes\" color: lightgreen }\n");
+                   break;
+                 
+                 case pkgCache::Dep::PreDepends:
+                   printf("label: \"predepends\" color: blue }\n");
+                   break;
+                 
+                 default:
+                   printf("}\n");
+                 break;
+              }               
+           }       
+        }
+      }
+   }   
+   
+   /* Draw the box colours after the fact since we can not tell what colour
+      they should be until everything is finished drawing */
+   for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
+   {
+      if (Show[Pkg->ID] < DoneNR)
+        continue;
+
+      if (Show[Pkg->ID] == DoneNR)
+        printf("node: { title: \"%s\" label: \"%s\" color: orange shape: %s }\n", Pkg.Name(), Pkg.Name(),
+               Shapes[ShapeMap[Pkg->ID]]);
+      else
+       printf("node: { title: \"%s\" label: \"%s\" shape: %s }\n", Pkg.Name(), Pkg.Name(), 
+               Shapes[ShapeMap[Pkg->ID]]);
+      
+   }
+   
+   printf("}\n");
+   return true;
+}
+                                                                       /*}}}*/
+
+
+// Dotty - Generate a graph for Dotty                                  /*{{{*/
+// ---------------------------------------------------------------------
+/* Dotty is the graphvis program for generating graphs. It is a fairly
+   simple queuing algorithm that just writes dependencies and nodes. 
+   http://www.research.att.com/sw/tools/graphviz/ */
+bool Dotty(CommandLine &CmdL)
+{
+   pkgCache &Cache = *GCache;
+   bool GivenOnly = _config->FindB("APT::Cache::GivenOnly",false);
+   
+   /* Normal packages are boxes
+      Pure Provides are triangles
+      Mixed are diamonds
+      Hexagons are missing packages*/
+   const char *Shapes[] = {"hexagon","triangle","box","diamond"};
+   
+   /* Initialize the list of packages to show.
+      1 = To Show
+      2 = To Show no recurse
+      3 = Emitted no recurse
+      4 = Emitted
+      0 = None */
+   enum States {None=0, ToShow, ToShowNR, DoneNR, Done};
+   enum TheFlags {ForceNR=(1<<0)};
+   unsigned char *Show = new unsigned char[Cache.Head().PackageCount];
+   unsigned char *Flags = new unsigned char[Cache.Head().PackageCount];
+   unsigned char *ShapeMap = new unsigned char[Cache.Head().PackageCount];
+   
+   // Show everything if no arguments given
+   if (CmdL.FileList[1] == 0)
+      for (unsigned long I = 0; I != Cache.Head().PackageCount; I++)
+        Show[I] = ToShow;
+   else
+      for (unsigned long I = 0; I != Cache.Head().PackageCount; I++)
+        Show[I] = None;
+   memset(Flags,0,sizeof(*Flags)*Cache.Head().PackageCount);
+   
+   // Map the shapes
+   for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
+   {   
+      if (Pkg->VersionList == 0)
+      {
+        // Missing
+        if (Pkg->ProvidesList == 0)
+           ShapeMap[Pkg->ID] = 0;
+        else
+           ShapeMap[Pkg->ID] = 1;
+      }
+      else
+      {
+        // Normal
+        if (Pkg->ProvidesList == 0)
+           ShapeMap[Pkg->ID] = 2;
+        else
+           ShapeMap[Pkg->ID] = 3;
+      }
+   }
+   
+   // Load the list of packages from the command line into the show list
+   for (const char **I = CmdL.FileList + 1; *I != 0; I++)
+   {
+      // Process per-package flags
+      string P = *I;
+      bool Force = false;
+      if (P.length() > 3)
+      {
+        if (P.end()[-1] == '^')
+        {
+           Force = true;
+           P.erase(P.end()-1);
+        }
+        
+        if (P.end()[-1] == ',')
+           P.erase(P.end()-1);
+      }
+      
+      // Locate the package
+      pkgCache::PkgIterator Pkg = Cache.FindPkg(P);
+      if (Pkg.end() == true)
+      {
+        _error->Warning(_("Unable to locate package %s"),*I);
+        continue;
+      }
+      Show[Pkg->ID] = ToShow;
+      
+      if (Force == true)
+        Flags[Pkg->ID] |= ForceNR;
+   }
+   
+   // Little header
+   printf("digraph packages {\n");
+   printf("concentrate=true;\n");
+   printf("size=\"30,40\";\n");
+   
+   bool Act = true;
+   while (Act == true)
+   {
+      Act = false;
+      for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
+      {
+        // See we need to show this package
+        if (Show[Pkg->ID] == None || Show[Pkg->ID] >= DoneNR)
+           continue;
+        
+        // Colour as done
+        if (Show[Pkg->ID] == ToShowNR || (Flags[Pkg->ID] & ForceNR) == ForceNR)
+        {
+           // Pure Provides and missing packages have no deps!
+           if (ShapeMap[Pkg->ID] == 0 || ShapeMap[Pkg->ID] == 1)
+              Show[Pkg->ID] = Done;
+           else
+              Show[Pkg->ID] = DoneNR;
+        }       
+        else
+           Show[Pkg->ID] = Done;
+        Act = true;
+
+        // No deps to map out
+        if (Pkg->VersionList == 0 || Show[Pkg->ID] == DoneNR)
+           continue;
+        
+        pkgCache::VerIterator Ver = Pkg.VersionList();
+        for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++)
+        {
+           // See if anything can meet this dep
+           // Walk along the actual package providing versions
+           bool Hit = false;
+           pkgCache::PkgIterator DPkg = D.TargetPkg();
+           for (pkgCache::VerIterator I = DPkg.VersionList();
+                     I.end() == false && Hit == false; I++)
+           {
+              if (Cache.VS->CheckDep(I.VerStr(),D->CompareOp,D.TargetVer()) == true)
+                 Hit = true;
+           }
+           
+           // Follow all provides
+           for (pkgCache::PrvIterator I = DPkg.ProvidesList(); 
+                     I.end() == false && Hit == false; I++)
+           {
+              if (Cache.VS->CheckDep(I.ProvideVersion(),D->CompareOp,D.TargetVer()) == false)
+                 Hit = true;
+           }
+           
+           // Only graph critical deps     
+           if (D.IsCritical() == true)
+           {
+              printf("\"%s\" -> \"%s\"",Pkg.Name(),D.TargetPkg().Name());
+              
+              // Colour the node for recursion
+              if (Show[D.TargetPkg()->ID] <= DoneNR)
+              {
+                 /* If a conflicts does not meet anything in the database
+                    then show the relation but do not recurse */
+                 if (Hit == false && 
+                     (D->Type == pkgCache::Dep::Conflicts ||
+                      D->Type == pkgCache::Dep::Obsoletes))
+                 {
+                    if (Show[D.TargetPkg()->ID] == None && 
+                        Show[D.TargetPkg()->ID] != ToShow)
+                       Show[D.TargetPkg()->ID] = ToShowNR;
+                 }               
+                 else
+                 {
+                    if (GivenOnly == true && Show[D.TargetPkg()->ID] != ToShow)
+                       Show[D.TargetPkg()->ID] = ToShowNR;
+                    else
+                       Show[D.TargetPkg()->ID] = ToShow;
+                 }
+              }
+              
+              // Edge colour
+              switch(D->Type)
+              {
+                 case pkgCache::Dep::Conflicts:
+                 case pkgCache::Dep::Obsoletes:
+                 printf("[color=springgreen];\n");
+                 break;
+                 
+                 case pkgCache::Dep::PreDepends:
+                 printf("[color=blue];\n");
+                 break;
+                 
+                 default:
+                 printf(";\n");
+                 break;
+              }               
+           }       
+        }
+      }
+   }   
+   
+   /* Draw the box colours after the fact since we can not tell what colour
+      they should be until everything is finished drawing */
+   for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
+   {
+      if (Show[Pkg->ID] < DoneNR)
+        continue;
+      
+      // Orange box for early recursion stoppage
+      if (Show[Pkg->ID] == DoneNR)
+        printf("\"%s\" [color=orange,shape=%s];\n",Pkg.Name(),
+               Shapes[ShapeMap[Pkg->ID]]);
+      else
+        printf("\"%s\" [shape=%s];\n",Pkg.Name(),
+               Shapes[ShapeMap[Pkg->ID]]);
+   }
+   
+   printf("}\n");
+   return true;
+}
+                                                                       /*}}}*/
+// DoAdd - Perform an adding operation                                 /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DoAdd(CommandLine &CmdL)
+{
+   return _error->Error("Unimplemented");
+#if 0   
+   // Make sure there is at least one argument
+   if (CmdL.FileSize() <= 1)
+      return _error->Error("You must give at least one file name");
+   
+   // Open the cache
+   FileFd CacheF(_config->FindFile("Dir::Cache::pkgcache"),FileFd::WriteAny);
+   if (_error->PendingError() == true)
+      return false;
+   
+   DynamicMMap Map(CacheF,MMap::Public);
+   if (_error->PendingError() == true)
+      return false;
+
+   OpTextProgress Progress(*_config);
+   pkgCacheGenerator Gen(Map,Progress);
+   if (_error->PendingError() == true)
+      return false;
+
+   unsigned long Length = CmdL.FileSize() - 1;
+   for (const char **I = CmdL.FileList + 1; *I != 0; I++)
+   {
+      Progress.OverallProgress(I - CmdL.FileList,Length,1,"Generating cache");
+      Progress.SubProgress(Length);
+
+      // Do the merge
+      FileFd TagF(*I,FileFd::ReadOnly);
+      debListParser Parser(TagF);
+      if (_error->PendingError() == true)
+        return _error->Error("Problem opening %s",*I);
+      
+      if (Gen.SelectFile(*I,"") == false)
+        return _error->Error("Problem with SelectFile");
+        
+      if (Gen.MergeList(Parser) == false)
+        return _error->Error("Problem with MergeList");
+   }
+
+   Progress.Done();
+   GCache = &Gen.GetCache();
+   Stats(CmdL);
+   
+   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 ||
+       fwrite(Buffer,1,V.FileList()->Size+1,stdout) < (size_t)(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;
+
+   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"));
+}
+                                                                       /*}}}*/
+// 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());
+        }       
+      }      
+   }
+   
+   return true;
+}
+                                                                       /*}}}*/
+// Madison - Look a bit like katie's madison                           /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool Madison(CommandLine &CmdL)
+{
+   if (SrcList == 0)
+      return _error->Error("Generate must be enabled for this function");
+
+   SrcList->ReadMainList();
+
+   pkgCache &Cache = *GCache;
+
+   // Create the src text record parsers and ignore errors about missing
+   // deb-src lines that are generated from pkgSrcRecords::pkgSrcRecords
+   pkgSrcRecords SrcRecs(*SrcList);
+   if (_error->PendingError() == true)
+      _error->Discard();
+
+   for (const char **I = CmdL.FileList + 1; *I != 0; I++)
+   {
+      pkgCache::PkgIterator Pkg = Cache.FindPkg(*I);
+
+      if (Pkg.end() == false)
+      {
+         for (pkgCache::VerIterator V = Pkg.VersionList(); V.end() == false; V++)
+         {
+            for (pkgCache::VerFileIterator VF = V.FileList(); VF.end() == false; VF++)
+            {
+// This might be nice, but wouldn't uniquely identify the source -mdz
+//                if (VF.File().Archive() != 0)
+//                {
+//                   cout << setw(10) << Pkg.Name() << " | " << setw(10) << V.VerStr() << " | "
+//                        << VF.File().Archive() << endl;
+//                }
+
+               // Locate the associated index files so we can derive a description
+               for (pkgSourceList::const_iterator S = SrcList->begin(); S != SrcList->end(); S++)
+               {
+                    vector<pkgIndexFile *> *Indexes = (*S)->GetIndexFiles();
+                    for (vector<pkgIndexFile *>::const_iterator IF = Indexes->begin();
+                         IF != Indexes->end(); IF++)
+                    {
+                         if ((*IF)->FindInCache(*(VF.File().Cache())) == VF.File())
+                         {
+                                   cout << setw(10) << Pkg.Name() << " | " << setw(10) << V.VerStr() << " | "
+                                        << (*IF)->Describe(true) << endl;
+                         }
+                    }
+               }
+            }
+         }
+      }
+
+      
+      SrcRecs.Restart();
+      pkgSrcRecords::Parser *SrcParser;
+      while ((SrcParser = SrcRecs.Find(*I,false)) != 0)
+      {
+         // Maybe support Release info here too eventually
+         cout << setw(10) << SrcParser->Package() << " | "
+              << setw(10) << SrcParser->Version() << " | "
+              << SrcParser->Index().Describe(true) << endl;
+      }
+   }
+
+   return true;
+}
+
+                                                                       /*}}}*/
+// GenCaches - Call the main cache generator                           /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool GenCaches(CommandLine &Cmd)
+{
+   OpTextProgress Progress(*_config);
+   
+   pkgSourceList List;
+   if (List.ReadMainList() == false)
+      return false;   
+   return pkgMakeStatusCache(List,Progress);
+}
+                                                                       /*}}}*/
+// ShowHelp - Show a help screen                                       /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool ShowHelp(CommandLine &Cmd)
+{
+   ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
+           COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
+   
+   if (_config->FindB("version") == true)
+     return true;
+
+   cout << 
+    _("Usage: apt-cache [options] command\n"
+      "       apt-cache [options] add file1 [file2 ...]\n"
+      "       apt-cache [options] showpkg pkg1 [pkg2 ...]\n"
+      "       apt-cache [options] showsrc pkg1 [pkg2 ...]\n"
+      "\n"
+      "apt-cache is a low-level tool used to manipulate APT's binary\n"
+      "cache files, and query information from them\n"
+      "\n"
+      "Commands:\n"
+      "   add - Add a package file to the source cache\n"
+      "   gencaches - Build both the package and source cache\n"
+      "   showpkg - Show some general information for a single package\n"
+      "   showsrc - Show source records\n"
+      "   stats - Show some basic statistics\n"
+      "   dump - Show the entire file in a terse form\n"
+      "   dumpavail - Print an available file to stdout\n"
+      "   unmet - Show unmet dependencies\n"
+      "   search - Search the package list for a regex pattern\n"
+      "   show - Show a readable record for the package\n"
+      "   depends - Show raw dependency information for a package\n"
+      "   rdepends - Show reverse dependency information for a package\n"
+      "   pkgnames - List the names of all packages\n"
+      "   dotty - Generate package graphs for GraphVis\n"
+      "   xvcg - Generate package graphs for xvcg\n"
+      "   policy - Show policy settings\n"
+      "\n"
+      "Options:\n"
+      "  -h   This help text.\n"
+      "  -p=? The package cache.\n"
+      "  -s=? The source cache.\n"
+      "  -q   Disable progress indicator.\n"
+      "  -i   Show only important deps for the unmet command.\n"
+      "  -c=? Read this configuration file\n"
+      "  -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
+      "See the apt-cache(8) and apt.conf(5) manual pages for more information.\n");
+   return true;
+}
+                                                                       /*}}}*/
+// CacheInitialize - Initialize things for apt-cache                   /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void CacheInitialize()
+{
+   _config->Set("quiet",0);
+   _config->Set("help",false);
+}
+                                                                       /*}}}*/
+
+int main(int argc,const char *argv[])
+{
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
+   CommandLine::Args Args[] = {
+      {'h',"help","help",0},
+      {'v',"version","version",0},
+      {'p',"pkg-cache","Dir::Cache::pkgcache",CommandLine::HasArg},
+      {'s',"src-cache","Dir::Cache::srcpkgcache",CommandLine::HasArg},
+      {'q',"quiet","quiet",CommandLine::IntLevel},
+      {'i',"important","APT::Cache::Important",0},
+      {'f',"full","APT::Cache::ShowFull",0},
+      {'g',"generate","APT::Cache::Generate",0},
+      {'a',"all-versions","APT::Cache::AllVersions",0},
+      {'n',"names-only","APT::Cache::NamesOnly",0},
+      {0,"all-names","APT::Cache::AllNames",0},
+      {0,"recurse","APT::Cache::RecurseDepends",0},
+      {'c',"config-file",0,CommandLine::ConfigFile},
+      {'o',"option",0,CommandLine::ArbItem},
+      {0,"installed","APT::Cache::Installed",0},
+      {0,0,0,0}};
+   CommandLine::Dispatch CmdsA[] = {{"help",&ShowHelp},
+                                    {"add",&DoAdd},
+                                    {"gencaches",&GenCaches},
+                                    {"showsrc",&ShowSrcPackage},
+                                    {0,0}};
+   CommandLine::Dispatch CmdsB[] = {{"showpkg",&DumpPackage},
+                                    {"stats",&Stats},
+                                    {"dump",&Dump},
+                                    {"dumpavail",&DumpAvail},
+                                    {"unmet",&UnMet},
+                                    {"search",&Search},
+                                    {"depends",&Depends},
+                                    {"rdepends",&RDepends},
+                                    {"dotty",&Dotty},
+                                    {"xvcg",&XVcg},
+                                    {"show",&ShowPackage},
+                                    {"pkgnames",&ShowPkgNames},
+                                    {"policy",&Policy},
+                                    {"madison",&Madison},
+                                    {0,0}};
+
+   CacheInitialize();
+
+   // Set up gettext support
+   setlocale(LC_ALL,"");
+   textdomain(PACKAGE);
+
+   // Parse the command line and initialize the package library
+   CommandLine CmdL(Args,_config);
+   if (pkgInitConfig(*_config) == false ||
+       CmdL.Parse(argc,argv) == false ||
+       pkgInitSystem(*_config,_system) == false)
+   {
+      _error->DumpErrors();
+      return 100;
+   }
+
+   // See if the help should be shown
+   if (_config->FindB("help") == true ||
+       CmdL.FileSize() == 0)
+   {
+      ShowHelp(CmdL);
+      return 0;
+   }
+   
+   // Deal with stdout not being a tty
+   if (isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1)
+      _config->Set("quiet","1");
+
+   if (CmdL.DispatchArg(CmdsA,false) == false && _error->PendingError() == false)
+   { 
+      MMap *Map = 0;
+      if (_config->FindB("APT::Cache::Generate",true) == false)
+      {
+        Map = new MMap(*new FileFd(_config->FindFile("Dir::Cache::pkgcache"),
+                                   FileFd::ReadOnly),MMap::Public|MMap::ReadOnly);
+      }
+      else
+      {
+        // Open the cache file
+        SrcList = new pkgSourceList;
+        SrcList->ReadMainList();
+
+        // Generate it and map it
+        OpProgress Prog;
+        pkgMakeStatusCache(*SrcList,Prog,&Map,true);
+      }
+      
+      if (_error->PendingError() == false)
+      {
+        pkgCache Cache(Map);   
+        GCache = &Cache;
+        if (_error->PendingError() == false)
+           CmdL.DispatchArg(CmdsB);
+      }
+      delete Map;
+   }
+   
+   // Print any errors or warnings found during parsing
+   if (_error->empty() == false)
+   {
+      bool Errors = _error->PendingError();
+      _error->DumpErrors();
+      return Errors == true?100:0;
+   }
+          
+   return 0;
+}
index 3e5a1a7eee99a64c579171653da1c7a48c5a4fbd..7d11585cc9160275b6de3d688e69fef247af6685 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // $Id: apt-cdrom.cc,v 1.45 2003/11/19 23:50:51 mdz Exp $
@@ -167,6 +171,13 @@ int ShowHelp()
 
 int main(int argc,const char *argv[])
 {
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
    CommandLine::Args Args[] = {
       {'h',"help","help",0},
       {'v',"version","version",0},
diff --git a/cmdline/apt-cdrom.cc.orig b/cmdline/apt-cdrom.cc.orig
new file mode 100644 (file)
index 0000000..3ce0fd7
--- /dev/null
@@ -0,0 +1,235 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
+// -*- mode: cpp; mode: fold -*-
+// Description                                                         /*{{{*/
+// $Id: apt-cdrom.cc,v 1.45 2003/11/19 23:50:51 mdz Exp $
+/* ######################################################################
+   
+   APT CDROM - Tool for handling APT's CDROM database.
+   
+   Currently the only option is 'add' which will take the current CD
+   in the drive and add it into the database.
+   
+   ##################################################################### */
+                                                                       /*}}}*/
+// Include Files                                                       /*{{{*/
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/cdromutl.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/acquire.h>
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/cdrom.h>
+#include <config.h>
+#include <apti18n.h>
+    
+//#include "indexcopy.h"
+
+#include <locale.h>
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <algorithm>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <stdio.h>
+                                                                       /*}}}*/
+
+using namespace std;
+
+                                                                        /*{{{*/
+class pkgCdromTextStatus : public pkgCdromStatus
+{
+protected:
+   OpTextProgress Progress;
+   void Prompt(const char *Text); 
+   string PromptLine(const char *Text);
+   bool AskCdromName(string &name);
+
+public:
+   virtual void Update(string text, int current);
+   virtual bool ChangeCdrom();
+   virtual OpProgress* GetOpProgress();
+};
+
+void pkgCdromTextStatus::Prompt(const char *Text) 
+{
+   char C;
+   cout << Text << ' ' << flush;
+   read(STDIN_FILENO,&C,1);
+   if (C != '\n')
+      cout << endl;
+}
+
+string pkgCdromTextStatus::PromptLine(const char *Text)
+{
+   cout << Text << ':' << endl;
+   
+   string Res;
+   getline(cin,Res);
+   return Res;
+}
+
+bool pkgCdromTextStatus::AskCdromName(string &name) 
+{
+   cout << _("Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'") << flush;
+   name = PromptLine("");
+        
+   return true;
+}
+   
+
+void pkgCdromTextStatus::Update(string text, int current) 
+{
+   if(text.size() > 0)
+      cout << text << flush;
+}
+
+bool pkgCdromTextStatus::ChangeCdrom() 
+{
+   Prompt(_("Please insert a Disc in the drive and press enter"));
+   return true;
+}
+
+OpProgress* pkgCdromTextStatus::GetOpProgress() 
+{ 
+   return &Progress; 
+};
+
+                                                                       /*}}}*/
+
+// DoAdd - Add a new CDROM                                             /*{{{*/
+// ---------------------------------------------------------------------
+/* This does the main add bit.. We show some status and things. The
+   sequence is to mount/umount the CD, Ident it then scan it for package 
+   files and reduce that list. Then we copy over the package files and
+   verify them. Then rewrite the database files */
+bool DoAdd(CommandLine &)
+{
+   bool res = false;
+   pkgCdromTextStatus log;
+   pkgCdrom cdrom;
+   res = cdrom.Add(&log);
+   if(res)
+      cout << _("Repeat this process for the rest of the CDs in your set.") << endl;
+   return res;
+}
+                                                                       /*}}}*/
+// DoIdent - Ident a CDROM                                             /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DoIdent(CommandLine &)
+{
+   string ident;
+   pkgCdromTextStatus log;
+   pkgCdrom cdrom;
+   return cdrom.Ident(ident, &log);
+}
+                                                                       /*}}}*/
+
+// ShowHelp - Show the help screen                                     /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+int ShowHelp()
+{
+   ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
+           COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
+   if (_config->FindB("version") == true)
+      return 0;
+   
+   cout << 
+      "Usage: apt-cdrom [options] command\n"
+      "\n"
+      "apt-cdrom is a tool to add CDROM's to APT's source list. The\n"
+      "CDROM mount point and device information is taken from apt.conf\n"
+      "and /etc/fstab.\n"
+      "\n"
+      "Commands:\n"
+      "   add - Add a CDROM\n"
+      "   ident - Report the identity of a CDROM\n"
+      "\n"
+      "Options:\n"
+      "  -h   This help text\n"
+      "  -d   CD-ROM mount point\n"
+      "  -r   Rename a recognized CD-ROM\n"
+      "  -m   No mounting\n"
+      "  -f   Fast mode, don't check package files\n"
+      "  -a   Thorough scan mode\n"
+      "  -c=? Read this configuration file\n"
+      "  -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
+      "See fstab(5)\n";
+   return 0;
+}
+                                                                       /*}}}*/
+
+int main(int argc,const char *argv[])
+{
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
+   CommandLine::Args Args[] = {
+      {'h',"help","help",0},
+      {'v',"version","version",0},
+      {'d',"cdrom","Acquire::cdrom::mount",CommandLine::HasArg},
+      {'r',"rename","APT::CDROM::Rename",0},
+      {'m',"no-mount","APT::CDROM::NoMount",0},
+      {'f',"fast","APT::CDROM::Fast",0},
+      {'n',"just-print","APT::CDROM::NoAct",0},
+      {'n',"recon","APT::CDROM::NoAct",0},      
+      {'n',"no-act","APT::CDROM::NoAct",0},
+      {'a',"thorough","APT::CDROM::Thorough",0},
+      {'c',"config-file",0,CommandLine::ConfigFile},
+      {'o',"option",0,CommandLine::ArbItem},
+      {0,0,0,0}};
+   CommandLine::Dispatch Cmds[] = {
+      {"add",&DoAdd},
+      {"ident",&DoIdent},
+      {0,0}};
+
+   // Set up gettext support
+   setlocale(LC_ALL,"");
+   textdomain(PACKAGE);
+
+   // Parse the command line and initialize the package library
+   CommandLine CmdL(Args,_config);
+   if (pkgInitConfig(*_config) == false ||
+       CmdL.Parse(argc,argv) == false ||
+       pkgInitSystem(*_config,_system) == false)
+   {
+      _error->DumpErrors();
+      return 100;
+   }
+
+   // See if the help should be shown
+   if (_config->FindB("help") == true || _config->FindB("version") == true ||
+       CmdL.FileSize() == 0)
+      return ShowHelp();
+
+   // Deal with stdout not being a tty
+   if (isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1)
+      _config->Set("quiet","1");
+   
+   // Match the operation
+   CmdL.DispatchArg(Cmds);
+
+   // Print any errors or warnings found during parsing
+   if (_error->empty() == false)
+   {
+      bool Errors = _error->PendingError();
+      _error->DumpErrors();
+      return Errors == true?100:0;
+   }
+   
+   return 0;
+}
index 58d945efa88b178a3dd944538a141db6328a89d8..faf11640c6c1bfdf7c58bcfc5644da7fca6077b3 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // $Id: apt-config.cc,v 1.11 2003/01/11 07:18:44 jgg Exp $
@@ -91,6 +95,13 @@ int ShowHelp()
 
 int main(int argc,const char *argv[])
 {
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
    CommandLine::Args Args[] = {
       {'h',"help","help",0},
       {'v',"version","version",0},
diff --git a/cmdline/apt-config.cc.orig b/cmdline/apt-config.cc.orig
new file mode 100644 (file)
index 0000000..0805c8e
--- /dev/null
@@ -0,0 +1,146 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
+// -*- mode: cpp; mode: fold -*-
+// Description                                                         /*{{{*/
+// $Id: apt-config.cc,v 1.11 2003/01/11 07:18:44 jgg Exp $
+/* ######################################################################
+   
+   APT Config - Program to manipulate APT configuration files
+   
+   This program will parse a config file and then do something with it.
+   
+   Commands:
+     shell - Shell mode. After this a series of word pairs should occure.
+             The first is the environment var to set and the second is
+             the key to set it from. Use like: 
+ eval `apt-config shell QMode apt::QMode`
+   
+   ##################################################################### */
+                                                                       /*}}}*/
+// Include Files                                                       /*{{{*/
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/strutl.h>
+
+#include <config.h>
+#include <apti18n.h>
+
+#include <locale.h>
+#include <iostream>
+#include <string>
+                                                                       /*}}}*/
+using namespace std;
+
+// DoShell - Handle the shell command                                  /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DoShell(CommandLine &CmdL)
+{
+   for (const char **I = CmdL.FileList + 1; *I != 0; I += 2)
+   {
+      if (I[1] == 0 || strlen(I[1]) == 0)
+        return _error->Error(_("Arguments not in pairs"));
+
+      string key = I[1];
+      if (key.end()[-1] == '/') // old directory format
+        key.append("d");
+
+      if (_config->ExistsAny(key.c_str()))
+        cout << *I << "='" << 
+                SubstVar(_config->FindAny(key.c_str()),"'","'\\''") << '\'' << endl;
+      
+   }
+   
+   return true;
+}
+                                                                       /*}}}*/
+// DoDump - Dump the configuration space                               /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DoDump(CommandLine &CmdL)
+{
+   _config->Dump(cout);
+   return true;
+}
+                                                                       /*}}}*/
+// ShowHelp - Show the help screen                                     /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+int ShowHelp()
+{
+   ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
+           COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
+   if (_config->FindB("version") == true)
+      return 0;
+   
+   cout <<
+    _("Usage: apt-config [options] command\n"
+      "\n"
+      "apt-config is a simple tool to read the APT config file\n"
+      "\n"
+      "Commands:\n"
+      "   shell - Shell mode\n"
+      "   dump - Show the configuration\n"
+      "\n"
+      "Options:\n"
+      "  -h   This help text.\n" 
+      "  -c=? Read this configuration file\n" 
+      "  -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n");
+   return 0;
+}
+                                                                       /*}}}*/
+
+int main(int argc,const char *argv[])
+{
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
+   CommandLine::Args Args[] = {
+      {'h',"help","help",0},
+      {'v',"version","version",0},
+      {'c',"config-file",0,CommandLine::ConfigFile},
+      {'o',"option",0,CommandLine::ArbItem},
+      {0,0,0,0}};
+   CommandLine::Dispatch Cmds[] = {{"shell",&DoShell},
+                                   {"dump",&DoDump},
+                                   {0,0}};
+
+   // Set up gettext support
+   setlocale(LC_ALL,"");
+   textdomain(PACKAGE);
+
+   // Parse the command line and initialize the package library
+   CommandLine CmdL(Args,_config);
+   if (pkgInitConfig(*_config) == false ||
+       CmdL.Parse(argc,argv) == false ||
+       pkgInitSystem(*_config,_system) == false)
+   {
+      _error->DumpErrors();
+      return 100;
+   }
+
+   // See if the help should be shown
+   if (_config->FindB("help") == true ||
+       CmdL.FileSize() == 0)
+      return ShowHelp();
+
+   // Match the operation
+   CmdL.DispatchArg(Cmds);
+   
+   // Print any errors or warnings found during parsing
+   if (_error->empty() == false)
+   {
+      bool Errors = _error->PendingError();
+      _error->DumpErrors();
+      return Errors == true?100:0;
+   }
+   
+   return 0;
+}
index a931b415fc1d275c871c31a5609469552da14d39..70020587354c0d74157981add5f90403ab22bef1 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // $Id: apt-extracttemplates.cc,v 1.15 2003/07/26 00:00:11 mdz Exp $
@@ -351,6 +355,13 @@ bool Go(CommandLine &CmdL)
 
 int main(int argc, const char **argv)
 {
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
        CommandLine::Args Args[] = {
                {'h',"help","help",0},
                {'v',"version","version",0},
diff --git a/cmdline/apt-extracttemplates.cc.orig b/cmdline/apt-extracttemplates.cc.orig
new file mode 100644 (file)
index 0000000..2edbfac
--- /dev/null
@@ -0,0 +1,404 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
+// -*- mode: cpp; mode: fold -*-
+// Description                                                         /*{{{*/
+// $Id: apt-extracttemplates.cc,v 1.15 2003/07/26 00:00:11 mdz Exp $
+/* ######################################################################
+   
+   APT Extract Templates - Program to extract debconf config and template
+                           files
+
+   This is a simple program to extract config and template information 
+   from Debian packages. It can be used to speed up the preconfiguration
+   process for debconf-enabled packages
+   
+   ##################################################################### */
+                                                                       /*}}}*/
+// Include Files                                                       /*{{{*/
+#include <apt-pkg/init.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/pkgcache.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/pkgcachegen.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/extracttar.h>
+#include <apt-pkg/arfile.h>
+#include <apt-pkg/deblistparser.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
+       
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fstream>
+
+#include <locale.h>
+#include <config.h>
+#include <apti18n.h>
+#include "apt-extracttemplates.h"
+                                                                       /*}}}*/
+
+using namespace std;
+
+#define TMPDIR         "/tmp"
+
+pkgCache *DebFile::Cache = 0;
+
+// DebFile::DebFile - Construct the DebFile object                     /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+DebFile::DebFile(const char *debfile)
+       : File(debfile, FileFd::ReadOnly), Control(0), DepOp(0), 
+          PreDepOp(0), Config(0), Template(0), Which(None)
+{
+}
+                                                                       /*}}}*/
+// DebFile::~DebFile - Destruct the DebFile object                     /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+DebFile::~DebFile()
+{
+       delete [] Control;
+       delete [] Config;
+       delete [] Template;
+}
+                                                                       /*}}}*/
+// DebFile::GetInstalledVer - Find out the installed version of a pkg  /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string DebFile::GetInstalledVer(const string &package)
+{
+       pkgCache::PkgIterator Pkg = Cache->FindPkg(package);
+       if (Pkg.end() == false) 
+       {
+               pkgCache::VerIterator V = Pkg.CurrentVer();
+               if (V.end() == false)
+               {
+                       return V.VerStr();
+               }
+       }
+
+       return string();
+}
+                                                                       /*}}}*/
+// DebFile::Go - Start extracting a debian package                     /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DebFile::Go()
+{
+       ARArchive AR(File);
+       if (_error->PendingError() == true)
+               return false;
+               
+       const ARArchive::Member *Member = AR.FindMember("control.tar.gz");
+       if (Member == 0)
+               return _error->Error(_("%s not a valid DEB package."),File.Name().c_str());
+       
+       if (File.Seek(Member->Start) == false)
+               return false;
+       ExtractTar Tar(File, Member->Size,"gzip");
+       return Tar.Go(*this);
+}
+                                                                       /*}}}*/
+// DebFile::DoItem examine element in package and mark                 /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DebFile::DoItem(Item &I, int &Fd)
+{
+       if (strcmp(I.Name, "control") == 0)
+       {
+               delete [] Control;
+               Control = new char[I.Size+1];
+               Control[I.Size] = 0;
+               Which = IsControl;
+               ControlLen = I.Size;
+               // make it call the Process method below. this is so evil
+               Fd = -2;
+       }
+       else if (strcmp(I.Name, "config") == 0)
+       {
+               delete [] Config;
+               Config = new char[I.Size+1];
+               Config[I.Size] = 0;
+               Which = IsConfig;
+               Fd = -2; 
+       } 
+       else if (strcmp(I.Name, "templates") == 0)
+       {
+               delete [] Template;
+               Template = new char[I.Size+1];
+               Template[I.Size] = 0;
+               Which = IsTemplate;
+               Fd = -2;
+       } 
+       else 
+       {
+               // Ignore it
+               Fd = -1;
+       }
+       return true;
+}
+                                                                       /*}}}*/
+// DebFile::Process examine element in package and copy                        /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DebFile::Process(Item &I, const unsigned char *data, 
+               unsigned long size, unsigned long pos)
+{
+       switch (Which)
+       {
+       case IsControl:
+               memcpy(Control + pos, data, size);
+               break;
+       case IsConfig:
+               memcpy(Config + pos, data, size);
+               break;
+       case IsTemplate:
+               memcpy(Template + pos, data, size);
+               break;
+       default: /* throw it away */ ;
+       }
+       return true;
+}
+                                                                       /*}}}*/
+// DebFile::ParseInfo - Parse control file for dependency info         /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DebFile::ParseInfo()
+{
+       if (Control == NULL) return false;
+       
+       pkgTagSection Section;
+       Section.Scan(Control, ControlLen);
+
+       Package = Section.FindS("Package");
+       Version = GetInstalledVer(Package);
+
+       const char *Start, *Stop;
+       if (Section.Find("Depends", Start, Stop) == true)
+       {
+               while (1)
+               {
+                       string P, V;
+                       unsigned int Op;
+                       Start = debListParser::ParseDepends(Start, Stop, P, V, Op);
+                       if (Start == 0) return false;
+                       if (P == "debconf")
+                       {
+                               DepVer = V;
+                               DepOp = Op;
+                               break;
+                       }
+                       if (Start == Stop) break;
+               }
+       }
+       
+       if (Section.Find("Pre-Depends", Start, Stop) == true)
+       {
+               while (1)
+               {
+                       string P, V;
+                       unsigned int Op;
+                       Start = debListParser::ParseDepends(Start, Stop, P, V, Op);
+                       if (Start == 0) return false;
+                       if (P == "debconf")
+                       {
+                               PreDepVer = V;
+                               PreDepOp = Op;
+                               break;
+                       }
+                       if (Start == Stop) break;
+               }
+       }
+       
+       return true;
+}
+                                                                       /*}}}*/
+// ShowHelp - show a short help text                                   /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+int ShowHelp(void)
+{
+       ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
+           COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
+
+       if (_config->FindB("version") == true) 
+               return 0;
+
+       cout << 
+               _("Usage: apt-extracttemplates file1 [file2 ...]\n"
+               "\n"
+               "apt-extracttemplates is a tool to extract config and template info\n"
+               "from debian packages\n"
+               "\n"
+               "Options:\n"
+               "  -h   This help text\n"
+               "  -t   Set the temp dir\n"
+               "  -c=? Read this configuration file\n"
+               "  -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n");
+       return 0;
+}
+                                                                       /*}}}*/
+// WriteFile - write the contents of the passed string to a file       /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string WriteFile(const char *package, const char *prefix, const char *data)
+{
+       char fn[512];
+       static int i;
+        char *tempdir = NULL;
+
+        tempdir = getenv("TMPDIR");
+        if (tempdir == NULL)
+             tempdir = TMPDIR;
+
+       snprintf(fn, sizeof(fn), "%s/%s.%s.%u%d",
+                 _config->Find("APT::ExtractTemplates::TempDir", tempdir).c_str(),
+                 package, prefix, getpid(), i++);
+       FileFd f;
+       if (data == NULL)
+               data = "";
+
+       if (!f.Open(fn, FileFd::WriteTemp, 0600))
+       {
+               _error->Errno("ofstream::ofstream",_("Unable to write to %s"),fn);
+               return string();
+       }
+
+       f.Write(data, strlen(data));
+       f.Close();
+       return fn;
+}
+                                                                       /*}}}*/
+// WriteConfig - write out the config data from a debian package file  /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void WriteConfig(const DebFile &file)
+{
+       string templatefile = WriteFile(file.Package.c_str(), "template", file.Template);
+       string configscript = WriteFile(file.Package.c_str(), "config", file.Config);
+
+       if (templatefile.empty() == true || configscript.empty() == true)
+               return;
+       cout << file.Package << " " << file.Version << " " 
+            << templatefile << " " << configscript << endl;
+}
+                                                                       /*}}}*/
+// InitCache - initialize the package cache                            /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool Go(CommandLine &CmdL)
+{      
+       // Initialize the apt cache
+       MMap *Map = 0;
+       pkgSourceList List;
+       List.ReadMainList();
+       OpProgress Prog;
+       pkgMakeStatusCache(List,Prog,&Map,true);
+       if (Map == 0)
+          return false;
+       DebFile::Cache = new pkgCache(Map);
+       if (_error->PendingError() == true)
+               return false;
+
+       // Find out what version of debconf is currently installed
+       string debconfver = DebFile::GetInstalledVer("debconf");
+       if (debconfver.empty() == true)
+               return _error->Error( _("Cannot get debconf version. Is debconf installed?"));
+
+       // Process each package passsed in
+       for (unsigned int I = 0; I != CmdL.FileSize(); I++)
+       {
+               // Will pick up the errors later..
+               DebFile file(CmdL.FileList[I]);
+               if (file.Go() == false)
+               {
+                       _error->Error("Prior errors apply to %s",CmdL.FileList[I]);
+                       continue;
+               }
+
+               // Does the package have templates?
+               if (file.Template != 0 && file.ParseInfo() == true)
+               {
+                       // Check to make sure debconf dependencies are
+                       // satisfied
+                       // cout << "Check " << file.DepVer << ',' << debconfver << endl;
+                       if (file.DepVer != "" &&
+                           DebFile::Cache->VS->CheckDep(debconfver.c_str(),
+                                       file.DepOp,file.DepVer.c_str()
+                                                        ) == false)
+                               continue;
+                       if (file.PreDepVer != "" &&
+                           DebFile::Cache->VS->CheckDep(debconfver.c_str(),
+                                       file.PreDepOp,file.PreDepVer.c_str()
+                                                        ) == false) 
+                               continue;
+
+                       WriteConfig(file);
+               }
+       }
+       
+
+       delete Map;
+       delete DebFile::Cache;
+       
+       return !_error->PendingError();
+}
+                                                                       /*}}}*/
+
+int main(int argc, const char **argv)
+{
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
+       CommandLine::Args Args[] = {
+               {'h',"help","help",0},
+               {'v',"version","version",0},
+               {'t',"tempdir","APT::ExtractTemplates::TempDir",CommandLine::HasArg},
+               {'c',"config-file",0,CommandLine::ConfigFile},
+               {'o',"option",0,CommandLine::ArbItem},
+               {0,0,0,0}};
+
+       // Set up gettext support
+       setlocale(LC_ALL,"");
+       textdomain(PACKAGE);
+
+       // Parse the command line and initialize the package library
+       CommandLine CmdL(Args,_config);
+       if (pkgInitConfig(*_config) == false ||
+           CmdL.Parse(argc,argv) == false ||
+           pkgInitSystem(*_config,_system) == false)
+       {
+               _error->DumpErrors();
+               return 100;
+       }
+       
+       // See if the help should be shown
+       if (_config->FindB("help") == true ||
+           CmdL.FileSize() == 0)
+               return ShowHelp();
+       
+       Go(CmdL);
+
+       // Print any errors or warnings found during operation
+       if (_error->empty() == false)
+       {
+               // This goes to stderr..
+               bool Errors = _error->PendingError();
+               _error->DumpErrors();
+               return Errors == true?100:0;
+       }
+       
+       return 0;
+}
index 7cae6e18bc856a9e333b389a5946b65e33f8d86f..8b2788603028b362e79e8f73df6343a48f5b9ab9 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // $Id: apt-get.cc,v 1.156 2004/08/28 01:05:16 mdz Exp $
@@ -2504,6 +2508,13 @@ void SigWinch(int)
 
 int main(int argc,const char *argv[])
 {
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
    CommandLine::Args Args[] = {
       {'h',"help","help",0},
       {'v',"version","version",0},
diff --git a/cmdline/apt-get.cc.orig b/cmdline/apt-get.cc.orig
new file mode 100644 (file)
index 0000000..f623710
--- /dev/null
@@ -0,0 +1,2628 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
+// -*- mode: cpp; mode: fold -*-
+// Description                                                         /*{{{*/
+// $Id: apt-get.cc,v 1.156 2004/08/28 01:05:16 mdz Exp $
+/* ######################################################################
+   
+   apt-get - Cover for dpkg
+   
+   This is an allout cover for dpkg implementing a safer front end. It is
+   based largely on libapt-pkg.
+
+   The syntax is different, 
+      apt-get [opt] command [things]
+   Where command is:
+      update - Resyncronize the package files from their sources
+      upgrade - Smart-Download the newest versions of all packages
+      dselect-upgrade - Follows dselect's changes to the Status: field
+                       and installes new and removes old packages
+      dist-upgrade - Powerfull upgrader designed to handle the issues with
+                    a new distribution.
+      install - Download and install a given package (by name, not by .deb)
+      check - Update the package cache and check for broken packages
+      clean - Erase the .debs downloaded to /var/cache/apt/archives and
+              the partial dir too
+
+   ##################################################################### */
+                                                                       /*}}}*/
+// Include Files                                                       /*{{{*/
+#include <apt-pkg/error.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/depcache.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/clean.h>
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/md5.h>
+#include <apt-pkg/versionmatch.h>
+    
+#include <config.h>
+#include <apti18n.h>
+
+#include "acqprogress.h"
+
+#include <set>
+#include <locale.h>
+#include <langinfo.h>
+#include <fstream>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <regex.h>
+#include <sys/wait.h>
+                                                                       /*}}}*/
+
+using namespace std;
+
+ostream c0out(0);
+ostream c1out(0);
+ostream c2out(0);
+ofstream devnull("/dev/null");
+unsigned int ScreenWidth = 80 - 1; /* - 1 for the cursor */
+
+// class CacheFile - Cover class for some dependency cache functions   /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+class CacheFile : public pkgCacheFile
+{
+   static pkgCache *SortCache;
+   static int NameComp(const void *a,const void *b);
+   
+   public:
+   pkgCache::Package **List;
+   
+   void Sort();
+   bool CheckDeps(bool AllowBroken = false);
+   bool BuildCaches(bool WithLock = true)
+   {
+      OpTextProgress Prog(*_config);
+      if (pkgCacheFile::BuildCaches(Prog,WithLock) == false)
+        return false;
+      return true;
+   }
+   bool Open(bool WithLock = true) 
+   {
+      OpTextProgress Prog(*_config);
+      if (pkgCacheFile::Open(Prog,WithLock) == false)
+        return false;
+      Sort();
+      
+      return true;
+   };
+   bool OpenForInstall()
+   {
+      if (_config->FindB("APT::Get::Print-URIs") == true)
+        return Open(false);
+      else
+        return Open(true);
+   }
+   CacheFile() : List(0) {};
+};
+                                                                       /*}}}*/
+
+// YnPrompt - Yes No Prompt.                                           /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns true on a Yes.*/
+bool YnPrompt(bool Default=true)
+{
+   if (_config->FindB("APT::Get::Assume-Yes",false) == true)
+   {
+      c1out << _("Y") << endl;
+      return true;
+   }
+
+   char response[1024] = "";
+   cin.getline(response, sizeof(response));
+
+   if (!cin)
+      return false;
+
+   if (strlen(response) == 0)
+      return Default;
+
+   regex_t Pattern;
+   int Res;
+
+   Res = regcomp(&Pattern, nl_langinfo(YESEXPR),
+                 REG_EXTENDED|REG_ICASE|REG_NOSUB);
+
+   if (Res != 0) {
+      char Error[300];        
+      regerror(Res,&Pattern,Error,sizeof(Error));
+      return _error->Error(_("Regex compilation error - %s"),Error);
+   }
+   
+   Res = regexec(&Pattern, response, 0, NULL, 0);
+   if (Res == 0)
+      return true;
+   return false;
+}
+                                                                       /*}}}*/
+// AnalPrompt - Annoying Yes No Prompt.                                        /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns true on a Yes.*/
+bool AnalPrompt(const char *Text)
+{
+   char Buf[1024];
+   cin.getline(Buf,sizeof(Buf));
+   if (strcmp(Buf,Text) == 0)
+      return true;
+   return false;
+}
+                                                                       /*}}}*/
+// ShowList - Show a list                                              /*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out a string of space separated words with a title and 
+   a two space indent line wraped to the current screen width. */
+bool ShowList(ostream &out,string Title,string List,string VersionsList)
+{
+   if (List.empty() == true)
+      return true;
+   // trim trailing space
+   int NonSpace = List.find_last_not_of(' ');
+   if (NonSpace != -1)
+   {
+      List = List.erase(NonSpace + 1);
+      if (List.empty() == true)
+        return true;
+   }
+
+   // Acount for the leading space
+   int ScreenWidth = ::ScreenWidth - 3;
+      
+   out << Title << endl;
+   string::size_type Start = 0;
+   string::size_type VersionsStart = 0;
+   while (Start < List.size())
+   {
+      if(_config->FindB("APT::Get::Show-Versions",false) == true &&
+         VersionsList.size() > 0) {
+         string::size_type End;
+         string::size_type VersionsEnd;
+         
+         End = List.find(' ',Start);
+         VersionsEnd = VersionsList.find('\n', VersionsStart);
+
+         out << "   " << string(List,Start,End - Start) << " (" << 
+            string(VersionsList,VersionsStart,VersionsEnd - VersionsStart) << 
+            ")" << endl;
+
+        if (End == string::npos || End < Start)
+           End = Start + ScreenWidth;
+
+         Start = End + 1;
+         VersionsStart = VersionsEnd + 1;
+      } else {
+         string::size_type End;
+
+         if (Start + ScreenWidth >= List.size())
+            End = List.size();
+         else
+            End = List.rfind(' ',Start+ScreenWidth);
+
+         if (End == string::npos || End < Start)
+            End = Start + ScreenWidth;
+         out << "  " << string(List,Start,End - Start) << endl;
+         Start = End + 1;
+      }
+   }   
+
+   return false;
+}
+                                                                       /*}}}*/
+// ShowBroken - Debugging aide                                         /*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out the names of all the packages that are broken along
+   with the name of each each broken dependency and a quite version 
+   description.
+   
+   The output looks like:
+ The following packages have unmet dependencies:
+     exim: Depends: libc6 (>= 2.1.94) but 2.1.3-10 is to be installed
+           Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed
+           Depends: libsasl7 but it is not going to be installed   
+ */
+void ShowBroken(ostream &out,CacheFile &Cache,bool Now)
+{
+   out << _("The following packages have unmet dependencies:") << endl;
+   for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+   {
+      pkgCache::PkgIterator I(Cache,Cache.List[J]);
+      
+      if (Now == true)
+      {
+        if (Cache[I].NowBroken() == false)
+           continue;
+      }
+      else
+      {
+        if (Cache[I].InstBroken() == false)
+           continue;
+      }
+      
+      // Print out each package and the failed dependencies
+      out <<"  " <<  I.Name() << ":";
+      unsigned Indent = strlen(I.Name()) + 3;
+      bool First = true;
+      pkgCache::VerIterator Ver;
+      
+      if (Now == true)
+        Ver = I.CurrentVer();
+      else
+        Ver = Cache[I].InstVerIter(Cache);
+      
+      if (Ver.end() == true)
+      {
+        out << endl;
+        continue;
+      }
+      
+      for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;)
+      {
+        // Compute a single dependency element (glob or)
+        pkgCache::DepIterator Start;
+        pkgCache::DepIterator End;
+        D.GlobOr(Start,End); // advances D
+
+        if (Cache->IsImportantDep(End) == false)
+           continue;
+        
+        if (Now == true)
+        {
+           if ((Cache[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow)
+              continue;
+        }
+        else
+        {
+           if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
+              continue;
+        }
+        
+        bool FirstOr = true;
+        while (1)
+        {
+           if (First == false)
+              for (unsigned J = 0; J != Indent; J++)
+                 out << ' ';
+           First = false;
+
+           if (FirstOr == false)
+           {
+              for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++)
+                 out << ' ';
+           }
+           else
+              out << ' ' << End.DepType() << ": ";
+           FirstOr = false;
+           
+           out << Start.TargetPkg().Name();
+        
+           // Show a quick summary of the version requirements
+           if (Start.TargetVer() != 0)
+              out << " (" << Start.CompType() << " " << Start.TargetVer() << ")";
+           
+           /* Show a summary of the target package if possible. In the case
+              of virtual packages we show nothing */    
+           pkgCache::PkgIterator Targ = Start.TargetPkg();
+           if (Targ->ProvidesList == 0)
+           {
+              out << ' ';
+              pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache);
+              if (Now == true)
+                 Ver = Targ.CurrentVer();
+                   
+              if (Ver.end() == false)
+              {
+                 if (Now == true)
+                    ioprintf(out,_("but %s is installed"),Ver.VerStr());
+                 else
+                    ioprintf(out,_("but %s is to be installed"),Ver.VerStr());
+              }               
+              else
+              {
+                 if (Cache[Targ].CandidateVerIter(Cache).end() == true)
+                 {
+                    if (Targ->ProvidesList == 0)
+                       out << _("but it is not installable");
+                    else
+                       out << _("but it is a virtual package");
+                 }               
+                 else
+                    out << (Now?_("but it is not installed"):_("but it is not going to be installed"));
+              }               
+           }
+           
+           if (Start != End)
+              out << _(" or");
+           out << endl;
+           
+           if (Start == End)
+              break;
+           Start++;
+        }       
+      }            
+   }   
+}
+                                                                       /*}}}*/
+// ShowNew - Show packages to newly install                            /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void ShowNew(ostream &out,CacheFile &Cache)
+{
+   /* Print out a list of packages that are going to be installed extra
+      to what the user asked */
+   string List;
+   string VersionsList;
+   for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+   {
+      pkgCache::PkgIterator I(Cache,Cache.List[J]);
+      if (Cache[I].NewInstall() == true) {
+         List += string(I.Name()) + " ";
+         VersionsList += string(Cache[I].CandVersion) + "\n";
+      }
+   }
+   
+   ShowList(out,_("The following NEW packages will be installed:"),List,VersionsList);
+}
+                                                                       /*}}}*/
+// ShowDel - Show packages to delete                                   /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void ShowDel(ostream &out,CacheFile &Cache)
+{
+   /* Print out a list of packages that are going to be removed extra
+      to what the user asked */
+   string List;
+   string VersionsList;
+   for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+   {
+      pkgCache::PkgIterator I(Cache,Cache.List[J]);
+      if (Cache[I].Delete() == true)
+      {
+        if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
+           List += string(I.Name()) + "* ";
+        else
+           List += string(I.Name()) + " ";
+     
+     VersionsList += string(Cache[I].CandVersion)+ "\n";
+      }
+   }
+   
+   ShowList(out,_("The following packages will be REMOVED:"),List,VersionsList);
+}
+                                                                       /*}}}*/
+// ShowKept - Show kept packages                                       /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void ShowKept(ostream &out,CacheFile &Cache)
+{
+   string List;
+   string VersionsList;
+   for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+   {    
+      pkgCache::PkgIterator I(Cache,Cache.List[J]);
+      
+      // Not interesting
+      if (Cache[I].Upgrade() == true || Cache[I].Upgradable() == false ||
+         I->CurrentVer == 0 || Cache[I].Delete() == true)
+        continue;
+      
+      List += string(I.Name()) + " ";
+      VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
+   }
+   ShowList(out,_("The following packages have been kept back:"),List,VersionsList);
+}
+                                                                       /*}}}*/
+// ShowUpgraded - Show upgraded packages                               /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void ShowUpgraded(ostream &out,CacheFile &Cache)
+{
+   string List;
+   string VersionsList;
+   for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+   {
+      pkgCache::PkgIterator I(Cache,Cache.List[J]);
+      
+      // Not interesting
+      if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
+        continue;
+      
+      List += string(I.Name()) + " ";
+      VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
+   }
+   ShowList(out,_("The following packages will be upgraded:"),List,VersionsList);
+}
+                                                                       /*}}}*/
+// ShowDowngraded - Show downgraded packages                           /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool ShowDowngraded(ostream &out,CacheFile &Cache)
+{
+   string List;
+   string VersionsList;
+   for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+   {
+      pkgCache::PkgIterator I(Cache,Cache.List[J]);
+      
+      // Not interesting
+      if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true)
+        continue;
+      
+      List += string(I.Name()) + " ";
+      VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
+   }
+   return ShowList(out,_("The following packages will be DOWNGRADED:"),List,VersionsList);
+}
+                                                                       /*}}}*/
+// ShowHold - Show held but changed packages                           /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool ShowHold(ostream &out,CacheFile &Cache)
+{
+   string List;
+   string VersionsList;
+   for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+   {
+      pkgCache::PkgIterator I(Cache,Cache.List[J]);
+      if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() &&
+          I->SelectedState == pkgCache::State::Hold) {
+         List += string(I.Name()) + " ";
+                VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
+      }
+   }
+
+   return ShowList(out,_("The following held packages will be changed:"),List,VersionsList);
+}
+                                                                       /*}}}*/
+// ShowEssential - Show an essential package warning                   /*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out a warning message that is not to be ignored. It shows
+   all essential packages and their dependents that are to be removed. 
+   It is insanely risky to remove the dependents of an essential package! */
+bool ShowEssential(ostream &out,CacheFile &Cache)
+{
+   string List;
+   string VersionsList;
+   bool *Added = new bool[Cache->Head().PackageCount];
+   for (unsigned int I = 0; I != Cache->Head().PackageCount; I++)
+      Added[I] = false;
+   
+   for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+   {
+      pkgCache::PkgIterator I(Cache,Cache.List[J]);
+      if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential &&
+         (I->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important)
+        continue;
+      
+      // The essential package is being removed
+      if (Cache[I].Delete() == true)
+      {
+        if (Added[I->ID] == false)
+        {
+           Added[I->ID] = true;
+           List += string(I.Name()) + " ";
+        //VersionsList += string(Cache[I].CurVersion) + "\n"; ???
+        }
+      }
+      
+      if (I->CurrentVer == 0)
+        continue;
+
+      // Print out any essential package depenendents that are to be removed
+      for (pkgCache::DepIterator D = I.CurrentVer().DependsList(); D.end() == false; D++)
+      {
+        // Skip everything but depends
+        if (D->Type != pkgCache::Dep::PreDepends &&
+            D->Type != pkgCache::Dep::Depends)
+           continue;
+        
+        pkgCache::PkgIterator P = D.SmartTargetPkg();
+        if (Cache[P].Delete() == true)
+        {
+           if (Added[P->ID] == true)
+              continue;
+           Added[P->ID] = true;
+           
+           char S[300];
+           snprintf(S,sizeof(S),_("%s (due to %s) "),P.Name(),I.Name());
+           List += S;
+        //VersionsList += "\n"; ???
+        }       
+      }      
+   }
+   
+   delete [] Added;
+   return ShowList(out,_("WARNING: The following essential packages will be removed.\n"
+                        "This should NOT be done unless you know exactly what you are doing!"),List,VersionsList);
+}
+
+                                                                       /*}}}*/
+// Stats - Show some statistics                                                /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void Stats(ostream &out,pkgDepCache &Dep)
+{
+   unsigned long Upgrade = 0;
+   unsigned long Downgrade = 0;
+   unsigned long Install = 0;
+   unsigned long ReInstall = 0;
+   for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; I++)
+   {
+      if (Dep[I].NewInstall() == true)
+        Install++;
+      else
+      {
+        if (Dep[I].Upgrade() == true)
+           Upgrade++;
+        else
+           if (Dep[I].Downgrade() == true)
+              Downgrade++;
+      }
+      
+      if (Dep[I].Delete() == false && (Dep[I].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)
+        ReInstall++;
+   }   
+
+   ioprintf(out,_("%lu upgraded, %lu newly installed, "),
+           Upgrade,Install);
+   
+   if (ReInstall != 0)
+      ioprintf(out,_("%lu reinstalled, "),ReInstall);
+   if (Downgrade != 0)
+      ioprintf(out,_("%lu downgraded, "),Downgrade);
+
+   ioprintf(out,_("%lu to remove and %lu not upgraded.\n"),
+           Dep.DelCount(),Dep.KeepCount());
+   
+   if (Dep.BadCount() != 0)
+      ioprintf(out,_("%lu not fully installed or removed.\n"),
+              Dep.BadCount());
+}
+                                                                       /*}}}*/
+
+// CacheFile::NameComp - QSort compare by name                         /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+pkgCache *CacheFile::SortCache = 0;
+int CacheFile::NameComp(const void *a,const void *b)
+{
+   if (*(pkgCache::Package **)a == 0 || *(pkgCache::Package **)b == 0)
+      return *(pkgCache::Package **)a - *(pkgCache::Package **)b;
+   
+   const pkgCache::Package &A = **(pkgCache::Package **)a;
+   const pkgCache::Package &B = **(pkgCache::Package **)b;
+
+   return strcmp(SortCache->StrP + A.Name,SortCache->StrP + B.Name);
+}
+                                                                       /*}}}*/
+// CacheFile::Sort - Sort by name                                      /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void CacheFile::Sort()
+{
+   delete [] List;
+   List = new pkgCache::Package *[Cache->Head().PackageCount];
+   memset(List,0,sizeof(*List)*Cache->Head().PackageCount);
+   pkgCache::PkgIterator I = Cache->PkgBegin();
+   for (;I.end() != true; I++)
+      List[I->ID] = I;
+
+   SortCache = *this;
+   qsort(List,Cache->Head().PackageCount,sizeof(*List),NameComp);
+}
+                                                                       /*}}}*/
+// CacheFile::CheckDeps - Open the cache file                          /*{{{*/
+// ---------------------------------------------------------------------
+/* This routine generates the caches and then opens the dependency cache
+   and verifies that the system is OK. */
+bool CacheFile::CheckDeps(bool AllowBroken)
+{
+   if (_error->PendingError() == true)
+      return false;
+
+   // Check that the system is OK
+   if (DCache->DelCount() != 0 || DCache->InstCount() != 0)
+      return _error->Error("Internal error, non-zero counts");
+   
+   // Apply corrections for half-installed packages
+   if (pkgApplyStatus(*DCache) == false)
+      return false;
+   
+   // Nothing is broken
+   if (DCache->BrokenCount() == 0 || AllowBroken == true)
+      return true;
+
+   // Attempt to fix broken things
+   if (_config->FindB("APT::Get::Fix-Broken",false) == true)
+   {
+      c1out << _("Correcting dependencies...") << flush;
+      if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0)
+      {
+        c1out << _(" failed.") << endl;
+        ShowBroken(c1out,*this,true);
+
+        return _error->Error(_("Unable to correct dependencies"));
+      }
+      if (pkgMinimizeUpgrade(*DCache) == false)
+        return _error->Error(_("Unable to minimize the upgrade set"));
+      
+      c1out << _(" Done") << endl;
+   }
+   else
+   {
+      c1out << _("You might want to run `apt-get -f install' to correct these.") << endl;
+      ShowBroken(c1out,*this,true);
+
+      return _error->Error(_("Unmet dependencies. Try using -f."));
+   }
+      
+   return true;
+}
+
+static bool CheckAuth(pkgAcquire& Fetcher)
+{
+   string UntrustedList;
+   for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd(); ++I)
+   {
+      if (!(*I)->IsTrusted())
+      {
+         UntrustedList += string((*I)->ShortDesc()) + " ";
+      }
+   }
+
+   if (UntrustedList == "")
+   {
+      return true;
+   }
+        
+   ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"),UntrustedList,"");
+
+   if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true)
+   {
+      c2out << _("Authentication warning overridden.\n");
+      return true;
+   }
+
+   if (_config->FindI("quiet",0) < 2
+       && _config->FindB("APT::Get::Assume-Yes",false) == false)
+   {
+      c2out << _("Install these packages without verification [y/N]? ") << flush;
+      if (!YnPrompt(false))
+         return _error->Error(_("Some packages could not be authenticated"));
+
+      return true;
+   }
+   else if (_config->FindB("APT::Get::Force-Yes",false) == true)
+   {
+      return true;
+   }
+
+   return _error->Error(_("There are problems and -y was used without --force-yes"));
+}
+
+
+                                                                       /*}}}*/
+
+// InstallPackages - Actually download and install the packages                /*{{{*/
+// ---------------------------------------------------------------------
+/* This displays the informative messages describing what is going to 
+   happen and then calls the download routines */
+bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
+                    bool Safety = true)
+{
+   if (_config->FindB("APT::Get::Purge",false) == true)
+   {
+      pkgCache::PkgIterator I = Cache->PkgBegin();
+      for (; I.end() == false; I++)
+      {
+        if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete)
+           Cache->MarkDelete(I,true);
+      }
+   }
+   
+   bool Fail = false;
+   bool Essential = false;
+   
+   // Show all the various warning indicators
+   ShowDel(c1out,Cache);
+   ShowNew(c1out,Cache);
+   if (ShwKept == true)
+      ShowKept(c1out,Cache);
+   Fail |= !ShowHold(c1out,Cache);
+   if (_config->FindB("APT::Get::Show-Upgraded",true) == true)
+      ShowUpgraded(c1out,Cache);
+   Fail |= !ShowDowngraded(c1out,Cache);
+   if (_config->FindB("APT::Get::Download-Only",false) == false)
+        Essential = !ShowEssential(c1out,Cache);
+   Fail |= Essential;
+   Stats(c1out,Cache);
+
+   // Sanity check
+   if (Cache->BrokenCount() != 0)
+   {
+      ShowBroken(c1out,Cache,false);
+      return _error->Error(_("Internal error, InstallPackages was called with broken packages!"));
+   }
+
+   if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
+       Cache->BadCount() == 0)
+      return true;
+
+   // No remove flag
+   if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false)
+      return _error->Error(_("Packages need to be removed but remove is disabled."));
+       
+   // Run the simulator ..
+   if (_config->FindB("APT::Get::Simulate") == true)
+   {
+      pkgSimulate PM(Cache);
+      int status_fd = _config->FindI("APT::Status-Fd",-1);
+      pkgPackageManager::OrderResult Res = PM.DoInstall(status_fd);
+      if (Res == pkgPackageManager::Failed)
+        return false;
+      if (Res != pkgPackageManager::Completed)
+        return _error->Error(_("Internal error, Ordering didn't finish"));
+      return true;
+   }
+   
+   // Create the text record parser
+   pkgRecords Recs(Cache);
+   if (_error->PendingError() == true)
+      return false;
+   
+   // Lock the archive directory
+   FileFd Lock;
+   if (_config->FindB("Debug::NoLocking",false) == false &&
+       _config->FindB("APT::Get::Print-URIs") == false)
+   {
+      Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
+      if (_error->PendingError() == true)
+        return _error->Error(_("Unable to lock the download directory"));
+   }
+   
+   // Create the download object
+   AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));   
+   pkgAcquire Fetcher(&Stat);
+
+   // Read the source list
+   pkgSourceList List;
+   if (List.ReadMainList() == false)
+      return _error->Error(_("The list of sources could not be read."));
+   
+   // Create the package manager and prepare to download
+   SPtr<pkgPackageManager> PM= _system->CreatePM(Cache);
+   if (PM->GetArchives(&Fetcher,&List,&Recs) == false || 
+       _error->PendingError() == true)
+      return false;
+
+   // Display statistics
+   double FetchBytes = Fetcher.FetchNeeded();
+   double FetchPBytes = Fetcher.PartialPresent();
+   double DebBytes = Fetcher.TotalNeeded();
+   if (DebBytes != Cache->DebSize())
+   {
+      c0out << DebBytes << ',' << Cache->DebSize() << endl;
+      c0out << _("How odd.. The sizes didn't match, email apt@packages.debian.org") << endl;
+   }
+   
+   // Number of bytes
+   if (DebBytes != FetchBytes)
+      ioprintf(c1out,_("Need to get %sB/%sB of archives.\n"),
+              SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
+   else
+      ioprintf(c1out,_("Need to get %sB of archives.\n"),
+              SizeToStr(DebBytes).c_str());
+
+   // Size delta
+   if (Cache->UsrSize() >= 0)
+      ioprintf(c1out,_("After unpacking %sB of additional disk space will be used.\n"),
+              SizeToStr(Cache->UsrSize()).c_str());
+   else
+      ioprintf(c1out,_("After unpacking %sB disk space will be freed.\n"),
+              SizeToStr(-1*Cache->UsrSize()).c_str());
+
+   if (_error->PendingError() == true)
+      return false;
+
+   /* Check for enough free space, but only if we are actually going to
+      download */
+   if (_config->FindB("APT::Get::Print-URIs") == false &&
+       _config->FindB("APT::Get::Download",true) == true)
+   {
+      struct statvfs Buf;
+      string OutputDir = _config->FindDir("Dir::Cache::Archives");
+      if (statvfs(OutputDir.c_str(),&Buf) != 0)
+        return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
+                             OutputDir.c_str());
+      if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
+        return _error->Error(_("You don't have enough free space in %s."),
+                             OutputDir.c_str());
+   }
+   
+   // Fail safe check
+   if (_config->FindI("quiet",0) >= 2 ||
+       _config->FindB("APT::Get::Assume-Yes",false) == true)
+   {
+      if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false)
+        return _error->Error(_("There are problems and -y was used without --force-yes"));
+   }         
+
+   if (Essential == true && Safety == true)
+   {
+      if (_config->FindB("APT::Get::Trivial-Only",false) == true)
+        return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
+      
+      const char *Prompt = _("Yes, do as I say!");
+      ioprintf(c2out,
+              _("You are about to do something potentially harmful.\n"
+                "To continue type in the phrase '%s'\n"
+                " ?] "),Prompt);
+      c2out << flush;
+      if (AnalPrompt(Prompt) == false)
+      {
+        c2out << _("Abort.") << endl;
+        exit(1);
+      }     
+   }
+   else
+   {      
+      // Prompt to continue
+      if (Ask == true || Fail == true)
+      {            
+        if (_config->FindB("APT::Get::Trivial-Only",false) == true)
+           return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
+        
+        if (_config->FindI("quiet",0) < 2 &&
+            _config->FindB("APT::Get::Assume-Yes",false) == false)
+        {
+           c2out << _("Do you want to continue [Y/n]? ") << flush;
+        
+           if (YnPrompt() == false)
+           {
+              c2out << _("Abort.") << endl;
+              exit(1);
+           }     
+        }       
+      }      
+   }
+   
+   // Just print out the uris an exit if the --print-uris flag was used
+   if (_config->FindB("APT::Get::Print-URIs") == true)
+   {
+      pkgAcquire::UriIterator I = Fetcher.UriBegin();
+      for (; I != Fetcher.UriEnd(); I++)
+        cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
+              I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
+      return true;
+   }
+
+   if (!CheckAuth(Fetcher))
+      return false;
+
+   /* Unlock the dpkg lock if we are not going to be doing an install
+      after. */
+   if (_config->FindB("APT::Get::Download-Only",false) == true)
+      _system->UnLock();
+   
+   // Run it
+   while (1)
+   {
+      bool Transient = false;
+      if (_config->FindB("APT::Get::Download",true) == false)
+      {
+        for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
+        {
+           if ((*I)->Local == true)
+           {
+              I++;
+              continue;
+           }
+
+           // Close the item and check if it was found in cache
+           (*I)->Finished();
+           if ((*I)->Complete == false)
+              Transient = true;
+           
+           // Clear it out of the fetch list
+           delete *I;
+           I = Fetcher.ItemsBegin();
+        }       
+      }
+      
+      if (Fetcher.Run() == pkgAcquire::Failed)
+        return false;
+      
+      // Print out errors
+      bool Failed = false;
+      for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
+      {
+        if ((*I)->Status == pkgAcquire::Item::StatDone &&
+            (*I)->Complete == true)
+           continue;
+        
+        if ((*I)->Status == pkgAcquire::Item::StatIdle)
+        {
+           Transient = true;
+           // Failed = true;
+           continue;
+        }
+
+        fprintf(stderr,_("Failed to fetch %s  %s\n"),(*I)->DescURI().c_str(),
+                (*I)->ErrorText.c_str());
+        Failed = true;
+      }
+
+      /* If we are in no download mode and missing files and there were
+         'failures' then the user must specify -m. Furthermore, there 
+         is no such thing as a transient error in no-download mode! */
+      if (Transient == true &&
+         _config->FindB("APT::Get::Download",true) == false)
+      {
+        Transient = false;
+        Failed = true;
+      }
+      
+      if (_config->FindB("APT::Get::Download-Only",false) == true)
+      {
+        if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
+           return _error->Error(_("Some files failed to download"));
+        c1out << _("Download complete and in download only mode") << endl;
+        return true;
+      }
+      
+      if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
+      {
+        return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
+      }
+      
+      if (Transient == true && Failed == true)
+        return _error->Error(_("--fix-missing and media swapping is not currently supported"));
+      
+      // Try to deal with missing package files
+      if (Failed == true && PM->FixMissing() == false)
+      {
+        cerr << _("Unable to correct missing packages.") << endl;
+        return _error->Error(_("Aborting install."));
+      }
+                
+      _system->UnLock();
+      int status_fd = _config->FindI("APT::Status-Fd",-1);
+      pkgPackageManager::OrderResult Res = PM->DoInstall(status_fd);
+      if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
+        return false;
+      if (Res == pkgPackageManager::Completed)
+        return true;
+      
+      // Reload the fetcher object and loop again for media swapping
+      Fetcher.Shutdown();
+      if (PM->GetArchives(&Fetcher,&List,&Recs) == false)
+        return false;
+      
+      _system->Lock();
+   }   
+}
+                                                                       /*}}}*/
+// TryToInstall - Try to install a single package                      /*{{{*/
+// ---------------------------------------------------------------------
+/* This used to be inlined in DoInstall, but with the advent of regex package
+   name matching it was split out.. */
+bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
+                 pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
+                 unsigned int &ExpectedInst,bool AllowFail = true)
+{
+   /* This is a pure virtual package and there is a single available 
+      provides */
+   if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0 &&
+       Pkg.ProvidesList()->NextProvides == 0)
+   {
+      pkgCache::PkgIterator Tmp = Pkg.ProvidesList().OwnerPkg();
+      ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
+              Tmp.Name(),Pkg.Name());
+      Pkg = Tmp;
+   }
+   
+   // Handle the no-upgrade case
+   if (_config->FindB("APT::Get::upgrade",true) == false &&
+       Pkg->CurrentVer != 0)
+   {
+      if (AllowFail == true)
+        ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
+                 Pkg.Name());
+      return true;
+   }
+   
+   // Check if there is something at all to install
+   pkgDepCache::StateCache &State = Cache[Pkg];
+   if (Remove == true && Pkg->CurrentVer == 0)
+   {
+      Fix.Clear(Pkg);
+      Fix.Protect(Pkg);
+      Fix.Remove(Pkg);
+      
+      /* We want to continue searching for regex hits, so we return false here
+         otherwise this is not really an error. */
+      if (AllowFail == false)
+        return false;
+      
+      ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.Name());
+      return true;
+   }
+   
+   if (State.CandidateVer == 0 && Remove == false)
+   {
+      if (AllowFail == false)
+        return false;
+      
+      if (Pkg->ProvidesList != 0)
+      {
+        ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
+                 Pkg.Name());
+        
+        pkgCache::PrvIterator I = Pkg.ProvidesList();
+        for (; I.end() == false; I++)
+        {
+           pkgCache::PkgIterator Pkg = I.OwnerPkg();
+           
+           if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer())
+           {
+              if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
+                 c1out << "  " << Pkg.Name() << " " << I.OwnerVer().VerStr() <<
+                 _(" [Installed]") << endl;
+              else
+                 c1out << "  " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl;
+           }      
+        }
+        c1out << _("You should explicitly select one to install.") << endl;
+      }
+      else
+      {
+        ioprintf(c1out,
+        _("Package %s is not available, but is referred to by another package.\n"
+          "This may mean that the package is missing, has been obsoleted, or\n"
+           "is only available from another source\n"),Pkg.Name());
+        
+        string List;
+        string VersionsList;
+        SPtrArray<bool> Seen = new bool[Cache.Head().PackageCount];
+        memset(Seen,0,Cache.Head().PackageCount*sizeof(*Seen));
+        pkgCache::DepIterator Dep = Pkg.RevDependsList();
+        for (; Dep.end() == false; Dep++)
+        {
+           if (Dep->Type != pkgCache::Dep::Replaces)
+              continue;
+           if (Seen[Dep.ParentPkg()->ID] == true)
+              continue;
+           Seen[Dep.ParentPkg()->ID] = true;
+           List += string(Dep.ParentPkg().Name()) + " ";
+        //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ???
+        }          
+        ShowList(c1out,_("However the following packages replace it:"),List,VersionsList);
+      }
+      
+      _error->Error(_("Package %s has no installation candidate"),Pkg.Name());
+      return false;
+   }
+
+   Fix.Clear(Pkg);
+   Fix.Protect(Pkg);   
+   if (Remove == true)
+   {
+      Fix.Remove(Pkg);
+      Cache.MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
+      return true;
+   }
+   
+   // Install it
+   Cache.MarkInstall(Pkg,false);
+   if (State.Install() == false)
+   {
+      if (_config->FindB("APT::Get::ReInstall",false) == true)
+      {
+        if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
+           ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
+                    Pkg.Name());
+        else
+           Cache.SetReInstall(Pkg,true);
+      }      
+      else
+      {
+        if (AllowFail == true)
+           ioprintf(c1out,_("%s is already the newest version.\n"),
+                    Pkg.Name());
+      }      
+   }   
+   else
+      ExpectedInst++;
+   
+   // Install it with autoinstalling enabled.
+   if (State.InstBroken() == true && BrokenFix == false)
+      Cache.MarkInstall(Pkg,true);
+   return true;
+}
+                                                                       /*}}}*/
+// TryToChangeVer - Try to change a candidate version                  /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool TryToChangeVer(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
+                   const char *VerTag,bool IsRel)
+{
+   pkgVersionMatch Match(VerTag,(IsRel == true?pkgVersionMatch::Release : 
+                                pkgVersionMatch::Version));
+   
+   pkgCache::VerIterator Ver = Match.Find(Pkg);
+                        
+   if (Ver.end() == true)
+   {
+      if (IsRel == true)
+        return _error->Error(_("Release '%s' for '%s' was not found"),
+                             VerTag,Pkg.Name());
+      return _error->Error(_("Version '%s' for '%s' was not found"),
+                          VerTag,Pkg.Name());
+   }
+   
+   if (strcmp(VerTag,Ver.VerStr()) != 0)
+   {
+      ioprintf(c1out,_("Selected version %s (%s) for %s\n"),
+              Ver.VerStr(),Ver.RelStr().c_str(),Pkg.Name());
+   }
+   
+   Cache.SetCandidateVersion(Ver);
+   return true;
+}
+                                                                       /*}}}*/
+// FindSrc - Find a source record                                      /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
+                              pkgSrcRecords &SrcRecs,string &Src,
+                              pkgDepCache &Cache)
+{
+   // We want to pull the version off the package specification..
+   string VerTag;
+   string TmpSrc = Name;
+   string::size_type Slash = TmpSrc.rfind('=');
+
+   // honor default release
+   string DefRel = _config->Find("APT::Default-Release");
+   pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc);
+
+   if (Slash != string::npos)
+   {
+      VerTag = string(TmpSrc.begin() + Slash + 1,TmpSrc.end());
+      TmpSrc = string(TmpSrc.begin(),TmpSrc.begin() + Slash);
+   } 
+   else  if(!Pkg.end() && DefRel.empty() == false)
+   {
+      // we have a default release, try to locate the pkg. we do it like
+      // this because GetCandidateVer() will not "downgrade", that means
+      // "apt-get source -t stable apt" won't work on a unstable system
+      for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; 
+          Ver++)
+      {
+        for (pkgCache::VerFileIterator VF = Ver.FileList(); VF.end() == false;
+             VF++)
+        {
+           /* If this is the status file, and the current version is not the
+              version in the status file (ie it is not installed, or somesuch)
+              then it is not a candidate for installation, ever. This weeds
+              out bogus entries that may be due to config-file states, or
+              other. */
+           if ((VF.File()->Flags & pkgCache::Flag::NotSource) == 
+               pkgCache::Flag::NotSource && Pkg.CurrentVer() != Ver)
+           continue;
+           
+           //std::cout << VF.File().Archive() << std::endl;
+           if(VF.File().Archive() && (VF.File().Archive() == DefRel)) 
+           {
+              VerTag = Ver.VerStr();
+              break;
+           }
+        }
+      }
+   }
+
+   /* Lookup the version of the package we would install if we were to
+      install a version and determine the source package name, then look
+      in the archive for a source package of the same name. */
+   if (_config->FindB("APT::Get::Only-Source") == false)
+   {
+      if (Pkg.end() == false)
+      {
+        pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg);
+        if (Ver.end() == false)
+        {
+           pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
+           Src = Parse.SourcePkg();
+        }
+      }   
+   }
+   
+   // No source package name..
+   if (Src.empty() == true)
+      Src = TmpSrc;
+   
+   // The best hit
+   pkgSrcRecords::Parser *Last = 0;
+   unsigned long Offset = 0;
+   string Version;
+   bool IsMatch = false;
+   
+   // If we are matching by version then we need exact matches to be happy
+   if (VerTag.empty() == false)
+      IsMatch = true;
+   
+   /* Iterate over all of the hits, which includes the resulting
+      binary packages in the search */
+   pkgSrcRecords::Parser *Parse;
+   SrcRecs.Restart();
+   while ((Parse = SrcRecs.Find(Src.c_str(),false)) != 0)
+   {
+      string Ver = Parse->Version();
+      
+      // Skip name mismatches
+      if (IsMatch == true && Parse->Package() != Src)
+        continue;
+      
+      if (VerTag.empty() == false)
+      {
+        /* Don't want to fall through because we are doing exact version 
+           matching. */
+        if (Cache.VS().CmpVersion(VerTag,Ver) != 0)
+           continue;
+        
+        Last = Parse;
+        Offset = Parse->Offset();
+        break;
+      }
+                                 
+      // Newer version or an exact match
+      if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0 || 
+         (Parse->Package() == Src && IsMatch == false))
+      {
+        IsMatch = Parse->Package() == Src;
+        Last = Parse;
+        Offset = Parse->Offset();
+        Version = Ver;
+      }      
+   }
+   
+   if (Last == 0 || Last->Jump(Offset) == false)
+      return 0;
+   
+   return Last;
+}
+                                                                       /*}}}*/
+
+// DoUpdate - Update the package lists                                 /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DoUpdate(CommandLine &CmdL)
+{
+   if (CmdL.FileSize() != 1)
+      return _error->Error(_("The update command takes no arguments"));
+   
+   // Get the source list
+   pkgSourceList List;
+   if (List.ReadMainList() == false)
+      return false;
+
+   // Lock the list directory
+   FileFd Lock;
+   if (_config->FindB("Debug::NoLocking",false) == false)
+   {
+      Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
+      if (_error->PendingError() == true)
+        return _error->Error(_("Unable to lock the list directory"));
+   }
+   
+   // Create the download object
+   AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
+   pkgAcquire Fetcher(&Stat);
+
+   
+   // Just print out the uris an exit if the --print-uris flag was used
+   if (_config->FindB("APT::Get::Print-URIs") == true)
+   {
+      // Populate it with the source selection and get all Indexes 
+      // (GetAll=true)
+      if (List.GetIndexes(&Fetcher,true) == false)
+        return false;
+
+      pkgAcquire::UriIterator I = Fetcher.UriBegin();
+      for (; I != Fetcher.UriEnd(); I++)
+        cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
+              I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
+      return true;
+   }
+
+   // Populate it with the source selection
+   if (List.GetIndexes(&Fetcher) == false)
+        return false;
+   
+   // Run it
+   if (Fetcher.Run() == pkgAcquire::Failed)
+      return false;
+
+   bool Failed = false;
+   for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
+   {
+      if ((*I)->Status == pkgAcquire::Item::StatDone)
+        continue;
+
+      (*I)->Finished();
+      
+      fprintf(stderr,_("Failed to fetch %s  %s\n"),(*I)->DescURI().c_str(),
+             (*I)->ErrorText.c_str());
+      Failed = true;
+   }
+   
+   // Clean out any old list files
+   if (!Failed && _config->FindB("APT::Get::List-Cleanup",true) == true)
+   {
+      if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
+         Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
+        return false;
+   }
+   
+   // Prepare the cache.   
+   CacheFile Cache;
+   if (Cache.BuildCaches() == false)
+      return false;
+   
+   if (Failed == true)
+      return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead."));
+   
+   return true;
+}
+                                                                       /*}}}*/
+// DoUpgrade - Upgrade all packages                                    /*{{{*/
+// ---------------------------------------------------------------------
+/* Upgrade all packages without installing new packages or erasing old
+   packages */
+bool DoUpgrade(CommandLine &CmdL)
+{
+   CacheFile Cache;
+   if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
+      return false;
+
+   // Do the upgrade
+   if (pkgAllUpgrade(Cache) == false)
+   {
+      ShowBroken(c1out,Cache,false);
+      return _error->Error(_("Internal error, AllUpgrade broke stuff"));
+   }
+   
+   return InstallPackages(Cache,true);
+}
+                                                                       /*}}}*/
+// DoInstall - Install packages from the command line                  /*{{{*/
+// ---------------------------------------------------------------------
+/* Install named packages */
+bool DoInstall(CommandLine &CmdL)
+{
+   CacheFile Cache;
+   if (Cache.OpenForInstall() == false || 
+       Cache.CheckDeps(CmdL.FileSize() != 1) == false)
+      return false;
+   
+   // Enter the special broken fixing mode if the user specified arguments
+   bool BrokenFix = false;
+   if (Cache->BrokenCount() != 0)
+      BrokenFix = true;
+   
+   unsigned int ExpectedInst = 0;
+   unsigned int Packages = 0;
+   pkgProblemResolver Fix(Cache);
+   
+   bool DefRemove = false;
+   if (strcasecmp(CmdL.FileList[0],"remove") == 0)
+      DefRemove = true;
+
+   for (const char **I = CmdL.FileList + 1; *I != 0; I++)
+   {
+      // Duplicate the string
+      unsigned int Length = strlen(*I);
+      char S[300];
+      if (Length >= sizeof(S))
+        continue;
+      strcpy(S,*I);
+      
+      // See if we are removing and special indicators..
+      bool Remove = DefRemove;
+      char *VerTag = 0;
+      bool VerIsRel = false;
+      while (Cache->FindPkg(S).end() == true)
+      {
+        // Handle an optional end tag indicating what to do
+        if (Length >= 1 && S[Length - 1] == '-')
+        {
+           Remove = true;
+           S[--Length] = 0;
+           continue;
+        }
+        
+        if (Length >= 1 && S[Length - 1] == '+')
+        {
+           Remove = false;
+           S[--Length] = 0;
+           continue;
+        }
+        
+        char *Slash = strchr(S,'=');
+        if (Slash != 0)
+        {
+           VerIsRel = false;
+           *Slash = 0;
+           VerTag = Slash + 1;
+        }
+        
+        Slash = strchr(S,'/');
+        if (Slash != 0)
+        {
+           VerIsRel = true;
+           *Slash = 0;
+           VerTag = Slash + 1;
+        }
+        
+        break;
+      }
+      
+      // Locate the package
+      pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
+      Packages++;
+      if (Pkg.end() == true)
+      {
+        // Check if the name is a regex
+        const char *I;
+        for (I = S; *I != 0; I++)
+           if (*I == '?' || *I == '*' || *I == '|' ||
+               *I == '[' || *I == '^' || *I == '$')
+              break;
+        if (*I == 0)
+           return _error->Error(_("Couldn't find package %s"),S);
+
+        // Regexs must always be confirmed
+        ExpectedInst += 1000;
+        
+        // Compile the regex pattern
+        regex_t Pattern;
+        int Res;
+        if ((Res = regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE |
+                    REG_NOSUB)) != 0)
+        {
+           char Error[300];        
+           regerror(Res,&Pattern,Error,sizeof(Error));
+           return _error->Error(_("Regex compilation error - %s"),Error);
+        }
+        
+        // Run over the matches
+        bool Hit = false;
+        for (Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++)
+        {
+           if (regexec(&Pattern,Pkg.Name(),0,0,0) != 0)
+              continue;
+           
+           ioprintf(c1out,_("Note, selecting %s for regex '%s'\n"),
+                    Pkg.Name(),S);
+           
+           if (VerTag != 0)
+              if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
+                 return false;
+           
+           Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,
+                               ExpectedInst,false);
+        }
+        regfree(&Pattern);
+        
+        if (Hit == false)
+           return _error->Error(_("Couldn't find package %s"),S);
+      }
+      else
+      {
+        if (VerTag != 0)
+           if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
+              return false;
+        if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false)
+           return false;
+      }      
+   }
+
+   /* If we are in the Broken fixing mode we do not attempt to fix the
+      problems. This is if the user invoked install without -f and gave
+      packages */
+   if (BrokenFix == true && Cache->BrokenCount() != 0)
+   {
+      c1out << _("You might want to run `apt-get -f install' to correct these:") << endl;
+      ShowBroken(c1out,Cache,false);
+
+      return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
+   }
+   
+   // Call the scored problem resolver
+   Fix.InstallProtect();
+   if (Fix.Resolve(true) == false)
+      _error->Discard();
+
+   // Now we check the state of the packages,
+   if (Cache->BrokenCount() != 0)
+   {
+      c1out << 
+       _("Some packages could not be installed. This may mean that you have\n" 
+        "requested an impossible situation or if you are using the unstable\n" 
+        "distribution that some required packages have not yet been created\n"
+        "or been moved out of Incoming.") << endl;
+      if (Packages == 1)
+      {
+        c1out << endl;
+        c1out << 
+         _("Since you only requested a single operation it is extremely likely that\n"
+           "the package is simply not installable and a bug report against\n" 
+           "that package should be filed.") << endl;
+      }
+
+      c1out << _("The following information may help to resolve the situation:") << endl;
+      c1out << endl;
+      ShowBroken(c1out,Cache,false);
+      return _error->Error(_("Broken packages"));
+   }   
+   
+   /* Print out a list of packages that are going to be installed extra
+      to what the user asked */
+   if (Cache->InstCount() != ExpectedInst)
+   {
+      string List;
+      string VersionsList;
+      for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+      {
+        pkgCache::PkgIterator I(Cache,Cache.List[J]);
+        if ((*Cache)[I].Install() == false)
+           continue;
+
+        const char **J;
+        for (J = CmdL.FileList + 1; *J != 0; J++)
+           if (strcmp(*J,I.Name()) == 0)
+               break;
+        
+        if (*J == 0) {
+           List += string(I.Name()) + " ";
+        VersionsList += string(Cache[I].CandVersion) + "\n";
+     }
+      }
+      
+      ShowList(c1out,_("The following extra packages will be installed:"),List,VersionsList);
+   }
+
+   /* Print out a list of suggested and recommended packages */
+   {
+      string SuggestsList, RecommendsList, List;
+      string SuggestsVersions, RecommendsVersions;
+      for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+      {
+        pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
+
+        /* Just look at the ones we want to install */
+        if ((*Cache)[Pkg].Install() == false)
+          continue;
+
+        // get the recommends/suggests for the candidate ver
+        pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
+        for (pkgCache::DepIterator D = CV.DependsList(); D.end() == false; )
+        {
+           pkgCache::DepIterator Start;
+           pkgCache::DepIterator End;
+           D.GlobOr(Start,End); // advances D
+
+           // FIXME: we really should display a or-group as a or-group to the user
+           //        the problem is that ShowList is incapable of doing this
+           string RecommendsOrList,RecommendsOrVersions;
+           string SuggestsOrList,SuggestsOrVersions;
+           bool foundInstalledInOrGroup = false;
+           for(;;)
+           {
+              /* Skip if package is  installed already, or is about to be */
+              string target = string(Start.TargetPkg().Name()) + " ";
+              
+              if ((*Start.TargetPkg()).SelectedState == pkgCache::State::Install
+                  || Cache[Start.TargetPkg()].Install())
+              {
+                 foundInstalledInOrGroup=true;
+                 break;
+              }
+
+              /* Skip if we already saw it */
+              if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1)
+              {
+                 foundInstalledInOrGroup=true;
+                 break; 
+              }
+
+              // this is a dep on a virtual pkg, check if any package that provides it
+              // should be installed
+              if(Start.TargetPkg().ProvidesList() != 0)
+              {
+                 pkgCache::PrvIterator I = Start.TargetPkg().ProvidesList();
+                 for (; I.end() == false; I++)
+                 {
+                    pkgCache::PkgIterator Pkg = I.OwnerPkg();
+                    if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer() && 
+                        Pkg.CurrentVer() != 0)
+                       foundInstalledInOrGroup=true;
+                 }
+              }
+
+              if (Start->Type == pkgCache::Dep::Suggests) 
+              {
+                 SuggestsOrList += target;
+                 SuggestsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
+              }
+              
+              if (Start->Type == pkgCache::Dep::Recommends) 
+              {
+                 RecommendsOrList += target;
+                 RecommendsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
+              }
+
+              if (Start >= End)
+                 break;
+              Start++;
+           }
+           
+           if(foundInstalledInOrGroup == false)
+           {
+              RecommendsList += RecommendsOrList;
+              RecommendsVersions += RecommendsOrVersions;
+              SuggestsList += SuggestsOrList;
+              SuggestsVersions += SuggestsOrVersions;
+           }
+              
+        }
+      }
+
+      ShowList(c1out,_("Suggested packages:"),SuggestsList,SuggestsVersions);
+      ShowList(c1out,_("Recommended packages:"),RecommendsList,RecommendsVersions);
+
+   }
+
+   // See if we need to prompt
+   if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
+      return InstallPackages(Cache,false,false);
+
+   return InstallPackages(Cache,false);   
+}
+                                                                       /*}}}*/
+// DoDistUpgrade - Automatic smart upgrader                            /*{{{*/
+// ---------------------------------------------------------------------
+/* Intelligent upgrader that will install and remove packages at will */
+bool DoDistUpgrade(CommandLine &CmdL)
+{
+   CacheFile Cache;
+   if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
+      return false;
+
+   c0out << _("Calculating upgrade... ") << flush;
+   if (pkgDistUpgrade(*Cache) == false)
+   {
+      c0out << _("Failed") << endl;
+      ShowBroken(c1out,Cache,false);
+      return false;
+   }
+   
+   c0out << _("Done") << endl;
+   
+   return InstallPackages(Cache,true);
+}
+                                                                       /*}}}*/
+// DoDSelectUpgrade - Do an upgrade by following dselects selections   /*{{{*/
+// ---------------------------------------------------------------------
+/* Follows dselect's selections */
+bool DoDSelectUpgrade(CommandLine &CmdL)
+{
+   CacheFile Cache;
+   if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
+      return false;
+   
+   // Install everything with the install flag set
+   pkgCache::PkgIterator I = Cache->PkgBegin();
+   for (;I.end() != true; I++)
+   {
+      /* Install the package only if it is a new install, the autoupgrader
+         will deal with the rest */
+      if (I->SelectedState == pkgCache::State::Install)
+        Cache->MarkInstall(I,false);
+   }
+
+   /* Now install their deps too, if we do this above then order of
+      the status file is significant for | groups */
+   for (I = Cache->PkgBegin();I.end() != true; I++)
+   {
+      /* Install the package only if it is a new install, the autoupgrader
+         will deal with the rest */
+      if (I->SelectedState == pkgCache::State::Install)
+        Cache->MarkInstall(I,true);
+   }
+   
+   // Apply erasures now, they override everything else.
+   for (I = Cache->PkgBegin();I.end() != true; I++)
+   {
+      // Remove packages 
+      if (I->SelectedState == pkgCache::State::DeInstall ||
+         I->SelectedState == pkgCache::State::Purge)
+        Cache->MarkDelete(I,I->SelectedState == pkgCache::State::Purge);
+   }
+
+   /* Resolve any problems that dselect created, allupgrade cannot handle
+      such things. We do so quite agressively too.. */
+   if (Cache->BrokenCount() != 0)
+   {      
+      pkgProblemResolver Fix(Cache);
+
+      // Hold back held packages.
+      if (_config->FindB("APT::Ignore-Hold",false) == false)
+      {
+        for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; I++)
+        {
+           if (I->SelectedState == pkgCache::State::Hold)
+           {
+              Fix.Protect(I);
+              Cache->MarkKeep(I);
+           }
+        }
+      }
+   
+      if (Fix.Resolve() == false)
+      {
+        ShowBroken(c1out,Cache,false);
+        return _error->Error(_("Internal error, problem resolver broke stuff"));
+      }
+   }
+
+   // Now upgrade everything
+   if (pkgAllUpgrade(Cache) == false)
+   {
+      ShowBroken(c1out,Cache,false);
+      return _error->Error(_("Internal error, problem resolver broke stuff"));
+   }
+   
+   return InstallPackages(Cache,false);
+}
+                                                                       /*}}}*/
+// DoClean - Remove download archives                                  /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DoClean(CommandLine &CmdL)
+{
+   if (_config->FindB("APT::Get::Simulate") == true)
+   {
+      cout << "Del " << _config->FindDir("Dir::Cache::archives") << "* " <<
+        _config->FindDir("Dir::Cache::archives") << "partial/*" << endl;
+      return true;
+   }
+   
+   // Lock the archive directory
+   FileFd Lock;
+   if (_config->FindB("Debug::NoLocking",false) == false)
+   {
+      Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
+      if (_error->PendingError() == true)
+        return _error->Error(_("Unable to lock the download directory"));
+   }
+   
+   pkgAcquire Fetcher;
+   Fetcher.Clean(_config->FindDir("Dir::Cache::archives"));
+   Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/");
+   return true;
+}
+                                                                       /*}}}*/
+// DoAutoClean - Smartly remove downloaded archives                    /*{{{*/
+// ---------------------------------------------------------------------
+/* This is similar to clean but it only purges things that cannot be 
+   downloaded, that is old versions of cached packages. */
+class LogCleaner : public pkgArchiveCleaner
+{
+   protected:
+   virtual void Erase(const char *File,string Pkg,string Ver,struct stat &St) 
+   {
+      c1out << "Del " << Pkg << " " << Ver << " [" << SizeToStr(St.st_size) << "B]" << endl;
+      
+      if (_config->FindB("APT::Get::Simulate") == false)
+        unlink(File);      
+   };
+};
+
+bool DoAutoClean(CommandLine &CmdL)
+{
+   // Lock the archive directory
+   FileFd Lock;
+   if (_config->FindB("Debug::NoLocking",false) == false)
+   {
+      Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
+      if (_error->PendingError() == true)
+        return _error->Error(_("Unable to lock the download directory"));
+   }
+   
+   CacheFile Cache;
+   if (Cache.Open() == false)
+      return false;
+   
+   LogCleaner Cleaner;
+   
+   return Cleaner.Go(_config->FindDir("Dir::Cache::archives"),*Cache) &&
+      Cleaner.Go(_config->FindDir("Dir::Cache::archives") + "partial/",*Cache);
+}
+                                                                       /*}}}*/
+// DoCheck - Perform the check operation                               /*{{{*/
+// ---------------------------------------------------------------------
+/* Opening automatically checks the system, this command is mostly used
+   for debugging */
+bool DoCheck(CommandLine &CmdL)
+{
+   CacheFile Cache;
+   Cache.Open();
+   Cache.CheckDeps();
+   
+   return true;
+}
+                                                                       /*}}}*/
+// DoSource - Fetch a source archive                                   /*{{{*/
+// ---------------------------------------------------------------------
+/* Fetch souce packages */
+struct DscFile
+{
+   string Package;
+   string Version;
+   string Dsc;
+};
+
+bool DoSource(CommandLine &CmdL)
+{
+   CacheFile Cache;
+   if (Cache.Open(false) == false)
+      return false;
+
+   if (CmdL.FileSize() <= 1)
+      return _error->Error(_("Must specify at least one package to fetch source for"));
+   
+   // Read the source list
+   pkgSourceList List;
+   if (List.ReadMainList() == false)
+      return _error->Error(_("The list of sources could not be read."));
+   
+   // Create the text record parsers
+   pkgRecords Recs(Cache);
+   pkgSrcRecords SrcRecs(List);
+   if (_error->PendingError() == true)
+      return false;
+
+   // Create the download object
+   AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));   
+   pkgAcquire Fetcher(&Stat);
+
+   DscFile *Dsc = new DscFile[CmdL.FileSize()];
+   
+   // insert all downloaded uris into this set to avoid downloading them
+   // twice
+   set<string> queued;
+   // Load the requestd sources into the fetcher
+   unsigned J = 0;
+   for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
+   {
+      string Src;
+      pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
+      
+      if (Last == 0)
+        return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
+      
+      // Back track
+      vector<pkgSrcRecords::File> Lst;
+      if (Last->Files(Lst) == false)
+        return false;
+
+      // Load them into the fetcher
+      for (vector<pkgSrcRecords::File>::const_iterator I = Lst.begin();
+          I != Lst.end(); I++)
+      {
+        // Try to guess what sort of file it is we are getting.
+        if (I->Type == "dsc")
+        {
+           Dsc[J].Package = Last->Package();
+           Dsc[J].Version = Last->Version();
+           Dsc[J].Dsc = flNotDir(I->Path);
+        }
+        
+        // Diff only mode only fetches .diff files
+        if (_config->FindB("APT::Get::Diff-Only",false) == true &&
+            I->Type != "diff")
+           continue;
+        
+        // Tar only mode only fetches .tar files
+        if (_config->FindB("APT::Get::Tar-Only",false) == true &&
+            I->Type != "tar")
+           continue;
+
+        // don't download the same uri twice (should this be moved to
+        // the fetcher interface itself?)
+        if(queued.find(Last->Index().ArchiveURI(I->Path)) != queued.end())
+           continue;
+        queued.insert(Last->Index().ArchiveURI(I->Path));
+           
+        // check if we have a file with that md5 sum already localy
+        if(!I->MD5Hash.empty() && FileExists(flNotDir(I->Path)))  
+        {
+           FileFd Fd(flNotDir(I->Path), FileFd::ReadOnly);
+           MD5Summation sum;
+           sum.AddFD(Fd.Fd(), Fd.Size());
+           Fd.Close();
+           if((string)sum.Result() == I->MD5Hash) 
+           {
+              ioprintf(c1out,_("Skipping already downloaded file '%s'\n"),
+                       flNotDir(I->Path).c_str());
+              continue;
+           }
+        }
+
+        new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path),
+                       I->MD5Hash,I->Size,
+                       Last->Index().SourceInfo(*Last,*I),Src);
+      }
+   }
+   
+   // Display statistics
+   double FetchBytes = Fetcher.FetchNeeded();
+   double FetchPBytes = Fetcher.PartialPresent();
+   double DebBytes = Fetcher.TotalNeeded();
+
+   // Check for enough free space
+   struct statvfs Buf;
+   string OutputDir = ".";
+   if (statvfs(OutputDir.c_str(),&Buf) != 0)
+      return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
+                          OutputDir.c_str());
+   if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
+      return _error->Error(_("You don't have enough free space in %s"),
+                          OutputDir.c_str());
+   
+   // Number of bytes
+   if (DebBytes != FetchBytes)
+      ioprintf(c1out,_("Need to get %sB/%sB of source archives.\n"),
+              SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
+   else
+      ioprintf(c1out,_("Need to get %sB of source archives.\n"),
+              SizeToStr(DebBytes).c_str());
+   
+   if (_config->FindB("APT::Get::Simulate",false) == true)
+   {
+      for (unsigned I = 0; I != J; I++)
+        ioprintf(cout,_("Fetch source %s\n"),Dsc[I].Package.c_str());
+      return true;
+   }
+   
+   // Just print out the uris an exit if the --print-uris flag was used
+   if (_config->FindB("APT::Get::Print-URIs") == true)
+   {
+      pkgAcquire::UriIterator I = Fetcher.UriBegin();
+      for (; I != Fetcher.UriEnd(); I++)
+        cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
+              I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
+      return true;
+   }
+   
+   // Run it
+   if (Fetcher.Run() == pkgAcquire::Failed)
+      return false;
+
+   // Print error messages
+   bool Failed = false;
+   for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
+   {
+      if ((*I)->Status == pkgAcquire::Item::StatDone &&
+         (*I)->Complete == true)
+        continue;
+      
+      fprintf(stderr,_("Failed to fetch %s  %s\n"),(*I)->DescURI().c_str(),
+             (*I)->ErrorText.c_str());
+      Failed = true;
+   }
+   if (Failed == true)
+      return _error->Error(_("Failed to fetch some archives."));
+   
+   if (_config->FindB("APT::Get::Download-only",false) == true)
+   {
+      c1out << _("Download complete and in download only mode") << endl;
+      return true;
+   }
+
+   // Unpack the sources
+   pid_t Process = ExecFork();
+   
+   if (Process == 0)
+   {
+      for (unsigned I = 0; I != J; I++)
+      {
+        string Dir = Dsc[I].Package + '-' + Cache->VS().UpstreamVersion(Dsc[I].Version.c_str());
+        
+        // Diff only mode only fetches .diff files
+        if (_config->FindB("APT::Get::Diff-Only",false) == true ||
+            _config->FindB("APT::Get::Tar-Only",false) == true ||
+            Dsc[I].Dsc.empty() == true)
+           continue;
+
+        // See if the package is already unpacked
+        struct stat Stat;
+        if (stat(Dir.c_str(),&Stat) == 0 &&
+            S_ISDIR(Stat.st_mode) != 0)
+        {
+           ioprintf(c0out ,_("Skipping unpack of already unpacked source in %s\n"),
+                             Dir.c_str());
+        }
+        else
+        {
+           // Call dpkg-source
+           char S[500];
+           snprintf(S,sizeof(S),"%s -x %s",
+                    _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(),
+                    Dsc[I].Dsc.c_str());
+           if (system(S) != 0)
+           {
+              fprintf(stderr,_("Unpack command '%s' failed.\n"),S);
+              fprintf(stderr,_("Check if the 'dpkg-dev' package is installed.\n"));
+              _exit(1);
+           }       
+        }
+        
+        // Try to compile it with dpkg-buildpackage
+        if (_config->FindB("APT::Get::Compile",false) == true)
+        {
+           // Call dpkg-buildpackage
+           char S[500];
+           snprintf(S,sizeof(S),"cd %s && %s %s",
+                    Dir.c_str(),
+                    _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
+                    _config->Find("DPkg::Build-Options","-b -uc").c_str());
+           
+           if (system(S) != 0)
+           {
+              fprintf(stderr,_("Build command '%s' failed.\n"),S);
+              _exit(1);
+           }       
+        }      
+      }
+      
+      _exit(0);
+   }
+   
+   // Wait for the subprocess
+   int Status = 0;
+   while (waitpid(Process,&Status,0) != Process)
+   {
+      if (errno == EINTR)
+        continue;
+      return _error->Errno("waitpid","Couldn't wait for subprocess");
+   }
+
+   if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
+      return _error->Error(_("Child process failed"));
+   
+   return true;
+}
+                                                                       /*}}}*/
+// DoBuildDep - Install/removes packages to satisfy build dependencies  /*{{{*/
+// ---------------------------------------------------------------------
+/* This function will look at the build depends list of the given source 
+   package and install the necessary packages to make it true, or fail. */
+bool DoBuildDep(CommandLine &CmdL)
+{
+   CacheFile Cache;
+   if (Cache.Open(true) == false)
+      return false;
+
+   if (CmdL.FileSize() <= 1)
+      return _error->Error(_("Must specify at least one package to check builddeps for"));
+   
+   // Read the source list
+   pkgSourceList List;
+   if (List.ReadMainList() == false)
+      return _error->Error(_("The list of sources could not be read."));
+   
+   // Create the text record parsers
+   pkgRecords Recs(Cache);
+   pkgSrcRecords SrcRecs(List);
+   if (_error->PendingError() == true)
+      return false;
+
+   // Create the download object
+   AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));   
+   pkgAcquire Fetcher(&Stat);
+
+   unsigned J = 0;
+   for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
+   {
+      string Src;
+      pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
+      if (Last == 0)
+        return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
+            
+      // Process the build-dependencies
+      vector<pkgSrcRecords::Parser::BuildDepRec> BuildDeps;
+      if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only",false)) == false)
+       return _error->Error(_("Unable to get build-dependency information for %s"),Src.c_str());
+   
+      // Also ensure that build-essential packages are present
+      Configuration::Item const *Opts = _config->Tree("APT::Build-Essential");
+      if (Opts) 
+        Opts = Opts->Child;
+      for (; Opts; Opts = Opts->Next)
+      {
+        if (Opts->Value.empty() == true)
+           continue;
+
+         pkgSrcRecords::Parser::BuildDepRec rec;
+        rec.Package = Opts->Value;
+        rec.Type = pkgSrcRecords::Parser::BuildDependIndep;
+        rec.Op = 0;
+        BuildDeps.push_back(rec);
+      }
+
+      if (BuildDeps.size() == 0)
+      {
+        ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str());
+        continue;
+      }
+      
+      // Install the requested packages
+      unsigned int ExpectedInst = 0;
+      vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
+      pkgProblemResolver Fix(Cache);
+      bool skipAlternatives = false; // skip remaining alternatives in an or group
+      for (D = BuildDeps.begin(); D != BuildDeps.end(); D++)
+      {
+         bool hasAlternatives = (((*D).Op & pkgCache::Dep::Or) == pkgCache::Dep::Or);
+
+         if (skipAlternatives == true)
+         {
+            if (!hasAlternatives)
+               skipAlternatives = false; // end of or group
+            continue;
+         }
+
+         if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
+            (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
+         {
+            pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
+            // Build-conflicts on unknown packages are silently ignored
+            if (Pkg.end() == true)
+               continue;
+
+            pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
+
+            /* 
+             * Remove if we have an installed version that satisfies the 
+             * version criteria
+             */
+            if (IV.end() == false && 
+                Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
+               TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst);
+         }
+        else // BuildDep || BuildDepIndep
+         {
+           pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
+            if (_config->FindB("Debug::BuildDeps",false) == true)
+                 cout << "Looking for " << (*D).Package << "...\n";
+
+           if (Pkg.end() == true)
+            {
+               if (_config->FindB("Debug::BuildDeps",false) == true)
+                    cout << " (not found)" << (*D).Package << endl;
+
+               if (hasAlternatives)
+                  continue;
+
+               return _error->Error(_("%s dependency for %s cannot be satisfied "
+                                      "because the package %s cannot be found"),
+                                    Last->BuildDepType((*D).Type),Src.c_str(),
+                                    (*D).Package.c_str());
+            }
+
+            /*
+             * if there are alternatives, we've already picked one, so skip
+             * the rest
+             *
+             * TODO: this means that if there's a build-dep on A|B and B is
+             * installed, we'll still try to install A; more importantly,
+             * if A is currently broken, we cannot go back and try B. To fix 
+             * this would require we do a Resolve cycle for each package we 
+             * add to the install list. Ugh
+             */
+                       
+           /* 
+            * If this is a virtual package, we need to check the list of
+            * packages that provide it and see if any of those are
+            * installed
+            */
+            pkgCache::PrvIterator Prv = Pkg.ProvidesList();
+            for (; Prv.end() != true; Prv++)
+           {
+               if (_config->FindB("Debug::BuildDeps",false) == true)
+                    cout << "  Checking provider " << Prv.OwnerPkg().Name() << endl;
+
+              if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
+                 break;
+            }
+            
+            // Get installed version and version we are going to install
+           pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
+
+            if ((*D).Version[0] != '\0') {
+                 // Versioned dependency
+
+                 pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
+
+                 for (; CV.end() != true; CV++)
+                 {
+                      if (Cache->VS().CheckDep(CV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
+                           break;
+                 }
+                 if (CV.end() == true)
+                  if (hasAlternatives)
+                  {
+                     continue;
+                  }
+                  else
+                  {
+                      return _error->Error(_("%s dependency for %s cannot be satisfied "
+                                             "because no available versions of package %s "
+                                             "can satisfy version requirements"),
+                                           Last->BuildDepType((*D).Type),Src.c_str(),
+                                           (*D).Package.c_str());
+                  }
+            }
+            else
+            {
+               // Only consider virtual packages if there is no versioned dependency
+               if (Prv.end() == false)
+               {
+                  if (_config->FindB("Debug::BuildDeps",false) == true)
+                     cout << "  Is provided by installed package " << Prv.OwnerPkg().Name() << endl;
+                  skipAlternatives = hasAlternatives;
+                  continue;
+               }
+            }
+
+            if (IV.end() == false)
+            {
+               if (_config->FindB("Debug::BuildDeps",false) == true)
+                  cout << "  Is installed\n";
+
+               if (Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
+               {
+                  skipAlternatives = hasAlternatives;
+                  continue;
+               }
+
+               if (_config->FindB("Debug::BuildDeps",false) == true)
+                  cout << "    ...but the installed version doesn't meet the version requirement\n";
+
+               if (((*D).Op & pkgCache::Dep::LessEq) == pkgCache::Dep::LessEq)
+               {
+                  return _error->Error(_("Failed to satisfy %s dependency for %s: Installed package %s is too new"),
+                                       Last->BuildDepType((*D).Type),
+                                       Src.c_str(),
+                                       Pkg.Name());
+               }
+            }
+
+
+            if (_config->FindB("Debug::BuildDeps",false) == true)
+               cout << "  Trying to install " << (*D).Package << endl;
+
+            if (TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst) == true)
+            {
+               // We successfully installed something; skip remaining alternatives
+               skipAlternatives = hasAlternatives;
+               continue;
+            }
+            else if (hasAlternatives)
+            {
+               if (_config->FindB("Debug::BuildDeps",false) == true)
+                  cout << "  Unsatisfiable, trying alternatives\n";
+               continue;
+            }
+            else
+            {
+               return _error->Error(_("Failed to satisfy %s dependency for %s: %s"),
+                                    Last->BuildDepType((*D).Type),
+                                    Src.c_str(),
+                                    (*D).Package.c_str());
+            }
+        }             
+      }
+      
+      Fix.InstallProtect();
+      if (Fix.Resolve(true) == false)
+        _error->Discard();
+      
+      // Now we check the state of the packages,
+      if (Cache->BrokenCount() != 0)
+         return _error->Error(_("Build-dependencies for %s could not be satisfied."),*I);
+   }
+  
+   if (InstallPackages(Cache, false, true) == false)
+      return _error->Error(_("Failed to process build dependencies"));
+   return true;
+}
+                                                                       /*}}}*/
+
+// DoMoo - Never Ask, Never Tell                                       /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DoMoo(CommandLine &CmdL)
+{
+   cout << 
+      "         (__) \n"
+      "         (oo) \n"
+      "   /------\\/ \n"
+      "  / |    ||   \n" 
+      " *  /\\---/\\ \n"
+      "    ~~   ~~   \n"
+      "....\"Have you mooed today?\"...\n";
+                           
+   return true;
+}
+                                                                       /*}}}*/
+// ShowHelp - Show a help screen                                       /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool ShowHelp(CommandLine &CmdL)
+{
+   ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
+           COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
+           
+   if (_config->FindB("version") == true)
+   {
+      cout << _("Supported modules:") << endl;
+      
+      for (unsigned I = 0; I != pkgVersioningSystem::GlobalListLen; I++)
+      {
+        pkgVersioningSystem *VS = pkgVersioningSystem::GlobalList[I];
+        if (_system != 0 && _system->VS == VS)
+           cout << '*';
+        else
+           cout << ' ';
+        cout << "Ver: " << VS->Label << endl;
+        
+        /* Print out all the packaging systems that will work with 
+           this VS */
+        for (unsigned J = 0; J != pkgSystem::GlobalListLen; J++)
+        {
+           pkgSystem *Sys = pkgSystem::GlobalList[J];
+           if (_system == Sys)
+              cout << '*';
+           else
+              cout << ' ';
+           if (Sys->VS->TestCompatibility(*VS) == true)
+              cout << "Pkg:  " << Sys->Label << " (Priority " << Sys->Score(*_config) << ")" << endl;
+        }
+      }
+      
+      for (unsigned I = 0; I != pkgSourceList::Type::GlobalListLen; I++)
+      {
+        pkgSourceList::Type *Type = pkgSourceList::Type::GlobalList[I];
+        cout << " S.L: '" << Type->Name << "' " << Type->Label << endl;
+      }      
+      
+      for (unsigned I = 0; I != pkgIndexFile::Type::GlobalListLen; I++)
+      {
+        pkgIndexFile::Type *Type = pkgIndexFile::Type::GlobalList[I];
+        cout << " Idx: " << Type->Label << endl;
+      }      
+      
+      return true;
+   }
+   
+   cout << 
+    _("Usage: apt-get [options] command\n"
+      "       apt-get [options] install|remove pkg1 [pkg2 ...]\n"
+      "       apt-get [options] source pkg1 [pkg2 ...]\n"
+      "\n"
+      "apt-get is a simple command line interface for downloading and\n"
+      "installing packages. The most frequently used commands are update\n"
+      "and install.\n"   
+      "\n"
+      "Commands:\n"
+      "   update - Retrieve new lists of packages\n"
+      "   upgrade - Perform an upgrade\n"
+      "   install - Install new packages (pkg is libc6 not libc6.deb)\n"
+      "   remove - Remove packages\n"
+      "   source - Download source archives\n"
+      "   build-dep - Configure build-dependencies for source packages\n"
+      "   dist-upgrade - Distribution upgrade, see apt-get(8)\n"
+      "   dselect-upgrade - Follow dselect selections\n"
+      "   clean - Erase downloaded archive files\n"
+      "   autoclean - Erase old downloaded archive files\n"
+      "   check - Verify that there are no broken dependencies\n"
+      "\n"
+      "Options:\n"
+      "  -h  This help text.\n"
+      "  -q  Loggable output - no progress indicator\n"
+      "  -qq No output except for errors\n"
+      "  -d  Download only - do NOT install or unpack archives\n"
+      "  -s  No-act. Perform ordering simulation\n"
+      "  -y  Assume Yes to all queries and do not prompt\n"
+      "  -f  Attempt to continue if the integrity check fails\n"
+      "  -m  Attempt to continue if archives are unlocatable\n"
+      "  -u  Show a list of upgraded packages as well\n"
+      "  -b  Build the source package after fetching it\n"
+      "  -V  Show verbose version numbers\n"
+      "  -c=? Read this configuration file\n"
+      "  -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
+      "See the apt-get(8), sources.list(5) and apt.conf(5) manual\n"
+      "pages for more information and options.\n"
+      "                       This APT has Super Cow Powers.\n");
+   return true;
+}
+                                                                       /*}}}*/
+// GetInitialize - Initialize things for apt-get                       /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void GetInitialize()
+{
+   _config->Set("quiet",0);
+   _config->Set("help",false);
+   _config->Set("APT::Get::Download-Only",false);
+   _config->Set("APT::Get::Simulate",false);
+   _config->Set("APT::Get::Assume-Yes",false);
+   _config->Set("APT::Get::Fix-Broken",false);
+   _config->Set("APT::Get::Force-Yes",false);
+   _config->Set("APT::Get::List-Cleanup",true);
+}
+                                                                       /*}}}*/
+// SigWinch - Window size change signal handler                                /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void SigWinch(int)
+{
+   // Riped from GNU ls
+#ifdef TIOCGWINSZ
+   struct winsize ws;
+  
+   if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
+      ScreenWidth = ws.ws_col - 1;
+#endif
+}
+                                                                       /*}}}*/
+
+int main(int argc,const char *argv[])
+{
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
+   CommandLine::Args Args[] = {
+      {'h',"help","help",0},
+      {'v',"version","version",0},
+      {'V',"verbose-versions","APT::Get::Show-Versions",0},
+      {'q',"quiet","quiet",CommandLine::IntLevel},
+      {'q',"silent","quiet",CommandLine::IntLevel},
+      {'d',"download-only","APT::Get::Download-Only",0},
+      {'b',"compile","APT::Get::Compile",0},
+      {'b',"build","APT::Get::Compile",0},
+      {'s',"simulate","APT::Get::Simulate",0},
+      {'s',"just-print","APT::Get::Simulate",0},
+      {'s',"recon","APT::Get::Simulate",0},
+      {'s',"dry-run","APT::Get::Simulate",0},
+      {'s',"no-act","APT::Get::Simulate",0},
+      {'y',"yes","APT::Get::Assume-Yes",0},
+      {'y',"assume-yes","APT::Get::Assume-Yes",0},      
+      {'f',"fix-broken","APT::Get::Fix-Broken",0},
+      {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
+      {'m',"ignore-missing","APT::Get::Fix-Missing",0},
+      {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
+      {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
+      {0,"download","APT::Get::Download",0},
+      {0,"fix-missing","APT::Get::Fix-Missing",0},
+      {0,"ignore-hold","APT::Ignore-Hold",0},      
+      {0,"upgrade","APT::Get::upgrade",0},
+      {0,"force-yes","APT::Get::force-yes",0},
+      {0,"print-uris","APT::Get::Print-URIs",0},
+      {0,"diff-only","APT::Get::Diff-Only",0},
+      {0,"tar-only","APT::Get::tar-Only",0},
+      {0,"purge","APT::Get::Purge",0},
+      {0,"list-cleanup","APT::Get::List-Cleanup",0},
+      {0,"reinstall","APT::Get::ReInstall",0},
+      {0,"trivial-only","APT::Get::Trivial-Only",0},
+      {0,"remove","APT::Get::Remove",0},
+      {0,"only-source","APT::Get::Only-Source",0},
+      {0,"arch-only","APT::Get::Arch-Only",0},
+      {0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0},
+      {'c',"config-file",0,CommandLine::ConfigFile},
+      {'o',"option",0,CommandLine::ArbItem},
+      {0,0,0,0}};
+   CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate},
+                                   {"upgrade",&DoUpgrade},
+                                   {"install",&DoInstall},
+                                   {"remove",&DoInstall},
+                                   {"dist-upgrade",&DoDistUpgrade},
+                                   {"dselect-upgrade",&DoDSelectUpgrade},
+                                  {"build-dep",&DoBuildDep},
+                                   {"clean",&DoClean},
+                                   {"autoclean",&DoAutoClean},
+                                   {"check",&DoCheck},
+                                  {"source",&DoSource},
+                                  {"moo",&DoMoo},
+                                  {"help",&ShowHelp},
+                                   {0,0}};
+
+   // Set up gettext support
+   setlocale(LC_ALL,"");
+   textdomain(PACKAGE);
+
+   // Parse the command line and initialize the package library
+   CommandLine CmdL(Args,_config);
+   if (pkgInitConfig(*_config) == false ||
+       CmdL.Parse(argc,argv) == false ||
+       pkgInitSystem(*_config,_system) == false)
+   {
+      if (_config->FindB("version") == true)
+        ShowHelp(CmdL);
+        
+      _error->DumpErrors();
+      return 100;
+   }
+
+   // See if the help should be shown
+   if (_config->FindB("help") == true ||
+       _config->FindB("version") == true ||
+       CmdL.FileSize() == 0)
+   {
+      ShowHelp(CmdL);
+      return 0;
+   }
+   
+   // Deal with stdout not being a tty
+   if (!isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1)
+      _config->Set("quiet","1");
+
+   // Setup the output streams
+   c0out.rdbuf(cout.rdbuf());
+   c1out.rdbuf(cout.rdbuf());
+   c2out.rdbuf(cout.rdbuf());
+   if (_config->FindI("quiet",0) > 0)
+      c0out.rdbuf(devnull.rdbuf());
+   if (_config->FindI("quiet",0) > 1)
+      c1out.rdbuf(devnull.rdbuf());
+
+   // Setup the signals
+   signal(SIGPIPE,SIG_IGN);
+   signal(SIGWINCH,SigWinch);
+   SigWinch(0);
+
+   // Match the operation
+   CmdL.DispatchArg(Cmds);
+
+   // Print any errors or warnings found during parsing
+   if (_error->empty() == false)
+   {
+      bool Errors = _error->PendingError();
+      _error->DumpErrors();
+      return Errors == true?100:0;
+   }
+   
+   return 0;   
+}
index c2b4f90db8ec9213ff6a0ac39d3df5ed27cb891e..5424a9ffd18f17e9f8f1d0b6f58957c8e45cdcb8 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // $Id: apt-sortpkgs.cc,v 1.5 2003/01/11 07:18:44 jgg Exp $
@@ -164,6 +168,13 @@ int ShowHelp()
 
 int main(unsigned int argc,const char *argv[])
 {
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
    CommandLine::Args Args[] = {
       {'h',"help","help",0},
       {'v',"version","version",0},
diff --git a/cmdline/apt-sortpkgs.cc.orig b/cmdline/apt-sortpkgs.cc.orig
new file mode 100644 (file)
index 0000000..4b3bba8
--- /dev/null
@@ -0,0 +1,219 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
+// -*- mode: cpp; mode: fold -*-
+// Description                                                         /*{{{*/
+// $Id: apt-sortpkgs.cc,v 1.5 2003/01/11 07:18:44 jgg Exp $
+/* ######################################################################
+   
+   APT Sort Packages - Program to sort Package and Source files
+
+   This program is quite simple, it just sorts the package files by
+   package and sorts the fields inside by the internal APT sort order.
+   Input is taken from a named file and sent to stdout.
+   
+   ##################################################################### */
+                                                                       /*}}}*/
+// Include Files                                                       /*{{{*/
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/strutl.h>
+
+#include <config.h>
+#include <apti18n.h>
+    
+#include <vector>
+#include <algorithm>
+
+#include <locale.h>
+#include <unistd.h>
+                                                                       /*}}}*/
+
+using namespace std;
+
+struct PkgName
+{
+   string Name;
+   string Ver;
+   string Arch;
+   unsigned long Offset;
+   unsigned long Length;
+   
+   inline int Compare3(const PkgName &x) const
+   {
+      int A = stringcasecmp(Name,x.Name);
+      if (A == 0)
+      {
+        A = stringcasecmp(Ver,x.Ver);
+        if (A == 0)
+           A = stringcasecmp(Arch,x.Arch);
+      }
+      return A;
+   }
+   
+   bool operator <(const PkgName &x) const {return Compare3(x) < 0;};
+   bool operator >(const PkgName &x) const {return Compare3(x) > 0;};
+   bool operator ==(const PkgName &x) const {return Compare3(x) == 0;};
+};
+
+// DoIt - Sort a single file                                           /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DoIt(string InFile)
+{
+   FileFd Fd(InFile,FileFd::ReadOnly);
+   pkgTagFile Tags(&Fd);
+   if (_error->PendingError() == true)
+      return false;
+   
+   // Parse.
+   vector<PkgName> List;
+   pkgTagSection Section;
+   unsigned long Largest = 0;
+   unsigned long Offset = Tags.Offset();
+   bool Source = _config->FindB("APT::SortPkgs::Source",false);
+   while (Tags.Step(Section) == true)
+   {
+      PkgName Tmp;
+      
+      /* Fetch the name, auto-detecting if this is a source file or a 
+         package file */
+      Tmp.Name = Section.FindS("Package");
+      Tmp.Ver = Section.FindS("Version");
+      Tmp.Arch = Section.FindS("Architecture");
+      
+      if (Tmp.Name.empty() == true)
+        return _error->Error(_("Unknown package record!"));
+      
+      Tmp.Offset = Offset;
+      Tmp.Length = Section.size();
+      if (Largest < Tmp.Length)
+        Largest = Tmp.Length;
+      
+      List.push_back(Tmp);
+      
+      Offset = Tags.Offset();
+   }
+   if (_error->PendingError() == true)
+      return false;
+   
+   // Sort it
+   sort(List.begin(),List.end());
+
+   const char **Order = TFRewritePackageOrder;
+   if (Source == true)
+      Order = TFRewriteSourceOrder;
+   
+   // Emit
+   unsigned char *Buffer = new unsigned char[Largest+1];
+   for (vector<PkgName>::iterator I = List.begin(); I != List.end(); I++)
+   {
+      // Read in the Record.
+      if (Fd.Seek(I->Offset) == false || Fd.Read(Buffer,I->Length) == false)
+      {
+        delete [] Buffer;
+        return false;
+      }
+      
+      Buffer[I->Length] = '\n';      
+      if (Section.Scan((char *)Buffer,I->Length+1) == false)
+      {
+        delete [] Buffer;
+        return _error->Error("Internal error, failed to scan buffer");
+      }
+
+      // Sort the section
+      if (TFRewrite(stdout,Section,Order,0) == false)
+      {
+        delete [] Buffer;
+        return _error->Error("Internal error, failed to sort fields");
+      }
+      
+      fputc('\n',stdout);      
+   }
+   
+   delete [] Buffer;
+   return true;
+}
+                                                                       /*}}}*/
+// ShowHelp - Show the help text                                       /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+int ShowHelp()
+{
+   ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
+           COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
+   if (_config->FindB("version") == true)
+      return 0;
+   
+   cout <<
+    _("Usage: apt-sortpkgs [options] file1 [file2 ...]\n"
+      "\n"
+      "apt-sortpkgs is a simple tool to sort package files. The -s option is used\n"
+      "to indicate what kind of file it is.\n"
+      "\n"
+      "Options:\n"
+      "  -h   This help text\n"
+      "  -s   Use source file sorting\n"
+      "  -c=? Read this configuration file\n"
+      "  -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n");
+
+   return 0;
+}
+                                                                       /*}}}*/
+
+int main(unsigned int argc,const char *argv[])
+{
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
+   CommandLine::Args Args[] = {
+      {'h',"help","help",0},
+      {'v',"version","version",0},
+      {'s',"source","APT::SortPkgs::Source",0},
+      {'c',"config-file",0,CommandLine::ConfigFile},
+      {'o',"option",0,CommandLine::ArbItem},
+      {0,0,0,0}};
+
+   // Set up gettext support
+   setlocale(LC_ALL,"");
+   textdomain(PACKAGE);
+
+   // Parse the command line and initialize the package library
+   CommandLine CmdL(Args,_config);
+   if (pkgInitConfig(*_config) == false ||
+       CmdL.Parse(argc,argv) == false ||
+       pkgInitSystem(*_config,_system) == false)
+   {
+      _error->DumpErrors();
+      return 100;
+   }
+
+   // See if the help should be shown
+   if (_config->FindB("help") == true ||
+       CmdL.FileSize() == 0)
+      return ShowHelp();
+
+   // Match the operation
+   for (unsigned int I = 0; I != CmdL.FileSize(); I++)
+      if (DoIt(CmdL.FileList[I]) == false)
+        break;
+   
+   // Print any errors or warnings found during parsing
+   if (_error->empty() == false)
+   {
+      bool Errors = _error->PendingError();
+      _error->DumpErrors();
+      return Errors == true?100:0;
+   }
+   
+   return 0;   
+}
index 0e2be8a00ad2843410754ff1b114e73633b4eed5..6d5c29d1ff435655d087ff380bb3eae9c3b317f4 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // $Id: apt-ftparchive.cc,v 1.8.2.3 2004/01/02 22:01:48 mdz Exp $
@@ -901,6 +905,13 @@ bool Clean(CommandLine &CmdL)
 
 int main(int argc, const char *argv[])
 {
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
    CommandLine::Args Args[] = {
       {'h',"help","help",0},
       {0,"md5","APT::FTPArchive::MD5",0},
index d6b8eae75c0dd4d6c810f0ab720b997c09dfdb76..2d6da2150551ac513ef4c0808138a32301b2ee9d 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // $Id: cdrom.cc,v 1.20.2.1 2004/01/16 18:58:50 mdz Exp $
@@ -193,6 +197,13 @@ bool CDROMMethod::Fetch(FetchItem *Itm)
 
 int main()
 {
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
    setlocale(LC_ALL, "");
 
    CDROMMethod Mth;
index d737e3c33cb851b646d726c24f00fad053098cce..32738537d673129f3df12dd85aecfb57d10785c4 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // $Id: copy.cc,v 1.7.2.1 2004/01/16 18:58:50 mdz Exp $
@@ -86,6 +90,13 @@ bool CopyMethod::Fetch(FetchItem *Itm)
 
 int main()
 {
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
    setlocale(LC_ALL, "");
 
    CopyMethod Mth;
index 9cdd5bc2d3b3a3ea9ff14f2732ef832780e146cd..0c903ccdd8d217f49b78db623eb34b7348a27702 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // $Id: file.cc,v 1.9.2.1 2004/01/16 18:58:50 mdz Exp $
@@ -89,6 +93,13 @@ bool FileMethod::Fetch(FetchItem *Itm)
 
 int main()
 {
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
    setlocale(LC_ALL, "");
 
    FileMethod Mth;
index 0c2aa00a76a599fc5c0dea110862db30b3fd5d08..9e1333acf9fcfdec260c06a3b1774d7550c145e3 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // $Id: ftp.cc,v 1.31.2.1 2004/01/16 18:58:50 mdz Exp $
@@ -1086,6 +1090,13 @@ bool FtpMethod::Fetch(FetchItem *Itm)
 
 int main(int argc,const char *argv[])
 { 
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
    setlocale(LC_ALL, "");
 
    /* See if we should be come the http client - we do this for http
index 227e08d63123e2c51ba77966dc218e41f13f217c..b03d4753cb9990c84fa856d3b5e86a3a1a4af73a 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 #include <apt-pkg/error.h>
 #include <apt-pkg/acquire-method.h>
 #include <apt-pkg/strutl.h>
@@ -302,6 +306,13 @@ bool GPGVMethod::Fetch(FetchItem *Itm)
 
 int main()
 {
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
    setlocale(LC_ALL, "");
    
    GPGVMethod Mth;
index f732c0b8600f227bd98e0fb088038aea4383e8c8..13a7302c2d769b7dc3f3cb3cc5ea0c62f36aa5f4 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // $Id: gzip.cc,v 1.17.2.1 2004/01/16 18:58:50 mdz Exp $
@@ -162,6 +166,13 @@ bool GzipMethod::Fetch(FetchItem *Itm)
 
 int main(int argc, char *argv[])
 {
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
    setlocale(LC_ALL, "");
 
    GzipMethod Mth;
index 1f3b038bc4a515391ff0feb8ac3ca326733cee1b..d84ce2874d6c7a3ecede838c1a2665609d1dc96d 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // $Id: http.cc,v 1.59 2004/05/08 19:42:35 mdz Exp $
@@ -1224,6 +1228,13 @@ int HttpMethod::Loop()
 
 int main()
 {
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
    setlocale(LC_ALL, "");
 
    HttpMethod Mth;
index 6fa57f3a60f58263da407f706ca31f9601a2aba3..3dd939b71988e50c464c08cdaeee42cafe651945 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/acquire-method.h>
@@ -253,6 +257,13 @@ bool RredMethod::Fetch(FetchItem *Itm)
 
 int main(int argc, char *argv[])
 {
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
    RredMethod Mth;
 
    Prog = strrchr(argv[0],'/');
index f0ccfc42d2890513c0b5048943915da75afcc184..3e5343ca4665fc5c00b9e1455bfd4bef60da8aaf 100644 (file)
@@ -1,3 +1,7 @@
+extern "C" {
+    #include <mach-o/nlist.h>
+}
+
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // $Id: rsh.cc,v 1.6.2.1 2004/01/16 18:58:50 mdz Exp $
@@ -511,6 +515,13 @@ bool RSHMethod::Fetch(FetchItem *Itm)
 
 int main(int argc, const char *argv[])
 {
+   struct nlist nl[2];
+   memset(nl, 0, sizeof(nl));
+   nl[0].n_un.n_name = "_useMDNSResponder";
+   nlist("/usr/lib/libc.dylib", nl);
+   if (nl[0].n_type != N_UNDF)
+       *(int *) nl[0].n_value = 0;
+
    setlocale(LC_ALL, "");
 
    RSHMethod Mth;