]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/contrib/fileutl.cc
Merge remote-tracking branch 'mvo/bugfix/coverity' into debian/sid
[apt.git] / apt-pkg / contrib / fileutl.cc
index c8e685a5a0bd1371956aabfddc195ee6c5f6aa63..dca468c6310d2db22aa5ce1276d207d88ec3184d 100644 (file)
@@ -41,6 +41,8 @@
 #include <dirent.h>
 #include <signal.h>
 #include <errno.h>
 #include <dirent.h>
 #include <signal.h>
 #include <errno.h>
+#include <glob.h>
+
 #include <set>
 #include <algorithm>
 
 #include <set>
 #include <algorithm>
 
@@ -81,6 +83,31 @@ class FileFdPrivate {
        FileFdPrivate() : gz(NULL), bz2(NULL),
                          compressed_fd(-1), compressor_pid(-1), pipe(false),
                          openmode(0), seekpos(0) {};
        FileFdPrivate() : gz(NULL), bz2(NULL),
                          compressed_fd(-1), compressor_pid(-1), pipe(false),
                          openmode(0), seekpos(0) {};
+       bool CloseDown(std::string const &FileName)
+       {
+          bool Res = true;
+#ifdef HAVE_ZLIB
+          if (gz != NULL) {
+             int const e = gzclose(gz);
+             gz = NULL;
+             // gzdclose() on empty files always fails with "buffer error" here, ignore that
+             if (e != 0 && e != Z_BUF_ERROR)
+                Res &= _error->Errno("close",_("Problem closing the gzip file %s"), FileName.c_str());
+          }
+#endif
+#ifdef HAVE_BZ2
+          if (bz2 != NULL) {
+             BZ2_bzclose(bz2);
+             bz2 = NULL;
+          }
+#endif
+          if (compressor_pid > 0)
+             ExecWait(compressor_pid, "FileFdCompressor", true);
+          compressor_pid = -1;
+
+          return Res;
+       }
+       ~FileFdPrivate() { CloseDown(""); }
 };
 
 // RunScripts - Run a set of scripts from a configuration subtree      /*{{{*/
 };
 
 // RunScripts - Run a set of scripts from a configuration subtree      /*{{{*/
@@ -159,7 +186,8 @@ bool RunScripts(const char *Cnf)
 /* The caller is expected to set things so that failure causes erasure */
 bool CopyFile(FileFd &From,FileFd &To)
 {
 /* The caller is expected to set things so that failure causes erasure */
 bool CopyFile(FileFd &From,FileFd &To)
 {
-   if (From.IsOpen() == false || To.IsOpen() == false)
+   if (From.IsOpen() == false || To.IsOpen() == false ||
+        From.Failed() == true || To.Failed() == true)
       return false;
    
    // Buffered copy between fds
       return false;
    
    // Buffered copy between fds
@@ -218,17 +246,20 @@ int GetLock(string File,bool Errors)
    fl.l_len = 0;
    if (fcntl(FD,F_SETLK,&fl) == -1)
    {
    fl.l_len = 0;
    if (fcntl(FD,F_SETLK,&fl) == -1)
    {
+      // always close to not leak resources
+      int Tmp = errno;
+      close(FD);
+      errno = Tmp;
+
       if (errno == ENOLCK)
       {
         _error->Warning(_("Not using locking for nfs mounted lock file %s"),File.c_str());
         return dup(0);       // Need something for the caller to close  
       if (errno == ENOLCK)
       {
         _error->Warning(_("Not using locking for nfs mounted lock file %s"),File.c_str());
         return dup(0);       // Need something for the caller to close  
-      }      
+      }
+  
       if (Errors == true)
         _error->Errno("open",_("Could not get lock %s"),File.c_str());
       
       if (Errors == true)
         _error->Errno("open",_("Could not get lock %s"),File.c_str());
       
-      int Tmp = errno;
-      close(FD);
-      errno = Tmp;
       return -1;
    }
 
       return -1;
    }
 
@@ -362,7 +393,7 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c
 
    std::vector<string> List;
 
 
    std::vector<string> List;
 
-   if (DirectoryExists(Dir.c_str()) == false)
+   if (DirectoryExists(Dir) == false)
    {
       _error->Error(_("List of files can't be created as '%s' is not a directory"), Dir.c_str());
       return List;
    {
       _error->Error(_("List of files can't be created as '%s' is not a directory"), Dir.c_str());
       return List;
@@ -388,14 +419,14 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c
       if (Ent->d_type != DT_REG)
 #endif
       {
       if (Ent->d_type != DT_REG)
 #endif
       {
-        if (RealFileExists(File.c_str()) == false)
+        if (RealFileExists(File) == false)
         {
            // do not show ignoration warnings for directories
            if (
 #ifdef _DIRENT_HAVE_D_TYPE
                Ent->d_type == DT_DIR ||
 #endif
         {
            // do not show ignoration warnings for directories
            if (
 #ifdef _DIRENT_HAVE_D_TYPE
                Ent->d_type == DT_DIR ||
 #endif
-               DirectoryExists(File.c_str()) == true)
+               DirectoryExists(File) == true)
               continue;
            if (SilentIgnore.Match(Ent->d_name) == false)
               _error->Notice(_("Ignoring '%s' in directory '%s' as it is not a regular file"), Ent->d_name, Dir.c_str());
               continue;
            if (SilentIgnore.Match(Ent->d_name) == false)
               _error->Notice(_("Ignoring '%s' in directory '%s' as it is not a regular file"), Ent->d_name, Dir.c_str());
@@ -476,7 +507,7 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, bool SortList)
 
    std::vector<string> List;
 
 
    std::vector<string> List;
 
-   if (DirectoryExists(Dir.c_str()) == false)
+   if (DirectoryExists(Dir) == false)
    {
       _error->Error(_("List of files can't be created as '%s' is not a directory"), Dir.c_str());
       return List;
    {
       _error->Error(_("List of files can't be created as '%s' is not a directory"), Dir.c_str());
       return List;
@@ -501,7 +532,7 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, bool SortList)
       if (Ent->d_type != DT_REG)
 #endif
       {
       if (Ent->d_type != DT_REG)
 #endif
       {
-        if (RealFileExists(File.c_str()) == false)
+        if (RealFileExists(File) == false)
         {
            if (Debug == true)
               std::clog << "Bad file: " << Ent->d_name << " → it is not a real file" << std::endl;
         {
            if (Debug == true)
               std::clog << "Bad file: " << Ent->d_name << " → it is not a real file" << std::endl;
@@ -836,7 +867,7 @@ bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress,
       return Open(FileName, ReadOnly, Gzip, Perms);
 
    if (Compress == Auto && (Mode & WriteOnly) == WriteOnly)
       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());
+      return FileFdError("Autodetection on %s only works in ReadOnly openmode!", FileName.c_str());
 
    std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors();
    std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin();
 
    std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors();
    std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin();
@@ -889,17 +920,17 @@ bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress,
       case Auto:
       case Extension:
         // Unreachable
       case Auto:
       case Extension:
         // Unreachable
-        return _error->Error("Opening File %s in None, Auto or Extension should be already handled?!?", FileName.c_str());
+        return FileFdError("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())
       }
       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 FileFdError("Can't find a configured compressor %s for file %s", name.c_str(), FileName.c_str());
    }
 
    if (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 FileFdError("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)
    return Open(FileName, Mode, *compressor, Perms);
 }
 bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor, unsigned long const Perms)
@@ -908,9 +939,9 @@ bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Co
    Flags = AutoClose;
 
    if ((Mode & WriteOnly) != WriteOnly && (Mode & (Atomic | Create | Empty | Exclusive)) != 0)
    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());
+      return FileFdError("ReadOnly mode for %s doesn't accept additional flags!", FileName.c_str());
    if ((Mode & ReadWrite) == 0)
    if ((Mode & ReadWrite) == 0)
-      return _error->Error("No openmode provided in FileFd::Open for %s", FileName.c_str());
+      return FileFdError("No openmode provided in FileFd::Open for %s", FileName.c_str());
 
    if ((Mode & Atomic) == Atomic)
    {
 
    if ((Mode & Atomic) == Atomic)
    {
@@ -956,7 +987,7 @@ bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Co
         close (iFd);
         iFd = -1;
       }
         close (iFd);
         iFd = -1;
       }
-      return _error->Errno("open",_("Could not open file %s"), FileName.c_str());
+      return FileFdErrno("open",_("Could not open file %s"), FileName.c_str());
    }
 
    SetCloseExec(iFd,true);
    }
 
    SetCloseExec(iFd,true);
@@ -985,27 +1016,55 @@ bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compre
    case Xz: name = "xz"; break;
    case Auto:
    case Extension:
    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);
+      if (AutoClose == true && Fd != -1)
+        close(Fd);
+      return FileFdError("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())
    }
    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 (AutoClose == true && Fd != -1)
+        close(Fd);
+      return FileFdError("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, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose)
 {
    Close();
    Flags = (AutoClose) ? FileFd::AutoClose : 0;
    return OpenDescriptor(Fd, Mode, *compressor, AutoClose);
 }
 bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose)
 {
    Close();
    Flags = (AutoClose) ? FileFd::AutoClose : 0;
-   iFd = Fd;
+   if (AutoClose == false && (
+#ifdef HAVE_ZLIB
+       compressor.Name == "gzip" ||
+#endif
+#ifdef HAVE_BZ2
+       compressor.Name == "bzip2" ||
+#endif
+       false))
+   {
+      // Need to duplicate fd here or gzclose for cleanup will close the fd as well
+      iFd = dup(Fd);
+   }
+   else
+      iFd = Fd;
    this->FileName = "";
    this->FileName = "";
-   if (OpenInternDescriptor(Mode, compressor) == false)
+   if (Fd == -1 || OpenInternDescriptor(Mode, compressor) == false)
    {
    {
-      if (AutoClose)
+      if (iFd != -1 && (
+#ifdef HAVE_ZLIB
+       compressor.Name == "gzip" ||
+#endif
+#ifdef HAVE_BZ2
+       compressor.Name == "bzip2" ||
+#endif
+       AutoClose == true))
+      {
         close (iFd);
         close (iFd);
-      return _error->Errno("gzdopen",_("Could not open file descriptor %d"), Fd);
+        iFd = -1;
+      }
+      return FileFdError(_("Could not open file descriptor %d"), Fd);
    }
    return true;
 }
    }
    return true;
 }
@@ -1067,10 +1126,7 @@ bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::C
       ExecWait(d->compressor_pid, "FileFdCompressor", true);
 
    if ((Mode & ReadWrite) == ReadWrite)
       ExecWait(d->compressor_pid, "FileFdCompressor", true);
 
    if ((Mode & ReadWrite) == ReadWrite)
-   {
-      Flags |= Fail;
-      return _error->Error("ReadWrite mode is not supported for file %s", FileName.c_str());
-   }
+      return FileFdError("ReadWrite mode is not supported for file %s", FileName.c_str());
 
    bool const Comp = (Mode & WriteOnly) == WriteOnly;
    if (Comp == false)
 
    bool const Comp = (Mode & WriteOnly) == WriteOnly;
    if (Comp == false)
@@ -1093,10 +1149,7 @@ bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::C
    // Create a data pipe
    int Pipe[2] = {-1,-1};
    if (pipe(Pipe) != 0)
    // Create a data pipe
    int Pipe[2] = {-1,-1};
    if (pipe(Pipe) != 0)
-   {
-      Flags |= Fail;
-      return _error->Errno("pipe",_("Failed to create subprocess IPC"));
-   }
+      return FileFdErrno("pipe",_("Failed to create subprocess IPC"));
    for (int J = 0; J != 2; J++)
       SetCloseExec(Pipe[J],true);
 
    for (int J = 0; J != 2; J++)
       SetCloseExec(Pipe[J],true);
 
@@ -1158,8 +1211,6 @@ bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::C
       close(Pipe[0]);
    else
       close(Pipe[1]);
       close(Pipe[0]);
    else
       close(Pipe[1]);
-   if ((Comp == true || FileName.empty() == true) && d->compressed_fd != -1)
-      close(d->compressed_fd);
 
    return true;
 }
 
    return true;
 }
@@ -1171,6 +1222,10 @@ bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::C
 FileFd::~FileFd()
 {
    Close();
 FileFd::~FileFd()
 {
    Close();
+   if (d != NULL)
+      d->CloseDown(FileName);
+   delete d;
+   d = NULL;
 }
                                                                        /*}}}*/
 // FileFd::Read - Read a bit of the file                               /*{{{*/
 }
                                                                        /*}}}*/
 // FileFd::Read - Read a bit of the file                               /*{{{*/
@@ -1202,14 +1257,13 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual)
       {
         if (errno == EINTR)
            continue;
       {
         if (errno == EINTR)
            continue;
-        Flags |= Fail;
 #ifdef HAVE_ZLIB
         if (d != NULL && d->gz != NULL)
         {
            int err;
            char const * const errmsg = gzerror(d->gz, &err);
            if (err != Z_ERRNO)
 #ifdef HAVE_ZLIB
         if (d != NULL && d->gz != NULL)
         {
            int err;
            char const * const errmsg = gzerror(d->gz, &err);
            if (err != Z_ERRNO)
-              return _error->Error("gzread: %s (%d: %s)", _("Read error"), err, errmsg);
+              return FileFdError("gzread: %s (%d: %s)", _("Read error"), err, errmsg);
         }
 #endif
 #ifdef HAVE_BZ2
         }
 #endif
 #ifdef HAVE_BZ2
@@ -1218,10 +1272,10 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual)
            int err;
            char const * const errmsg = BZ2_bzerror(d->bz2, &err);
            if (err != BZ_IO_ERROR)
            int err;
            char const * const errmsg = BZ2_bzerror(d->bz2, &err);
            if (err != BZ_IO_ERROR)
-              return _error->Error("BZ2_bzread: %s (%d: %s)", _("Read error"), err, errmsg);
+              return FileFdError("BZ2_bzread: %s (%d: %s)", _("Read error"), err, errmsg);
         }
 #endif
         }
 #endif
-        return _error->Errno("read",_("Read error"));
+        return FileFdErrno("read",_("Read error"));
       }
       
       To = (char *)To + Res;
       }
       
       To = (char *)To + Res;
@@ -1242,9 +1296,8 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual)
       Flags |= HitEof;
       return true;
    }
       Flags |= HitEof;
       return true;
    }
-   
-   Flags |= Fail;
-   return _error->Error(_("read, still have %llu to read but none left"), Size);
+
+   return FileFdError(_("read, still have %llu to read but none left"), Size);
 }
                                                                        /*}}}*/
 // FileFd::ReadLine - Read a complete line from the file               /*{{{*/
 }
                                                                        /*}}}*/
 // FileFd::ReadLine - Read a complete line from the file               /*{{{*/
@@ -1300,14 +1353,13 @@ bool FileFd::Write(const void *From,unsigned long long Size)
         continue;
       if (Res < 0)
       {
         continue;
       if (Res < 0)
       {
-        Flags |= Fail;
 #ifdef HAVE_ZLIB
         if (d != NULL && d->gz != NULL)
         {
            int err;
            char const * const errmsg = gzerror(d->gz, &err);
            if (err != Z_ERRNO)
 #ifdef HAVE_ZLIB
         if (d != NULL && d->gz != NULL)
         {
            int err;
            char const * const errmsg = gzerror(d->gz, &err);
            if (err != Z_ERRNO)
-              return _error->Error("gzwrite: %s (%d: %s)", _("Write error"), err, errmsg);
+              return FileFdError("gzwrite: %s (%d: %s)", _("Write error"), err, errmsg);
         }
 #endif
 #ifdef HAVE_BZ2
         }
 #endif
 #ifdef HAVE_BZ2
@@ -1316,10 +1368,10 @@ bool FileFd::Write(const void *From,unsigned long long Size)
            int err;
            char const * const errmsg = BZ2_bzerror(d->bz2, &err);
            if (err != BZ_IO_ERROR)
            int err;
            char const * const errmsg = BZ2_bzerror(d->bz2, &err);
            if (err != BZ_IO_ERROR)
-              return _error->Error("BZ2_bzwrite: %s (%d: %s)", _("Write error"), err, errmsg);
+              return FileFdError("BZ2_bzwrite: %s (%d: %s)", _("Write error"), err, errmsg);
         }
 #endif
         }
 #endif
-        return _error->Errno("write",_("Write error"));
+        return FileFdErrno("write",_("Write error"));
       }
       
       From = (char *)From + Res;
       }
       
       From = (char *)From + Res;
@@ -1331,9 +1383,8 @@ bool FileFd::Write(const void *From,unsigned long long Size)
    
    if (Size == 0)
       return true;
    
    if (Size == 0)
       return true;
-   
-   Flags |= Fail;
-   return _error->Error(_("write, still have %llu to write but couldn't"), Size);
+
+   return FileFdError(_("write, still have %llu to write but couldn't"), Size);
 }
 bool FileFd::Write(int Fd, const void *From, unsigned long long Size)
 {
 }
 bool FileFd::Write(int Fd, const void *From, unsigned long long Size)
 {
@@ -1377,13 +1428,13 @@ bool FileFd::Seek(unsigned long long To)
         return Skip(To - seekpos);
 
       if ((d->openmode & ReadOnly) != ReadOnly)
         return Skip(To - seekpos);
 
       if ((d->openmode & ReadOnly) != ReadOnly)
-      {
-        Flags |= Fail;
-        return _error->Error("Reopen is only implemented for read-only files!");
-      }
+        return FileFdError("Reopen is only implemented for read-only files!");
 #ifdef HAVE_BZ2
 #ifdef HAVE_BZ2
-      if (d->bz2 != NULL)
-        BZ2_bzclose(d->bz2);
+     if (d->bz2 != NULL) 
+     {
+       BZ2_bzclose(d->bz2);
+       d->bz2 = NULL;
+     }
 #endif
       if (iFd != -1)
         close(iFd);
 #endif
       if (iFd != -1)
         close(iFd);
@@ -1397,18 +1448,12 @@ bool FileFd::Seek(unsigned long long To)
         if (d->compressed_fd > 0)
            if (lseek(d->compressed_fd, 0, SEEK_SET) != 0)
               iFd = d->compressed_fd;
         if (d->compressed_fd > 0)
            if (lseek(d->compressed_fd, 0, SEEK_SET) != 0)
               iFd = d->compressed_fd;
-        if (iFd <= 0)
-        {
-           Flags |= Fail;
-           return _error->Error("Reopen is not implemented for pipes opened with FileFd::OpenDescriptor()!");
-        }
+        if (iFd < 0)
+           return FileFdError("Reopen is not implemented for pipes opened with FileFd::OpenDescriptor()!");
       }
 
       if (OpenInternDescriptor(d->openmode, d->compressor) == false)
       }
 
       if (OpenInternDescriptor(d->openmode, d->compressor) == false)
-      {
-        Flags |= Fail;
-        return _error->Error("Seek on file %s because it couldn't be reopened", FileName.c_str());
-      }
+        return FileFdError("Seek on file %s because it couldn't be reopened", FileName.c_str());
 
       if (To != 0)
         return Skip(To);
 
       if (To != 0)
         return Skip(To);
@@ -1424,10 +1469,7 @@ bool FileFd::Seek(unsigned long long To)
 #endif
       res = lseek(iFd,To,SEEK_SET);
    if (res != (signed)To)
 #endif
       res = lseek(iFd,To,SEEK_SET);
    if (res != (signed)To)
-   {
-      Flags |= Fail;
-      return _error->Error("Unable to seek to %llu", To);
-   }
+      return FileFdError("Unable to seek to %llu", To);
 
    if (d != NULL)
       d->seekpos = To;
 
    if (d != NULL)
       d->seekpos = To;
@@ -1451,10 +1493,7 @@ bool FileFd::Skip(unsigned long long Over)
       {
         unsigned long long toread = std::min((unsigned long long) sizeof(buffer), Over);
         if (Read(buffer, toread) == false)
       {
         unsigned long long toread = std::min((unsigned long long) sizeof(buffer), Over);
         if (Read(buffer, toread) == false)
-        {
-           Flags |= Fail;
-           return _error->Error("Unable to seek ahead %llu",Over);
-        }
+           return FileFdError("Unable to seek ahead %llu",Over);
         Over -= toread;
       }
       return true;
         Over -= toread;
       }
       return true;
@@ -1468,10 +1507,7 @@ bool FileFd::Skip(unsigned long long Over)
 #endif
       res = lseek(iFd,Over,SEEK_CUR);
    if (res < 0)
 #endif
       res = lseek(iFd,Over,SEEK_CUR);
    if (res < 0)
-   {
-      Flags |= Fail;
-      return _error->Error("Unable to seek ahead %llu",Over);
-   }
+      return FileFdError("Unable to seek ahead %llu",Over);
    if (d != NULL)
       d->seekpos = res;
 
    if (d != NULL)
       d->seekpos = res;
 
@@ -1485,17 +1521,11 @@ bool FileFd::Truncate(unsigned long long To)
 {
 #if defined HAVE_ZLIB || defined HAVE_BZ2
    if (d != NULL && (d->gz != NULL || d->bz2 != NULL))
 {
 #if defined HAVE_ZLIB || defined HAVE_BZ2
    if (d != NULL && (d->gz != NULL || d->bz2 != NULL))
-   {
-      Flags |= Fail;
-      return _error->Error("Truncating compressed files is not implemented (%s)", FileName.c_str());
-   }
+      return FileFdError("Truncating compressed files is not implemented (%s)", FileName.c_str());
 #endif
    if (ftruncate(iFd,To) != 0)
 #endif
    if (ftruncate(iFd,To) != 0)
-   {
-      Flags |= Fail;
-      return _error->Error("Unable to truncate to %llu",To);
-   }
-   
+      return FileFdError("Unable to truncate to %llu",To);
+
    return true;
 }
                                                                        /*}}}*/
    return true;
 }
                                                                        /*}}}*/
@@ -1523,10 +1553,7 @@ unsigned long long FileFd::Tell()
 #endif
      Res = lseek(iFd,0,SEEK_CUR);
    if (Res == (off_t)-1)
 #endif
      Res = lseek(iFd,0,SEEK_CUR);
    if (Res == (off_t)-1)
-   {
-      Flags |= Fail;
-      _error->Errno("lseek","Failed to determine the current file position");
-   }
+      FileFdErrno("lseek","Failed to determine the current file position");
    if (d != NULL)
       d->seekpos = Res;
    return Res;
    if (d != NULL)
       d->seekpos = Res;
    return Res;
@@ -1539,10 +1566,7 @@ unsigned long long FileFd::FileSize()
 {
    struct stat Buf;
    if ((d == NULL || d->pipe == false) && fstat(iFd,&Buf) != 0)
 {
    struct stat Buf;
    if ((d == NULL || d->pipe == false) && fstat(iFd,&Buf) != 0)
-   {
-      Flags |= Fail;
-      return _error->Errno("fstat","Unable to determine the file size");
-   }
+      return FileFdErrno("fstat","Unable to determine the file size");
 
    // for compressor pipes st_size is undefined and at 'best' zero
    if ((d != NULL && d->pipe == true) || S_ISFIFO(Buf.st_mode))
 
    // for compressor pipes st_size is undefined and at 'best' zero
    if ((d != NULL && d->pipe == true) || S_ISFIFO(Buf.st_mode))
@@ -1552,10 +1576,7 @@ unsigned long long FileFd::FileSize()
       if (d != NULL)
         d->pipe = true;
       if (stat(FileName.c_str(), &Buf) != 0)
       if (d != NULL)
         d->pipe = true;
       if (stat(FileName.c_str(), &Buf) != 0)
-      {
-        Flags |= Fail;
-        return _error->Errno("stat","Unable to determine the file size");
-      }
+        return FileFdErrno("stat","Unable to determine the file size");
    }
 
    return Buf.st_size;
    }
 
    return Buf.st_size;
@@ -1580,7 +1601,11 @@ unsigned long long FileFd::Size()
       char ignore[1000];
       unsigned long long read = 0;
       do {
       char ignore[1000];
       unsigned long long read = 0;
       do {
-        Read(ignore, sizeof(ignore), &read);
+        if (Read(ignore, sizeof(ignore), &read) == false)
+        {
+           Seek(oldSeek);
+           return 0;
+        }
       } while(read != 0);
       size = Tell();
       Seek(oldSeek);
       } while(read != 0);
       size = Tell();
       Seek(oldSeek);
@@ -1598,14 +1623,14 @@ unsigned long long FileFd::Size()
        // FIXME: Size for gz-files is limited by 32bit… no largefile support
        if (lseek(iFd, -4, SEEK_END) < 0)
        {
        // FIXME: Size for gz-files is limited by 32bit… no largefile support
        if (lseek(iFd, -4, SEEK_END) < 0)
        {
-         Flags |= Fail;
-         return _error->Errno("lseek","Unable to seek to end of gzipped file");
+         FileFdErrno("lseek","Unable to seek to end of gzipped file");
+         return 0;
        }
        }
-       size = 0L;
+       size = 0;
        if (read(iFd, &size, 4) != 4)
        {
        if (read(iFd, &size, 4) != 4)
        {
-         Flags |= Fail;
-         return _error->Errno("read","Unable to read original size of gzipped file");
+         FileFdErrno("read","Unable to read original size of gzipped file");
+         return 0;
        }
 
 #ifdef WORDS_BIGENDIAN
        }
 
 #ifdef WORDS_BIGENDIAN
@@ -1617,8 +1642,8 @@ unsigned long long FileFd::Size()
 
        if (lseek(iFd, oldPos, SEEK_SET) < 0)
        {
 
        if (lseek(iFd, oldPos, SEEK_SET) < 0)
        {
-         Flags |= Fail;
-         return _error->Errno("lseek","Unable to seek in gzipped file");
+         FileFdErrno("lseek","Unable to seek in gzipped file");
+         return 0;
        }
 
        return size;
        }
 
        return size;
@@ -1636,8 +1661,7 @@ time_t FileFd::ModificationTime()
    struct stat Buf;
    if ((d == NULL || d->pipe == false) && fstat(iFd,&Buf) != 0)
    {
    struct stat Buf;
    if ((d == NULL || d->pipe == false) && fstat(iFd,&Buf) != 0)
    {
-      Flags |= Fail;
-      _error->Errno("fstat","Unable to determine the modification time of file %s", FileName.c_str());
+      FileFdErrno("fstat","Unable to determine the modification time of file %s", FileName.c_str());
       return 0;
    }
 
       return 0;
    }
 
@@ -1650,8 +1674,7 @@ time_t FileFd::ModificationTime()
         d->pipe = true;
       if (stat(FileName.c_str(), &Buf) != 0)
       {
         d->pipe = true;
       if (stat(FileName.c_str(), &Buf) != 0)
       {
-        Flags |= Fail;
-        _error->Errno("fstat","Unable to determine the modification time of file %s", FileName.c_str());
+        FileFdErrno("fstat","Unable to determine the modification time of file %s", FileName.c_str());
         return 0;
       }
    }
         return 0;
       }
    }
@@ -1670,24 +1693,18 @@ bool FileFd::Close()
    bool Res = true;
    if ((Flags & AutoClose) == AutoClose)
    {
    bool Res = true;
    if ((Flags & AutoClose) == AutoClose)
    {
-#ifdef HAVE_ZLIB
-      if (d != NULL && d->gz != NULL) {
-        int const e = gzclose(d->gz);
-        // gzdclose() on empty files always fails with "buffer error" here, ignore that
-        if (e != 0 && e != Z_BUF_ERROR)
-           Res &= _error->Errno("close",_("Problem closing the gzip file %s"), FileName.c_str());
-      } else
-#endif
-#ifdef HAVE_BZ2
-      if (d != NULL && d->bz2 != NULL)
-        BZ2_bzclose(d->bz2);
-      else
-#endif
-        if (iFd > 0 && close(iFd) != 0)
-           Res &= _error->Errno("close",_("Problem closing the file %s"), FileName.c_str());
+      if ((Flags & Compressed) != Compressed && iFd > 0 && close(iFd) != 0)
+        Res &= _error->Errno("close",_("Problem closing the file %s"), FileName.c_str());
+
+      if (d != NULL)
+      {
+        Res &= d->CloseDown(FileName);
+        delete d;
+        d = NULL;
+      }
    }
 
    }
 
-   if ((Flags & Replace) == Replace && iFd >= 0) {
+   if ((Flags & Replace) == Replace) {
       if (rename(TemporaryFileName.c_str(), FileName.c_str()) != 0)
         Res &= _error->Errno("rename",_("Problem renaming the file %s to %s"), TemporaryFileName.c_str(), FileName.c_str());
 
       if (rename(TemporaryFileName.c_str(), FileName.c_str()) != 0)
         Res &= _error->Errno("rename",_("Problem renaming the file %s to %s"), TemporaryFileName.c_str(), FileName.c_str());
 
@@ -1702,14 +1719,6 @@ bool FileFd::Close()
       if (unlink(FileName.c_str()) != 0)
         Res &= _error->WarningE("unlnk",_("Problem unlinking the file %s"), FileName.c_str());
 
       if (unlink(FileName.c_str()) != 0)
         Res &= _error->WarningE("unlnk",_("Problem unlinking the file %s"), FileName.c_str());
 
-   if (d != NULL)
-   {
-      if (d->compressor_pid > 0)
-        ExecWait(d->compressor_pid, "FileFdCompressor", true);
-      delete d;
-      d = NULL;
-   }
-
    if (Res == false)
       Flags |= Fail;
    return Res;
    if (Res == false)
       Flags |= Fail;
    return Res;
@@ -1720,15 +1729,71 @@ bool FileFd::Close()
 /* */
 bool FileFd::Sync()
 {
 /* */
 bool FileFd::Sync()
 {
-#ifdef _POSIX_SYNCHRONIZED_IO
    if (fsync(iFd) != 0)
    if (fsync(iFd) != 0)
+      return FileFdErrno("sync",_("Problem syncing the file"));
+   return true;
+}
+                                                                       /*}}}*/
+// FileFd::FileFdErrno - set Fail and call _error->Errno               *{{{*/
+bool FileFd::FileFdErrno(const char *Function, const char *Description,...)
+{
+   Flags |= Fail;
+   va_list args;
+   size_t msgSize = 400;
+   int const errsv = errno;
+   while (true)
    {
    {
-      Flags |= Fail;
-      return _error->Errno("sync",_("Problem syncing the file"));
+      va_start(args,Description);
+      if (_error->InsertErrno(GlobalError::ERROR, Function, Description, args, errsv, msgSize) == false)
+        break;
+      va_end(args);
    }
    }
-#endif
-   return true;
+   return false;
+}
+                                                                       /*}}}*/
+// FileFd::FileFdError - set Fail and call _error->Error               *{{{*/
+bool FileFd::FileFdError(const char *Description,...) {
+   Flags |= Fail;
+   va_list args;
+   size_t msgSize = 400;
+   while (true)
+   {
+      va_start(args,Description);
+      if (_error->Insert(GlobalError::ERROR, Description, args, msgSize) == false)
+        break;
+      va_end(args);
+   }
+   return false;
 }
                                                                        /*}}}*/
 
 gzFile FileFd::gzFd() { return (gzFile) d->gz; }
 }
                                                                        /*}}}*/
 
 gzFile FileFd::gzFd() { return (gzFile) d->gz; }
+
+
+// Glob - wrapper around "glob()"                                      /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+std::vector<std::string> Glob(std::string const &pattern, int flags)
+{
+   std::vector<std::string> result;
+   glob_t globbuf;
+   int glob_res, i;
+
+   glob_res = glob(pattern.c_str(),  flags, NULL, &globbuf);
+
+   if (glob_res != 0)
+   {
+      if(glob_res != GLOB_NOMATCH) {
+         _error->Errno("glob", "Problem with glob");
+         return result;
+      }
+   }
+
+   // append results
+   for(i=0;i<globbuf.gl_pathc;i++)
+      result.push_back(string(globbuf.gl_pathv[i]));
+
+   globfree(&globbuf);
+   return result;
+}
+                                                                       /*}}}*/