summaryrefslogtreecommitdiff
path: root/apt-pkg/contrib/fileutl.cc
diff options
context:
space:
mode:
authorDavid Kalnischkies <kalnischkies@gmail.com>2011-12-10 19:31:36 +0100
committerDavid Kalnischkies <kalnischkies@gmail.com>2011-12-10 19:31:36 +0100
commit468720c59fcf48b20332cdb7b601b2b0d7cbbfbb (patch)
treef01d2dcf5827a86706567387c1a0af50c4cf21dd /apt-pkg/contrib/fileutl.cc
parent8e16d8c39447809506a8cd8e6f88cae3c168f82d (diff)
enable FileFd to guess the compressor based on the filename if requested or
to search for compressed silbings of the given filename and use this guessing instead of hardcoding Gzip compression
Diffstat (limited to 'apt-pkg/contrib/fileutl.cc')
-rw-r--r--apt-pkg/contrib/fileutl.cc129
1 files changed, 112 insertions, 17 deletions
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index d5e7192e3..1cb3fab1e 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -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,18 +867,34 @@ 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 /*{{{*/
// ---------------------------------------------------------------------