summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/contrib/fileutl.cc129
-rw-r--r--apt-pkg/contrib/fileutl.h14
-rw-r--r--apt-pkg/deb/debindexfile.cc13
-rw-r--r--apt-pkg/deb/debrecords.cc2
-rw-r--r--apt-pkg/deb/debsrcrecords.h2
-rw-r--r--cmdline/apt-cache.cc2
-rw-r--r--methods/gzip.cc2
-rw-r--r--methods/rred.cc2
8 files changed, 135 insertions, 31 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 /*{{{*/
// ---------------------------------------------------------------------
diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h
index fa8f92272..59a9d97e3 100644
--- a/apt-pkg/contrib/fileutl.h
+++ b/apt-pkg/contrib/fileutl.h
@@ -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);
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc
index 27c1f7f32..d9c448598 100644
--- a/apt-pkg/deb/debindexfile.cc
+++ b/apt-pkg/deb/debindexfile.cc
@@ -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);
diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc
index 1afa7b74d..184c07c33 100644
--- a/apt-pkg/deb/debrecords.cc
+++ b/apt-pkg/deb/debrecords.cc
@@ -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)
{
diff --git a/apt-pkg/deb/debsrcrecords.h b/apt-pkg/deb/debsrcrecords.h
index 4c8d03224..5d2a67f4f 100644
--- a/apt-pkg/deb/debsrcrecords.h
+++ b/apt-pkg/deb/debsrcrecords.h
@@ -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();
};
diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc
index 65d7b0ccd..1cd5080cc 100644
--- a/cmdline/apt-cache.cc
+++ b/cmdline/apt-cache.cc
@@ -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
diff --git a/methods/gzip.cc b/methods/gzip.cc
index a51497948..6ab6548ef 100644
--- a/methods/gzip.cc
+++ b/methods/gzip.cc
@@ -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"));
diff --git a/methods/rred.cc b/methods/rred.cc
index ef00fcaa3..56ad8220b 100644
--- a/methods/rred.cc
+++ b/methods/rred.cc
@@ -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)