#include <bzlib.h>
#endif
#ifdef HAVE_LZMA
- #include <stdint.h>
#include <lzma.h>
#endif
-
-#ifdef WORDS_BIGENDIAN
-#include <inttypes.h>
-#endif
+#include <endian.h>
+#include <stdint.h>
#include <apti18n.h>
/*}}}*/
{
if (Opts->Value.empty() == true)
continue;
-
+
+ if(_config->FindB("Debug::RunScripts", false) == true)
+ std::clog << "Running external script: '"
+ << Opts->Value << "'" << std::endl;
+
if (system(Opts->Value.c_str()) != 0)
_exit(100+Count);
}
// 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)
+bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress, unsigned long const AccessMode)
{
if (Mode == ReadOnlyGzip)
- return Open(FileName, ReadOnly, Gzip, Perms);
+ return Open(FileName, ReadOnly, Gzip, AccessMode);
if (Compress == Auto && (Mode & WriteOnly) == WriteOnly)
return FileFdError("Autodetection on %s only works in ReadOnly openmode!", FileName.c_str());
if (compressor == compressors.end())
return FileFdError("Can't find a match for specified compressor mode for file %s", FileName.c_str());
- return Open(FileName, Mode, *compressor, Perms);
+ return Open(FileName, Mode, *compressor, AccessMode);
}
-bool FileFd::Open(string FileName,unsigned int const 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 AccessMode)
{
Close();
Flags = AutoClose;
TemporaryFileName = string(name);
free(name);
- if(Perms != 600 && fchmod(iFd, Perms) == -1)
+ // umask() will always set the umask and return the previous value, so
+ // we first set the umask and then reset it to the old value
+ mode_t const CurrentUmask = umask(0);
+ umask(CurrentUmask);
+ // calculate the actual file permissions (just like open/creat)
+ mode_t const FilePermissions = (AccessMode & ~CurrentUmask);
+
+ if(fchmod(iFd, FilePermissions) == -1)
return FileFdErrno("fchmod", "Could not change permissions for temporary file %s", TemporaryFileName.c_str());
}
else
- iFd = open(FileName.c_str(), fileflags, Perms);
+ iFd = open(FileName.c_str(), fileflags, AccessMode);
this->FileName = FileName;
if (iFd == -1 || OpenInternDescriptor(Mode, compressor) == false)
d->openmode = Mode;
d->compressor = compressor;
#if defined HAVE_ZLIB || defined HAVE_BZ2 || defined HAVE_LZMA
- if (AutoClose == false && compress_open != NULL)
+ if ((Flags & AutoClose) != AutoClose && compress_open != NULL)
{
// Need to duplicate fd here or gz/bz2 close for cleanup will close the fd as well
int const internFd = dup(iFd);
if (d->lzma == NULL)
d->lzma = new FileFdPrivate::LZMAFILE;
d->lzma->file = (FILE*) compress_struct;
- d->lzma->stream = LZMA_STREAM_INIT;
+ lzma_stream tmp_stream = LZMA_STREAM_INIT;
+ d->lzma->stream = tmp_stream;
if ((Mode & ReadWrite) == ReadWrite)
return FileFdError("ReadWrite mode is not supported for file %s", FileName.c_str());
Args.push_back(a->c_str());
if (Comp == false && FileName.empty() == false)
{
- Args.push_back("--stdout");
+ // commands not needing arguments, do not need to be told about using standard output
+ // in reality, only testcases with tools like cat, rev, rot13, … are able to trigger this
+ if (compressor.CompressArgs.empty() == false && compressor.UncompressArgs.empty() == false)
+ Args.push_back("--stdout");
if (TemporaryFileName.empty() == false)
Args.push_back(TemporaryFileName.c_str());
else
errno = 0;
}
else
+ {
Res = Size - d->lzma->stream.avail_out;
+ if (Res == 0)
+ {
+ // lzma run was okay, but produced no output…
+ Res = -1;
+ errno = EINTR;
+ }
+ }
}
#endif
else
if (Res < 0)
{
if (errno == EINTR)
+ {
+ // trick the while-loop into running again
+ Res = 1;
+ errno = 0;
continue;
+ }
if (false)
/* dummy so that the rest can be 'else if's */;
#ifdef HAVE_ZLIB
/* */
bool FileFd::Seek(unsigned long long To)
{
+ Flags &= ~HitEof;
+
if (d != NULL && (d->pipe == true || d->InternalStream() == true))
{
// Our poor man seeking in pipes is costly, so try to avoid it
{
if (d != NULL && (d->pipe == true || d->InternalStream() == true))
{
- d->seekpos += Over;
char buffer[1024];
while (Over != 0)
{
// higher-level code will generate more meaningful messages,
// even translated this would be meaningless for users
return _error->Errno("fstat", "Unable to determine %s for fd %i", msg, iFd);
- ispipe = S_ISFIFO(Buf.st_mode);
+ if (FileName.empty() == false)
+ ispipe = S_ISFIFO(Buf.st_mode);
}
// for compressor pipes st_size is undefined and at 'best' zero
FileFdErrno("lseek","Unable to seek to end of gzipped file");
return 0;
}
- size = 0;
+ uint32_t size = 0;
if (read(iFd, &size, 4) != 4)
{
FileFdErrno("read","Unable to read original size of gzipped file");
return 0;
}
-
-#ifdef WORDS_BIGENDIAN
- uint32_t tmp_size = size;
- uint8_t const * const p = (uint8_t const * const) &tmp_size;
- tmp_size = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
- size = tmp_size;
-#endif
+ size = le32toh(size);
if (lseek(iFd, oldPos, SEEK_SET) < 0)
{
return string(tmpdir);
}
+
+bool Rename(std::string From, std::string To)
+{
+ if (rename(From.c_str(),To.c_str()) != 0)
+ {
+ _error->Error(_("rename failed, %s (%s -> %s)."),strerror(errno),
+ From.c_str(),To.c_str());
+ return false;
+ }
+ return true;
+}