1 // -*- mode: cpp; mode: fold -*- 
   3 // $Id: gzip.cc,v 1.17.2.1 2004/01/16 18:58:50 mdz Exp $ 
   4 /* ###################################################################### 
   6    GZip method - Take a file URI in and decompress it into the target  
   9    ##################################################################### */ 
  11 // Include Files                                                        /*{{{*/ 
  14 #include <apt-pkg/fileutl.h> 
  15 #include <apt-pkg/error.h> 
  16 #include <apt-pkg/acquire-method.h> 
  17 #include <apt-pkg/strutl.h> 
  18 #include <apt-pkg/hashes.h> 
  30 class GzipMethod 
: public pkgAcqMethod
 
  32    virtual bool Fetch(FetchItem 
*Itm
); 
  36    GzipMethod() : pkgAcqMethod("1.1",SingleInstance 
| SendConfig
) {}; 
  40 // GzipMethod::Fetch - Decompress the passed URI                        /*{{{*/ 
  41 // --------------------------------------------------------------------- 
  43 bool GzipMethod::Fetch(FetchItem 
*Itm
) 
  46    std::string Path 
= Get
.Host 
+ Get
.Path
; // To account for relative paths 
  49    Res
.Filename 
= Itm
->DestFile
; 
  52    std::vector
<APT::Configuration::Compressor
> const compressors 
= APT::Configuration::getCompressors(); 
  53    std::vector
<APT::Configuration::Compressor
>::const_iterator compressor 
= compressors
.begin(); 
  54    for (; compressor 
!= compressors
.end(); ++compressor
) 
  55       if (compressor
->Name 
== Prog
) 
  57    if (compressor 
== compressors
.end()) 
  58       return _error
->Error("Extraction of file %s requires unknown compressor %s", Path
.c_str(), Prog
); 
  60    // Open the source and destination files 
  62    From
.Open(Path
, FileFd::ReadOnly
, *compressor
); 
  64    if(From
.FileSize() == 0) 
  65       return _error
->Error(_("Empty files can't be valid archives")); 
  67    FileFd 
To(Itm
->DestFile
,FileFd::WriteAtomic
);    
  69    if (_error
->PendingError() == true) 
  72    // Read data from source, generate checksums and write 
  77       unsigned char Buffer
[4*1024]; 
  78       unsigned long long Count 
= 0; 
  80       if (!From
.Read(Buffer
,sizeof(Buffer
),&Count
)) 
  88       Hash
.Add(Buffer
,Count
); 
  89       if (To
.Write(Buffer
,Count
) == false) 
  97    Res
.Size 
= To
.FileSize(); 
 103    // Transfer the modification times 
 105    if (stat(Path
.c_str(),&Buf
) != 0) 
 106       return _error
->Errno("stat",_("Failed to stat")); 
 108    struct timeval times
[2]; 
 109    times
[0].tv_sec 
= Buf
.st_atime
; 
 110    Res
.LastModified 
= times
[1].tv_sec 
= Buf
.st_mtime
; 
 111    times
[0].tv_usec 
= times
[1].tv_usec 
= 0; 
 112    if (utimes(Itm
->DestFile
.c_str(), times
) != 0) 
 113       return _error
->Errno("utimes",_("Failed to set modification time")); 
 115    // Return a Done response 
 116    Res
.TakeHashes(Hash
); 
 123 int main(int argc
, char *argv
[]) 
 125    setlocale(LC_ALL
, ""); 
 127    Prog 
= strrchr(argv
[0],'/');