- if (Comp == true)
- OutFd = open(FileName.c_str(), O_WRONLY, 0666);
- else
- OutFd = open(FileName.c_str(), O_RDONLY);
- return true;
- }
-
- // Handle 'decompression' of empty files
- if (Comp == false)
- {
- struct stat Buf;
- stat(FileName.c_str(), &Buf);
- if (Buf.st_size == 0)
- {
- OutFd = open(FileName.c_str(), O_RDONLY);
- return true;
- }
- }
-
- // Create a data pipe
- int Pipe[2] = {-1,-1};
- if (pipe(Pipe) != 0)
- return _error->Errno("pipe",_("Failed to create subprocess IPC"));
- for (int J = 0; J != 2; J++)
- SetCloseExec(Pipe[J],true);
-
- int FileFd = -1;
- if (Comp == true)
- {
- OutFd = Pipe[1];
- // FIXME: we should handle openmode and permission from Open() here
- FileFd = open(FileName.c_str(), O_WRONLY, 0666);
- }
- else
- OutFd = Pipe[0];
-
- // The child..
- pid_t child = ExecFork();
- if (Pid != NULL)
- *Pid = child;
- if (child == 0)
- {
- if (Comp == true)
- {
- dup2(Pipe[0],STDIN_FILENO);
- dup2(FileFd,STDOUT_FILENO);
- SetCloseExec(STDIN_FILENO,false);
- }
- else
- {
- dup2(Pipe[1],STDOUT_FILENO);
- }
- SetCloseExec(STDOUT_FILENO,false);
-
- std::vector<char const*> Args;
- Args.push_back(Prog.Binary.c_str());
- std::vector<std::string> const * const addArgs =
- (Comp == true) ? &(Prog.CompressArgs) : &(Prog.UncompressArgs);
- for (std::vector<std::string>::const_iterator a = addArgs->begin();
- a != addArgs->end(); ++a)
- Args.push_back(a->c_str());
- if (Comp == false)
- {
- Args.push_back("--stdout");
- Args.push_back(FileName.c_str());
- }
- Args.push_back(NULL);
-
- execvp(Args[0],(char **)&Args[0]);
- cerr << _("Failed to exec compressor ") << Args[0] << endl;
- _exit(100);
- }
- if (Comp == true)
- {
- close(Pipe[0]);
- close(FileFd);
- }
- else
- close(Pipe[1]);
-
- if (Pid == NULL)
- ExecWait(child, Prog.Binary.c_str(), false);
-
- return true;
-}
- /*}}}*/
-
-// FileFd::Open - Open a file /*{{{*/
-// ---------------------------------------------------------------------
-/* The most commonly used open mode combinations are given with Mode */
-bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress, unsigned long const Perms)
-{
- if (Mode == ReadOnlyGzip)
- return Open(FileName, ReadOnly, Gzip, Perms);
-
- if (Compress == Auto && (Mode & WriteOnly) == WriteOnly)
- return _error->Error("Autodetection on %s only works in ReadOnly openmode!", FileName.c_str());
-
- // 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)
- {
- for (; compressor != compressors.end(); ++compressor)
- {
- std::string file = std::string(FileName).append(compressor->Extension);
- if (FileExists(file) == false)
- continue;
- FileName = file;
- break;
- }
- }
- else if (Compress == Extension)
- {
- std::string::size_type const found = FileName.find_last_of('.');
- std::string ext;
- if (found != std::string::npos)
- {
- ext = FileName.substr(found);
- if (ext == ".new" || ext == ".bak")
- {
- std::string::size_type const found2 = FileName.find_last_of('.', found - 1);
- if (found2 != std::string::npos)
- ext = FileName.substr(found2, found - found2);
- else
- ext.clear();
- }
- }
- 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
- {
- 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:
- // 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())
- return _error->Error("Can't find a configured compressor %s for file %s", name.c_str(), FileName.c_str());
- }
-
- 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,unsigned int const 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)
- {
- Flags |= Replace;
- char *name = strdup((FileName + ".XXXXXX").c_str());
- TemporaryFileName = string(mktemp(name));
- free(name);