#define APT_USE_ZLIB 1
#if APT_USE_ZLIB
#include <zlib.h>
+#else
+#warning "Usage of zlib is DISABLED!"
#endif
#ifdef WORDS_BIGENDIAN
pid_t compressor_pid;
bool pipe;
APT::Configuration::Compressor compressor;
- FileFd::OpenMode openmode;
+ unsigned int openmode;
FileFdPrivate() : gz(NULL), compressor_pid(-1), pipe(false) {};
};
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];
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);
}
+ SetCloseExec(STDOUT_FILENO,false);
std::vector<char const*> Args;
Args.push_back(Prog.Binary.c_str());
for (std::vector<std::string>::const_iterator a = addArgs->begin();
a != addArgs->end(); ++a)
Args.push_back(a->c_str());
- Args.push_back("--stdout");
- Args.push_back(FileName.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]);
_exit(100);
}
if (Comp == true)
+ {
close(Pipe[0]);
+ close(FileFd);
+ }
else
close(Pipe[1]);
// FileFd::Open - Open a file /*{{{*/
// ---------------------------------------------------------------------
/* The most commonly used open mode combinations are given with Mode */
-bool FileFd::Open(string FileName,OpenMode Mode,CompressMode Compress, unsigned long const Perms)
+bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress, unsigned long const Perms)
{
if (Mode == ReadOnlyGzip)
return Open(FileName, ReadOnly, Gzip, Perms);
}
else if (Compress == Extension)
{
- std::string ext = flExtension(FileName);
- if (ext == FileName)
- ext.clear();
- else
- ext = "." + ext;
+ 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;
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());
+ // 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)
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)
+bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor, unsigned long const Perms)
{
Close();
d = new FileFdPrivate;
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());
- 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 ((Mode & (WriteOnly | Create)) == (WriteOnly | Create))
+ {
+ if (TemporaryFileName.empty() == false)
+ {
+ if (RealFileExists(TemporaryFileName) == false)
+ {
+ iFd = open(TemporaryFileName.c_str(), O_WRONLY | O_CREAT, Perms);
+ close(iFd);
+ iFd = -1;
+ }
+ }
+ else if (RealFileExists(FileName) == false)
+ {
+ iFd = open(FileName.c_str(), O_WRONLY | O_CREAT, Perms);
+ close(iFd);
+ iFd = -1;
+ }
+ }
+
+ if (TemporaryFileName.empty() == false)
+ {
+ if (ExecCompressor(compressor, &(d->compressor_pid), TemporaryFileName, iFd, ((Mode & ReadOnly) != ReadOnly)) == false)
+ return _error->Error("Forking external compressor %s is not implemented for %s", compressor.Name.c_str(), TemporaryFileName.c_str());
+ }
+ else
+ {
+ if (ExecCompressor(compressor, &(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;
}
// FileFd::OpenDescriptor - Open a filedescriptor /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool FileFd::OpenDescriptor(int Fd, OpenMode Mode, CompressMode Compress, bool AutoClose)
+bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compress, bool AutoClose)
{
std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors();
std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin();
return OpenDescriptor(Fd, Mode, *compressor, AutoClose);
}
-bool FileFd::OpenDescriptor(int Fd, OpenMode Mode, APT::Configuration::Compressor const &compressor, bool AutoClose)
+bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose)
{
Close();
d = new FileFdPrivate;
this->FileName = "";
return true;
}
-bool FileFd::OpenInternDescriptor(OpenMode Mode, APT::Configuration::Compressor const &compressor)
+bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::Compressor const &compressor)
{
if (compressor.Name == ".")
return true;
if (d != NULL)
{
-// if (d->compressor_pid != -1)
-// ExecWait(d->compressor_pid, "FileFdCompressor", true);
+ if (d->compressor_pid != -1)
+ ExecWait(d->compressor_pid, "FileFdCompressor", true);
delete d;
d = NULL;
}
return T;
}
- 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) {
+ bool Open(std::string FileName,unsigned int const Mode,CompressMode Compress,unsigned long const Perms = 0666);
+ bool Open(std::string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor,unsigned long const Perms = 0666);
+ inline bool Open(std::string const &FileName,unsigned int const 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) {
+ bool OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compress, bool AutoClose=false);
+ bool OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose=false);
+ inline bool OpenDescriptor(int Fd, unsigned int const Mode, bool AutoClose=false) {
return OpenDescriptor(Fd, Mode, None, AutoClose);
};
bool Close();
inline bool IsCompressed() {return (Flags & Compressed) == Compressed;};
inline std::string &Name() {return FileName;};
- FileFd(std::string FileName,OpenMode Mode,unsigned long Perms = 0666) : iFd(-1), Flags(0), d(NULL)
+ FileFd(std::string FileName,unsigned int const Mode,unsigned long Perms = 0666) : iFd(-1), Flags(0), d(NULL)
{
Open(FileName,Mode, None, Perms);
};
- FileFd(std::string FileName,OpenMode Mode, CompressMode Compress, unsigned long Perms = 0666) : iFd(-1), Flags(0), d(NULL)
+ FileFd(std::string FileName,unsigned int const Mode, CompressMode Compress, unsigned long Perms = 0666) : iFd(-1), Flags(0), d(NULL)
{
Open(FileName,Mode, Compress, Perms);
};
FileFd() : iFd(-1), Flags(AutoClose), d(NULL) {};
- FileFd(int const Fd, OpenMode Mode = ReadWrite, CompressMode Compress = None) : iFd(-1), Flags(0), d(NULL)
+ FileFd(int const Fd, unsigned int const Mode = ReadWrite, CompressMode Compress = None) : iFd(-1), Flags(0), d(NULL)
{
OpenDescriptor(Fd, Mode, Compress);
};
private:
FileFdPrivate* d;
- bool OpenInternDescriptor(OpenMode Mode, APT::Configuration::Compressor const &compressor);
+ bool OpenInternDescriptor(unsigned int const Mode, APT::Configuration::Compressor const &compressor);
};
bool RunScripts(const char *Cnf);
/* Open all the temp files now so we can report any errors. File is
made unreable to prevent people from touching it during creating. */
for (Files *I = Outputs; I != 0; I = I->Next)
- I->TmpFile.Open(I->Output + ".new",FileFd::WriteEmpty,0600);
+ I->TmpFile.Open(I->Output + ".new", FileFd::WriteOnly | FileFd::Create | FileFd::Empty, FileFd::Extension, 0600);
if (_error->PendingError() == true)
return;
_exit(0);
};
- /* Tidy up the temp files, we open them in the constructor so as to
- get proper error reporting. Close them now. */
- for (Files *I = Outputs; I != 0; I = I->Next)
- I->TmpFile.Close();
-
close(Pipe[0]);
Input = fdopen(Pipe[1],"w");
if (Input == 0)
is new then the temp files are renamed, otherwise they are erased. */
bool MultiCompress::Child(int const &FD)
{
- // Start the compression children.
- for (Files *I = Outputs; I != 0; I = I->Next)
- {
- if (ExecCompressor(I->CompressProg,&(I->CompressProc),I->TmpFile.Fd(),
- I->Fd,true) == false)
- return false;
- }
-
/* Okay, now we just feed data from FD to all the other FDs. Also
stash a hash of the data to use later. */
SetNonBlock(FD,false);
FileSize += Res;
for (Files *I = Outputs; I != 0; I = I->Next)
{
- if (write(I->Fd,Buffer,Res) != Res)
+ if (I->TmpFile.Write(Buffer, Res) == false)
{
_error->Errno("write",_("IO to subprocess/file failed"));
break;
}
}
}
-
- // Close all the writers
- for (Files *I = Outputs; I != 0; I = I->Next)
- close(I->Fd);
-
- // Wait for the compressors to exit
- for (Files *I = Outputs; I != 0; I = I->Next)
- {
- if (I->CompressProc != -1)
- ExecWait(I->CompressProc, I->CompressProg.Binary.c_str(), false);
- }
-
+
if (_error->PendingError() == true)
return false;