]> git.saurik.com Git - apt.git/commitdiff
enable FileFd to guess the compressor based on the filename if requested or
authorDavid Kalnischkies <kalnischkies@gmail.com>
Sat, 10 Dec 2011 18:31:36 +0000 (19:31 +0100)
committerDavid Kalnischkies <kalnischkies@gmail.com>
Sat, 10 Dec 2011 18:31:36 +0000 (19:31 +0100)
to search for compressed silbings of the given filename and use this guessing
instead of hardcoding Gzip compression

apt-pkg/contrib/fileutl.cc
apt-pkg/contrib/fileutl.h
apt-pkg/deb/debindexfile.cc
apt-pkg/deb/debrecords.cc
apt-pkg/deb/debsrcrecords.h
cmdline/apt-cache.cc
methods/gzip.cc
methods/rred.cc

index d5e7192e3d4a854ed3319848602d5218736434ad..1cb3fab1e5a55f292f0d954f09eddfad1118025a 100644 (file)
@@ -24,6 +24,7 @@
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/sptr.h>
+#include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/configuration.h>
 
 #include <cstdlib>
@@ -725,6 +726,11 @@ bool FileFd::Open(string FileName,OpenMode Mode,CompressMode Compress, unsigned
    Close();
    Flags = AutoClose;
 
+   if (Compress == Auto && (Mode & WriteOnly) == WriteOnly)
+      return _error->Error("Autodetection on %s only works in ReadOnly openmode!", FileName.c_str());
+   if ((Mode & WriteOnly) != WriteOnly && (Mode & (Atomic | Create | Empty | Exclusive)) != 0)
+      return _error->Error("ReadOnly mode for %s doesn't accept additional flags!", FileName.c_str());
+
    int fileflags = 0;
 #define if_FLAGGED_SET(FLAG, MODE) if ((Mode & FLAG) == FLAG) fileflags |= MODE
    if_FLAGGED_SET(ReadWrite, O_RDWR);
@@ -738,6 +744,70 @@ bool FileFd::Open(string FileName,OpenMode Mode,CompressMode Compress, unsigned
    if_FLAGGED_SET(Empty, O_TRUNC);
 #undef if_FLAGGED_SET
 
+   // FIXME: Denote inbuilt compressors somehow - as we don't need to have the binaries for them
+   std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors();
+   std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin();
+   if (Compress == Auto)
+   {
+      Compress = None;
+      for (; compressor != compressors.end(); ++compressor)
+      {
+        std::string file = std::string(FileName).append(compressor->Extension);
+        if (FileExists(file) == false)
+           continue;
+        FileName = file;
+        if (compressor->Binary == ".")
+           Compress = None;
+        else
+           Compress = Extension;
+        break;
+      }
+   }
+   else if (Compress == Extension)
+   {
+      Compress = None;
+      std::string ext = flExtension(FileName);
+      if (ext != FileName)
+      {
+        ext = "." + ext;
+        for (; compressor != compressors.end(); ++compressor)
+           if (ext == compressor->Extension)
+              break;
+      }
+   }
+   else if (Compress != None)
+   {
+      std::string name;
+      switch (Compress)
+      {
+      case Gzip: name = "gzip"; break;
+      case Bzip2: name = "bzip2"; break;
+      case Lzma: name = "lzma"; break;
+      case Xz: name = "xz"; break;
+      default: return _error->Error("Can't find a match for specified compressor mode for file %s", FileName.c_str());
+      }
+      for (; compressor != compressors.end(); ++compressor)
+        if (compressor->Name == name)
+           break;
+      if (compressor == compressors.end() && name != "gzip")
+        return _error->Error("Can't find a configured compressor %s for file %s", name.c_str(), FileName.c_str());
+   }
+
+   // if we have them, use inbuilt compressors instead of forking
+   if (compressor != compressors.end())
+   {
+      if (compressor->Name == "gzip")
+      {
+        Compress = Gzip;
+        compressor = compressors.end();
+      }
+      else if (compressor->Name == "." || Compress == None)
+      {
+        Compress = None;
+        compressor = compressors.end();
+      }
+   }
+
    if ((Mode & Atomic) == Atomic)
    {
       Flags |= Replace;
@@ -757,18 +827,27 @@ bool FileFd::Open(string FileName,OpenMode Mode,CompressMode Compress, unsigned
         unlink(FileName.c_str());
    }
 
-   if (TemporaryFileName.empty() == false)
-      iFd = open(TemporaryFileName.c_str(), fileflags, Perms);
-   else
-      iFd = open(FileName.c_str(), fileflags, Perms);
+   if (compressor != compressors.end())
+   {
+      if ((Mode & ReadWrite) == ReadWrite)
+        _error->Error("External compressors like %s do not support readwrite mode for file %s", compressor->Name.c_str(), FileName.c_str());
 
-   if (iFd != -1 && Compress == Gzip)
+      _error->Error("Forking external compressor %s is not implemented for %s", compressor->Name.c_str(), FileName.c_str());
+   }
+   else
    {
-      gz = gzdopen (iFd, "r");
-      if (gz == NULL)
+      if (TemporaryFileName.empty() == false)
+        iFd = open(TemporaryFileName.c_str(), fileflags, Perms);
+      else
+        iFd = open(FileName.c_str(), fileflags, Perms);
+
+      if (iFd != -1)
       {
-        close (iFd);
-        iFd = -1;
+        if (OpenInternDescriptor(Mode, Compress) == false)
+        {
+           close (iFd);
+           iFd = -1;
+        }
       }
    }
 
@@ -788,17 +867,33 @@ bool FileFd::OpenDescriptor(int Fd, OpenMode Mode, CompressMode Compress, bool A
    Close();
    Flags = (AutoClose) ? FileFd::AutoClose : 0;
    iFd = Fd;
-   if (Mode == ReadOnlyGzip) {
-      gz = gzdopen (iFd, "r");
-      if (gz == NULL) {
-        if (AutoClose)
-           close (iFd);
-        return _error->Errno("gzdopen",_("Could not open file descriptor %d"),
-                             Fd);
-      }
+   if (OpenInternDescriptor(Mode, Compress) == false)
+   {
+      if (AutoClose)
+        close (iFd);
+      return _error->Errno("gzdopen",_("Could not open file descriptor %d"), Fd);
    }
    this->FileName = "";
    return true;
+}
+bool FileFd::OpenInternDescriptor(OpenMode Mode, CompressMode Compress)
+{
+   if (Compress == None)
+      return true;
+   else if (Compress == Gzip)
+   {
+      if ((Mode & ReadWrite) == ReadWrite)
+        gz = gzdopen(iFd, "r+");
+      else if ((Mode & WriteOnly) == WriteOnly)
+        gz = gzdopen(iFd, "w");
+      else
+        gz = gzdopen (iFd, "r");
+      if (gz == NULL)
+        return false;
+   }
+   else
+      return false;
+   return true;
 }
                                                                        /*}}}*/
 // FileFd::~File - Closes the file                                     /*{{{*/
index fa8f92272d21cbb4161cc97e094bb29f329bc9f6..59a9d97e3995367213a6ed29c4cd0ede4fccc6ad 100644 (file)
@@ -61,7 +61,7 @@ class FileFd
        ReadOnlyGzip,
        WriteAtomic = ReadWrite | Create | Atomic
    };
-   enum CompressMode { Auto, None, Gzip, Bzip2, Lzma, Xz };
+   enum CompressMode { Auto = 'A', None = 'N', Extension = 'E', Gzip = 'G', Bzip2 = 'B', Lzma = 'L', Xz = 'X' };
    
    inline bool Read(void *To,unsigned long long Size,bool AllowEof)
    {
@@ -94,7 +94,7 @@ class FileFd
    }
 
    bool Open(std::string FileName,OpenMode Mode,CompressMode Compress,unsigned long Perms = 0666);
-   inline bool Open(std::string const &FileName,OpenMode Mode,unsigned long Perms = 0666) {
+   inline bool Open(std::string const &FileName,OpenMode Mode, unsigned long Perms = 0666) {
       return Open(FileName, Mode, None, Perms);
    };
    bool OpenDescriptor(int Fd, OpenMode Mode, CompressMode Compress, bool AutoClose=false);
@@ -118,11 +118,19 @@ class FileFd
    FileFd(std::string FileName,OpenMode Mode,unsigned long Perms = 0666) : iFd(-1), 
             Flags(0), gz(NULL)
    {
-      Open(FileName,Mode,Perms);
+      Open(FileName,Mode, None, Perms);
+   };
+   FileFd(std::string FileName,OpenMode Mode, CompressMode Compress, unsigned long Perms = 0666) :
+           iFd(-1), Flags(0), gz(NULL)
+   {
+      Open(FileName,Mode, Compress, Perms);
    };
    FileFd(int Fd = -1) : iFd(Fd), Flags(AutoClose), gz(NULL) {};
    FileFd(int Fd,bool) : iFd(Fd), Flags(0), gz(NULL) {};
    virtual ~FileFd();
+
+   private:
+   bool OpenInternDescriptor(OpenMode Mode, CompressMode Compress);
 };
 
 bool RunScripts(const char *Cnf);
index 27c1f7f3222b9b3b255841e7ba2d7b925b3ac4a7..d9c448598ab879f3dd25605dc42dd310f6b77d92 100644 (file)
@@ -159,7 +159,7 @@ unsigned long debSourcesIndex::Size() const
    /* we need to ignore errors here; if the lists are absent, just return 0 */
    _error->PushToStack();
 
-   FileFd f = FileFd (IndexFile("Sources"), FileFd::ReadOnlyGzip);
+   FileFd f = FileFd (IndexFile("Sources"), FileFd::ReadOnly, FileFd::Extension);
    if (!f.Failed())
       size = f.Size();
 
@@ -288,7 +288,7 @@ unsigned long debPackagesIndex::Size() const
    /* we need to ignore errors here; if the lists are absent, just return 0 */
    _error->PushToStack();
 
-   FileFd f = FileFd (IndexFile("Packages"), FileFd::ReadOnlyGzip);
+   FileFd f = FileFd (IndexFile("Packages"), FileFd::ReadOnly, FileFd::Extension);
    if (!f.Failed())
       size = f.Size();
 
@@ -305,7 +305,7 @@ unsigned long debPackagesIndex::Size() const
 bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 {
    string PackageFile = IndexFile("Packages");
-   FileFd Pkg(PackageFile,FileFd::ReadOnlyGzip);
+   FileFd Pkg(PackageFile,FileFd::ReadOnly, FileFd::Extension);
    debListParser Parser(&Pkg, Architecture);
 
    if (_error->PendingError() == true)
@@ -319,6 +319,7 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
    // Store the IMS information
    pkgCache::PkgFileIterator File = Gen.GetCurFile();
    pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(File);
+   // FIXME: Get this info from FileFd instead
    struct stat St;
    if (fstat(Pkg.Fd(),&St) != 0)
       return _error->Errno("fstat","Failed to stat");
@@ -489,7 +490,7 @@ unsigned long debTranslationsIndex::Size() const
    /* we need to ignore errors here; if the lists are absent, just return 0 */
    _error->PushToStack();
 
-   FileFd f = FileFd (IndexFile(Language), FileFd::ReadOnlyGzip);
+   FileFd f = FileFd (IndexFile(Language), FileFd::ReadOnly, FileFd::Extension);
    if (!f.Failed())
       size = f.Size();
 
@@ -509,7 +510,7 @@ bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
    string TranslationFile = IndexFile(Language);
    if (FileExists(TranslationFile))
    {
-     FileFd Trans(TranslationFile,FileFd::ReadOnlyGzip);
+     FileFd Trans(TranslationFile,FileFd::ReadOnly, FileFd::Extension);
      debListParser TransParser(&Trans);
      if (_error->PendingError() == true)
        return false;
@@ -590,7 +591,7 @@ unsigned long debStatusIndex::Size() const
 /* */
 bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 {
-   FileFd Pkg(File,FileFd::ReadOnlyGzip);
+   FileFd Pkg(File,FileFd::ReadOnly, FileFd::Extension);
    if (_error->PendingError() == true)
       return false;
    debListParser Parser(&Pkg);
index 1afa7b74deef56ead984475330725e3eb3c1335d..184c07c33b2d9b2f2ea47036e8824fdd76ecfe5c 100644 (file)
@@ -25,7 +25,7 @@ using std::string;
 // ---------------------------------------------------------------------
 /* */
 debRecordParser::debRecordParser(string FileName,pkgCache &Cache) : 
-                  File(FileName,FileFd::ReadOnlyGzip), 
+                  File(FileName,FileFd::ReadOnly, FileFd::Extension),
                   Tags(&File, std::max(Cache.Head().MaxVerFileSize, 
                                       Cache.Head().MaxDescFileSize) + 200)
 {
index 4c8d03224b8c821fb57b3113e01df48d96558985..5d2a67f4f599643a18791dbae4bc59666e7c41ff 100644 (file)
@@ -50,7 +50,7 @@ class debSrcRecordParser : public pkgSrcRecords::Parser
    virtual bool Files(std::vector<pkgSrcRecords::File> &F);
 
    debSrcRecordParser(std::string const &File,pkgIndexFile const *Index) 
-      : Parser(Index), Fd(File,FileFd::ReadOnlyGzip), Tags(&Fd,102400), 
+      : Parser(Index), Fd(File,FileFd::ReadOnly, FileFd::Extension), Tags(&Fd,102400), 
         Buffer(NULL) {}
    virtual ~debSrcRecordParser();
 };
index 65d7b0ccdcdb12adf16a4af2a4fb1c9bbde272e5..1cd5080cc44214504a3d46fb3c7036e778a977e7 100644 (file)
@@ -1143,7 +1143,7 @@ bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
       return _error->Error(_("Package file %s is out of sync."),I.FileName());
 
    FileFd PkgF;
-   if (PkgF.Open(I.FileName(), FileFd::ReadOnlyGzip) == false)
+   if (PkgF.Open(I.FileName(), FileFd::ReadOnly, FileFd::Extension) == false)
       return false;
 
    // Read the record
index a51497948646d1d0ac98e2bb70017f1cbbcaaf7b..6ab6548efb56f82edea77f4de17763e14d3c2953 100644 (file)
@@ -48,7 +48,7 @@ bool GzipMethod::Fetch(FetchItem *Itm)
    URIStart(Res);
    
    // Open the source and destination files
-   FileFd From(Path,FileFd::ReadOnlyGzip);
+   FileFd From(Path,FileFd::ReadOnly, FileFd::Gzip);
 
    if(From.FileSize() == 0)
       return _error->Error(_("Empty files can't be valid archives"));
index ef00fcaa39de83364d5b284e77d0955378481096..56ad8220b8006e5ff2d4cd33140bb3064d794ff0 100644 (file)
@@ -489,7 +489,7 @@ bool RredMethod::Fetch(FetchItem *Itm)                                              /*{{{*/
    // Open the source and destination files (the d'tor of FileFd will do 
    // the cleanup/closing of the fds)
    FileFd From(Path,FileFd::ReadOnly);
-   FileFd Patch(Path+".ed",FileFd::ReadOnlyGzip);
+   FileFd Patch(Path+".ed",FileFd::ReadOnly, FileFd::Gzip);
    FileFd To(Itm->DestFile,FileFd::WriteAtomic);   
    To.EraseOnFailure();
    if (_error->PendingError() == true)