From aee1aac6f75906ec73dacffc55e7026002201f98 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 13 Dec 2011 23:48:14 +0100 Subject: [PATCH] allow Open() and OpenDescriptor() to be called with a Compressor --- apt-pkg/contrib/fileutl.cc | 187 +++++++++++++++++++------------------ apt-pkg/contrib/fileutl.h | 4 +- 2 files changed, 98 insertions(+), 93 deletions(-) diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 25ac5275c..c2b684089 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -48,7 +48,7 @@ // so while the current implementation satisfies the testcases it is not a real option // to disable it for now #define APT_USE_ZLIB 1 -#ifdef APT_USE_ZLIB +#if APT_USE_ZLIB #include #endif @@ -63,7 +63,7 @@ using namespace std; class FileFdPrivate { public: -#ifdef APT_USE_ZLIB +#if APT_USE_ZLIB gzFile gz; #else void* gz; @@ -914,95 +914,77 @@ bool FileFd::Open(string FileName,OpenMode Mode,CompressMode Compress, unsigned { if (Mode == ReadOnlyGzip) return Open(FileName, ReadOnly, Gzip, Perms); - Close(); - d = new FileFdPrivate; - d->openmode = Mode; - 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); - else if_FLAGGED_SET(ReadOnly, O_RDONLY); - else if_FLAGGED_SET(WriteOnly, O_WRONLY); - else return _error->Error("No openmode provided in FileFd::Open for %s", FileName.c_str()); - - if_FLAGGED_SET(Create, O_CREAT); - if_FLAGGED_SET(Exclusive, O_EXCL); - else if_FLAGGED_SET(Atomic, O_EXCL); - 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 const compressors = APT::Configuration::getCompressors(); std::vector::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) - { + if (ext == FileName) + ext.clear(); + else ext = "." + ext; - for (; compressor != compressors.end(); ++compressor) - if (ext == compressor->Extension) + for (; compressor != compressors.end(); ++compressor) + if (ext == compressor->Extension) + break; + // no matching extension - assume uncompressed (imagine files like 'example.org_Packages') + if (compressor == compressors.end()) + for (compressor = compressors.begin(); compressor != compressors.end(); ++compressor) + if (compressor->Name == ".") break; - } } - else if (Compress != None) + else { std::string name; switch (Compress) { + case None: name = "."; break; 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()); + case Auto: + case Extension: + // Unreachable + return _error->Error("Opening File %s in None, Auto or Extension should be already handled?!?", FileName.c_str()); } for (; compressor != compressors.end(); ++compressor) if (compressor->Name == name) break; - if (compressor == compressors.end() && name != "gzip") + if (compressor == compressors.end()) 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()) - { -#ifdef APT_USE_ZLIB - if (compressor->Name == "gzip") - { - Compress = Gzip; - compressor = compressors.end(); - } - else -#endif - if (compressor->Name == ".") - { - Compress = None; - compressor = compressors.end(); - } - } + if (compressor == compressors.end()) + return _error->Error("Can't find a match for specified compressor mode for file %s", FileName.c_str()); + return Open(FileName, Mode, *compressor, Perms); +} +bool FileFd::Open(string FileName,OpenMode Mode,APT::Configuration::Compressor const &compressor, unsigned long const Perms) +{ + Close(); + d = new FileFdPrivate; + d->openmode = Mode; + Flags = AutoClose; + + 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()); + if ((Mode & ReadWrite) == 0) + return _error->Error("No openmode provided in FileFd::Open for %s", FileName.c_str()); if ((Mode & Atomic) == Atomic) { @@ -1023,18 +1005,35 @@ bool FileFd::Open(string FileName,OpenMode Mode,CompressMode Compress, unsigned unlink(FileName.c_str()); } - if (compressor != compressors.end()) + // if we have them, use inbuilt compressors instead of forking + if (compressor.Name != "." +#if APT_USE_ZLIB + && compressor.Name != "gzip" +#endif + ) { if ((Mode & ReadWrite) == ReadWrite) - return _error->Error("External compressors like %s do not support readwrite mode for file %s", compressor->Name.c_str(), FileName.c_str()); + return _error->Error("External compressors like %s do not support readwrite mode for file %s", compressor.Name.c_str(), FileName.c_str()); - if (ExecCompressor(*compressor, NULL /*d->compressor_pid*/, FileName, iFd, ((Mode & ReadOnly) != ReadOnly)) == false) - return _error->Error("Forking external compressor %s is not implemented for %s", compressor->Name.c_str(), FileName.c_str()); + if (ExecCompressor(compressor, NULL /*d->compressor_pid*/, FileName, iFd, ((Mode & ReadOnly) != ReadOnly)) == false) + return _error->Error("Forking external compressor %s is not implemented for %s", compressor.Name.c_str(), FileName.c_str()); d->pipe = true; - d->compressor = *compressor; + d->compressor = compressor; } else { + int fileflags = 0; + #define if_FLAGGED_SET(FLAG, MODE) if ((Mode & FLAG) == FLAG) fileflags |= MODE + if_FLAGGED_SET(ReadWrite, O_RDWR); + else if_FLAGGED_SET(ReadOnly, O_RDONLY); + else if_FLAGGED_SET(WriteOnly, O_WRONLY); + + if_FLAGGED_SET(Create, O_CREAT); + if_FLAGGED_SET(Exclusive, O_EXCL); + else if_FLAGGED_SET(Atomic, O_EXCL); + if_FLAGGED_SET(Empty, O_TRUNC); + #undef if_FLAGGED_SET + if (TemporaryFileName.empty() == false) iFd = open(TemporaryFileName.c_str(), fileflags, Perms); else @@ -1042,7 +1041,7 @@ bool FileFd::Open(string FileName,OpenMode Mode,CompressMode Compress, unsigned if (iFd != -1) { - if (OpenInternDescriptor(Mode, Compress) == false) + if (OpenInternDescriptor(Mode, compressor) == false) { close (iFd); iFd = -1; @@ -1062,13 +1061,37 @@ bool FileFd::Open(string FileName,OpenMode Mode,CompressMode Compress, unsigned // --------------------------------------------------------------------- /* */ bool FileFd::OpenDescriptor(int Fd, OpenMode Mode, CompressMode Compress, bool AutoClose) +{ + std::vector const compressors = APT::Configuration::getCompressors(); + std::vector::const_iterator compressor = compressors.begin(); + std::string name; + switch (Compress) + { + case None: name = "."; break; + case Gzip: name = "gzip"; break; + case Bzip2: name = "bzip2"; break; + case Lzma: name = "lzma"; break; + case Xz: name = "xz"; break; + case Auto: + case Extension: + return _error->Error("Opening Fd %d in Auto or Extension compression mode is not supported", Fd); + } + for (; compressor != compressors.end(); ++compressor) + if (compressor->Name == name) + break; + if (compressor == compressors.end()) + return _error->Error("Can't find a configured compressor %s for file %s", name.c_str(), FileName.c_str()); + + return OpenDescriptor(Fd, Mode, *compressor, AutoClose); +} +bool FileFd::OpenDescriptor(int Fd, OpenMode Mode, APT::Configuration::Compressor const &compressor, bool AutoClose) { Close(); d = new FileFdPrivate; d->openmode = Mode; Flags = (AutoClose) ? FileFd::AutoClose : 0; iFd = Fd; - if (OpenInternDescriptor(Mode, Compress) == false) + if (OpenInternDescriptor(Mode, compressor) == false) { if (AutoClose) close (iFd); @@ -1077,12 +1100,12 @@ bool FileFd::OpenDescriptor(int Fd, OpenMode Mode, CompressMode Compress, bool A this->FileName = ""; return true; } -bool FileFd::OpenInternDescriptor(OpenMode Mode, CompressMode Compress) +bool FileFd::OpenInternDescriptor(OpenMode Mode, APT::Configuration::Compressor const &compressor) { - if (Compress == None) + if (compressor.Name == ".") return true; -#ifdef APT_USE_ZLIB - else if (Compress == Gzip) +#if APT_USE_ZLIB + else if (compressor.Name == "gzip") { if ((Mode & ReadWrite) == ReadWrite) d->gz = gzdopen(iFd, "r+"); @@ -1096,27 +1119,7 @@ bool FileFd::OpenInternDescriptor(OpenMode Mode, CompressMode Compress) } #endif else - { - 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()); - } - std::vector const compressors = APT::Configuration::getCompressors(); - std::vector::const_iterator compressor = compressors.begin(); - for (; compressor != compressors.end(); ++compressor) - if (compressor->Name == name) - break; - if (compressor == compressors.end() || - ExecCompressor(*compressor, NULL /*&(d->compressor_pid)*/, - FileName, iFd, ((Mode & ReadOnly) != ReadOnly)) == false) - return _error->Error("Forking external compressor %s is not implemented for %s", name.c_str(), FileName.c_str()); - d->pipe = true; - } + return _error->Error("Can't find a match for specified compressor %s for file %s", compressor.Name.c_str(), FileName.c_str()); return true; } /*}}}*/ @@ -1142,7 +1145,7 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual) *((char *)To) = '\0'; do { -#ifdef APT_USE_ZLIB +#if APT_USE_ZLIB if (d->gz != NULL) Res = gzread(d->gz,To,Size); else @@ -1184,7 +1187,7 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual) char* FileFd::ReadLine(char *To, unsigned long long const Size) { *To = '\0'; -#ifdef APT_USE_ZLIB +#if APT_USE_ZLIB if (d->gz != NULL) return gzgets(d->gz, To, Size); #endif @@ -1211,7 +1214,7 @@ bool FileFd::Write(const void *From,unsigned long long Size) errno = 0; do { -#ifdef APT_USE_ZLIB +#if APT_USE_ZLIB if (d->gz != NULL) Res = gzwrite(d->gz,From,Size); else @@ -1252,7 +1255,7 @@ bool FileFd::Seek(unsigned long long To) return result; } int res; -#ifdef APT_USE_ZLIB +#if APT_USE_ZLIB if (d->gz) res = gzseek(d->gz,To,SEEK_SET); else @@ -1273,7 +1276,7 @@ bool FileFd::Seek(unsigned long long To) bool FileFd::Skip(unsigned long long Over) { int res; -#ifdef APT_USE_ZLIB +#if APT_USE_ZLIB if (d->gz != NULL) res = gzseek(d->gz,Over,SEEK_CUR); else @@ -1313,7 +1316,7 @@ bool FileFd::Truncate(unsigned long long To) unsigned long long FileFd::Tell() { off_t Res; -#ifdef APT_USE_ZLIB +#if APT_USE_ZLIB if (d->gz != NULL) Res = gztell(d->gz); else @@ -1367,7 +1370,7 @@ unsigned long long FileFd::Size() } while(read != 0); Seek(0); } -#ifdef APT_USE_ZLIB +#if APT_USE_ZLIB // only check gzsize if we are actually a gzip file, just checking for // "gz" is not sufficient as uncompressed files could be opened with // gzopen in "direct" mode as well @@ -1439,7 +1442,7 @@ bool FileFd::Close() bool Res = true; if ((Flags & AutoClose) == AutoClose) { -#ifdef APT_USE_ZLIB +#if APT_USE_ZLIB if (d != NULL && d->gz != NULL) { int const e = gzclose(d->gz); // gzdopen() on empty files always fails with "buffer error" here, ignore that diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 8a986b82b..51277290e 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -101,10 +101,12 @@ class FileFd } bool Open(std::string FileName,OpenMode Mode,CompressMode Compress,unsigned long const Perms = 0666); + bool Open(std::string FileName,OpenMode Mode,APT::Configuration::Compressor const &compressor,unsigned long const Perms = 0666); inline bool Open(std::string const &FileName,OpenMode Mode, unsigned long const Perms = 0666) { return Open(FileName, Mode, None, Perms); }; bool OpenDescriptor(int Fd, OpenMode Mode, CompressMode Compress, bool AutoClose=false); + bool OpenDescriptor(int Fd, OpenMode Mode, APT::Configuration::Compressor const &compressor, bool AutoClose=false); inline bool OpenDescriptor(int Fd, OpenMode Mode, bool AutoClose=false) { return OpenDescriptor(Fd, Mode, None, AutoClose); }; @@ -145,7 +147,7 @@ class FileFd private: FileFdPrivate* d; - bool OpenInternDescriptor(OpenMode Mode, CompressMode Compress); + bool OpenInternDescriptor(OpenMode Mode, APT::Configuration::Compressor const &compressor); }; bool RunScripts(const char *Cnf); -- 2.45.2