]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/contrib/fileutl.cc
fix FileFd::Size bitswap on big-endian architectures
[apt.git] / apt-pkg / contrib / fileutl.cc
index 69406a9bf11f30c348cce891e7ec494f9c971f56..b77c7ff7fd153a2d3fc228d6e5850f5deb367fb1 100644 (file)
        #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>
                                                                        /*}}}*/
@@ -104,7 +101,11 @@ bool RunScripts(const char *Cnf)
       {
         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);
       }
@@ -954,10 +955,10 @@ class FileFdPrivate {                                                     /*{{{*/
 // 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());
@@ -1024,9 +1025,9 @@ bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress,
 
    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;
@@ -1076,11 +1077,18 @@ bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Co
       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)
@@ -1349,7 +1357,10 @@ bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::C
         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
@@ -1642,6 +1653,8 @@ bool FileFd::Write(int Fd, const void *From, unsigned long long Size)
 /* */
 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
@@ -1701,7 +1714,6 @@ bool FileFd::Skip(unsigned long long Over)
 {
    if (d != NULL && (d->pipe == true || d->InternalStream() == true))
    {
-      d->seekpos += Over;
       char buffer[1024];
       while (Over != 0)
       {
@@ -1865,19 +1877,13 @@ unsigned long long FileFd::Size()
          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)
        {