From dfe2511e31f232a8a8880eba40af40d1deb0e49c Mon Sep 17 00:00:00 2001
From: Julian Andres Klode <julian.klode@canonical.com>
Date: Mon, 6 May 2019 11:40:08 +0200
Subject: Merge libapt-inst into libapt-pkg

---
 CMakeLists.txt                         |   1 -
 abicheck/apt_build.xml.in              |   1 -
 apt-inst/CMakeLists.txt                |  31 ----
 apt-inst/apt-inst.pc.in                |   9 -
 apt-inst/contrib/arfile.cc             | 160 -----------------
 apt-inst/contrib/arfile.h              |  69 --------
 apt-inst/contrib/extracttar.cc         | 306 ---------------------------------
 apt-inst/contrib/extracttar.h          |  60 -------
 apt-inst/deb/debfile.cc                | 250 ---------------------------
 apt-inst/deb/debfile.h                 |  95 ----------
 apt-inst/dirstream.cc                  | 118 -------------
 apt-inst/dirstream.h                   |  57 ------
 apt-inst/dpkg-diffs.txt                |   5 -
 apt-pkg/contrib/arfile.cc              | 160 +++++++++++++++++
 apt-pkg/contrib/arfile.h               |  69 ++++++++
 apt-pkg/contrib/extracttar.cc          | 306 +++++++++++++++++++++++++++++++++
 apt-pkg/contrib/extracttar.h           |  60 +++++++
 apt-pkg/deb/debfile.cc                 | 250 +++++++++++++++++++++++++++
 apt-pkg/deb/debfile.h                  |  95 ++++++++++
 apt-pkg/dirstream.cc                   | 118 +++++++++++++
 apt-pkg/dirstream.h                    |  57 ++++++
 cmdline/CMakeLists.txt                 |   8 +-
 debian/control                         |  17 +-
 debian/libapt-inst3.0.install          |   2 -
 debian/libapt-inst3.0.symbols          |  68 --------
 debian/libapt-pkg-dev.install          |   1 -
 debian/libapt-pkg6.0.symbols           |  42 +++++
 ftparchive/CMakeLists.txt              |   2 +-
 po/CMakeLists.txt                      |   7 -
 prepare-release                        |   5 +-
 test/interactive-helper/CMakeLists.txt |   4 +-
 test/libapt/CMakeLists.txt             |   2 +-
 32 files changed, 1167 insertions(+), 1268 deletions(-)
 delete mode 100644 apt-inst/CMakeLists.txt
 delete mode 100644 apt-inst/apt-inst.pc.in
 delete mode 100644 apt-inst/contrib/arfile.cc
 delete mode 100644 apt-inst/contrib/arfile.h
 delete mode 100644 apt-inst/contrib/extracttar.cc
 delete mode 100644 apt-inst/contrib/extracttar.h
 delete mode 100644 apt-inst/deb/debfile.cc
 delete mode 100644 apt-inst/deb/debfile.h
 delete mode 100644 apt-inst/dirstream.cc
 delete mode 100644 apt-inst/dirstream.h
 delete mode 100644 apt-inst/dpkg-diffs.txt
 create mode 100644 apt-pkg/contrib/arfile.cc
 create mode 100644 apt-pkg/contrib/arfile.h
 create mode 100644 apt-pkg/contrib/extracttar.cc
 create mode 100644 apt-pkg/contrib/extracttar.h
 create mode 100644 apt-pkg/deb/debfile.cc
 create mode 100644 apt-pkg/deb/debfile.h
 create mode 100644 apt-pkg/dirstream.cc
 create mode 100644 apt-pkg/dirstream.h
 delete mode 100644 debian/libapt-inst3.0.install
 delete mode 100644 debian/libapt-inst3.0.symbols

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e47e867bf..2a06da34f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -232,7 +232,6 @@ configure_file(CMake/apti18n.h.in ${PROJECT_BINARY_DIR}/include/apti18n.h)
 add_subdirectory(vendor)
 add_subdirectory(apt-pkg)
 add_subdirectory(apt-private)
-add_subdirectory(apt-inst)
 add_subdirectory(cmdline)
 add_subdirectory(completions)
 add_subdirectory(doc)
diff --git a/abicheck/apt_build.xml.in b/abicheck/apt_build.xml.in
index 32886d931..ec3946648 100644
--- a/abicheck/apt_build.xml.in
+++ b/abicheck/apt_build.xml.in
@@ -8,5 +8,4 @@
    
  <libs>
   @build_path@/apt-pkg/
-  @build_path@/apt-inst/
  </libs>
diff --git a/apt-inst/CMakeLists.txt b/apt-inst/CMakeLists.txt
deleted file mode 100644
index e4e91e493..000000000
--- a/apt-inst/CMakeLists.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-# Include apt-pkg directly, as some files have #include <system.h>
-include_directories(${PROJECT_BINARY_DIR}/include/apt-pkg)
-
-# Set the version of the library
-set(MAJOR 3.0)
-set(MINOR 0)
-set(APT_INST_MAJOR ${MAJOR} PARENT_SCOPE)
-
-# Definition of the C++ files used to build the library - note that this
-# is expanded at CMake time, so you have to rerun cmake if you add or remove
-# a file (you can just run cmake . in the build directory)
-file(GLOB_RECURSE library "*.cc")
-file(GLOB_RECURSE headers "*.h")
-
-configure_file(apt-inst.pc.in ${CMAKE_CURRENT_BINARY_DIR}/apt-inst.pc @ONLY)
-
-# Create a library using the C++ files
-add_library(apt-inst SHARED ${library})
-
-# Link the library and set the SONAME
-target_link_libraries(apt-inst PUBLIC apt-pkg ${CMAKE_THREAD_LIBS_INIT})
-target_link_libraries(apt-inst PRIVATE ${CMAKE_THREAD_LIBS_INIT})
-set_target_properties(apt-inst PROPERTIES VERSION ${MAJOR}.${MINOR})
-set_target_properties(apt-inst PROPERTIES SOVERSION ${MAJOR})
-add_version_script(apt-inst)
-
-# Install the library and the headers
-install(TARGETS apt-inst LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
-install(FILES ${headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/apt-pkg)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/apt-inst.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
-flatify(${PROJECT_BINARY_DIR}/include/apt-pkg/ "${headers}")
diff --git a/apt-inst/apt-inst.pc.in b/apt-inst/apt-inst.pc.in
deleted file mode 100644
index 1d61a202f..000000000
--- a/apt-inst/apt-inst.pc.in
+++ /dev/null
@@ -1,9 +0,0 @@
-libdir=@CMAKE_INSTALL_FULL_LIBDIR@
-includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
-
-Name: apt-inst
-Description: deb package format runtime library
-Version: @PROJECT_VERSION@
-Libs: -L${libdir} -lapt-inst
-Cflags: -I${includedir}
-Requires: apt-pkg
diff --git a/apt-inst/contrib/arfile.cc b/apt-inst/contrib/arfile.cc
deleted file mode 100644
index 3fc3afedb..000000000
--- a/apt-inst/contrib/arfile.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description								/*{{{*/
-/* ######################################################################
-
-   AR File - Handle an 'AR' archive
-   
-   AR Archives have plain text headers at the start of each file
-   section. The headers are aligned on a 2 byte boundary.
-   
-   Information about the structure of AR files can be found in ar(5)
-   on a BSD system, or in the binutils source.
-
-   ##################################################################### */
-									/*}}}*/
-// Include Files							/*{{{*/
-#include <config.h>
-
-#include <apt-pkg/arfile.h>
-#include <apt-pkg/error.h>
-#include <apt-pkg/fileutl.h>
-#include <apt-pkg/strutl.h>
-
-#include <string>
-#include <string.h>
-#include <sys/types.h>
-
-#include <apti18n.h>
-									/*}}}*/
-
-struct ARArchive::MemberHeader
-{
-   char Name[16];
-   char MTime[12];
-   char UID[6];
-   char GID[6];
-   char Mode[8];
-   char Size[10];
-   char Magic[2];
-};
-
-// ARArchive::ARArchive - Constructor					/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-ARArchive::ARArchive(FileFd &File) : List(0), File(File)
-{
-   LoadHeaders();
-}
-									/*}}}*/
-// ARArchive::~ARArchive - Destructor					/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-ARArchive::~ARArchive()
-{
-   while (List != 0)
-   {
-      Member *Tmp = List;
-      List = List->Next;
-      delete Tmp;
-   }   
-}
-									/*}}}*/
-// ARArchive::LoadHeaders - Load the headers from each file		/*{{{*/
-// ---------------------------------------------------------------------
-/* AR files are structured with a 8 byte magic string followed by a 60
-   byte plain text header then the file data, another header, data, etc */
-bool ARArchive::LoadHeaders()
-{
-   off_t Left = File.Size();
-   
-   // Check the magic byte
-   char Magic[8];
-   if (File.Read(Magic,sizeof(Magic)) == false)
-      return false;
-   if (memcmp(Magic,"!<arch>\012",sizeof(Magic)) != 0)
-      return _error->Error(_("Invalid archive signature"));
-   Left -= sizeof(Magic);
-   
-   // Read the member list
-   while (Left > 0)
-   {
-      MemberHeader Head;
-      if (File.Read(&Head,sizeof(Head)) == false)
-	 return _error->Error(_("Error reading archive member header"));
-      Left -= sizeof(Head);
-
-      // Convert all of the integer members
-      Member *Memb = new Member();
-      if (StrToNum(Head.MTime,Memb->MTime,sizeof(Head.MTime)) == false ||
-	  StrToNum(Head.UID,Memb->UID,sizeof(Head.UID)) == false ||
-	  StrToNum(Head.GID,Memb->GID,sizeof(Head.GID)) == false ||
-	  StrToNum(Head.Mode,Memb->Mode,sizeof(Head.Mode),8) == false ||
-	  StrToNum(Head.Size,Memb->Size,sizeof(Head.Size)) == false)
-      {
-	 delete Memb;
-	 return _error->Error(_("Invalid archive member header %s"), Head.Name);
-      }
-	 
-      // Check for an extra long name string
-      if (memcmp(Head.Name,"#1/",3) == 0)
-      {
-	 char S[300];
-	 unsigned long Len;
-	 if (StrToNum(Head.Name+3,Len,sizeof(Head.Size)-3) == false ||
-	     Len >= sizeof(S))
-	 {
-	    delete Memb;
-	    return _error->Error(_("Invalid archive member header"));
-	 }
-	 if (File.Read(S,Len) == false)
-	 {
-	    delete Memb;
-	    return false;
-	 }
-	 S[Len] = 0;
-	 Memb->Name = S;
-	 Memb->Size -= Len;
-	 Left -= Len;
-      }
-      else
-      {
-	 unsigned int I = sizeof(Head.Name) - 1;
-	 for (; Head.Name[I] == ' ' || Head.Name[I] == '/'; I--);
-	 Memb->Name = std::string(Head.Name,I+1);
-      }
-
-      // Account for the AR header alignment 
-      off_t Skip = Memb->Size % 2;
-      
-      // Add it to the list
-      Memb->Next = List;
-      List = Memb;
-      Memb->Start = File.Tell();
-      if (File.Skip(Memb->Size + Skip) == false)
-	 return false;
-      if (Left < (off_t)(Memb->Size + Skip))
-	 return _error->Error(_("Archive is too short"));
-      Left -= Memb->Size + Skip;
-   }   
-   if (Left != 0)
-      return _error->Error(_("Failed to read the archive headers"));
-   
-   return true;
-}
-									/*}}}*/
-// ARArchive::FindMember - Find a name in the member list		/*{{{*/
-// ---------------------------------------------------------------------
-/* Find a member with the given name */
-const ARArchive::Member *ARArchive::FindMember(const char *Name) const
-{
-   const Member *Res = List;
-   while (Res != 0)
-   {
-      if (Res->Name == Name)
-	 return Res;
-      Res = Res->Next;
-   }
-   
-   return 0;
-}
-									/*}}}*/
diff --git a/apt-inst/contrib/arfile.h b/apt-inst/contrib/arfile.h
deleted file mode 100644
index cf454941e..000000000
--- a/apt-inst/contrib/arfile.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description								/*{{{*/
-/* ######################################################################
-
-   AR File - Handle an 'AR' archive
-   
-   This is a reader for the usual 4.4 BSD AR format. It allows raw
-   stream access to a single member at a time. Basically all this class
-   provides is header parsing and verification. It is up to the client
-   to correctly make use of the stream start/stop points.
-   
-   ##################################################################### */
-									/*}}}*/
-#ifndef PKGLIB_ARFILE_H
-#define PKGLIB_ARFILE_H
-
-#include <apt-pkg/macros.h>
-#include <string>
-#ifndef APT_8_CLEANER_HEADERS
-#include <apt-pkg/fileutl.h>
-#endif
-
-class FileFd;
-
-class ARArchive
-{
-   struct MemberHeader;
-   public:
-   struct Member;
-   
-   protected:
-
-   // Linked list of members
-   Member *List;
-   
-   bool LoadHeaders();
-
-   public:
-   
-   // The stream file
-   FileFd &File;
-
-   // Locate a member by name
-   const Member *FindMember(const char *Name) const;
-   inline Member *Members() { return List; }
-   
-   explicit ARArchive(FileFd &File);
-   ~ARArchive();
-};
-
-// A member of the archive
-struct ARArchive::Member
-{
-   // Fields from the header
-   std::string Name;
-   unsigned long MTime;
-   unsigned long UID;
-   unsigned long GID;
-   unsigned long Mode;
-   unsigned long long Size;
-   
-   // Location of the data.
-   unsigned long long Start;
-   Member *Next;
-   
-   Member() : Start(0), Next(0) {};
-};
-
-#endif
diff --git a/apt-inst/contrib/extracttar.cc b/apt-inst/contrib/extracttar.cc
deleted file mode 100644
index 9bb0a55c0..000000000
--- a/apt-inst/contrib/extracttar.cc
+++ /dev/null
@@ -1,306 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description								/*{{{*/
-/* ######################################################################
-
-   Extract a Tar - Tar Extractor
-
-   Some performance measurements showed that zlib performed quite poorly
-   in comparison to a forked gzip process. This tar extractor makes use
-   of the fact that dup'd file descriptors have the same seek pointer
-   and that gzip will not read past the end of a compressed stream, 
-   even if there is more data. We use the dup property to track extraction
-   progress and the gzip feature to just feed gzip a fd in the middle
-   of an AR file. 
-   
-   ##################################################################### */
-									/*}}}*/
-// Include Files							/*{{{*/
-#include <config.h>
-
-#include <apt-pkg/configuration.h>
-#include <apt-pkg/dirstream.h>
-#include <apt-pkg/error.h>
-#include <apt-pkg/extracttar.h>
-#include <apt-pkg/fileutl.h>
-#include <apt-pkg/strutl.h>
-
-#include <algorithm>
-#include <iostream>
-#include <string>
-#include <fcntl.h>
-#include <signal.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <apti18n.h>
-									/*}}}*/
-
-using namespace std;
-    
-// The on disk header for a tar file.
-struct ExtractTar::TarHeader
-{
-   char Name[100];
-   char Mode[8];
-   char UserID[8];
-   char GroupID[8];
-   char Size[12];
-   char MTime[12];
-   char Checksum[8];
-   char LinkFlag;
-   char LinkName[100];
-   char MagicNumber[8];
-   char UserName[32];
-   char GroupName[32];
-   char Major[8];
-   char Minor[8];      
-};
-   
-// ExtractTar::ExtractTar - Constructor					/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-ExtractTar::ExtractTar(FileFd &Fd,unsigned long long Max,string DecompressionProgram)
-	: File(Fd), MaxInSize(Max), DecompressProg(DecompressionProgram)
-{
-   GZPid = -1;
-   Eof = false;
-}
-									/*}}}*/
-// ExtractTar::ExtractTar - Destructor					/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-ExtractTar::~ExtractTar()
-{
-   // Error close
-   Done();
-}
-									/*}}}*/
-// ExtractTar::Done - Reap the gzip sub process				/*{{{*/
-bool ExtractTar::Done()
-{
-   return InFd.Close();
-}
-									/*}}}*/
-// ExtractTar::StartGzip - Startup gzip					/*{{{*/
-// ---------------------------------------------------------------------
-/* This creates a gzip sub process that has its input as the file itself.
-   If this tar file is embedded into something like an ar file then 
-   gzip will efficiently ignore the extra bits. */
-bool ExtractTar::StartGzip()
-{
-   if (DecompressProg.empty())
-   {
-      InFd.OpenDescriptor(File.Fd(), FileFd::ReadOnly, FileFd::None, false);
-      return true;
-   }
-
-   std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors();
-   std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin();
-   for (; compressor != compressors.end(); ++compressor) {
-      if (compressor->Name == DecompressProg) {
-	 return InFd.OpenDescriptor(File.Fd(), FileFd::ReadOnly, *compressor, false);
-      }
-   }
-
-   return _error->Error(_("Cannot find a configured compressor for '%s'"),
-			DecompressProg.c_str());
-
-}
-									/*}}}*/
-// ExtractTar::Go - Perform extraction					/*{{{*/
-// ---------------------------------------------------------------------
-/* This reads each 512 byte block from the archive and extracts the header
-   information into the Item structure. Then it resolves the UID/GID and
-   invokes the correct processing function. */
-bool ExtractTar::Go(pkgDirStream &Stream)
-{   
-   if (StartGzip() == false)
-      return false;
-   
-   // Loop over all blocks
-   string LastLongLink, ItemLink;
-   string LastLongName, ItemName;
-   while (1)
-   {
-      bool BadRecord = false;      
-      unsigned char Block[512];      
-      if (InFd.Read(Block,sizeof(Block),true) == false)
-	 return false;
-      
-      if (InFd.Eof() == true)
-	 break;
-
-      // Get the checksum
-      TarHeader *Tar = (TarHeader *)Block;
-      unsigned long CheckSum;
-      if (StrToNum(Tar->Checksum,CheckSum,sizeof(Tar->Checksum),8) == false)
-	 return _error->Error(_("Corrupted archive"));
-      
-      /* Compute the checksum field. The actual checksum is blanked out
-         with spaces so it is not included in the computation */
-      unsigned long NewSum = 0;
-      memset(Tar->Checksum,' ',sizeof(Tar->Checksum));
-      for (int I = 0; I != sizeof(Block); I++)
-	 NewSum += Block[I];
-      
-      /* Check for a block of nulls - in this case we kill gzip, GNU tar
-       	 does this.. */
-      if (NewSum == ' '*sizeof(Tar->Checksum))
-	 return Done();
-      
-      if (NewSum != CheckSum)
-	 return _error->Error(_("Tar checksum failed, archive corrupted"));
-   
-      // Decode all of the fields
-      pkgDirStream::Item Itm;
-      if (StrToNum(Tar->Mode,Itm.Mode,sizeof(Tar->Mode),8) == false ||
-          (Base256ToNum(Tar->UserID,Itm.UID,8) == false &&
-	     StrToNum(Tar->UserID,Itm.UID,sizeof(Tar->UserID),8) == false) ||
-          (Base256ToNum(Tar->GroupID,Itm.GID,8) == false &&
-	     StrToNum(Tar->GroupID,Itm.GID,sizeof(Tar->GroupID),8) == false) ||
-          (Base256ToNum(Tar->Size,Itm.Size,12) == false &&
-	     StrToNum(Tar->Size,Itm.Size,sizeof(Tar->Size),8) == false) ||
-          (Base256ToNum(Tar->MTime,Itm.MTime,12) == false &&
-	     StrToNum(Tar->MTime,Itm.MTime,sizeof(Tar->MTime),8) == false) ||
-	  StrToNum(Tar->Major,Itm.Major,sizeof(Tar->Major),8) == false ||
-	  StrToNum(Tar->Minor,Itm.Minor,sizeof(Tar->Minor),8) == false)
-	 return _error->Error(_("Corrupted archive"));
-
-      // Grab the filename and link target: use last long name if one was
-      // set, otherwise use the header value as-is, but remember that it may
-      // fill the entire 100-byte block and needs to be zero-terminated.
-      // See Debian Bug #689582.
-      if (LastLongName.empty() == false)
-	 Itm.Name = (char *)LastLongName.c_str();
-      else
-	 Itm.Name = (char *)ItemName.assign(Tar->Name, sizeof(Tar->Name)).c_str();
-      if (Itm.Name[0] == '.' && Itm.Name[1] == '/' && Itm.Name[2] != 0)
-	 Itm.Name += 2;
-
-      if (LastLongLink.empty() == false)
-	 Itm.LinkTarget = (char *)LastLongLink.c_str();
-      else
-	 Itm.LinkTarget = (char *)ItemLink.assign(Tar->LinkName, sizeof(Tar->LinkName)).c_str();
-
-      // Convert the type over
-      switch (Tar->LinkFlag)
-      {
-	 case NormalFile0:
-	 case NormalFile:
-	 Itm.Type = pkgDirStream::Item::File;
-	 break;
-	 
-	 case HardLink:
-	 Itm.Type = pkgDirStream::Item::HardLink;
-	 break;
-	 
-	 case SymbolicLink:
-	 Itm.Type = pkgDirStream::Item::SymbolicLink;
-	 break;
-	 
-	 case CharacterDevice:
-	 Itm.Type = pkgDirStream::Item::CharDevice;
-	 break;
-	    
-	 case BlockDevice:
-	 Itm.Type = pkgDirStream::Item::BlockDevice;
-	 break;
-	 
-	 case Directory:
-	 Itm.Type = pkgDirStream::Item::Directory;
-	 break;
-	 
-	 case FIFO:
-	 Itm.Type = pkgDirStream::Item::FIFO;
-	 break;
-
-	 case GNU_LongLink:
-	 {
-	    unsigned long long Length = Itm.Size;
-	    unsigned char Block[512];
-	    while (Length > 0)
-	    {
-	       if (InFd.Read(Block,sizeof(Block),true) == false)
-		  return false;
-	       if (Length <= sizeof(Block))
-	       {
-		  LastLongLink.append(Block,Block+sizeof(Block));
-		  break;
-	       }	       
-	       LastLongLink.append(Block,Block+sizeof(Block));
-	       Length -= sizeof(Block);
-	    }
-	    continue;
-	 }
-	 
-	 case GNU_LongName:
-	 {
-	    unsigned long long Length = Itm.Size;
-	    unsigned char Block[512];
-	    while (Length > 0)
-	    {
-	       if (InFd.Read(Block,sizeof(Block),true) == false)
-		  return false;
-	       if (Length < sizeof(Block))
-	       {
-		  LastLongName.append(Block,Block+sizeof(Block));
-		  break;
-	       }	       
-	       LastLongName.append(Block,Block+sizeof(Block));
-	       Length -= sizeof(Block);
-	    }
-	    continue;
-	 }
-	 
-	 default:
-	 BadRecord = true;
-	 _error->Warning(_("Unknown TAR header type %u, member %s"),(unsigned)Tar->LinkFlag,Tar->Name);
-	 break;
-      }
-      
-      int Fd = -1;
-      if (BadRecord == false)
-	 if (Stream.DoItem(Itm,Fd) == false)
-	    return false;
-      
-      // Copy the file over the FD
-      unsigned long long Size = Itm.Size;
-      while (Size != 0)
-      {
-	 unsigned char Junk[32*1024];
-	 unsigned long Read = min(Size, (unsigned long long)sizeof(Junk));
-	 if (InFd.Read(Junk,((Read+511)/512)*512) == false)
-	    return false;
-	 
-	 if (BadRecord == false)
-	 {
-	    if (Fd > 0)
-	    {
-	       if (write(Fd,Junk,Read) != (signed)Read)
-		  return Stream.Fail(Itm,Fd);
-	    }
-	    else
-	    {
-	       /* An Fd of -2 means to send to a special processing
-		  function */
-	       if (Fd == -2)
-		  if (Stream.Process(Itm,Junk,Read,Itm.Size - Size) == false)
-		     return Stream.Fail(Itm,Fd);
-	    }
-	 }
-	 
-	 Size -= Read;
-      }
-      
-      // And finish up
-      if (BadRecord == false)
-	 if (Stream.FinishedFile(Itm,Fd) == false)
-	    return false;
-      
-      LastLongName.erase();
-      LastLongLink.erase();
-   }
-   
-   return Done();
-}
-									/*}}}*/
diff --git a/apt-inst/contrib/extracttar.h b/apt-inst/contrib/extracttar.h
deleted file mode 100644
index adde21352..000000000
--- a/apt-inst/contrib/extracttar.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description								/*{{{*/
-/* ######################################################################
-
-   Extract a Tar - Tar Extractor
-   
-   The tar extractor takes an ordinary gzip compressed tar stream from 
-   the given file and explodes it, passing the individual items to the
-   given Directory Stream for processing.
-   
-   ##################################################################### */
-									/*}}}*/
-#ifndef PKGLIB_EXTRACTTAR_H
-#define PKGLIB_EXTRACTTAR_H
-
-#include <apt-pkg/fileutl.h>
-#include <apt-pkg/macros.h>
-
-#include <string>
-
-#ifndef APT_8_CLEANER_HEADERS
-#include <apt-pkg/dirstream.h>
-#include <algorithm>
-using std::min;
-#endif
-
-class pkgDirStream;
-
-class ExtractTar
-{
-   protected:
-   
-   struct TarHeader;
-   
-   // The varios types items can be
-   enum ItemType {NormalFile0 = '\0',NormalFile = '0',HardLink = '1',
-                  SymbolicLink = '2',CharacterDevice = '3',
-                  BlockDevice = '4',Directory = '5',FIFO = '6',
-                  GNU_LongLink = 'K',GNU_LongName = 'L'};
-
-   FileFd &File;
-   unsigned long long MaxInSize;
-   int GZPid;
-   FileFd InFd;
-   bool Eof;
-   std::string DecompressProg;
-   
-   // Fork and reap gzip
-   bool StartGzip();
-   bool Done();
-
-   public:
-
-   bool Go(pkgDirStream &Stream);
-
-   ExtractTar(FileFd &Fd,unsigned long long Max,std::string DecompressionProgram);
-   virtual ~ExtractTar();
-};
-
-#endif
diff --git a/apt-inst/deb/debfile.cc b/apt-inst/deb/debfile.cc
deleted file mode 100644
index f8d752e7f..000000000
--- a/apt-inst/deb/debfile.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description								/*{{{*/
-/* ######################################################################
-
-   Debian Archive File (.deb)
-   
-   .DEB archives are AR files containing two tars and an empty marker
-   member called 'debian-binary'. The two tars contain the meta data and
-   the actual archive contents. Thus this class is a very simple wrapper
-   around ar/tar to simply extract the right tar files.
-   
-   It also uses the deb package list parser to parse the control file 
-   into the cache.
-   
-   ##################################################################### */
-									/*}}}*/
-// Include Files							/*{{{*/
-#include <config.h>
-
-#include <apt-pkg/aptconfiguration.h>
-#include <apt-pkg/arfile.h>
-#include <apt-pkg/debfile.h>
-#include <apt-pkg/dirstream.h>
-#include <apt-pkg/error.h>
-#include <apt-pkg/extracttar.h>
-#include <apt-pkg/fileutl.h>
-#include <apt-pkg/tagfile.h>
-
-#include <string>
-#include <vector>
-#include <string.h>
-#include <sys/stat.h>
-
-#include <apti18n.h>
-									/*}}}*/
-
-// DebFile::debDebFile - Constructor					/*{{{*/
-// ---------------------------------------------------------------------
-/* Open the AR file and check for consistency */
-debDebFile::debDebFile(FileFd &File) : File(File), AR(File)
-{
-   if (_error->PendingError() == true)
-      return;
-
-   if (!CheckMember("debian-binary")) {
-      _error->Error(_("This is not a valid DEB archive, missing '%s' member"), "debian-binary");
-      return;
-   }
-
-   if (!CheckMember("control.tar") &&
-       !CheckMember("control.tar.gz") &&
-       !CheckMember("control.tar.xz") &&
-       !CheckMember("control.tar.zst"))
-   {
-      _error->Error(_("This is not a valid DEB archive, missing '%s' member"), "control.tar");
-      return;
-   }
-
-   if (!CheckMember("data.tar") &&
-       !CheckMember("data.tar.gz") &&
-       !CheckMember("data.tar.bz2") &&
-       !CheckMember("data.tar.lzma") &&
-       !CheckMember("data.tar.xz") &&
-       !CheckMember("data.tar.zst"))
-   {
-      _error->Error(_("This is not a valid DEB archive, missing '%s' member"), "data.tar");
-      return;
-   }
-}
-									/*}}}*/
-// DebFile::CheckMember - Check if a named member is in the archive	/*{{{*/
-// ---------------------------------------------------------------------
-/* This is used to check for a correct deb and to give nicer error messages
-   for people playing around. */
-bool debDebFile::CheckMember(const char *Name)
-{
-   if (AR.FindMember(Name) == 0)
-      return false;
-   return true;
-}
-									/*}}}*/
-// DebFile::GotoMember - Jump to a Member				/*{{{*/
-// ---------------------------------------------------------------------
-/* Jump in the file to the start of a named member and return the information
-   about that member. The caller can then read from the file up to the 
-   returned size. Note, since this relies on the file position this is
-   a destructive operation, it also changes the last returned Member
-   structure - so don't nest them! */
-const ARArchive::Member *debDebFile::GotoMember(const char *Name)
-{
-   // Get the archive member and positition the file
-   const ARArchive::Member *Member = AR.FindMember(Name);
-   if (Member == 0)
-   {
-      return 0;
-   }
-   if (File.Seek(Member->Start) == false)
-      return 0;
-      
-   return Member;
-}
-									/*}}}*/
-// DebFile::ExtractTarMember - Extract the contents of a tar member	/*{{{*/
-// ---------------------------------------------------------------------
-/* Simple wrapper around tar.. */
-bool debDebFile::ExtractTarMember(pkgDirStream &Stream,const char *Name)
-{
-   // Get the archive member
-   const ARArchive::Member *Member = NULL;
-   std::string Compressor;
-
-   std::vector<APT::Configuration::Compressor> compressor = APT::Configuration::getCompressors();
-   for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
-	c != compressor.end(); ++c)
-   {
-      Member = AR.FindMember(std::string(Name).append(c->Extension).c_str());
-      if (Member == NULL)
-	 continue;
-      Compressor = c->Name;
-      break;
-   }
-
-   if (Member == NULL)
-      Member = AR.FindMember(std::string(Name).c_str());
-
-   if (Member == NULL)
-   {
-      std::string ext = std::string(Name) + ".{";
-      for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
-	   c != compressor.end(); ++c) {
-	 if (!c->Extension.empty())
-	    ext.append(c->Extension.substr(1));
-      }
-      ext.append("}");
-      return _error->Error(_("Internal error, could not locate member %s"), ext.c_str());
-   }
-
-   if (File.Seek(Member->Start) == false)
-      return false;
-
-   // Prepare Tar
-   ExtractTar Tar(File,Member->Size,Compressor);
-   if (_error->PendingError() == true)
-      return false;
-   return Tar.Go(Stream);
-}
-									/*}}}*/
-// DebFile::ExtractArchive - Extract the archive data itself		/*{{{*/
-// ---------------------------------------------------------------------
-/* Simple wrapper around DebFile::ExtractTarMember. */
-bool debDebFile::ExtractArchive(pkgDirStream &Stream)
-{
-   return ExtractTarMember(Stream, "data.tar");
-}
-									/*}}}*/
-
-// DebFile::ControlExtract::DoItem - Control Tar Extraction		/*{{{*/
-// ---------------------------------------------------------------------
-/* This directory stream handler for the control tar handles extracting
-   it into the temporary meta directory. It only extracts files, it does
-   not create directories, links or anything else. */
-bool debDebFile::ControlExtract::DoItem(Item &Itm,int &Fd)
-{
-   if (Itm.Type != Item::File)
-      return true;
-   
-   /* Cleanse the file name, prevent people from trying to unpack into
-      absolute paths, .., etc */
-   for (char *I = Itm.Name; *I != 0; I++)
-      if (*I == '/')
-	 *I = '_';
-
-   /* Force the ownership to be root and ensure correct permissions, 
-      go-w, the rest are left untouched */
-   Itm.UID = 0;
-   Itm.GID = 0;
-   Itm.Mode &= ~(S_IWGRP | S_IWOTH);
-   
-   return pkgDirStream::DoItem(Itm,Fd);
-}
-									/*}}}*/
-
-// MemControlExtract::DoItem - Check if it is the control file		/*{{{*/
-// ---------------------------------------------------------------------
-/* This sets up to extract the control block member file into a memory 
-   block of just the right size. All other files go into the bit bucket. */
-bool debDebFile::MemControlExtract::DoItem(Item &Itm,int &Fd)
-{
-   // At the control file, allocate buffer memory.
-   if (Member == Itm.Name)
-   {
-      delete [] Control;
-      Control = new char[Itm.Size+2];
-      IsControl = true;
-      Fd = -2; // Signal to pass to Process
-      Length = Itm.Size;
-   }   
-   else
-      IsControl = false;
-   
-   return true;
-}
-									/*}}}*/
-// MemControlExtract::Process - Process extracting the control file	/*{{{*/
-// ---------------------------------------------------------------------
-/* Just memcopy the block from the tar extractor and put it in the right
-   place in the pre-allocated memory block. */
-bool debDebFile::MemControlExtract::Process(Item &/*Itm*/,const unsigned char *Data,
-			     unsigned long long Size,unsigned long long Pos)
-{
-   memcpy(Control + Pos, Data,Size);
-   return true;
-}
-									/*}}}*/
-// MemControlExtract::Read - Read the control information from the deb	/*{{{*/
-// ---------------------------------------------------------------------
-/* This uses the internal tar extractor to fetch the control file, and then
-   it parses it into a tag section parser. */
-bool debDebFile::MemControlExtract::Read(debDebFile &Deb)
-{
-   if (Deb.ExtractTarMember(*this, "control.tar") == false)
-      return false;
-
-   if (Control == 0)
-      return true;
-   
-   Control[Length] = '\n';
-   Control[Length+1] = '\n';
-   if (Section.Scan(Control,Length+2) == false)
-      return _error->Error(_("Unparsable control file"));
-   return true;
-}
-									/*}}}*/
-// MemControlExtract::TakeControl - Parse a memory block		/*{{{*/
-// ---------------------------------------------------------------------
-/* The given memory block is loaded into the parser and parsed as a control
-   record. */
-bool debDebFile::MemControlExtract::TakeControl(const void *Data,unsigned long long Size)
-{
-   delete [] Control;
-   Control = new char[Size+2];
-   Length = Size;
-   memcpy(Control,Data,Size);
-   
-   Control[Length] = '\n';
-   Control[Length+1] = '\n';
-   return Section.Scan(Control,Length+2);
-}
-									/*}}}*/
-
diff --git a/apt-inst/deb/debfile.h b/apt-inst/deb/debfile.h
deleted file mode 100644
index 21c59a567..000000000
--- a/apt-inst/deb/debfile.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description								/*{{{*/
-/* ######################################################################
-
-   Debian Archive File (.deb)
-
-   This Class handles all the operations performed directly on .deb 
-   files. It makes use of the AR and TAR classes to give the necessary
-   external interface.
-   
-   There are only two things that can be done with a raw package, 
-   extract it's control information and extract the contents itself. 
-
-   This should probably subclass an as-yet unwritten super class to
-   produce a generic archive mechanism.
-  
-   The memory control file extractor is useful to extract a single file
-   into memory from the control.tar.gz
-   
-   ##################################################################### */
-									/*}}}*/
-#ifndef PKGLIB_DEBFILE_H
-#define PKGLIB_DEBFILE_H
-
-#include <apt-pkg/arfile.h>
-#include <apt-pkg/dirstream.h>
-#include <apt-pkg/macros.h>
-#include <apt-pkg/tagfile.h>
-
-#include <string>
-
-#ifndef APT_8_CLEANER_HEADERS
-#include <apt-pkg/md5.h>
-#endif
-#ifndef APT_10_CLEANER_HEADERS
-#include <apt-pkg/pkgcache.h>
-#endif
-
-class FileFd;
-
-class debDebFile
-{
-   protected:
-   
-   FileFd &File;
-   ARArchive AR;
-   
-   bool CheckMember(const char *Name);
-   
-   public:
-   class ControlExtract;
-   class MemControlExtract;
-
-   bool ExtractTarMember(pkgDirStream &Stream, const char *Name);
-   bool ExtractArchive(pkgDirStream &Stream);
-   const ARArchive::Member *GotoMember(const char *Name);
-   inline FileFd &GetFile() {return File;};
-   
-   explicit debDebFile(FileFd &File);
-};
-
-class debDebFile::ControlExtract : public pkgDirStream
-{
-   public:
-   
-   virtual bool DoItem(Item &Itm,int &Fd) APT_OVERRIDE;
-};
-
-class debDebFile::MemControlExtract : public pkgDirStream
-{
-   bool IsControl;
-   
-   public:
-   
-   char *Control;
-   pkgTagSection Section;
-   unsigned long Length;
-   std::string Member;
-   
-   // Members from DirStream
-   virtual bool DoItem(Item &Itm,int &Fd) APT_OVERRIDE;
-   virtual bool Process(Item &Itm,const unsigned char *Data,
-			unsigned long long Size,unsigned long long Pos) APT_OVERRIDE;
-
-   // Helpers
-   bool Read(debDebFile &Deb);
-   bool TakeControl(const void *Data,unsigned long long Size);
-
-   MemControlExtract() : IsControl(false), Control(0), Length(0), Member("control") {};
-   explicit MemControlExtract(std::string Member) : IsControl(false), Control(0), Length(0), Member(Member) {};
-   ~MemControlExtract() {delete [] Control;};   
-};
-									/*}}}*/
-
-#endif
diff --git a/apt-inst/dirstream.cc b/apt-inst/dirstream.cc
deleted file mode 100644
index d6cf0ab3f..000000000
--- a/apt-inst/dirstream.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description								/*{{{*/
-/* ######################################################################
-
-   Directory Stream 
-   
-   This class provides a simple basic extractor that can be used for
-   a number of purposes.
-   
-   ##################################################################### */
-									/*}}}*/
-// Include Files							/*{{{*/
-#include <config.h>
-
-#include <apt-pkg/dirstream.h>
-#include <apt-pkg/error.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <apti18n.h>
-									/*}}}*/
-
-// DirStream::DoItem - Process an item					/*{{{*/
-// ---------------------------------------------------------------------
-/* This is a very simple extractor, it does not deal with things like
-   overwriting directories with files and so on. */
-bool pkgDirStream::DoItem(Item &Itm,int &Fd)
-{
-   switch (Itm.Type)
-   {
-      case Item::File:
-      {
-	 /* Open the output file, NDELAY is used to prevent this from 
-	    blowing up on device special files.. */
-	 int iFd = open(Itm.Name,O_NDELAY|O_WRONLY|O_CREAT|O_TRUNC|O_APPEND,
-		       Itm.Mode);
-	 if (iFd < 0)
-	    return _error->Errno("open",_("Failed to write file %s"),
-				 Itm.Name);
-	 
-	 // fchmod deals with umask and fchown sets the ownership
-	 if (fchmod(iFd,Itm.Mode) != 0)
-	 {
-	    close(iFd);
-	    return _error->Errno("fchmod",_("Failed to write file %s"), Itm.Name);
-	 }
-	 if (fchown(iFd,Itm.UID,Itm.GID) != 0 && errno != EPERM)
-	 {
-	    close(iFd);
-	    return _error->Errno("fchown",_("Failed to write file %s"), Itm.Name);
-	 }
-	 Fd = iFd;
-	 return true;
-      }
-      
-      case Item::HardLink:
-      case Item::SymbolicLink:
-      case Item::CharDevice:
-      case Item::BlockDevice:
-      case Item::Directory:
-      {
-	 struct stat Buf;
-	 // check if the dir is already there, if so return true
-	 if (stat(Itm.Name,&Buf) == 0)
-	 {
-	    if(S_ISDIR(Buf.st_mode))
-	       return true;
-	    // something else is there already, return false
-	    return false;
-	 }
-	 // nothing here, create the dir
-	 if(mkdir(Itm.Name,Itm.Mode) < 0)
-	    return false;
-	 return true;
-      }
-      case Item::FIFO:
-      break;
-   }
-   
-   return true;
-}
-									/*}}}*/
-// DirStream::FinishedFile - Finished processing a file			/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool pkgDirStream::FinishedFile(Item &Itm,int Fd)
-{
-   if (Fd < 0)
-      return true;
-
-   /* Set the modification times. The only way it can fail is if someone
-      has futzed with our file, which is intolerable :> */
-   struct timeval times[2];
-   times[0].tv_sec = times[1].tv_sec = Itm.MTime;
-   times[0].tv_usec = times[1].tv_usec = 0;
-   if (utimes(Itm.Name, times) != 0)
-      _error->Errno("utimes", "Failed to set modification time for %s",Itm.Name);
-
-   if (close(Fd) != 0)
-      return _error->Errno("close",_("Failed to close file %s"),Itm.Name);
-   return true;
-}
-									/*}}}*/
-// DirStream::Fail - Failed processing a file				/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool pkgDirStream::Fail(Item &/*Itm*/, int Fd)
-{
-   if (Fd < 0)
-      return true;
-   
-   close(Fd);
-   return false;
-}
-									/*}}}*/
diff --git a/apt-inst/dirstream.h b/apt-inst/dirstream.h
deleted file mode 100644
index 0f0e348d0..000000000
--- a/apt-inst/dirstream.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description								/*{{{*/
-/* ######################################################################
-
-   Directory Stream 
-
-   When unpacking the contents of the archive are passed into a directory
-   stream class for analysis and processing. The class controls all aspects
-   of actually writing the directory stream from disk. The low level
-   archive handlers are only responsible for decoding the archive format
-   and sending events (via method calls) to the specified directory
-   stream.
-   
-   When unpacking a real file the archive handler is passed back a file 
-   handle to write the data to, this is to support strange 
-   archives+unpacking methods. If that fd is -1 then the file data is 
-   simply ignored.
-   
-   The provided defaults do the 'Right Thing' for a normal unpacking
-   process (ie 'tar')
-   
-   ##################################################################### */
-									/*}}}*/
-#ifndef PKGLIB_DIRSTREAM_H
-#define PKGLIB_DIRSTREAM_H
-
-#include <apt-pkg/macros.h>
-
-class pkgDirStream
-{ 
-   public:
-
-   // All possible information about a component
-   struct Item
-   {
-      enum Type_t {File, HardLink, SymbolicLink, CharDevice, BlockDevice,
-	           Directory, FIFO} Type;
-      char *Name;
-      char *LinkTarget;
-      unsigned long Mode;
-      unsigned long UID;
-      unsigned long GID;
-      unsigned long long Size;
-      unsigned long MTime;
-      unsigned long Major;
-      unsigned long Minor;
-   };
-   
-   virtual bool DoItem(Item &Itm,int &Fd);
-   virtual bool Fail(Item &Itm,int Fd);
-   virtual bool FinishedFile(Item &Itm,int Fd);
-   virtual bool Process(Item &/*Itm*/,const unsigned char * /*Data*/,
-			unsigned long long /*Size*/,unsigned long long /*Pos*/) {return true;};
-   virtual ~pkgDirStream() {};   
-};
-
-#endif
diff --git a/apt-inst/dpkg-diffs.txt b/apt-inst/dpkg-diffs.txt
deleted file mode 100644
index d161055f7..000000000
--- a/apt-inst/dpkg-diffs.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-- Replacing directories with files
-  dpkg permits this with the weak condition that the directory is owned only
-  by the package. APT requires that the directory have no files that are not
-  owned by the package. Replaces are specifically not checked to prevent
-  file list corruption.
diff --git a/apt-pkg/contrib/arfile.cc b/apt-pkg/contrib/arfile.cc
new file mode 100644
index 000000000..3fc3afedb
--- /dev/null
+++ b/apt-pkg/contrib/arfile.cc
@@ -0,0 +1,160 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+
+   AR File - Handle an 'AR' archive
+   
+   AR Archives have plain text headers at the start of each file
+   section. The headers are aligned on a 2 byte boundary.
+   
+   Information about the structure of AR files can be found in ar(5)
+   on a BSD system, or in the binutils source.
+
+   ##################################################################### */
+									/*}}}*/
+// Include Files							/*{{{*/
+#include <config.h>
+
+#include <apt-pkg/arfile.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/strutl.h>
+
+#include <string>
+#include <string.h>
+#include <sys/types.h>
+
+#include <apti18n.h>
+									/*}}}*/
+
+struct ARArchive::MemberHeader
+{
+   char Name[16];
+   char MTime[12];
+   char UID[6];
+   char GID[6];
+   char Mode[8];
+   char Size[10];
+   char Magic[2];
+};
+
+// ARArchive::ARArchive - Constructor					/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+ARArchive::ARArchive(FileFd &File) : List(0), File(File)
+{
+   LoadHeaders();
+}
+									/*}}}*/
+// ARArchive::~ARArchive - Destructor					/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+ARArchive::~ARArchive()
+{
+   while (List != 0)
+   {
+      Member *Tmp = List;
+      List = List->Next;
+      delete Tmp;
+   }   
+}
+									/*}}}*/
+// ARArchive::LoadHeaders - Load the headers from each file		/*{{{*/
+// ---------------------------------------------------------------------
+/* AR files are structured with a 8 byte magic string followed by a 60
+   byte plain text header then the file data, another header, data, etc */
+bool ARArchive::LoadHeaders()
+{
+   off_t Left = File.Size();
+   
+   // Check the magic byte
+   char Magic[8];
+   if (File.Read(Magic,sizeof(Magic)) == false)
+      return false;
+   if (memcmp(Magic,"!<arch>\012",sizeof(Magic)) != 0)
+      return _error->Error(_("Invalid archive signature"));
+   Left -= sizeof(Magic);
+   
+   // Read the member list
+   while (Left > 0)
+   {
+      MemberHeader Head;
+      if (File.Read(&Head,sizeof(Head)) == false)
+	 return _error->Error(_("Error reading archive member header"));
+      Left -= sizeof(Head);
+
+      // Convert all of the integer members
+      Member *Memb = new Member();
+      if (StrToNum(Head.MTime,Memb->MTime,sizeof(Head.MTime)) == false ||
+	  StrToNum(Head.UID,Memb->UID,sizeof(Head.UID)) == false ||
+	  StrToNum(Head.GID,Memb->GID,sizeof(Head.GID)) == false ||
+	  StrToNum(Head.Mode,Memb->Mode,sizeof(Head.Mode),8) == false ||
+	  StrToNum(Head.Size,Memb->Size,sizeof(Head.Size)) == false)
+      {
+	 delete Memb;
+	 return _error->Error(_("Invalid archive member header %s"), Head.Name);
+      }
+	 
+      // Check for an extra long name string
+      if (memcmp(Head.Name,"#1/",3) == 0)
+      {
+	 char S[300];
+	 unsigned long Len;
+	 if (StrToNum(Head.Name+3,Len,sizeof(Head.Size)-3) == false ||
+	     Len >= sizeof(S))
+	 {
+	    delete Memb;
+	    return _error->Error(_("Invalid archive member header"));
+	 }
+	 if (File.Read(S,Len) == false)
+	 {
+	    delete Memb;
+	    return false;
+	 }
+	 S[Len] = 0;
+	 Memb->Name = S;
+	 Memb->Size -= Len;
+	 Left -= Len;
+      }
+      else
+      {
+	 unsigned int I = sizeof(Head.Name) - 1;
+	 for (; Head.Name[I] == ' ' || Head.Name[I] == '/'; I--);
+	 Memb->Name = std::string(Head.Name,I+1);
+      }
+
+      // Account for the AR header alignment 
+      off_t Skip = Memb->Size % 2;
+      
+      // Add it to the list
+      Memb->Next = List;
+      List = Memb;
+      Memb->Start = File.Tell();
+      if (File.Skip(Memb->Size + Skip) == false)
+	 return false;
+      if (Left < (off_t)(Memb->Size + Skip))
+	 return _error->Error(_("Archive is too short"));
+      Left -= Memb->Size + Skip;
+   }   
+   if (Left != 0)
+      return _error->Error(_("Failed to read the archive headers"));
+   
+   return true;
+}
+									/*}}}*/
+// ARArchive::FindMember - Find a name in the member list		/*{{{*/
+// ---------------------------------------------------------------------
+/* Find a member with the given name */
+const ARArchive::Member *ARArchive::FindMember(const char *Name) const
+{
+   const Member *Res = List;
+   while (Res != 0)
+   {
+      if (Res->Name == Name)
+	 return Res;
+      Res = Res->Next;
+   }
+   
+   return 0;
+}
+									/*}}}*/
diff --git a/apt-pkg/contrib/arfile.h b/apt-pkg/contrib/arfile.h
new file mode 100644
index 000000000..cf454941e
--- /dev/null
+++ b/apt-pkg/contrib/arfile.h
@@ -0,0 +1,69 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+
+   AR File - Handle an 'AR' archive
+   
+   This is a reader for the usual 4.4 BSD AR format. It allows raw
+   stream access to a single member at a time. Basically all this class
+   provides is header parsing and verification. It is up to the client
+   to correctly make use of the stream start/stop points.
+   
+   ##################################################################### */
+									/*}}}*/
+#ifndef PKGLIB_ARFILE_H
+#define PKGLIB_ARFILE_H
+
+#include <apt-pkg/macros.h>
+#include <string>
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/fileutl.h>
+#endif
+
+class FileFd;
+
+class ARArchive
+{
+   struct MemberHeader;
+   public:
+   struct Member;
+   
+   protected:
+
+   // Linked list of members
+   Member *List;
+   
+   bool LoadHeaders();
+
+   public:
+   
+   // The stream file
+   FileFd &File;
+
+   // Locate a member by name
+   const Member *FindMember(const char *Name) const;
+   inline Member *Members() { return List; }
+   
+   explicit ARArchive(FileFd &File);
+   ~ARArchive();
+};
+
+// A member of the archive
+struct ARArchive::Member
+{
+   // Fields from the header
+   std::string Name;
+   unsigned long MTime;
+   unsigned long UID;
+   unsigned long GID;
+   unsigned long Mode;
+   unsigned long long Size;
+   
+   // Location of the data.
+   unsigned long long Start;
+   Member *Next;
+   
+   Member() : Start(0), Next(0) {};
+};
+
+#endif
diff --git a/apt-pkg/contrib/extracttar.cc b/apt-pkg/contrib/extracttar.cc
new file mode 100644
index 000000000..9bb0a55c0
--- /dev/null
+++ b/apt-pkg/contrib/extracttar.cc
@@ -0,0 +1,306 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+
+   Extract a Tar - Tar Extractor
+
+   Some performance measurements showed that zlib performed quite poorly
+   in comparison to a forked gzip process. This tar extractor makes use
+   of the fact that dup'd file descriptors have the same seek pointer
+   and that gzip will not read past the end of a compressed stream, 
+   even if there is more data. We use the dup property to track extraction
+   progress and the gzip feature to just feed gzip a fd in the middle
+   of an AR file. 
+   
+   ##################################################################### */
+									/*}}}*/
+// Include Files							/*{{{*/
+#include <config.h>
+
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/dirstream.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/extracttar.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/strutl.h>
+
+#include <algorithm>
+#include <iostream>
+#include <string>
+#include <fcntl.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <apti18n.h>
+									/*}}}*/
+
+using namespace std;
+    
+// The on disk header for a tar file.
+struct ExtractTar::TarHeader
+{
+   char Name[100];
+   char Mode[8];
+   char UserID[8];
+   char GroupID[8];
+   char Size[12];
+   char MTime[12];
+   char Checksum[8];
+   char LinkFlag;
+   char LinkName[100];
+   char MagicNumber[8];
+   char UserName[32];
+   char GroupName[32];
+   char Major[8];
+   char Minor[8];      
+};
+   
+// ExtractTar::ExtractTar - Constructor					/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+ExtractTar::ExtractTar(FileFd &Fd,unsigned long long Max,string DecompressionProgram)
+	: File(Fd), MaxInSize(Max), DecompressProg(DecompressionProgram)
+{
+   GZPid = -1;
+   Eof = false;
+}
+									/*}}}*/
+// ExtractTar::ExtractTar - Destructor					/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+ExtractTar::~ExtractTar()
+{
+   // Error close
+   Done();
+}
+									/*}}}*/
+// ExtractTar::Done - Reap the gzip sub process				/*{{{*/
+bool ExtractTar::Done()
+{
+   return InFd.Close();
+}
+									/*}}}*/
+// ExtractTar::StartGzip - Startup gzip					/*{{{*/
+// ---------------------------------------------------------------------
+/* This creates a gzip sub process that has its input as the file itself.
+   If this tar file is embedded into something like an ar file then 
+   gzip will efficiently ignore the extra bits. */
+bool ExtractTar::StartGzip()
+{
+   if (DecompressProg.empty())
+   {
+      InFd.OpenDescriptor(File.Fd(), FileFd::ReadOnly, FileFd::None, false);
+      return true;
+   }
+
+   std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors();
+   std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin();
+   for (; compressor != compressors.end(); ++compressor) {
+      if (compressor->Name == DecompressProg) {
+	 return InFd.OpenDescriptor(File.Fd(), FileFd::ReadOnly, *compressor, false);
+      }
+   }
+
+   return _error->Error(_("Cannot find a configured compressor for '%s'"),
+			DecompressProg.c_str());
+
+}
+									/*}}}*/
+// ExtractTar::Go - Perform extraction					/*{{{*/
+// ---------------------------------------------------------------------
+/* This reads each 512 byte block from the archive and extracts the header
+   information into the Item structure. Then it resolves the UID/GID and
+   invokes the correct processing function. */
+bool ExtractTar::Go(pkgDirStream &Stream)
+{   
+   if (StartGzip() == false)
+      return false;
+   
+   // Loop over all blocks
+   string LastLongLink, ItemLink;
+   string LastLongName, ItemName;
+   while (1)
+   {
+      bool BadRecord = false;      
+      unsigned char Block[512];      
+      if (InFd.Read(Block,sizeof(Block),true) == false)
+	 return false;
+      
+      if (InFd.Eof() == true)
+	 break;
+
+      // Get the checksum
+      TarHeader *Tar = (TarHeader *)Block;
+      unsigned long CheckSum;
+      if (StrToNum(Tar->Checksum,CheckSum,sizeof(Tar->Checksum),8) == false)
+	 return _error->Error(_("Corrupted archive"));
+      
+      /* Compute the checksum field. The actual checksum is blanked out
+         with spaces so it is not included in the computation */
+      unsigned long NewSum = 0;
+      memset(Tar->Checksum,' ',sizeof(Tar->Checksum));
+      for (int I = 0; I != sizeof(Block); I++)
+	 NewSum += Block[I];
+      
+      /* Check for a block of nulls - in this case we kill gzip, GNU tar
+       	 does this.. */
+      if (NewSum == ' '*sizeof(Tar->Checksum))
+	 return Done();
+      
+      if (NewSum != CheckSum)
+	 return _error->Error(_("Tar checksum failed, archive corrupted"));
+   
+      // Decode all of the fields
+      pkgDirStream::Item Itm;
+      if (StrToNum(Tar->Mode,Itm.Mode,sizeof(Tar->Mode),8) == false ||
+          (Base256ToNum(Tar->UserID,Itm.UID,8) == false &&
+	     StrToNum(Tar->UserID,Itm.UID,sizeof(Tar->UserID),8) == false) ||
+          (Base256ToNum(Tar->GroupID,Itm.GID,8) == false &&
+	     StrToNum(Tar->GroupID,Itm.GID,sizeof(Tar->GroupID),8) == false) ||
+          (Base256ToNum(Tar->Size,Itm.Size,12) == false &&
+	     StrToNum(Tar->Size,Itm.Size,sizeof(Tar->Size),8) == false) ||
+          (Base256ToNum(Tar->MTime,Itm.MTime,12) == false &&
+	     StrToNum(Tar->MTime,Itm.MTime,sizeof(Tar->MTime),8) == false) ||
+	  StrToNum(Tar->Major,Itm.Major,sizeof(Tar->Major),8) == false ||
+	  StrToNum(Tar->Minor,Itm.Minor,sizeof(Tar->Minor),8) == false)
+	 return _error->Error(_("Corrupted archive"));
+
+      // Grab the filename and link target: use last long name if one was
+      // set, otherwise use the header value as-is, but remember that it may
+      // fill the entire 100-byte block and needs to be zero-terminated.
+      // See Debian Bug #689582.
+      if (LastLongName.empty() == false)
+	 Itm.Name = (char *)LastLongName.c_str();
+      else
+	 Itm.Name = (char *)ItemName.assign(Tar->Name, sizeof(Tar->Name)).c_str();
+      if (Itm.Name[0] == '.' && Itm.Name[1] == '/' && Itm.Name[2] != 0)
+	 Itm.Name += 2;
+
+      if (LastLongLink.empty() == false)
+	 Itm.LinkTarget = (char *)LastLongLink.c_str();
+      else
+	 Itm.LinkTarget = (char *)ItemLink.assign(Tar->LinkName, sizeof(Tar->LinkName)).c_str();
+
+      // Convert the type over
+      switch (Tar->LinkFlag)
+      {
+	 case NormalFile0:
+	 case NormalFile:
+	 Itm.Type = pkgDirStream::Item::File;
+	 break;
+	 
+	 case HardLink:
+	 Itm.Type = pkgDirStream::Item::HardLink;
+	 break;
+	 
+	 case SymbolicLink:
+	 Itm.Type = pkgDirStream::Item::SymbolicLink;
+	 break;
+	 
+	 case CharacterDevice:
+	 Itm.Type = pkgDirStream::Item::CharDevice;
+	 break;
+	    
+	 case BlockDevice:
+	 Itm.Type = pkgDirStream::Item::BlockDevice;
+	 break;
+	 
+	 case Directory:
+	 Itm.Type = pkgDirStream::Item::Directory;
+	 break;
+	 
+	 case FIFO:
+	 Itm.Type = pkgDirStream::Item::FIFO;
+	 break;
+
+	 case GNU_LongLink:
+	 {
+	    unsigned long long Length = Itm.Size;
+	    unsigned char Block[512];
+	    while (Length > 0)
+	    {
+	       if (InFd.Read(Block,sizeof(Block),true) == false)
+		  return false;
+	       if (Length <= sizeof(Block))
+	       {
+		  LastLongLink.append(Block,Block+sizeof(Block));
+		  break;
+	       }	       
+	       LastLongLink.append(Block,Block+sizeof(Block));
+	       Length -= sizeof(Block);
+	    }
+	    continue;
+	 }
+	 
+	 case GNU_LongName:
+	 {
+	    unsigned long long Length = Itm.Size;
+	    unsigned char Block[512];
+	    while (Length > 0)
+	    {
+	       if (InFd.Read(Block,sizeof(Block),true) == false)
+		  return false;
+	       if (Length < sizeof(Block))
+	       {
+		  LastLongName.append(Block,Block+sizeof(Block));
+		  break;
+	       }	       
+	       LastLongName.append(Block,Block+sizeof(Block));
+	       Length -= sizeof(Block);
+	    }
+	    continue;
+	 }
+	 
+	 default:
+	 BadRecord = true;
+	 _error->Warning(_("Unknown TAR header type %u, member %s"),(unsigned)Tar->LinkFlag,Tar->Name);
+	 break;
+      }
+      
+      int Fd = -1;
+      if (BadRecord == false)
+	 if (Stream.DoItem(Itm,Fd) == false)
+	    return false;
+      
+      // Copy the file over the FD
+      unsigned long long Size = Itm.Size;
+      while (Size != 0)
+      {
+	 unsigned char Junk[32*1024];
+	 unsigned long Read = min(Size, (unsigned long long)sizeof(Junk));
+	 if (InFd.Read(Junk,((Read+511)/512)*512) == false)
+	    return false;
+	 
+	 if (BadRecord == false)
+	 {
+	    if (Fd > 0)
+	    {
+	       if (write(Fd,Junk,Read) != (signed)Read)
+		  return Stream.Fail(Itm,Fd);
+	    }
+	    else
+	    {
+	       /* An Fd of -2 means to send to a special processing
+		  function */
+	       if (Fd == -2)
+		  if (Stream.Process(Itm,Junk,Read,Itm.Size - Size) == false)
+		     return Stream.Fail(Itm,Fd);
+	    }
+	 }
+	 
+	 Size -= Read;
+      }
+      
+      // And finish up
+      if (BadRecord == false)
+	 if (Stream.FinishedFile(Itm,Fd) == false)
+	    return false;
+      
+      LastLongName.erase();
+      LastLongLink.erase();
+   }
+   
+   return Done();
+}
+									/*}}}*/
diff --git a/apt-pkg/contrib/extracttar.h b/apt-pkg/contrib/extracttar.h
new file mode 100644
index 000000000..adde21352
--- /dev/null
+++ b/apt-pkg/contrib/extracttar.h
@@ -0,0 +1,60 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+
+   Extract a Tar - Tar Extractor
+   
+   The tar extractor takes an ordinary gzip compressed tar stream from 
+   the given file and explodes it, passing the individual items to the
+   given Directory Stream for processing.
+   
+   ##################################################################### */
+									/*}}}*/
+#ifndef PKGLIB_EXTRACTTAR_H
+#define PKGLIB_EXTRACTTAR_H
+
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/macros.h>
+
+#include <string>
+
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/dirstream.h>
+#include <algorithm>
+using std::min;
+#endif
+
+class pkgDirStream;
+
+class ExtractTar
+{
+   protected:
+   
+   struct TarHeader;
+   
+   // The varios types items can be
+   enum ItemType {NormalFile0 = '\0',NormalFile = '0',HardLink = '1',
+                  SymbolicLink = '2',CharacterDevice = '3',
+                  BlockDevice = '4',Directory = '5',FIFO = '6',
+                  GNU_LongLink = 'K',GNU_LongName = 'L'};
+
+   FileFd &File;
+   unsigned long long MaxInSize;
+   int GZPid;
+   FileFd InFd;
+   bool Eof;
+   std::string DecompressProg;
+   
+   // Fork and reap gzip
+   bool StartGzip();
+   bool Done();
+
+   public:
+
+   bool Go(pkgDirStream &Stream);
+
+   ExtractTar(FileFd &Fd,unsigned long long Max,std::string DecompressionProgram);
+   virtual ~ExtractTar();
+};
+
+#endif
diff --git a/apt-pkg/deb/debfile.cc b/apt-pkg/deb/debfile.cc
new file mode 100644
index 000000000..f8d752e7f
--- /dev/null
+++ b/apt-pkg/deb/debfile.cc
@@ -0,0 +1,250 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+
+   Debian Archive File (.deb)
+   
+   .DEB archives are AR files containing two tars and an empty marker
+   member called 'debian-binary'. The two tars contain the meta data and
+   the actual archive contents. Thus this class is a very simple wrapper
+   around ar/tar to simply extract the right tar files.
+   
+   It also uses the deb package list parser to parse the control file 
+   into the cache.
+   
+   ##################################################################### */
+									/*}}}*/
+// Include Files							/*{{{*/
+#include <config.h>
+
+#include <apt-pkg/aptconfiguration.h>
+#include <apt-pkg/arfile.h>
+#include <apt-pkg/debfile.h>
+#include <apt-pkg/dirstream.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/extracttar.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/tagfile.h>
+
+#include <string>
+#include <vector>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <apti18n.h>
+									/*}}}*/
+
+// DebFile::debDebFile - Constructor					/*{{{*/
+// ---------------------------------------------------------------------
+/* Open the AR file and check for consistency */
+debDebFile::debDebFile(FileFd &File) : File(File), AR(File)
+{
+   if (_error->PendingError() == true)
+      return;
+
+   if (!CheckMember("debian-binary")) {
+      _error->Error(_("This is not a valid DEB archive, missing '%s' member"), "debian-binary");
+      return;
+   }
+
+   if (!CheckMember("control.tar") &&
+       !CheckMember("control.tar.gz") &&
+       !CheckMember("control.tar.xz") &&
+       !CheckMember("control.tar.zst"))
+   {
+      _error->Error(_("This is not a valid DEB archive, missing '%s' member"), "control.tar");
+      return;
+   }
+
+   if (!CheckMember("data.tar") &&
+       !CheckMember("data.tar.gz") &&
+       !CheckMember("data.tar.bz2") &&
+       !CheckMember("data.tar.lzma") &&
+       !CheckMember("data.tar.xz") &&
+       !CheckMember("data.tar.zst"))
+   {
+      _error->Error(_("This is not a valid DEB archive, missing '%s' member"), "data.tar");
+      return;
+   }
+}
+									/*}}}*/
+// DebFile::CheckMember - Check if a named member is in the archive	/*{{{*/
+// ---------------------------------------------------------------------
+/* This is used to check for a correct deb and to give nicer error messages
+   for people playing around. */
+bool debDebFile::CheckMember(const char *Name)
+{
+   if (AR.FindMember(Name) == 0)
+      return false;
+   return true;
+}
+									/*}}}*/
+// DebFile::GotoMember - Jump to a Member				/*{{{*/
+// ---------------------------------------------------------------------
+/* Jump in the file to the start of a named member and return the information
+   about that member. The caller can then read from the file up to the 
+   returned size. Note, since this relies on the file position this is
+   a destructive operation, it also changes the last returned Member
+   structure - so don't nest them! */
+const ARArchive::Member *debDebFile::GotoMember(const char *Name)
+{
+   // Get the archive member and positition the file
+   const ARArchive::Member *Member = AR.FindMember(Name);
+   if (Member == 0)
+   {
+      return 0;
+   }
+   if (File.Seek(Member->Start) == false)
+      return 0;
+      
+   return Member;
+}
+									/*}}}*/
+// DebFile::ExtractTarMember - Extract the contents of a tar member	/*{{{*/
+// ---------------------------------------------------------------------
+/* Simple wrapper around tar.. */
+bool debDebFile::ExtractTarMember(pkgDirStream &Stream,const char *Name)
+{
+   // Get the archive member
+   const ARArchive::Member *Member = NULL;
+   std::string Compressor;
+
+   std::vector<APT::Configuration::Compressor> compressor = APT::Configuration::getCompressors();
+   for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
+	c != compressor.end(); ++c)
+   {
+      Member = AR.FindMember(std::string(Name).append(c->Extension).c_str());
+      if (Member == NULL)
+	 continue;
+      Compressor = c->Name;
+      break;
+   }
+
+   if (Member == NULL)
+      Member = AR.FindMember(std::string(Name).c_str());
+
+   if (Member == NULL)
+   {
+      std::string ext = std::string(Name) + ".{";
+      for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
+	   c != compressor.end(); ++c) {
+	 if (!c->Extension.empty())
+	    ext.append(c->Extension.substr(1));
+      }
+      ext.append("}");
+      return _error->Error(_("Internal error, could not locate member %s"), ext.c_str());
+   }
+
+   if (File.Seek(Member->Start) == false)
+      return false;
+
+   // Prepare Tar
+   ExtractTar Tar(File,Member->Size,Compressor);
+   if (_error->PendingError() == true)
+      return false;
+   return Tar.Go(Stream);
+}
+									/*}}}*/
+// DebFile::ExtractArchive - Extract the archive data itself		/*{{{*/
+// ---------------------------------------------------------------------
+/* Simple wrapper around DebFile::ExtractTarMember. */
+bool debDebFile::ExtractArchive(pkgDirStream &Stream)
+{
+   return ExtractTarMember(Stream, "data.tar");
+}
+									/*}}}*/
+
+// DebFile::ControlExtract::DoItem - Control Tar Extraction		/*{{{*/
+// ---------------------------------------------------------------------
+/* This directory stream handler for the control tar handles extracting
+   it into the temporary meta directory. It only extracts files, it does
+   not create directories, links or anything else. */
+bool debDebFile::ControlExtract::DoItem(Item &Itm,int &Fd)
+{
+   if (Itm.Type != Item::File)
+      return true;
+   
+   /* Cleanse the file name, prevent people from trying to unpack into
+      absolute paths, .., etc */
+   for (char *I = Itm.Name; *I != 0; I++)
+      if (*I == '/')
+	 *I = '_';
+
+   /* Force the ownership to be root and ensure correct permissions, 
+      go-w, the rest are left untouched */
+   Itm.UID = 0;
+   Itm.GID = 0;
+   Itm.Mode &= ~(S_IWGRP | S_IWOTH);
+   
+   return pkgDirStream::DoItem(Itm,Fd);
+}
+									/*}}}*/
+
+// MemControlExtract::DoItem - Check if it is the control file		/*{{{*/
+// ---------------------------------------------------------------------
+/* This sets up to extract the control block member file into a memory 
+   block of just the right size. All other files go into the bit bucket. */
+bool debDebFile::MemControlExtract::DoItem(Item &Itm,int &Fd)
+{
+   // At the control file, allocate buffer memory.
+   if (Member == Itm.Name)
+   {
+      delete [] Control;
+      Control = new char[Itm.Size+2];
+      IsControl = true;
+      Fd = -2; // Signal to pass to Process
+      Length = Itm.Size;
+   }   
+   else
+      IsControl = false;
+   
+   return true;
+}
+									/*}}}*/
+// MemControlExtract::Process - Process extracting the control file	/*{{{*/
+// ---------------------------------------------------------------------
+/* Just memcopy the block from the tar extractor and put it in the right
+   place in the pre-allocated memory block. */
+bool debDebFile::MemControlExtract::Process(Item &/*Itm*/,const unsigned char *Data,
+			     unsigned long long Size,unsigned long long Pos)
+{
+   memcpy(Control + Pos, Data,Size);
+   return true;
+}
+									/*}}}*/
+// MemControlExtract::Read - Read the control information from the deb	/*{{{*/
+// ---------------------------------------------------------------------
+/* This uses the internal tar extractor to fetch the control file, and then
+   it parses it into a tag section parser. */
+bool debDebFile::MemControlExtract::Read(debDebFile &Deb)
+{
+   if (Deb.ExtractTarMember(*this, "control.tar") == false)
+      return false;
+
+   if (Control == 0)
+      return true;
+   
+   Control[Length] = '\n';
+   Control[Length+1] = '\n';
+   if (Section.Scan(Control,Length+2) == false)
+      return _error->Error(_("Unparsable control file"));
+   return true;
+}
+									/*}}}*/
+// MemControlExtract::TakeControl - Parse a memory block		/*{{{*/
+// ---------------------------------------------------------------------
+/* The given memory block is loaded into the parser and parsed as a control
+   record. */
+bool debDebFile::MemControlExtract::TakeControl(const void *Data,unsigned long long Size)
+{
+   delete [] Control;
+   Control = new char[Size+2];
+   Length = Size;
+   memcpy(Control,Data,Size);
+   
+   Control[Length] = '\n';
+   Control[Length+1] = '\n';
+   return Section.Scan(Control,Length+2);
+}
+									/*}}}*/
+
diff --git a/apt-pkg/deb/debfile.h b/apt-pkg/deb/debfile.h
new file mode 100644
index 000000000..21c59a567
--- /dev/null
+++ b/apt-pkg/deb/debfile.h
@@ -0,0 +1,95 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+
+   Debian Archive File (.deb)
+
+   This Class handles all the operations performed directly on .deb 
+   files. It makes use of the AR and TAR classes to give the necessary
+   external interface.
+   
+   There are only two things that can be done with a raw package, 
+   extract it's control information and extract the contents itself. 
+
+   This should probably subclass an as-yet unwritten super class to
+   produce a generic archive mechanism.
+  
+   The memory control file extractor is useful to extract a single file
+   into memory from the control.tar.gz
+   
+   ##################################################################### */
+									/*}}}*/
+#ifndef PKGLIB_DEBFILE_H
+#define PKGLIB_DEBFILE_H
+
+#include <apt-pkg/arfile.h>
+#include <apt-pkg/dirstream.h>
+#include <apt-pkg/macros.h>
+#include <apt-pkg/tagfile.h>
+
+#include <string>
+
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/md5.h>
+#endif
+#ifndef APT_10_CLEANER_HEADERS
+#include <apt-pkg/pkgcache.h>
+#endif
+
+class FileFd;
+
+class debDebFile
+{
+   protected:
+   
+   FileFd &File;
+   ARArchive AR;
+   
+   bool CheckMember(const char *Name);
+   
+   public:
+   class ControlExtract;
+   class MemControlExtract;
+
+   bool ExtractTarMember(pkgDirStream &Stream, const char *Name);
+   bool ExtractArchive(pkgDirStream &Stream);
+   const ARArchive::Member *GotoMember(const char *Name);
+   inline FileFd &GetFile() {return File;};
+   
+   explicit debDebFile(FileFd &File);
+};
+
+class debDebFile::ControlExtract : public pkgDirStream
+{
+   public:
+   
+   virtual bool DoItem(Item &Itm,int &Fd) APT_OVERRIDE;
+};
+
+class debDebFile::MemControlExtract : public pkgDirStream
+{
+   bool IsControl;
+   
+   public:
+   
+   char *Control;
+   pkgTagSection Section;
+   unsigned long Length;
+   std::string Member;
+   
+   // Members from DirStream
+   virtual bool DoItem(Item &Itm,int &Fd) APT_OVERRIDE;
+   virtual bool Process(Item &Itm,const unsigned char *Data,
+			unsigned long long Size,unsigned long long Pos) APT_OVERRIDE;
+
+   // Helpers
+   bool Read(debDebFile &Deb);
+   bool TakeControl(const void *Data,unsigned long long Size);
+
+   MemControlExtract() : IsControl(false), Control(0), Length(0), Member("control") {};
+   explicit MemControlExtract(std::string Member) : IsControl(false), Control(0), Length(0), Member(Member) {};
+   ~MemControlExtract() {delete [] Control;};   
+};
+									/*}}}*/
+
+#endif
diff --git a/apt-pkg/dirstream.cc b/apt-pkg/dirstream.cc
new file mode 100644
index 000000000..d6cf0ab3f
--- /dev/null
+++ b/apt-pkg/dirstream.cc
@@ -0,0 +1,118 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+
+   Directory Stream 
+   
+   This class provides a simple basic extractor that can be used for
+   a number of purposes.
+   
+   ##################################################################### */
+									/*}}}*/
+// Include Files							/*{{{*/
+#include <config.h>
+
+#include <apt-pkg/dirstream.h>
+#include <apt-pkg/error.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <apti18n.h>
+									/*}}}*/
+
+// DirStream::DoItem - Process an item					/*{{{*/
+// ---------------------------------------------------------------------
+/* This is a very simple extractor, it does not deal with things like
+   overwriting directories with files and so on. */
+bool pkgDirStream::DoItem(Item &Itm,int &Fd)
+{
+   switch (Itm.Type)
+   {
+      case Item::File:
+      {
+	 /* Open the output file, NDELAY is used to prevent this from 
+	    blowing up on device special files.. */
+	 int iFd = open(Itm.Name,O_NDELAY|O_WRONLY|O_CREAT|O_TRUNC|O_APPEND,
+		       Itm.Mode);
+	 if (iFd < 0)
+	    return _error->Errno("open",_("Failed to write file %s"),
+				 Itm.Name);
+	 
+	 // fchmod deals with umask and fchown sets the ownership
+	 if (fchmod(iFd,Itm.Mode) != 0)
+	 {
+	    close(iFd);
+	    return _error->Errno("fchmod",_("Failed to write file %s"), Itm.Name);
+	 }
+	 if (fchown(iFd,Itm.UID,Itm.GID) != 0 && errno != EPERM)
+	 {
+	    close(iFd);
+	    return _error->Errno("fchown",_("Failed to write file %s"), Itm.Name);
+	 }
+	 Fd = iFd;
+	 return true;
+      }
+      
+      case Item::HardLink:
+      case Item::SymbolicLink:
+      case Item::CharDevice:
+      case Item::BlockDevice:
+      case Item::Directory:
+      {
+	 struct stat Buf;
+	 // check if the dir is already there, if so return true
+	 if (stat(Itm.Name,&Buf) == 0)
+	 {
+	    if(S_ISDIR(Buf.st_mode))
+	       return true;
+	    // something else is there already, return false
+	    return false;
+	 }
+	 // nothing here, create the dir
+	 if(mkdir(Itm.Name,Itm.Mode) < 0)
+	    return false;
+	 return true;
+      }
+      case Item::FIFO:
+      break;
+   }
+   
+   return true;
+}
+									/*}}}*/
+// DirStream::FinishedFile - Finished processing a file			/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool pkgDirStream::FinishedFile(Item &Itm,int Fd)
+{
+   if (Fd < 0)
+      return true;
+
+   /* Set the modification times. The only way it can fail is if someone
+      has futzed with our file, which is intolerable :> */
+   struct timeval times[2];
+   times[0].tv_sec = times[1].tv_sec = Itm.MTime;
+   times[0].tv_usec = times[1].tv_usec = 0;
+   if (utimes(Itm.Name, times) != 0)
+      _error->Errno("utimes", "Failed to set modification time for %s",Itm.Name);
+
+   if (close(Fd) != 0)
+      return _error->Errno("close",_("Failed to close file %s"),Itm.Name);
+   return true;
+}
+									/*}}}*/
+// DirStream::Fail - Failed processing a file				/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool pkgDirStream::Fail(Item &/*Itm*/, int Fd)
+{
+   if (Fd < 0)
+      return true;
+   
+   close(Fd);
+   return false;
+}
+									/*}}}*/
diff --git a/apt-pkg/dirstream.h b/apt-pkg/dirstream.h
new file mode 100644
index 000000000..0f0e348d0
--- /dev/null
+++ b/apt-pkg/dirstream.h
@@ -0,0 +1,57 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+
+   Directory Stream 
+
+   When unpacking the contents of the archive are passed into a directory
+   stream class for analysis and processing. The class controls all aspects
+   of actually writing the directory stream from disk. The low level
+   archive handlers are only responsible for decoding the archive format
+   and sending events (via method calls) to the specified directory
+   stream.
+   
+   When unpacking a real file the archive handler is passed back a file 
+   handle to write the data to, this is to support strange 
+   archives+unpacking methods. If that fd is -1 then the file data is 
+   simply ignored.
+   
+   The provided defaults do the 'Right Thing' for a normal unpacking
+   process (ie 'tar')
+   
+   ##################################################################### */
+									/*}}}*/
+#ifndef PKGLIB_DIRSTREAM_H
+#define PKGLIB_DIRSTREAM_H
+
+#include <apt-pkg/macros.h>
+
+class pkgDirStream
+{ 
+   public:
+
+   // All possible information about a component
+   struct Item
+   {
+      enum Type_t {File, HardLink, SymbolicLink, CharDevice, BlockDevice,
+	           Directory, FIFO} Type;
+      char *Name;
+      char *LinkTarget;
+      unsigned long Mode;
+      unsigned long UID;
+      unsigned long GID;
+      unsigned long long Size;
+      unsigned long MTime;
+      unsigned long Major;
+      unsigned long Minor;
+   };
+   
+   virtual bool DoItem(Item &Itm,int &Fd);
+   virtual bool Fail(Item &Itm,int Fd);
+   virtual bool FinishedFile(Item &Itm,int Fd);
+   virtual bool Process(Item &/*Itm*/,const unsigned char * /*Data*/,
+			unsigned long long /*Size*/,unsigned long long /*Pos*/) {return true;};
+   virtual ~pkgDirStream() {};   
+};
+
+#endif
diff --git a/cmdline/CMakeLists.txt b/cmdline/CMakeLists.txt
index 8977b45d1..d82239bee 100644
--- a/cmdline/CMakeLists.txt
+++ b/cmdline/CMakeLists.txt
@@ -29,10 +29,10 @@ target_link_libraries(apt-cdrom apt-pkg apt-private)
 target_link_libraries(apt-helper apt-pkg apt-private)
 target_link_libraries(apt-mark apt-pkg apt-private)
 target_link_libraries(apt-sortpkgs apt-pkg apt-private)
-target_link_libraries(apt-extracttemplates apt-pkg apt-inst apt-private)
-target_link_libraries(apt-internal-solver apt-pkg apt-inst apt-private)
-target_link_libraries(apt-dump-solver apt-pkg apt-inst apt-private)
-target_link_libraries(apt-internal-planner apt-pkg apt-inst apt-private)
+target_link_libraries(apt-extracttemplates apt-pkg apt-private)
+target_link_libraries(apt-internal-solver apt-pkg apt-private)
+target_link_libraries(apt-dump-solver apt-pkg apt-private)
+target_link_libraries(apt-internal-planner apt-pkg apt-private)
 
 set_target_properties(apt-dump-solver
                       PROPERTIES RUNTIME_OUTPUT_DIRECTORY solvers
diff --git a/debian/control b/debian/control
index 4aca00b95..26ab624ef 100644
--- a/debian/control
+++ b/debian/control
@@ -94,19 +94,6 @@ Description: package management runtime library
     http(s), rsh as well as an interface to add more transports like
     tor+http(s) (apt-transport-tor).
 
-Package: libapt-inst3.0
-Architecture: any
-Multi-Arch: same
-Priority: optional
-Pre-Depends: ${misc:Pre-Depends}
-Depends: ${misc:Depends}, ${shlibs:Depends}
-Section: libs
-Provides: libapt-inst (= ${binary:Version})
-Description: deb package format runtime library
- This library provides methods to query and extract information
- from deb packages. This includes the control data and the package
- file content.
-
 Package: apt-doc
 Architecture: all
 Priority: optional
@@ -121,8 +108,7 @@ Architecture: any
 Multi-Arch: same
 Priority: optional
 Pre-Depends: ${misc:Pre-Depends}
-Depends: libapt-inst (= ${binary:Version}),
-         libapt-pkg (= ${binary:Version}),
+Depends: libapt-pkg (= ${binary:Version}),
          zlib1g-dev,
          ${misc:Depends}
 Section: libdevel
@@ -146,7 +132,6 @@ Description: documentation for APT development
 Package: apt-utils
 Architecture: any
 Depends: apt (= ${binary:Version}),
-         libapt-inst3.0 (>= ${binary:Version}),
          ${misc:Depends},
          ${shlibs:Depends}
 Description: package management related utility programs
diff --git a/debian/libapt-inst3.0.install b/debian/libapt-inst3.0.install
deleted file mode 100644
index a8ddd5e2d..000000000
--- a/debian/libapt-inst3.0.install
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/lib/*/libapt-inst*.so.*
-usr/share/locale/*/*/libapt-inst*.mo
diff --git a/debian/libapt-inst3.0.symbols b/debian/libapt-inst3.0.symbols
deleted file mode 100644
index 67f095116..000000000
--- a/debian/libapt-inst3.0.symbols
+++ /dev/null
@@ -1,68 +0,0 @@
-libapt-inst.so.3.0 libapt-inst3.0 #MINVER#
-* Build-Depends-Package: libapt-pkg-dev
- (c++)"ExtractTar::Done()@APTINST_3.0" 1.1~exp12
- (c++)"ExtractTar::Go(pkgDirStream&)@APTINST_3.0" 0.8.0
- (c++)"ExtractTar::StartGzip()@APTINST_3.0" 0.8.0
- (c++)"ExtractTar::ExtractTar(FileFd&, unsigned long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)@APTINST_3.0" 1.0.5
- (c++)"ExtractTar::~ExtractTar()@APTINST_3.0" 0.8.0
- (c++)"debDebFile::GotoMember(char const*)@APTINST_3.0" 0.8.0
- (c++)"debDebFile::CheckMember(char const*)@APTINST_3.0" 0.8.0
- (c++)"debDebFile::ControlExtract::DoItem(pkgDirStream::Item&, int&)@APTINST_3.0" 0.8.0
- (c++)"debDebFile::ExtractTarMember(pkgDirStream&, char const*)@APTINST_3.0" 0.9.15.4
- (c++)"debDebFile::ExtractArchive(pkgDirStream&)@APTINST_3.0" 0.8.0
- (c++)"debDebFile::MemControlExtract::TakeControl(void const*, unsigned long long)@APTINST_3.0" 1.0.5
- (c++)"debDebFile::MemControlExtract::Read(debDebFile&)@APTINST_3.0" 0.8.0
- (c++)"debDebFile::MemControlExtract::DoItem(pkgDirStream::Item&, int&)@APTINST_3.0" 0.8.0
- (c++)"debDebFile::MemControlExtract::Process(pkgDirStream::Item&, unsigned char const*, unsigned long long, unsigned long long)@APTINST_3.0" 1.0.5
- (c++)"debDebFile::debDebFile(FileFd&)@APTINST_3.0" 0.8.0
- (c++)"pkgExtract::FinishedFile(pkgDirStream::Item&, int)@APTINST_3.0" 0.8.0
- (c++)"pkgExtract::CheckDirReplace(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int)@APTINST_3.0" 0.8.0
- (c++)"pkgExtract::HandleOverwrites(pkgFLCache::NodeIterator, bool)@APTINST_3.0" 0.8.0
- (c++)"pkgExtract::Fail(pkgDirStream::Item&, int)@APTINST_3.0" 0.8.0
- (c++)"pkgExtract::DoItem(pkgDirStream::Item&, int&)@APTINST_3.0" 0.8.0
- (c++)"pkgExtract::Aborted()@APTINST_3.0" 0.8.0
- (c++)"pkgExtract::Finished()@APTINST_3.0" 0.8.0
- (c++)"pkgExtract::pkgExtract(pkgFLCache&, pkgCache::VerIterator)@APTINST_3.0" 0.8.0
- (c++)"pkgFLCache::TreeLookup(unsigned int*, char const*, char const*, unsigned long, unsigned int*, bool)@APTINST_3.0" 0.8.0
- (c++)"pkgFLCache::AddConfFile(char const*, char const*, pkgFLCache::PkgIterator const&, unsigned char const*)@APTINST_3.0" 0.8.0
- (c++)"pkgFLCache::AddDiversion(pkgFLCache::PkgIterator const&, char const*, char const*)@APTINST_3.0" 0.8.0
- (c++)"pkgFLCache::BeginDiverLoad()@APTINST_3.0" 0.8.0
- (c++)"pkgFLCache::FinishDiverLoad()@APTINST_3.0" 0.8.0
- (c++)"pkgFLCache::GetPkg(char const*, char const*, bool)@APTINST_3.0" 0.8.0
- (c++)"pkgFLCache::Header::Header()@APTINST_3.0" 0.8.0
- (c++)"pkgFLCache::GetNode(char const*, char const*, unsigned int, bool, bool)@APTINST_3.0" 0.8.0
- (c++)"pkgFLCache::DropNode(unsigned int)@APTINST_3.0" 0.8.0
- (c++)"pkgFLCache::HashNode(pkgFLCache::NodeIterator const&)@APTINST_3.0" 0.8.0
- (c++)"pkgFLCache::PrintTree(unsigned int, unsigned long)@APTINST_3.0" 0.8.0
- (c++)"pkgFLCache::pkgFLCache(DynamicMMap&)@APTINST_3.0" 0.8.0
- (c++)"pkgDirStream::FinishedFile(pkgDirStream::Item&, int)@APTINST_3.0" 0.8.0
- (c++)"pkgDirStream::Fail(pkgDirStream::Item&, int)@APTINST_3.0" 0.8.0
- (c++)"pkgDirStream::DoItem(pkgDirStream::Item&, int&)@APTINST_3.0" 0.8.0
- (c++)"ARArchive::LoadHeaders()@APTINST_3.0" 0.8.0
- (c++)"ARArchive::ARArchive(FileFd&)@APTINST_3.0" 0.8.0
- (c++)"ARArchive::~ARArchive()@APTINST_3.0" 0.8.0
- (c++)"pkgFLCache::NodeIterator::RealPackage() const@APTINST_3.0" 0.8.0
- (c++)"pkgFLCache::Header::CheckSizes(pkgFLCache::Header&) const@APTINST_3.0" 0.8.0
- (c++)"ARArchive::FindMember(char const*) const@APTINST_3.0" 0.8.0
- (c++)"typeinfo for ExtractTar@APTINST_3.0" 0.8.0
- (c++)"typeinfo for pkgExtract@APTINST_3.0" 0.8.0
- (c++)"typeinfo for pkgDirStream@APTINST_3.0" 0.8.0
- (c++)"typeinfo for debDebFile::ControlExtract@APTINST_3.0" 0.8.0
- (c++)"typeinfo for debDebFile::MemControlExtract@APTINST_3.0" 0.8.0
- (c++)"typeinfo name for ExtractTar@APTINST_3.0" 0.8.0
- (c++)"typeinfo name for pkgExtract@APTINST_3.0" 0.8.0
- (c++)"typeinfo name for pkgDirStream@APTINST_3.0" 0.8.0
- (c++)"typeinfo name for debDebFile::ControlExtract@APTINST_3.0" 0.8.0
- (c++)"typeinfo name for debDebFile::MemControlExtract@APTINST_3.0" 0.8.0
- (c++)"vtable for ExtractTar@APTINST_3.0" 0.8.0
- (c++)"vtable for pkgExtract@APTINST_3.0" 0.8.0
- (c++)"vtable for pkgDirStream@APTINST_3.0" 0.8.0
- (c++)"vtable for debDebFile::ControlExtract@APTINST_3.0" 0.8.0
- (c++)"vtable for debDebFile::MemControlExtract@APTINST_3.0" 0.8.0
-### gcc artifacts
- (c++|optional=std)"std::vector<APT::Configuration::Compressor, std::allocator<APT::Configuration::Compressor> >::~vector()@APTINST_3.0" 0.8.12
- (c++|optional=std)"void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag)@APTINST_3.0" 1.7.0~alpha3~
- (c++|optional=std)"void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag)@APTINST_3.0" 1.7.0~alpha3~
-### symbol versioning
- APTINST_3.0@APTINST_3.0 1.1~exp9
-### try to ignore std:: template instances
diff --git a/debian/libapt-pkg-dev.install b/debian/libapt-pkg-dev.install
index 563e99909..eea242896 100644
--- a/debian/libapt-pkg-dev.install
+++ b/debian/libapt-pkg-dev.install
@@ -1,4 +1,3 @@
 usr/include/apt-pkg/
-usr/lib/*/libapt-inst*.so
 usr/lib/*/libapt-pkg*.so
 usr/lib/*/pkgconfig/apt-*.pc
diff --git a/debian/libapt-pkg6.0.symbols b/debian/libapt-pkg6.0.symbols
index 5be6fa880..a850daa09 100644
--- a/debian/libapt-pkg6.0.symbols
+++ b/debian/libapt-pkg6.0.symbols
@@ -1471,3 +1471,45 @@ libapt-pkg.so.6.0 libapt-pkg6.0 #MINVER#
  (c++|optional=std)"void std::vector<APT::Configuration::Compressor, std::allocator<APT::Configuration::Compressor> >::emplace_back<char const (&) [6], char const (&) [5], char const (&) [6], char const (&) [3], char const (&) [3], int>(char const (&) [6], char const (&) [5], char const (&) [6], char const (&) [3], char const (&) [3], int&&)@APTPKG_6.0" 1.7.0~alpha3~
  (c++|optional=std)"void std::vector<APT::Configuration::Compressor, std::allocator<APT::Configuration::Compressor> >::emplace_back<char const (&) [6], char const (&) [5], char const (&) [6], decltype(nullptr), decltype(nullptr), int>(char const (&) [6], char const (&) [5], char const (&) [6], decltype(nullptr)&&, decltype(nullptr)&&, int&&)@APTPKG_6.0" 1.7.0~alpha3~
  (c++|optional=std)"void std::vector<re_pattern_buffer*, std::allocator<re_pattern_buffer*> >::emplace_back<re_pattern_buffer*>(re_pattern_buffer*&&)@APTPKG_6.0" 1.7.0~alpha3~
+* Build-Depends-Package: libapt-pkg-dev
+ (c++)"ExtractTar::Done()@APTPKG_6.0" 1.1~exp12
+ (c++)"ExtractTar::Go(pkgDirStream&)@APTPKG_6.0" 0.8.0
+ (c++)"ExtractTar::StartGzip()@APTPKG_6.0" 0.8.0
+ (c++)"ExtractTar::ExtractTar(FileFd&, unsigned long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)@APTPKG_6.0" 1.0.5
+ (c++)"ExtractTar::~ExtractTar()@APTPKG_6.0" 0.8.0
+ (c++)"debDebFile::GotoMember(char const*)@APTPKG_6.0" 0.8.0
+ (c++)"debDebFile::CheckMember(char const*)@APTPKG_6.0" 0.8.0
+ (c++)"debDebFile::ControlExtract::DoItem(pkgDirStream::Item&, int&)@APTPKG_6.0" 0.8.0
+ (c++)"debDebFile::ExtractTarMember(pkgDirStream&, char const*)@APTPKG_6.0" 0.9.15.4
+ (c++)"debDebFile::ExtractArchive(pkgDirStream&)@APTPKG_6.0" 0.8.0
+ (c++)"debDebFile::MemControlExtract::TakeControl(void const*, unsigned long long)@APTPKG_6.0" 1.0.5
+ (c++)"debDebFile::MemControlExtract::Read(debDebFile&)@APTPKG_6.0" 0.8.0
+ (c++)"debDebFile::MemControlExtract::DoItem(pkgDirStream::Item&, int&)@APTPKG_6.0" 0.8.0
+ (c++)"debDebFile::MemControlExtract::Process(pkgDirStream::Item&, unsigned char const*, unsigned long long, unsigned long long)@APTPKG_6.0" 1.0.5
+ (c++)"debDebFile::debDebFile(FileFd&)@APTPKG_6.0" 0.8.0
+ (c++)"pkgDirStream::FinishedFile(pkgDirStream::Item&, int)@APTPKG_6.0" 0.8.0
+ (c++)"pkgDirStream::Fail(pkgDirStream::Item&, int)@APTPKG_6.0" 0.8.0
+ (c++)"pkgDirStream::DoItem(pkgDirStream::Item&, int&)@APTPKG_6.0" 0.8.0
+ (c++)"ARArchive::LoadHeaders()@APTPKG_6.0" 0.8.0
+ (c++)"ARArchive::ARArchive(FileFd&)@APTPKG_6.0" 0.8.0
+ (c++)"ARArchive::~ARArchive()@APTPKG_6.0" 0.8.0
+ (c++)"ARArchive::FindMember(char const*) const@APTPKG_6.0" 0.8.0
+ (c++)"typeinfo for ExtractTar@APTPKG_6.0" 0.8.0
+ (c++)"typeinfo for pkgDirStream@APTPKG_6.0" 0.8.0
+ (c++)"typeinfo for debDebFile::ControlExtract@APTPKG_6.0" 0.8.0
+ (c++)"typeinfo for debDebFile::MemControlExtract@APTPKG_6.0" 0.8.0
+ (c++)"typeinfo name for ExtractTar@APTPKG_6.0" 0.8.0
+ (c++)"typeinfo name for pkgDirStream@APTPKG_6.0" 0.8.0
+ (c++)"typeinfo name for debDebFile::ControlExtract@APTPKG_6.0" 0.8.0
+ (c++)"typeinfo name for debDebFile::MemControlExtract@APTPKG_6.0" 0.8.0
+ (c++)"vtable for ExtractTar@APTPKG_6.0" 0.8.0
+ (c++)"vtable for pkgDirStream@APTPKG_6.0" 0.8.0
+ (c++)"vtable for debDebFile::ControlExtract@APTPKG_6.0" 0.8.0
+ (c++)"vtable for debDebFile::MemControlExtract@APTPKG_6.0" 0.8.0
+### gcc artifacts
+ (c++|optional=std)"std::vector<APT::Configuration::Compressor, std::allocator<APT::Configuration::Compressor> >::~vector()@APTPKG_6.0" 0.8.12
+ (c++|optional=std)"void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag)@APTPKG_6.0" 1.7.0~alpha3~
+ (c++|optional=std)"void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag)@APTPKG_6.0" 1.7.0~alpha3~
+### symbol versioning
+ APTPKG_6.0@APTINST_3.0 1.1~exp9
+### try to ignore std:: template instances
diff --git a/ftparchive/CMakeLists.txt b/ftparchive/CMakeLists.txt
index bbd2848c1..9aa6606f1 100644
--- a/ftparchive/CMakeLists.txt
+++ b/ftparchive/CMakeLists.txt
@@ -7,7 +7,7 @@ add_executable(apt-ftparchive ${source})
 
 # Link the executables against the libraries
 target_include_directories(apt-ftparchive PRIVATE ${BERKELEY_DB_INCLUDE_DIRS})
-target_link_libraries(apt-ftparchive apt-inst apt-pkg apt-private ${BERKELEY_DB_LIBRARIES})
+target_link_libraries(apt-ftparchive apt-pkg apt-private ${BERKELEY_DB_LIBRARIES})
 
 # Install the executables
 install(TARGETS apt-ftparchive RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt
index a8893e8ba..c03d6d03e 100644
--- a/po/CMakeLists.txt
+++ b/po/CMakeLists.txt
@@ -31,18 +31,11 @@ apt_add_translation_domain(
     EXCLUDE_LANGUAGES ${languages_excluded}
 )
 
-apt_add_translation_domain(
-    DOMAIN libapt-inst${APT_INST_MAJOR}
-    TARGETS apt-inst
-    EXCLUDE_LANGUAGES ${languages_excluded}
-)
-
 apt_add_update_po(
     TEMPLATE
         apt-all
     DOMAINS
         libapt-pkg${APT_PKG_MAJOR}
-        libapt-inst${APT_INST_MAJOR}
         apt
         apt-utils
     EXCLUDE_LANGUAGES
diff --git a/prepare-release b/prepare-release
index ea749f85d..919450b33 100755
--- a/prepare-release
+++ b/prepare-release
@@ -11,7 +11,6 @@ VERSION=$(dpkg-parsechangelog | sed -n -e '/^Version:/s/^Version: //p')
 DISTRIBUTION=$(dpkg-parsechangelog | sed -n -e '/^Distribution:/s/^Distribution: //p')
 
 LIBAPTPKGVERSION="$(awk -v ORS='.' '/^\#define APT_PKG_M/ {print $3}' apt-pkg/contrib/macros.h | sed 's/\.$//')"
-LIBAPTINSTVERSION="$(sed -nr 's/set\(MAJOR ([^)]*)\)/\1/p' apt-inst/CMakeLists.txt)"
 
 librarysymbolsfromfile() {
 	local MISSING="$(grep '^+#MISSING' "$1")"
@@ -64,7 +63,6 @@ if [ "$1" = 'pre-export' ]; then
 	}
 
 	libraryversioncheck 'libapt-pkg' "$LIBAPTPKGVERSION"
-	libraryversioncheck 'libapt-inst' "$LIBAPTINSTVERSION"
 
 
 	if [ "$DISTRIBUTION" = 'sid' ]; then
@@ -181,7 +179,6 @@ elif [ "$1" = 'library' ]; then
 	}
 	librarysymbols 'libapt-pkg' "${LIBAPTPKGVERSION}"
 	echo
-	librarysymbols 'libapt-inst' "${LIBAPTINSTVERSION}"
 elif [ "$1" = 'buildlog' ]; then
 	while [ -n "$2" ]; do
 		librarysymbolsfromfile "$2" 'UNKNOWN'
@@ -222,7 +219,7 @@ elif [ "$1" = 'coverage' ]; then
 	}
 	grep 'build/include/' "${DIR}/apt.coverage.fixed" | sed "s#^SF:$(pwd)/##" | while read file; do
 		rewritefile "$file" 'apt-pkg' 'apt-pkg/deb' 'apt-pkg/edsp' 'apt-pkg/contrib' \
-		   'apt-inst' 'apt-inst/deb' 'apt-inst/contrib' 'apt-private'
+		  'apt-private'
 	done
 	genhtml --output-directory "${DIR}" "${DIR}/apt.coverage.fixed" ${LCOVRC}
 elif [ "$1" = 'spellcheckers' -o "$1" = 'lint' ]; then
diff --git a/test/interactive-helper/CMakeLists.txt b/test/interactive-helper/CMakeLists.txt
index 5a32ca17e..f4238665d 100644
--- a/test/interactive-helper/CMakeLists.txt
+++ b/test/interactive-helper/CMakeLists.txt
@@ -1,9 +1,9 @@
 add_executable(mthdcat mthdcat.cc)
 target_link_libraries(mthdcat apt-pkg)
 add_executable(testdeb testdeb.cc)
-target_link_libraries(testdeb apt-pkg apt-inst)
+target_link_libraries(testdeb apt-pkg)
 add_executable(extract-control extract-control.cc)
-target_link_libraries(extract-control apt-pkg apt-inst)
+target_link_libraries(extract-control apt-pkg)
 add_executable(aptwebserver aptwebserver.cc)
 target_link_libraries(aptwebserver apt-pkg  ${CMAKE_THREAD_LIBS_INIT})
 add_executable(aptdropprivs aptdropprivs.cc)
diff --git a/test/libapt/CMakeLists.txt b/test/libapt/CMakeLists.txt
index 035ff07b1..57ef5ac3f 100644
--- a/test/libapt/CMakeLists.txt
+++ b/test/libapt/CMakeLists.txt
@@ -1,4 +1,4 @@
-set(PROJECT_TEST_LIBRARIES apt-private apt-inst)
+set(PROJECT_TEST_LIBRARIES apt-private)
 find_path(GTEST_ROOT src/gtest.cc
    /usr/src/googletest/googletest
    /usr/src/gtest
-- 
cgit v1.2.3