]> git.saurik.com Git - apt.git/blobdiff - apt-inst/deb/debfile.cc
Fix ar and tar code to be LFS-safe
[apt.git] / apt-inst / deb / debfile.cc
index d3a39911d6ae27832d67a752f21488001523c9a5..4853a13c7ebd3c404a467da40b75ba8c0a11757f 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: debfile.cc,v 1.4 2004/01/07 20:39:37 mdz Exp $
+// $Id: debfile.cc,v 1.3.2.1 2004/01/16 18:58:50 mdz Exp $
 /* ######################################################################
 
    Debian Archive File (.deb)
    ##################################################################### */
                                                                        /*}}}*/
 // Include Files                                                       /*{{{*/
-#ifdef __GNUG__
-#pragma implementation "apt-pkg/debfile.h"
-#endif
+#include<config.h>
 
 #include <apt-pkg/debfile.h>
 #include <apt-pkg/extracttar.h>
 #include <apt-pkg/error.h>
-#include <apt-pkg/deblistparser.h>
+#include <apt-pkg/aptconfiguration.h>
+#include <apt-pkg/arfile.h>
+#include <apt-pkg/dirstream.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/tagfile.h>
 
+#include <string.h>
+#include <string>
+#include <vector>
 #include <sys/stat.h>
-#include <unistd.h>
+
 #include <apti18n.h>
                                                                        /*}}}*/
 
@@ -37,12 +42,27 @@ debDebFile::debDebFile(FileFd &File) : File(File), AR(File)
 {
    if (_error->PendingError() == true)
       return;
-   
-   // Check the members for validity
-   if (CheckMember("debian-binary") == false ||
-       CheckMember("control.tar.gz") == false ||
-       CheckMember("data.tar.gz") == false)
+
+   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")) {
+      _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")) {
+      _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    /*{{{*/
@@ -52,7 +72,7 @@ debDebFile::debDebFile(FileFd &File) : File(File), AR(File)
 bool debDebFile::CheckMember(const char *Name)
 {
    if (AR.FindMember(Name) == 0)
-      return _error->Error(_("This is not a valid DEB archive, missing '%s' member"),Name);
+      return false;
    return true;
 }
                                                                        /*}}}*/
@@ -69,7 +89,6 @@ const ARArchive::Member *debDebFile::GotoMember(const char *Name)
    const ARArchive::Member *Member = AR.FindMember(Name);
    if (Member == 0)
    {
-      _error->Error(_("Internal Error, could not locate member %s"),Name);
       return 0;
    }
    if (File.Seek(Member->Start) == false)
@@ -78,85 +97,57 @@ const ARArchive::Member *debDebFile::GotoMember(const char *Name)
    return Member;
 }
                                                                        /*}}}*/
-// DebFile::ExtractControl - Extract Control information               /*{{{*/
-// ---------------------------------------------------------------------
-/* Extract the control information into the Database's temporary 
-   directory. */
-bool debDebFile::ExtractControl(pkgDataBase &DB)
-{
-   // Get the archive member and positition the file
-   const ARArchive::Member *Member = GotoMember("control.tar.gz");
-   if (Member == 0)
-      return false;
-      
-   // Prepare Tar
-   ControlExtract Extract;
-   ExtractTar Tar(File,Member->Size);
-   if (_error->PendingError() == true)
-      return false;
-   
-   // Get into the temporary directory
-   string Cwd = SafeGetCWD();
-   string Tmp;
-   if (DB.GetMetaTmp(Tmp) == false)
-      return false;
-   if (chdir(Tmp.c_str()) != 0)
-      return _error->Errno("chdir",_("Couldn't change to %s"),Tmp.c_str());
-   
-   // Do extraction
-   if (Tar.Go(Extract) == false)
-      return false;
-   
-   // Switch out of the tmp directory.
-   if (chdir(Cwd.c_str()) != 0)
-      chdir("/");
-   
-   return true;
-}
-                                                                       /*}}}*/
-// DebFile::ExtractArchive - Extract the archive data itself           /*{{{*/
+// DebFile::ExtractTarMember - Extract the contents of a tar member    /*{{{*/
 // ---------------------------------------------------------------------
 /* Simple wrapper around tar.. */
-bool debDebFile::ExtractArchive(pkgDirStream &Stream)
+bool debDebFile::ExtractTarMember(pkgDirStream &Stream,const char *Name)
 {
-   // Get the archive member and positition the file 
-   const ARArchive::Member *Member = AR.FindMember("data.tar.gz");
-   if (Member == 0)
-      return _error->Error(_("Internal Error, could not locate member"));   
+   // 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->Binary;
+      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);
+   ExtractTar Tar(File,Member->Size,Compressor);
    if (_error->PendingError() == true)
       return false;
    return Tar.Go(Stream);
 }
                                                                        /*}}}*/
-// DebFile::MergeControl - Merge the control information               /*{{{*/
+// DebFile::ExtractArchive - Extract the archive data itself           /*{{{*/
 // ---------------------------------------------------------------------
-/* This reads the extracted control file into the cache and returns the
-   version that was parsed. All this really does is select the correct
-   parser and correct file to parse. */
-pkgCache::VerIterator debDebFile::MergeControl(pkgDataBase &DB)
+/* Simple wrapper around DebFile::ExtractTarMember. */
+bool debDebFile::ExtractArchive(pkgDirStream &Stream)
 {
-   // Open the control file
-   string Tmp;
-   if (DB.GetMetaTmp(Tmp) == false)
-      return pkgCache::VerIterator(DB.GetCache());
-   FileFd Fd(Tmp + "control",FileFd::ReadOnly);
-   if (_error->PendingError() == true)
-      return pkgCache::VerIterator(DB.GetCache());
-   
-   // Parse it
-   debListParser Parse(&Fd);
-   pkgCache::VerIterator Ver(DB.GetCache());
-   if (DB.GetGenerator().MergeList(Parse,&Ver) == false)
-      return pkgCache::VerIterator(DB.GetCache());
-   
-   if (Ver.end() == true)
-      _error->Error(_("Failed to locate a valid control file"));
-   return Ver;
+   return ExtractTarMember(Stream, "data.tar");
 }
                                                                        /*}}}*/
 
@@ -211,8 +202,8 @@ bool debDebFile::MemControlExtract::DoItem(Item &Itm,int &Fd)
 // ---------------------------------------------------------------------
 /* 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 Size,unsigned long Pos)
+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;
@@ -224,14 +215,7 @@ bool debDebFile::MemControlExtract::Process(Item &Itm,const unsigned char *Data,
    it parses it into a tag section parser. */
 bool debDebFile::MemControlExtract::Read(debDebFile &Deb)
 {
-   // Get the archive member and positition the file 
-   const ARArchive::Member *Member = Deb.GotoMember("control.tar.gz");
-   if (Member == 0)
-      return false;
-
-   // Extract it.
-   ExtractTar Tar(Deb.GetFile(),Member->Size);
-   if (Tar.Go(*this) == false)
+   if (Deb.ExtractTarMember(*this, "control.tar") == false)
       return false;
 
    if (Control == 0)
@@ -240,7 +224,7 @@ bool debDebFile::MemControlExtract::Read(debDebFile &Deb)
    Control[Length] = '\n';
    Control[Length+1] = '\n';
    if (Section.Scan(Control,Length+2) == false)
-      return _error->Error(_("Unparsible control file"));
+      return _error->Error(_("Unparsable control file"));
    return true;
 }
                                                                        /*}}}*/
@@ -248,7 +232,7 @@ bool debDebFile::MemControlExtract::Read(debDebFile &Deb)
 // ---------------------------------------------------------------------
 /* The given memory block is loaded into the parser and parsed as a control
    record. */
-bool debDebFile::MemControlExtract::TakeControl(const void *Data,unsigned long Size)
+bool debDebFile::MemControlExtract::TakeControl(const void *Data,unsigned long long Size)
 {
    delete [] Control;
    Control = new char[Size+2];