1 // -*- mode: cpp; mode: fold -*- 
   3 // $Id: fileutl.cc,v 1.42 2002/09/14 05:29:22 jgg Exp $ 
   4 /* ###################################################################### 
   8    CopyFile - Buffered copy of a single file 
   9    GetLock - dpkg compatible lock file manipulation (fcntl) 
  11    Most of this source is placed in the Public Domain, do with it what  
  13    It was originally written by Jason Gunthorpe <jgg@debian.org>. 
  14    FileFd gzip support added by Martin Pitt <martin.pitt@canonical.com> 
  16    The exception is RunScripts() it is under the GPLv2 
  18    ##################################################################### */ 
  20 // Include Files                                                        /*{{{*/ 
  23 #include <apt-pkg/fileutl.h> 
  24 #include <apt-pkg/strutl.h> 
  25 #include <apt-pkg/error.h> 
  26 #include <apt-pkg/sptr.h> 
  27 #include <apt-pkg/aptconfiguration.h> 
  28 #include <apt-pkg/configuration.h> 
  38 #include <sys/types.h> 
  54 #ifdef WORDS_BIGENDIAN 
  78         APT::Configuration::Compressor compressor
; 
  79         unsigned int openmode
; 
  80         unsigned long long seekpos
; 
  81         FileFdPrivate() : gz(NULL
), bz2(NULL
), 
  82                           compressed_fd(-1), compressor_pid(-1), pipe(false), 
  83                           openmode(0), seekpos(0) {}; 
  84         bool CloseDown(std::string 
const &FileName
) 
  89               int const e 
= gzclose(gz
); 
  91               // gzdclose() on empty files always fails with "buffer error" here, ignore that 
  92               if (e 
!= 0 && e 
!= Z_BUF_ERROR
) 
  93                  Res 
&= _error
->Errno("close",_("Problem closing the gzip file %s"), FileName
.c_str()); 
 102            if (compressor_pid 
> 0) 
 103               ExecWait(compressor_pid
, "FileFdCompressor", true); 
 108         ~FileFdPrivate() { CloseDown(""); } 
 111 // RunScripts - Run a set of scripts from a configuration subtree       /*{{{*/ 
 112 // --------------------------------------------------------------------- 
 114 bool RunScripts(const char *Cnf
) 
 116    Configuration::Item 
const *Opts 
= _config
->Tree(Cnf
); 
 117    if (Opts 
== 0 || Opts
->Child 
== 0) 
 121    // Fork for running the system calls 
 122    pid_t Child 
= ExecFork(); 
 127       if (_config
->FindDir("DPkg::Chroot-Directory","/") != "/")  
 129          std::cerr 
<< "Chrooting into "  
 130                    << _config
->FindDir("DPkg::Chroot-Directory")  
 132          if (chroot(_config
->FindDir("DPkg::Chroot-Directory","/").c_str()) != 0) 
 136       if (chdir("/tmp/") != 0) 
 139       unsigned int Count 
= 1; 
 140       for (; Opts 
!= 0; Opts 
= Opts
->Next
, Count
++) 
 142          if (Opts
->Value
.empty() == true) 
 145          if (system(Opts
->Value
.c_str()) != 0) 
 151    // Wait for the child 
 153    while (waitpid(Child
,&Status
,0) != Child
) 
 157       return _error
->Errno("waitpid","Couldn't wait for subprocess"); 
 160    // Restore sig int/quit 
 161    signal(SIGQUIT
,SIG_DFL
); 
 162    signal(SIGINT
,SIG_DFL
);    
 164    // Check for an error code. 
 165    if (WIFEXITED(Status
) == 0 || WEXITSTATUS(Status
) != 0) 
 167       unsigned int Count 
= WEXITSTATUS(Status
); 
 171          for (; Opts 
!= 0 && Count 
!= 1; Opts 
= Opts
->Next
, Count
--); 
 172          _error
->Error("Problem executing scripts %s '%s'",Cnf
,Opts
->Value
.c_str()); 
 175       return _error
->Error("Sub-process returned an error code"); 
 182 // CopyFile - Buffered copy of a file                                   /*{{{*/ 
 183 // --------------------------------------------------------------------- 
 184 /* The caller is expected to set things so that failure causes erasure */ 
 185 bool CopyFile(FileFd 
&From
,FileFd 
&To
) 
 187    if (From
.IsOpen() == false || To
.IsOpen() == false) 
 190    // Buffered copy between fds 
 191    SPtrArray
<unsigned char> Buf 
= new unsigned char[64000]; 
 192    unsigned long long Size 
= From
.Size(); 
 195       unsigned long long ToRead 
= Size
; 
 199       if (From
.Read(Buf
,ToRead
) == false ||  
 200           To
.Write(Buf
,ToRead
) == false) 
 209 // GetLock - Gets a lock file                                           /*{{{*/ 
 210 // --------------------------------------------------------------------- 
 211 /* This will create an empty file of the given name and lock it. Once this 
 212    is done all other calls to GetLock in any other process will fail with 
 213    -1. The return result is the fd of the file, the call should call 
 214    close at some time. */ 
 215 int GetLock(string File
,bool Errors
) 
 217    // GetLock() is used in aptitude on directories with public-write access 
 218    // Use O_NOFOLLOW here to prevent symlink traversal attacks 
 219    int FD 
= open(File
.c_str(),O_RDWR 
| O_CREAT 
| O_NOFOLLOW
,0640); 
 222       // Read only .. cant have locking problems there. 
 225          _error
->Warning(_("Not using locking for read only lock file %s"),File
.c_str()); 
 226          return dup(0);       // Need something for the caller to close 
 230          _error
->Errno("open",_("Could not open lock file %s"),File
.c_str()); 
 232       // Feh.. We do this to distinguish the lock vs open case.. 
 236    SetCloseExec(FD
,true); 
 238    // Aquire a write lock 
 241    fl
.l_whence 
= SEEK_SET
; 
 244    if (fcntl(FD
,F_SETLK
,&fl
) == -1) 
 248          _error
->Warning(_("Not using locking for nfs mounted lock file %s"),File
.c_str()); 
 249          return dup(0);       // Need something for the caller to close   
 252          _error
->Errno("open",_("Could not get lock %s"),File
.c_str()); 
 263 // FileExists - Check if a file exists                                  /*{{{*/ 
 264 // --------------------------------------------------------------------- 
 265 /* Beware: Directories are also files! */ 
 266 bool FileExists(string File
) 
 269    if (stat(File
.c_str(),&Buf
) != 0) 
 274 // RealFileExists - Check if a file exists and if it is really a file   /*{{{*/ 
 275 // --------------------------------------------------------------------- 
 277 bool RealFileExists(string File
) 
 280    if (stat(File
.c_str(),&Buf
) != 0) 
 282    return ((Buf
.st_mode 
& S_IFREG
) != 0); 
 285 // DirectoryExists - Check if a directory exists and is really one      /*{{{*/ 
 286 // --------------------------------------------------------------------- 
 288 bool DirectoryExists(string 
const &Path
) 
 291    if (stat(Path
.c_str(),&Buf
) != 0) 
 293    return ((Buf
.st_mode 
& S_IFDIR
) != 0); 
 296 // CreateDirectory - poor man's mkdir -p guarded by a parent directory  /*{{{*/ 
 297 // --------------------------------------------------------------------- 
 298 /* This method will create all directories needed for path in good old 
 299    mkdir -p style but refuses to do this if Parent is not a prefix of 
 300    this Path. Example: /var/cache/ and /var/cache/apt/archives are given, 
 301    so it will create apt/archives if /var/cache exists - on the other 
 302    hand if the parent is /var/lib the creation will fail as this path 
 303    is not a parent of the path to be generated. */ 
 304 bool CreateDirectory(string 
const &Parent
, string 
const &Path
) 
 306    if (Parent
.empty() == true || Path
.empty() == true) 
 309    if (DirectoryExists(Path
) == true) 
 312    if (DirectoryExists(Parent
) == false) 
 315    // we are not going to create directories "into the blue" 
 316    if (Path
.find(Parent
, 0) != 0) 
 319    vector
<string
> const dirs 
= VectorizeString(Path
.substr(Parent
.size()), '/'); 
 320    string progress 
= Parent
; 
 321    for (vector
<string
>::const_iterator d 
= dirs
.begin(); d 
!= dirs
.end(); ++d
) 
 323       if (d
->empty() == true) 
 326       progress
.append("/").append(*d
); 
 327       if (DirectoryExists(progress
) == true) 
 330       if (mkdir(progress
.c_str(), 0755) != 0) 
 336 // CreateAPTDirectoryIfNeeded - ensure that the given directory exists          /*{{{*/ 
 337 // --------------------------------------------------------------------- 
 338 /* a small wrapper around CreateDirectory to check if it exists and to 
 339    remove the trailing "/apt/" from the parent directory if needed */ 
 340 bool CreateAPTDirectoryIfNeeded(string 
const &Parent
, string 
const &Path
) 
 342    if (DirectoryExists(Path
) == true) 
 345    size_t const len 
= Parent
.size(); 
 346    if (len 
> 5 && Parent
.find("/apt/", len 
- 6, 5) == len 
- 5) 
 348       if (CreateDirectory(Parent
.substr(0,len
-5), Path
) == true) 
 351    else if (CreateDirectory(Parent
, Path
) == true) 
 357 // GetListOfFilesInDir - returns a vector of files in the given dir     /*{{{*/ 
 358 // --------------------------------------------------------------------- 
 359 /* If an extension is given only files with this extension are included 
 360    in the returned vector, otherwise every "normal" file is included. */ 
 361 std::vector
<string
> GetListOfFilesInDir(string 
const &Dir
, string 
const &Ext
, 
 362                                         bool const &SortList
, bool const &AllowNoExt
) 
 364    std::vector
<string
> ext
; 
 366    if (Ext
.empty() == false) 
 368    if (AllowNoExt 
== true && ext
.empty() == false) 
 370    return GetListOfFilesInDir(Dir
, ext
, SortList
); 
 372 std::vector
<string
> GetListOfFilesInDir(string 
const &Dir
, std::vector
<string
> const &Ext
, 
 373                                         bool const &SortList
) 
 375    // Attention debuggers: need to be set with the environment config file! 
 376    bool const Debug 
= _config
->FindB("Debug::GetListOfFilesInDir", false); 
 379       std::clog 
<< "Accept in " << Dir 
<< " only files with the following " << Ext
.size() << " extensions:" << std::endl
; 
 380       if (Ext
.empty() == true) 
 381          std::clog 
<< "\tNO extension" << std::endl
; 
 383          for (std::vector
<string
>::const_iterator e 
= Ext
.begin(); 
 385             std::clog 
<< '\t' << (e
->empty() == true ? "NO" : *e
) << " extension" << std::endl
; 
 388    std::vector
<string
> List
; 
 390    if (DirectoryExists(Dir
) == false) 
 392       _error
->Error(_("List of files can't be created as '%s' is not a directory"), Dir
.c_str()); 
 396    Configuration::MatchAgainstConfig 
SilentIgnore("Dir::Ignore-Files-Silently"); 
 397    DIR *D 
= opendir(Dir
.c_str()); 
 400       _error
->Errno("opendir",_("Unable to read %s"),Dir
.c_str()); 
 404    for (struct dirent 
*Ent 
= readdir(D
); Ent 
!= 0; Ent 
= readdir(D
))  
 406       // skip "hidden" files 
 407       if (Ent
->d_name
[0] == '.') 
 410       // Make sure it is a file and not something else 
 411       string 
const File 
= flCombine(Dir
,Ent
->d_name
); 
 412 #ifdef _DIRENT_HAVE_D_TYPE 
 413       if (Ent
->d_type 
!= DT_REG
) 
 416          if (RealFileExists(File
) == false) 
 418             // do not show ignoration warnings for directories 
 420 #ifdef _DIRENT_HAVE_D_TYPE 
 421                 Ent
->d_type 
== DT_DIR 
|| 
 423                 DirectoryExists(File
) == true) 
 425             if (SilentIgnore
.Match(Ent
->d_name
) == false) 
 426                _error
->Notice(_("Ignoring '%s' in directory '%s' as it is not a regular file"), Ent
->d_name
, Dir
.c_str()); 
 431       // check for accepted extension: 
 432       // no extension given -> periods are bad as hell! 
 433       // extensions given -> "" extension allows no extension 
 434       if (Ext
.empty() == false) 
 436          string d_ext 
= flExtension(Ent
->d_name
); 
 437          if (d_ext 
== Ent
->d_name
) // no extension 
 439             if (std::find(Ext
.begin(), Ext
.end(), "") == Ext
.end()) 
 442                   std::clog 
<< "Bad file: " << Ent
->d_name 
<< " → no extension" << std::endl
; 
 443                if (SilentIgnore
.Match(Ent
->d_name
) == false) 
 444                   _error
->Notice(_("Ignoring file '%s' in directory '%s' as it has no filename extension"), Ent
->d_name
, Dir
.c_str()); 
 448          else if (std::find(Ext
.begin(), Ext
.end(), d_ext
) == Ext
.end()) 
 451                std::clog 
<< "Bad file: " << Ent
->d_name 
<< " → bad extension »" << flExtension(Ent
->d_name
) << "«" << std::endl
; 
 452             if (SilentIgnore
.Match(Ent
->d_name
) == false) 
 453                _error
->Notice(_("Ignoring file '%s' in directory '%s' as it has an invalid filename extension"), Ent
->d_name
, Dir
.c_str()); 
 458       // Skip bad filenames ala run-parts 
 459       const char *C 
= Ent
->d_name
; 
 461          if (isalpha(*C
) == 0 && isdigit(*C
) == 0 
 462              && *C 
!= '_' && *C 
!= '-') { 
 463             // no required extension -> dot is a bad character 
 464             if (*C 
== '.' && Ext
.empty() == false) 
 469       // we don't reach the end of the name -> bad character included 
 473             std::clog 
<< "Bad file: " << Ent
->d_name 
<< " → bad character »" 
 474                << *C 
<< "« in filename (period allowed: " << (Ext
.empty() ? "no" : "yes") << ")" << std::endl
; 
 478       // skip filenames which end with a period. These are never valid 
 482             std::clog 
<< "Bad file: " << Ent
->d_name 
<< " → Period as last character" << std::endl
; 
 487          std::clog 
<< "Accept file: " << Ent
->d_name 
<< " in " << Dir 
<< std::endl
; 
 488       List
.push_back(File
); 
 492    if (SortList 
== true) 
 493       std::sort(List
.begin(),List
.end()); 
 496 std::vector
<string
> GetListOfFilesInDir(string 
const &Dir
, bool SortList
) 
 498    bool const Debug 
= _config
->FindB("Debug::GetListOfFilesInDir", false); 
 500       std::clog 
<< "Accept in " << Dir 
<< " all regular files" << std::endl
; 
 502    std::vector
<string
> List
; 
 504    if (DirectoryExists(Dir
) == false) 
 506       _error
->Error(_("List of files can't be created as '%s' is not a directory"), Dir
.c_str()); 
 510    DIR *D 
= opendir(Dir
.c_str()); 
 513       _error
->Errno("opendir",_("Unable to read %s"),Dir
.c_str()); 
 517    for (struct dirent 
*Ent 
= readdir(D
); Ent 
!= 0; Ent 
= readdir(D
))  
 519       // skip "hidden" files 
 520       if (Ent
->d_name
[0] == '.') 
 523       // Make sure it is a file and not something else 
 524       string 
const File 
= flCombine(Dir
,Ent
->d_name
); 
 525 #ifdef _DIRENT_HAVE_D_TYPE 
 526       if (Ent
->d_type 
!= DT_REG
) 
 529          if (RealFileExists(File
) == false) 
 532                std::clog 
<< "Bad file: " << Ent
->d_name 
<< " → it is not a real file" << std::endl
; 
 537       // Skip bad filenames ala run-parts 
 538       const char *C 
= Ent
->d_name
; 
 540          if (isalpha(*C
) == 0 && isdigit(*C
) == 0 
 541              && *C 
!= '_' && *C 
!= '-' && *C 
!= '.') 
 544       // we don't reach the end of the name -> bad character included 
 548             std::clog 
<< "Bad file: " << Ent
->d_name 
<< " → bad character »" << *C 
<< "« in filename" << std::endl
; 
 552       // skip filenames which end with a period. These are never valid 
 556             std::clog 
<< "Bad file: " << Ent
->d_name 
<< " → Period as last character" << std::endl
; 
 561          std::clog 
<< "Accept file: " << Ent
->d_name 
<< " in " << Dir 
<< std::endl
; 
 562       List
.push_back(File
); 
 566    if (SortList 
== true) 
 567       std::sort(List
.begin(),List
.end()); 
 571 // SafeGetCWD - This is a safer getcwd that returns a dynamic string    /*{{{*/ 
 572 // --------------------------------------------------------------------- 
 573 /* We return / on failure. */ 
 576    // Stash the current dir. 
 579    if (getcwd(S
,sizeof(S
)-2) == 0) 
 581    unsigned int Len 
= strlen(S
); 
 587 // GetModificationTime - Get the mtime of the given file or -1 on error /*{{{*/ 
 588 // --------------------------------------------------------------------- 
 589 /* We return / on failure. */ 
 590 time_t GetModificationTime(string 
const &Path
) 
 593    if (stat(Path
.c_str(), &St
) < 0) 
 598 // flNotDir - Strip the directory from the filename                     /*{{{*/ 
 599 // --------------------------------------------------------------------- 
 601 string 
flNotDir(string File
) 
 603    string::size_type Res 
= File
.rfind('/'); 
 604    if (Res 
== string::npos
) 
 607    return string(File
,Res
,Res 
- File
.length()); 
 610 // flNotFile - Strip the file from the directory name                   /*{{{*/ 
 611 // --------------------------------------------------------------------- 
 612 /* Result ends in a / */ 
 613 string 
flNotFile(string File
) 
 615    string::size_type Res 
= File
.rfind('/'); 
 616    if (Res 
== string::npos
) 
 619    return string(File
,0,Res
); 
 622 // flExtension - Return the extension for the file                      /*{{{*/ 
 623 // --------------------------------------------------------------------- 
 625 string 
flExtension(string File
) 
 627    string::size_type Res 
= File
.rfind('.'); 
 628    if (Res 
== string::npos
) 
 631    return string(File
,Res
,Res 
- File
.length()); 
 634 // flNoLink - If file is a symlink then deref it                        /*{{{*/ 
 635 // --------------------------------------------------------------------- 
 636 /* If the name is not a link then the returned path is the input. */ 
 637 string 
flNoLink(string File
) 
 640    if (lstat(File
.c_str(),&St
) != 0 || S_ISLNK(St
.st_mode
) == 0) 
 642    if (stat(File
.c_str(),&St
) != 0) 
 645    /* Loop resolving the link. There is no need to limit the number of  
 646       loops because the stat call above ensures that the symlink is not  
 654       if ((Res 
= readlink(NFile
.c_str(),Buffer
,sizeof(Buffer
))) <= 0 ||  
 655           (unsigned)Res 
>= sizeof(Buffer
)) 
 658       // Append or replace the previous path 
 660       if (Buffer
[0] == '/') 
 663          NFile 
= flNotFile(NFile
) + Buffer
; 
 665       // See if we are done 
 666       if (lstat(NFile
.c_str(),&St
) != 0) 
 668       if (S_ISLNK(St
.st_mode
) == 0) 
 673 // flCombine - Combine a file and a directory                           /*{{{*/ 
 674 // --------------------------------------------------------------------- 
 675 /* If the file is an absolute path then it is just returned, otherwise 
 676    the directory is pre-pended to it. */ 
 677 string 
flCombine(string Dir
,string File
) 
 679    if (File
.empty() == true) 
 682    if (File
[0] == '/' || Dir
.empty() == true) 
 684    if (File
.length() >= 2 && File
[0] == '.' && File
[1] == '/') 
 686    if (Dir
[Dir
.length()-1] == '/') 
 688    return Dir 
+ '/' + File
; 
 691 // SetCloseExec - Set the close on exec flag                            /*{{{*/ 
 692 // --------------------------------------------------------------------- 
 694 void SetCloseExec(int Fd
,bool Close
) 
 696    if (fcntl(Fd
,F_SETFD
,(Close 
== false)?0:FD_CLOEXEC
) != 0) 
 698       cerr 
<< "FATAL -> Could not set close on exec " << strerror(errno
) << endl
; 
 703 // SetNonBlock - Set the nonblocking flag                               /*{{{*/ 
 704 // --------------------------------------------------------------------- 
 706 void SetNonBlock(int Fd
,bool Block
) 
 708    int Flags 
= fcntl(Fd
,F_GETFL
) & (~O_NONBLOCK
); 
 709    if (fcntl(Fd
,F_SETFL
,Flags 
| ((Block 
== false)?0:O_NONBLOCK
)) != 0) 
 711       cerr 
<< "FATAL -> Could not set non-blocking flag " << strerror(errno
) << endl
; 
 716 // WaitFd - Wait for a FD to become readable                            /*{{{*/ 
 717 // --------------------------------------------------------------------- 
 718 /* This waits for a FD to become readable using select. It is useful for 
 719    applications making use of non-blocking sockets. The timeout is  
 721 bool WaitFd(int Fd
,bool write
,unsigned long timeout
) 
 734          Res 
= select(Fd
+1,0,&Set
,0,(timeout 
!= 0?&tv
:0)); 
 736       while (Res 
< 0 && errno 
== EINTR
); 
 746          Res 
= select(Fd
+1,&Set
,0,0,(timeout 
!= 0?&tv
:0)); 
 748       while (Res 
< 0 && errno 
== EINTR
); 
 757 // ExecFork - Magical fork that sanitizes the context before execing    /*{{{*/ 
 758 // --------------------------------------------------------------------- 
 759 /* This is used if you want to cleanse the environment for the forked  
 760    child, it fixes up the important signals and nukes all of the fds, 
 761    otherwise acts like normal fork. */ 
 764    // Fork off the process 
 765    pid_t Process 
= fork(); 
 768       cerr 
<< "FATAL -> Failed to fork." << endl
; 
 772    // Spawn the subprocess 
 776       signal(SIGPIPE
,SIG_DFL
); 
 777       signal(SIGQUIT
,SIG_DFL
); 
 778       signal(SIGINT
,SIG_DFL
); 
 779       signal(SIGWINCH
,SIG_DFL
); 
 780       signal(SIGCONT
,SIG_DFL
); 
 781       signal(SIGTSTP
,SIG_DFL
); 
 784       Configuration::Item 
const *Opts 
= _config
->Tree("APT::Keep-Fds"); 
 785       if (Opts 
!= 0 && Opts
->Child 
!= 0) 
 788          for (; Opts 
!= 0; Opts 
= Opts
->Next
) 
 790             if (Opts
->Value
.empty() == true) 
 792             int fd 
= atoi(Opts
->Value
.c_str()); 
 797       // Close all of our FDs - just in case 
 798       for (int K 
= 3; K 
!= 40; K
++) 
 800          if(KeepFDs
.find(K
) == KeepFDs
.end()) 
 801             fcntl(K
,F_SETFD
,FD_CLOEXEC
); 
 808 // ExecWait - Fancy waitpid                                             /*{{{*/ 
 809 // --------------------------------------------------------------------- 
 810 /* Waits for the given sub process. If Reap is set then no errors are  
 811    generated. Otherwise a failed subprocess will generate a proper descriptive 
 813 bool ExecWait(pid_t Pid
,const char *Name
,bool Reap
) 
 818    // Wait and collect the error code 
 820    while (waitpid(Pid
,&Status
,0) != Pid
) 
 828       return _error
->Error(_("Waited for %s but it wasn't there"),Name
); 
 832    // Check for an error code. 
 833    if (WIFEXITED(Status
) == 0 || WEXITSTATUS(Status
) != 0) 
 837       if (WIFSIGNALED(Status
) != 0) 
 839          if( WTERMSIG(Status
) == SIGSEGV
) 
 840             return _error
->Error(_("Sub-process %s received a segmentation fault."),Name
); 
 842             return _error
->Error(_("Sub-process %s received signal %u."),Name
, WTERMSIG(Status
)); 
 845       if (WIFEXITED(Status
) != 0) 
 846          return _error
->Error(_("Sub-process %s returned an error code (%u)"),Name
,WEXITSTATUS(Status
)); 
 848       return _error
->Error(_("Sub-process %s exited unexpectedly"),Name
); 
 855 // FileFd::Open - Open a file                                           /*{{{*/ 
 856 // --------------------------------------------------------------------- 
 857 /* The most commonly used open mode combinations are given with Mode */ 
 858 bool FileFd::Open(string FileName
,unsigned int const Mode
,CompressMode Compress
, unsigned long const Perms
) 
 860    if (Mode 
== ReadOnlyGzip
) 
 861       return Open(FileName
, ReadOnly
, Gzip
, Perms
); 
 863    if (Compress 
== Auto 
&& (Mode 
& WriteOnly
) == WriteOnly
) 
 864       return FileFdError("Autodetection on %s only works in ReadOnly openmode!", FileName
.c_str()); 
 866    std::vector
<APT::Configuration::Compressor
> const compressors 
= APT::Configuration::getCompressors(); 
 867    std::vector
<APT::Configuration::Compressor
>::const_iterator compressor 
= compressors
.begin(); 
 868    if (Compress 
== Auto
) 
 870       for (; compressor 
!= compressors
.end(); ++compressor
) 
 872          std::string file 
= std::string(FileName
).append(compressor
->Extension
); 
 873          if (FileExists(file
) == false) 
 879    else if (Compress 
== Extension
) 
 881       std::string::size_type 
const found 
= FileName
.find_last_of('.'); 
 883       if (found 
!= std::string::npos
) 
 885          ext 
= FileName
.substr(found
); 
 886          if (ext 
== ".new" || ext 
== ".bak") 
 888             std::string::size_type 
const found2 
= FileName
.find_last_of('.', found 
- 1); 
 889             if (found2 
!= std::string::npos
) 
 890                ext 
= FileName
.substr(found2
, found 
- found2
); 
 895       for (; compressor 
!= compressors
.end(); ++compressor
) 
 896          if (ext 
== compressor
->Extension
) 
 898       // no matching extension - assume uncompressed (imagine files like 'example.org_Packages') 
 899       if (compressor 
== compressors
.end()) 
 900          for (compressor 
= compressors
.begin(); compressor 
!= compressors
.end(); ++compressor
) 
 901             if (compressor
->Name 
== ".") 
 909       case None
: name 
= "."; break; 
 910       case Gzip
: name 
= "gzip"; break; 
 911       case Bzip2
: name 
= "bzip2"; break; 
 912       case Lzma
: name 
= "lzma"; break; 
 913       case Xz
: name 
= "xz"; break; 
 917          return FileFdError("Opening File %s in None, Auto or Extension should be already handled?!?", FileName
.c_str()); 
 919       for (; compressor 
!= compressors
.end(); ++compressor
) 
 920          if (compressor
->Name 
== name
) 
 922       if (compressor 
== compressors
.end()) 
 923          return FileFdError("Can't find a configured compressor %s for file %s", name
.c_str(), FileName
.c_str()); 
 926    if (compressor 
== compressors
.end()) 
 927       return FileFdError("Can't find a match for specified compressor mode for file %s", FileName
.c_str()); 
 928    return Open(FileName
, Mode
, *compressor
, Perms
); 
 930 bool FileFd::Open(string FileName
,unsigned int const Mode
,APT::Configuration::Compressor 
const &compressor
, unsigned long const Perms
) 
 935    if ((Mode 
& WriteOnly
) != WriteOnly 
&& (Mode 
& (Atomic 
| Create 
| Empty 
| Exclusive
)) != 0) 
 936       return FileFdError("ReadOnly mode for %s doesn't accept additional flags!", FileName
.c_str()); 
 937    if ((Mode 
& ReadWrite
) == 0) 
 938       return FileFdError("No openmode provided in FileFd::Open for %s", FileName
.c_str()); 
 940    if ((Mode 
& Atomic
) == Atomic
) 
 943       char *name 
= strdup((FileName 
+ ".XXXXXX").c_str()); 
 944       TemporaryFileName 
= string(mktemp(name
)); 
 947    else if ((Mode 
& (Exclusive 
| Create
)) == (Exclusive 
| Create
)) 
 949       // for atomic, this will be done by rename in Close() 
 950       unlink(FileName
.c_str()); 
 952    if ((Mode 
& Empty
) == Empty
) 
 955       if (lstat(FileName
.c_str(),&Buf
) == 0 && S_ISLNK(Buf
.st_mode
)) 
 956          unlink(FileName
.c_str()); 
 960    #define if_FLAGGED_SET(FLAG, MODE) if ((Mode & FLAG) == FLAG) fileflags |= MODE 
 961    if_FLAGGED_SET(ReadWrite
, O_RDWR
); 
 962    else if_FLAGGED_SET(ReadOnly
, O_RDONLY
); 
 963    else if_FLAGGED_SET(WriteOnly
, O_WRONLY
); 
 965    if_FLAGGED_SET(Create
, O_CREAT
); 
 966    if_FLAGGED_SET(Empty
, O_TRUNC
); 
 967    if_FLAGGED_SET(Exclusive
, O_EXCL
); 
 968    else if_FLAGGED_SET(Atomic
, O_EXCL
); 
 969    #undef if_FLAGGED_SET 
 971    if (TemporaryFileName
.empty() == false) 
 972       iFd 
= open(TemporaryFileName
.c_str(), fileflags
, Perms
); 
 974       iFd 
= open(FileName
.c_str(), fileflags
, Perms
); 
 976    this->FileName 
= FileName
; 
 977    if (iFd 
== -1 || OpenInternDescriptor(Mode
, compressor
) == false) 
 984       return FileFdErrno("open",_("Could not open file %s"), FileName
.c_str()); 
 987    SetCloseExec(iFd
,true); 
 991 // FileFd::OpenDescriptor - Open a filedescriptor                       /*{{{*/ 
 992 // --------------------------------------------------------------------- 
 994 bool FileFd::OpenDescriptor(int Fd
, unsigned int const Mode
, CompressMode Compress
, bool AutoClose
) 
 996    std::vector
<APT::Configuration::Compressor
> const compressors 
= APT::Configuration::getCompressors(); 
 997    std::vector
<APT::Configuration::Compressor
>::const_iterator compressor 
= compressors
.begin(); 
1000    // compat with the old API 
1001    if (Mode 
== ReadOnlyGzip 
&& Compress 
== None
) 
1006    case None
: name 
= "."; break; 
1007    case Gzip
: name 
= "gzip"; break; 
1008    case Bzip2
: name 
= "bzip2"; break; 
1009    case Lzma
: name 
= "lzma"; break; 
1010    case Xz
: name 
= "xz"; break; 
1013       if (AutoClose 
== true && Fd 
!= -1) 
1015       return FileFdError("Opening Fd %d in Auto or Extension compression mode is not supported", Fd
); 
1017    for (; compressor 
!= compressors
.end(); ++compressor
) 
1018       if (compressor
->Name 
== name
) 
1020    if (compressor 
== compressors
.end()) 
1022       if (AutoClose 
== true && Fd 
!= -1) 
1024       return FileFdError("Can't find a configured compressor %s for file %s", name
.c_str(), FileName
.c_str()); 
1026    return OpenDescriptor(Fd
, Mode
, *compressor
, AutoClose
); 
1028 bool FileFd::OpenDescriptor(int Fd
, unsigned int const Mode
, APT::Configuration::Compressor 
const &compressor
, bool AutoClose
) 
1031    Flags 
= (AutoClose
) ? FileFd::AutoClose 
: 0; 
1032    if (AutoClose 
== false && ( 
1034         compressor
.Name 
== "gzip" || 
1037         compressor
.Name 
== "bzip2" || 
1041       // Need to duplicate fd here or gzclose for cleanup will close the fd as well 
1046    this->FileName 
= ""; 
1047    if (Fd 
== -1 || OpenInternDescriptor(Mode
, compressor
) == false) 
1051         compressor
.Name 
== "gzip" || 
1054         compressor
.Name 
== "bzip2" || 
1061       return FileFdError(_("Could not open file descriptor %d"), Fd
); 
1065 bool FileFd::OpenInternDescriptor(unsigned int const Mode
, APT::Configuration::Compressor 
const &compressor
) 
1067    if (compressor
.Name 
== "." || compressor
.Binary
.empty() == true) 
1072       d 
= new FileFdPrivate(); 
1074       d
->compressor 
= compressor
; 
1078    if (compressor
.Name 
== "gzip") 
1085       if ((Mode 
& ReadWrite
) == ReadWrite
) 
1086          d
->gz 
= gzdopen(iFd
, "r+"); 
1087       else if ((Mode 
& WriteOnly
) == WriteOnly
) 
1088          d
->gz 
= gzdopen(iFd
, "w"); 
1090          d
->gz 
= gzdopen(iFd
, "r"); 
1093       Flags 
|= Compressed
; 
1098    if (compressor
.Name 
== "bzip2") 
1102          BZ2_bzclose(d
->bz2
); 
1105       if ((Mode 
& ReadWrite
) == ReadWrite
) 
1106          d
->bz2 
= BZ2_bzdopen(iFd
, "r+"); 
1107       else if ((Mode 
& WriteOnly
) == WriteOnly
) 
1108          d
->bz2 
= BZ2_bzdopen(iFd
, "w"); 
1110          d
->bz2 
= BZ2_bzdopen(iFd
, "r"); 
1113       Flags 
|= Compressed
; 
1118    // collect zombies here in case we reopen 
1119    if (d
->compressor_pid 
> 0) 
1120       ExecWait(d
->compressor_pid
, "FileFdCompressor", true); 
1122    if ((Mode 
& ReadWrite
) == ReadWrite
) 
1123       return FileFdError("ReadWrite mode is not supported for file %s", FileName
.c_str()); 
1125    bool const Comp 
= (Mode 
& WriteOnly
) == WriteOnly
; 
1128       // Handle 'decompression' of empty files 
1131       if (Buf
.st_size 
== 0 && S_ISFIFO(Buf
.st_mode
) == false) 
1134       // We don't need the file open - instead let the compressor open it 
1135       // as he properly knows better how to efficiently read from 'his' file 
1136       if (FileName
.empty() == false) 
1143    // Create a data pipe 
1144    int Pipe
[2] = {-1,-1}; 
1145    if (pipe(Pipe
) != 0) 
1146       return FileFdErrno("pipe",_("Failed to create subprocess IPC")); 
1147    for (int J 
= 0; J 
!= 2; J
++) 
1148       SetCloseExec(Pipe
[J
],true); 
1150    d
->compressed_fd 
= iFd
; 
1159    d
->compressor_pid 
= ExecFork(); 
1160    if (d
->compressor_pid 
== 0) 
1164          dup2(d
->compressed_fd
,STDOUT_FILENO
); 
1165          dup2(Pipe
[0],STDIN_FILENO
); 
1169          if (FileName
.empty() == true) 
1170             dup2(d
->compressed_fd
,STDIN_FILENO
); 
1171          dup2(Pipe
[1],STDOUT_FILENO
); 
1173       int const nullfd 
= open("/dev/null", O_WRONLY
); 
1176          dup2(nullfd
,STDERR_FILENO
); 
1180       SetCloseExec(STDOUT_FILENO
,false); 
1181       SetCloseExec(STDIN_FILENO
,false); 
1183       std::vector
<char const*> Args
; 
1184       Args
.push_back(compressor
.Binary
.c_str()); 
1185       std::vector
<std::string
> const * const addArgs 
= 
1186                 (Comp 
== true) ? &(compressor
.CompressArgs
) : &(compressor
.UncompressArgs
); 
1187       for (std::vector
<std::string
>::const_iterator a 
= addArgs
->begin(); 
1188            a 
!= addArgs
->end(); ++a
) 
1189          Args
.push_back(a
->c_str()); 
1190       if (Comp 
== false && FileName
.empty() == false) 
1192          Args
.push_back("--stdout"); 
1193          if (TemporaryFileName
.empty() == false) 
1194             Args
.push_back(TemporaryFileName
.c_str()); 
1196             Args
.push_back(FileName
.c_str()); 
1198       Args
.push_back(NULL
); 
1200       execvp(Args
[0],(char **)&Args
[0]); 
1201       cerr 
<< _("Failed to exec compressor ") << Args
[0] << endl
; 
1212 // FileFd::~File - Closes the file                                      /*{{{*/ 
1213 // --------------------------------------------------------------------- 
1214 /* If the proper modes are selected then we close the Fd and possibly 
1215    unlink the file on error. */ 
1221       d
->CloseDown(FileName
); 
1227 // FileFd::Read - Read a bit of the file                                /*{{{*/ 
1228 // --------------------------------------------------------------------- 
1229 /* We are carefull to handle interruption by a signal while reading  
1231 bool FileFd::Read(void *To
,unsigned long long Size
,unsigned long long *Actual
) 
1237    *((char *)To
) = '\0'; 
1241       if (d 
!= NULL 
&& d
->gz 
!= NULL
) 
1242          Res 
= gzread(d
->gz
,To
,Size
); 
1246       if (d 
!= NULL 
&& d
->bz2 
!= NULL
) 
1247          Res 
= BZ2_bzread(d
->bz2
,To
,Size
); 
1250          Res 
= read(iFd
,To
,Size
); 
1257          if (d 
!= NULL 
&& d
->gz 
!= NULL
) 
1260             char const * const errmsg 
= gzerror(d
->gz
, &err
); 
1262                return FileFdError("gzread: %s (%d: %s)", _("Read error"), err
, errmsg
); 
1266          if (d 
!= NULL 
&& d
->bz2 
!= NULL
) 
1269             char const * const errmsg 
= BZ2_bzerror(d
->bz2
, &err
); 
1270             if (err 
!= BZ_IO_ERROR
) 
1271                return FileFdError("BZ2_bzread: %s (%d: %s)", _("Read error"), err
, errmsg
); 
1274          return FileFdErrno("read",_("Read error")); 
1277       To 
= (char *)To 
+ Res
; 
1284    while (Res 
> 0 && Size 
> 0); 
1296    return FileFdError(_("read, still have %llu to read but none left"), Size
); 
1299 // FileFd::ReadLine - Read a complete line from the file                /*{{{*/ 
1300 // --------------------------------------------------------------------- 
1301 /* Beware: This method can be quiet slow for big buffers on UNcompressed 
1302    files because of the naive implementation! */ 
1303 char* FileFd::ReadLine(char *To
, unsigned long long const Size
) 
1307    if (d 
!= NULL 
&& d
->gz 
!= NULL
) 
1308       return gzgets(d
->gz
, To
, Size
); 
1311    unsigned long long read 
= 0; 
1312    while ((Size 
- 1) != read
) 
1314       unsigned long long done 
= 0; 
1315       if (Read(To 
+ read
, 1, &done
) == false) 
1319       if (To
[read
++] == '\n') 
1328 // FileFd::Write - Write to the file                                    /*{{{*/ 
1329 // --------------------------------------------------------------------- 
1331 bool FileFd::Write(const void *From
,unsigned long long Size
) 
1338       if (d 
!= NULL 
&& d
->gz 
!= NULL
) 
1339          Res 
= gzwrite(d
->gz
,From
,Size
); 
1343       if (d 
!= NULL 
&& d
->bz2 
!= NULL
) 
1344          Res 
= BZ2_bzwrite(d
->bz2
,(void*)From
,Size
); 
1347          Res 
= write(iFd
,From
,Size
); 
1348       if (Res 
< 0 && errno 
== EINTR
) 
1353          if (d 
!= NULL 
&& d
->gz 
!= NULL
) 
1356             char const * const errmsg 
= gzerror(d
->gz
, &err
); 
1358                return FileFdError("gzwrite: %s (%d: %s)", _("Write error"), err
, errmsg
); 
1362          if (d 
!= NULL 
&& d
->bz2 
!= NULL
) 
1365             char const * const errmsg 
= BZ2_bzerror(d
->bz2
, &err
); 
1366             if (err 
!= BZ_IO_ERROR
) 
1367                return FileFdError("BZ2_bzwrite: %s (%d: %s)", _("Write error"), err
, errmsg
); 
1370          return FileFdErrno("write",_("Write error")); 
1373       From 
= (char *)From 
+ Res
; 
1378    while (Res 
> 0 && Size 
> 0); 
1383    return FileFdError(_("write, still have %llu to write but couldn't"), Size
); 
1385 bool FileFd::Write(int Fd
, const void *From
, unsigned long long Size
) 
1391       Res 
= write(Fd
,From
,Size
); 
1392       if (Res 
< 0 && errno 
== EINTR
) 
1395          return _error
->Errno("write",_("Write error")); 
1397       From 
= (char *)From 
+ Res
; 
1400    while (Res 
> 0 && Size 
> 0); 
1405    return _error
->Error(_("write, still have %llu to write but couldn't"), Size
); 
1408 // FileFd::Seek - Seek in the file                                      /*{{{*/ 
1409 // --------------------------------------------------------------------- 
1411 bool FileFd::Seek(unsigned long long To
) 
1413    if (d 
!= NULL 
&& (d
->pipe 
== true 
1419       // Our poor man seeking in pipes is costly, so try to avoid it 
1420       unsigned long long seekpos 
= Tell(); 
1423       else if (seekpos 
< To
) 
1424          return Skip(To 
- seekpos
); 
1426       if ((d
->openmode 
& ReadOnly
) != ReadOnly
) 
1427          return FileFdError("Reopen is only implemented for read-only files!"); 
1431         BZ2_bzclose(d
->bz2
); 
1438       if (TemporaryFileName
.empty() == false) 
1439          iFd 
= open(TemporaryFileName
.c_str(), O_RDONLY
); 
1440       else if (FileName
.empty() == false) 
1441          iFd 
= open(FileName
.c_str(), O_RDONLY
); 
1444          if (d
->compressed_fd 
> 0) 
1445             if (lseek(d
->compressed_fd
, 0, SEEK_SET
) != 0) 
1446                iFd 
= d
->compressed_fd
; 
1448             return FileFdError("Reopen is not implemented for pipes opened with FileFd::OpenDescriptor()!"); 
1451       if (OpenInternDescriptor(d
->openmode
, d
->compressor
) == false) 
1452          return FileFdError("Seek on file %s because it couldn't be reopened", FileName
.c_str()); 
1462    if (d 
!= NULL 
&& d
->gz
) 
1463       res 
= gzseek(d
->gz
,To
,SEEK_SET
); 
1466       res 
= lseek(iFd
,To
,SEEK_SET
); 
1467    if (res 
!= (signed)To
) 
1468       return FileFdError("Unable to seek to %llu", To
); 
1475 // FileFd::Skip - Seek in the file                                      /*{{{*/ 
1476 // --------------------------------------------------------------------- 
1478 bool FileFd::Skip(unsigned long long Over
) 
1480    if (d 
!= NULL 
&& (d
->pipe 
== true 
1490          unsigned long long toread 
= std::min((unsigned long long) sizeof(buffer
), Over
); 
1491          if (Read(buffer
, toread
) == false) 
1492             return FileFdError("Unable to seek ahead %llu",Over
); 
1500    if (d 
!= NULL 
&& d
->gz 
!= NULL
) 
1501       res 
= gzseek(d
->gz
,Over
,SEEK_CUR
); 
1504       res 
= lseek(iFd
,Over
,SEEK_CUR
); 
1506       return FileFdError("Unable to seek ahead %llu",Over
); 
1513 // FileFd::Truncate - Truncate the file                                 /*{{{*/ 
1514 // --------------------------------------------------------------------- 
1516 bool FileFd::Truncate(unsigned long long To
) 
1518 #if defined HAVE_ZLIB || defined HAVE_BZ2 
1519    if (d 
!= NULL 
&& (d
->gz 
!= NULL 
|| d
->bz2 
!= NULL
)) 
1520       return FileFdError("Truncating compressed files is not implemented (%s)", FileName
.c_str()); 
1522    if (ftruncate(iFd
,To
) != 0) 
1523       return FileFdError("Unable to truncate to %llu",To
); 
1528 // FileFd::Tell - Current seek position                                 /*{{{*/ 
1529 // --------------------------------------------------------------------- 
1531 unsigned long long FileFd::Tell() 
1533    // In theory, we could just return seekpos here always instead of 
1534    // seeking around, but not all users of FileFd use always Seek() and co 
1535    // so d->seekpos isn't always true and we can just use it as a hint if 
1536    // we have nothing else, but not always as an authority… 
1537    if (d 
!= NULL 
&& (d
->pipe 
== true 
1546    if (d 
!= NULL 
&& d
->gz 
!= NULL
) 
1547      Res 
= gztell(d
->gz
); 
1550      Res 
= lseek(iFd
,0,SEEK_CUR
); 
1551    if (Res 
== (off_t
)-1) 
1552       FileFdErrno("lseek","Failed to determine the current file position"); 
1558 // FileFd::FileSize - Return the size of the file                       /*{{{*/ 
1559 // --------------------------------------------------------------------- 
1561 unsigned long long FileFd::FileSize() 
1564    if ((d 
== NULL 
|| d
->pipe 
== false) && fstat(iFd
,&Buf
) != 0) 
1565       return FileFdErrno("fstat","Unable to determine the file size"); 
1567    // for compressor pipes st_size is undefined and at 'best' zero 
1568    if ((d 
!= NULL 
&& d
->pipe 
== true) || S_ISFIFO(Buf
.st_mode
)) 
1570       // we set it here, too, as we get the info here for free 
1571       // in theory the Open-methods should take care of it already 
1574       if (stat(FileName
.c_str(), &Buf
) != 0) 
1575          return FileFdErrno("stat","Unable to determine the file size"); 
1581 // FileFd::Size - Return the size of the content in the file            /*{{{*/ 
1582 // --------------------------------------------------------------------- 
1584 unsigned long long FileFd::Size() 
1586    unsigned long long size 
= FileSize(); 
1588    // for compressor pipes st_size is undefined and at 'best' zero, 
1589    // so we 'read' the content and 'seek' back - see there 
1590    if (d 
!= NULL 
&& (d
->pipe 
== true 
1592                         || (d
->bz2 
&& size 
> 0) 
1596       unsigned long long const oldSeek 
= Tell(); 
1598       unsigned long long read 
= 0; 
1600          Read(ignore
, sizeof(ignore
), &read
); 
1606    // only check gzsize if we are actually a gzip file, just checking for 
1607    // "gz" is not sufficient as uncompressed files could be opened with 
1608    // gzopen in "direct" mode as well 
1609    else if (d 
!= NULL 
&& d
->gz 
&& !gzdirect(d
->gz
) && size 
> 0) 
1611        off_t 
const oldPos 
= lseek(iFd
,0,SEEK_CUR
); 
1612        /* unfortunately zlib.h doesn't provide a gzsize(), so we have to do 
1613         * this ourselves; the original (uncompressed) file size is the last 32 
1614         * bits of the file */ 
1615        // FIXME: Size for gz-files is limited by 32bit… no largefile support 
1616        if (lseek(iFd
, -4, SEEK_END
) < 0) 
1617           return FileFdErrno("lseek","Unable to seek to end of gzipped file"); 
1619        if (read(iFd
, &size
, 4) != 4) 
1620           return FileFdErrno("read","Unable to read original size of gzipped file"); 
1622 #ifdef WORDS_BIGENDIAN 
1623        uint32_t tmp_size 
= size
; 
1624        uint8_t const * const p 
= (uint8_t const * const) &tmp_size
; 
1625        tmp_size 
= (p
[3] << 24) | (p
[2] << 16) | (p
[1] << 8) | p
[0]; 
1629        if (lseek(iFd
, oldPos
, SEEK_SET
) < 0) 
1630           return FileFdErrno("lseek","Unable to seek in gzipped file"); 
1639 // FileFd::ModificationTime - Return the time of last touch             /*{{{*/ 
1640 // --------------------------------------------------------------------- 
1642 time_t FileFd::ModificationTime() 
1645    if ((d 
== NULL 
|| d
->pipe 
== false) && fstat(iFd
,&Buf
) != 0) 
1647       FileFdErrno("fstat","Unable to determine the modification time of file %s", FileName
.c_str()); 
1651    // for compressor pipes st_size is undefined and at 'best' zero 
1652    if ((d 
!= NULL 
&& d
->pipe 
== true) || S_ISFIFO(Buf
.st_mode
)) 
1654       // we set it here, too, as we get the info here for free 
1655       // in theory the Open-methods should take care of it already 
1658       if (stat(FileName
.c_str(), &Buf
) != 0) 
1660          FileFdErrno("fstat","Unable to determine the modification time of file %s", FileName
.c_str()); 
1665    return Buf
.st_mtime
; 
1668 // FileFd::Close - Close the file if the close flag is set              /*{{{*/ 
1669 // --------------------------------------------------------------------- 
1671 bool FileFd::Close() 
1677    if ((Flags 
& AutoClose
) == AutoClose
) 
1679       if ((Flags 
& Compressed
) != Compressed 
&& iFd 
> 0 && close(iFd
) != 0) 
1680          Res 
&= _error
->Errno("close",_("Problem closing the file %s"), FileName
.c_str()); 
1684          Res 
&= d
->CloseDown(FileName
); 
1690    if ((Flags 
& Replace
) == Replace
) { 
1691       if (rename(TemporaryFileName
.c_str(), FileName
.c_str()) != 0) 
1692          Res 
&= _error
->Errno("rename",_("Problem renaming the file %s to %s"), TemporaryFileName
.c_str(), FileName
.c_str()); 
1694       FileName 
= TemporaryFileName
; // for the unlink() below. 
1695       TemporaryFileName
.clear(); 
1700    if ((Flags 
& Fail
) == Fail 
&& (Flags 
& DelOnFail
) == DelOnFail 
&& 
1701        FileName
.empty() == false) 
1702       if (unlink(FileName
.c_str()) != 0) 
1703          Res 
&= _error
->WarningE("unlnk",_("Problem unlinking the file %s"), FileName
.c_str()); 
1710 // FileFd::Sync - Sync the file                                         /*{{{*/ 
1711 // --------------------------------------------------------------------- 
1715    if (fsync(iFd
) != 0) 
1716       return FileFdErrno("sync",_("Problem syncing the file")); 
1720 // FileFd::FileFdErrno - set Fail and call _error->Errno                *{{{*/ 
1721 bool FileFd::FileFdErrno(const char *Function
, const char *Description
,...) 
1725    size_t msgSize 
= 400; 
1726    int const errsv 
= errno
; 
1729       va_start(args
,Description
); 
1730       if (_error
->InsertErrno(GlobalError::ERROR
, Function
, Description
, args
, errsv
, msgSize
) == false) 
1737 // FileFd::FileFdError - set Fail and call _error->Error                *{{{*/ 
1738 bool FileFd::FileFdError(const char *Description
,...) { 
1741    size_t msgSize 
= 400; 
1744       va_start(args
,Description
); 
1745       if (_error
->Insert(GlobalError::ERROR
, Description
, args
, msgSize
) == false) 
1753 gzFile 
FileFd::gzFd() { return (gzFile
) d
->gz
; }