]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/indexcopy.cc
fix another hickup in the changelog
[apt.git] / apt-pkg / indexcopy.cc
index 31c577705ebbb1ebe0e7dabf7efc856f5c527e6a..84f9fd420c5dde38118436e03a10174bbea02bae 100644 (file)
@@ -10,7 +10,7 @@
    ##################################################################### */
                                                                        /*}}}*/
 // Include Files                                                       /*{{{*/
-#include "indexcopy.h"
+#include<config.h>
 
 #include <apt-pkg/error.h>
 #include <apt-pkg/progress.h>
@@ -21,7 +21,6 @@
 #include <apt-pkg/indexrecords.h>
 #include <apt-pkg/md5.h>
 #include <apt-pkg/cdrom.h>
-#include <apti18n.h>
 
 #include <iostream>
 #include <sstream>
 #include <sys/types.h>
 #include <fcntl.h>
 #include <stdio.h>
+#include <stdlib.h>
+
+#include "indexcopy.h"
+#include <apti18n.h>
                                                                        /*}}}*/
 
 using namespace std;
 
-
-
+// DecompressFile - wrapper for decompressing gzip/bzip2/xz compressed files   /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DecompressFile(string Filename, int *fd, off_t *FileSize)
+{
+    string CompressProg;
+    string CompressProgFind;
+    FileFd From;
+    struct stat Buf;
+    *fd = -1;        
+
+    if (stat((Filename + ".gz").c_str(), &Buf) == 0)
+    {
+        CompressProg = "gzip";
+        CompressProgFind = "Dir::bin::gzip";
+        From.Open(Filename + ".gz",FileFd::ReadOnly);
+    }
+    else if (stat((Filename + ".bz2").c_str(), &Buf) == 0)
+    {
+        CompressProg = "bzip2";
+        CompressProgFind = "Dir::bin::bzip2";
+        From.Open(Filename + ".bz2",FileFd::ReadOnly);
+    }
+    else if (stat((Filename + ".xz").c_str(), &Buf) == 0)
+    {
+        CompressProg = "xz";
+        CompressProgFind = "Dir::bin::xz";
+        From.Open(Filename + ".xz",FileFd::ReadOnly);
+    }
+    else
+    {
+        return _error->Errno("decompressor", "Unable to parse file");
+    }
+
+    if (_error->PendingError() == true)
+        return -1;
+        
+    *FileSize = Buf.st_size;
+            
+    // Get a temp file
+    FILE *tmp = tmpfile();
+    if (tmp == 0)
+        return _error->Errno("tmpfile","Unable to create a tmp file");
+    *fd = dup(fileno(tmp));
+    fclose(tmp);
+        
+    // Fork decompressor
+    pid_t Process = fork();
+    if (Process < 0)
+        return _error->Errno("fork","Couldn't fork to run decompressor");
+        
+    // The child
+    if (Process == 0)
+    {      
+        dup2(From.Fd(),STDIN_FILENO);
+        dup2(*fd,STDOUT_FILENO);
+        SetCloseExec(STDIN_FILENO,false);
+        SetCloseExec(STDOUT_FILENO,false);
+           
+        const char *Args[3];
+        string Tmp =  _config->Find(CompressProgFind, CompressProg);
+        Args[0] = Tmp.c_str();
+        Args[1] = "-d";
+        Args[2] = 0;
+        if(execvp(Args[0],(char **)Args))
+            return(_error->Errno("decompressor","decompress failed"));
+        /* Should never get here */
+        exit(100);
+    }
+
+    // Wait for decompress to finish
+    if (ExecWait(Process,CompressProg.c_str(),false) == false)
+        return false;
+    
+    return true;
+}
+                                                                       /*}}}*/
 // IndexCopy::CopyPackages - Copy the package files from the CD                /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -43,7 +121,7 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
                             pkgCdromStatus *log)
 {
    OpProgress *Progress = NULL;
-   if (List.size() == 0)
+   if (List.empty() == true)
       return true;
    
    if(log) 
@@ -53,25 +131,27 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
    bool Debug = _config->FindB("Debug::aptcdrom",false);
    
    // Prepare the progress indicator
-   unsigned long TotalSize = 0;
-   for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+   off_t TotalSize = 0;
+   for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
    {
       struct stat Buf;
       if (stat(string(*I + GetFileName()).c_str(),&Buf) != 0 &&
-         stat(string(*I + GetFileName() + ".gz").c_str(),&Buf) != 0)
+            stat(string(*I + GetFileName() + ".gz").c_str(),&Buf) != 0 &&
+            stat(string(*I + GetFileName() + ".xz").c_str(),&Buf) != 0 &&
+            stat(string(*I + GetFileName() + ".bz2").c_str(),&Buf) != 0)
         return _error->Errno("stat","Stat failed for %s",
                              string(*I + GetFileName()).c_str());
       TotalSize += Buf.st_size;
    }   
 
-   unsigned long CurrentSize = 0;
+   off_t CurrentSize = 0;
    unsigned int NotFound = 0;
    unsigned int WrongSize = 0;
    unsigned int Packages = 0;
-   for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+   for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
    {      
       string OrigPath = string(*I,CDROM.length());
-      unsigned long FileSize = 0;
+      off_t FileSize = 0;
       
       // Open the package file
       FileFd Pkg;
@@ -82,46 +162,14 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
       }      
       else
       {
-        FileFd From(*I + GetFileName() + ".gz",FileFd::ReadOnly);
-        if (_error->PendingError() == true)
-           return false;
-        FileSize = From.Size();
-        
-        // Get a temp file
-        FILE *tmp = tmpfile();
-        if (tmp == 0)
-           return _error->Errno("tmpfile","Unable to create a tmp file");
-        Pkg.Fd(dup(fileno(tmp)));
-        fclose(tmp);
-        
-        // Fork gzip
-        pid_t Process = fork();
-        if (Process < 0)
-           return _error->Errno("fork","Couldn't fork gzip");
-        
-        // The child
-        if (Process == 0)
-        {          
-           dup2(From.Fd(),STDIN_FILENO);
-           dup2(Pkg.Fd(),STDOUT_FILENO);
-           SetCloseExec(STDIN_FILENO,false);
-           SetCloseExec(STDOUT_FILENO,false);
-           
-           const char *Args[3];
-           string Tmp =  _config->Find("Dir::bin::gzip","gzip");
-           Args[0] = Tmp.c_str();
-           Args[1] = "-d";
-           Args[2] = 0;
-           execvp(Args[0],(char **)Args);
-           exit(100);
-        }
-        
-        // Wait for gzip to finish
-        if (ExecWait(Process,_config->Find("Dir::bin::gzip","gzip").c_str(),false) == false)
-           return _error->Error("gzip failed, perhaps the disk is full.");
-        
+            int fd;
+            if (!DecompressFile(string(*I + GetFileName()), &fd, &FileSize))
+                return _error->Errno("decompress","Decompress failed for %s",
+                                     string(*I + GetFileName()).c_str());                
+            Pkg.Fd(dup(fd));
         Pkg.Seek(0);
       }
+
       pkgTagFile Parser(&Pkg);
       if (_error->PendingError() == true)
         return false;
@@ -164,7 +212,7 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
         if(Progress)
            Progress->Progress(Parser.Offset());
         string File;
-        unsigned long Size;
+        unsigned long long Size;
         if (GetFile(File,Size) == false)
         {
            fclose(TargetFl);
@@ -219,7 +267,7 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
            }       
                                            
            // Size match
-           if ((unsigned)Buf.st_size != Size)
+           if ((unsigned long long)Buf.st_size != Size)
            {
               if (Debug == true)
                  clog << "Wrong Size: " << File << endl;
@@ -453,7 +501,7 @@ bool IndexCopy::GrabFirst(string Path,string &To,unsigned int Depth)
 // PackageCopy::GetFile - Get the file information from the section    /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-bool PackageCopy::GetFile(string &File,unsigned long &Size)
+bool PackageCopy::GetFile(string &File,unsigned long long &Size)
 {
    File = Section->FindS("Filename");
    Size = Section->FindI("Size");
@@ -479,7 +527,7 @@ bool PackageCopy::RewriteEntry(FILE *Target,string File)
 // SourceCopy::GetFile - Get the file information from the section     /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-bool SourceCopy::GetFile(string &File,unsigned long &Size)
+bool SourceCopy::GetFile(string &File,unsigned long long &Size)
 {
    string Files = Section->FindS("Files");
    if (Files.empty() == true)
@@ -502,7 +550,7 @@ bool SourceCopy::GetFile(string &File,unsigned long &Size)
       return _error->Error("Error parsing file record");
    
    // Parse the size and append the directory
-   Size = atoi(sSize.c_str());
+   Size = strtoull(sSize.c_str(), NULL, 10);
    File = Base + File;
    return true;
 }
@@ -583,13 +631,13 @@ bool SigVerify::CopyMetaIndex(string CDROM, string CDName,                /*{{{*/
 bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,        /*{{{*/
                              vector<string> PkgList,vector<string> SrcList)
 {
-   if (SigList.size() == 0)
+   if (SigList.empty() == true)
       return true;
 
    bool Debug = _config->FindB("Debug::aptcdrom",false);
 
    // Read all Release files
-   for (vector<string>::iterator I = SigList.begin(); I != SigList.end(); I++)
+   for (vector<string>::iterator I = SigList.begin(); I != SigList.end(); ++I)
    { 
       if(Debug)
         cout << "Signature verify for: " << *I << endl;
@@ -633,7 +681,7 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
       // go over the Indexfiles and see if they verify
       // if so, remove them from our copy of the lists
       vector<string> keys = MetaIndex->MetaKeys();
-      for (vector<string>::iterator I = keys.begin(); I != keys.end(); I++)
+      for (vector<string>::iterator I = keys.begin(); I != keys.end(); ++I)
       { 
         if(!Verify(prefix,*I, MetaIndex)) {
            // something went wrong, don't copy the Release.gpg
@@ -776,7 +824,7 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name,   /*{{{*/
                                vector<string> &List, pkgCdromStatus *log)
 {
    OpProgress *Progress = NULL;
-   if (List.size() == 0)
+   if (List.empty() == true)
       return true;
    
    if(log) 
@@ -785,25 +833,28 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/
    bool Debug = _config->FindB("Debug::aptcdrom",false);
    
    // Prepare the progress indicator
-   unsigned long TotalSize = 0;
-   for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+   off_t TotalSize = 0;
+   for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
    {
       struct stat Buf;
+      
       if (stat(string(*I).c_str(),&Buf) != 0 &&
-         stat(string(*I + ".gz").c_str(),&Buf) != 0)
+          stat(string(*I + ".gz").c_str(),&Buf) != 0 &&
+          stat(string(*I + ".bz2").c_str(),&Buf) != 0 &&
+          stat(string(*I + ".xz").c_str(),&Buf) != 0)
         return _error->Errno("stat","Stat failed for %s",
                              string(*I).c_str());
       TotalSize += Buf.st_size;
    }   
 
-   unsigned long CurrentSize = 0;
+   off_t CurrentSize = 0;
    unsigned int NotFound = 0;
    unsigned int WrongSize = 0;
    unsigned int Packages = 0;
-   for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+   for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
    {      
       string OrigPath = string(*I,CDROM.length());
-      unsigned long FileSize = 0;
+      off_t FileSize = 0;
       
       // Open the package file
       FileFd Pkg;
@@ -814,44 +865,10 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/
       }      
       else
       {
-        FileFd From(*I + ".gz",FileFd::ReadOnly);
-        if (_error->PendingError() == true)
-           return false;
-        FileSize = From.Size();
-        
-        // Get a temp file
-        FILE *tmp = tmpfile();
-        if (tmp == 0)
-           return _error->Errno("tmpfile","Unable to create a tmp file");
-        Pkg.Fd(dup(fileno(tmp)));
-        fclose(tmp);
-        
-        // Fork gzip
-        pid_t Process = fork();
-        if (Process < 0)
-           return _error->Errno("fork","Couldn't fork gzip");
-        
-        // The child
-        if (Process == 0)
-        {          
-           dup2(From.Fd(),STDIN_FILENO);
-           dup2(Pkg.Fd(),STDOUT_FILENO);
-           SetCloseExec(STDIN_FILENO,false);
-           SetCloseExec(STDOUT_FILENO,false);
-           
-           const char *Args[3];
-           string Tmp =  _config->Find("Dir::bin::gzip","gzip");
-           Args[0] = Tmp.c_str();
-           Args[1] = "-d";
-           Args[2] = 0;
-           execvp(Args[0],(char **)Args);
-           exit(100);
-        }
-        
-        // Wait for gzip to finish
-        if (ExecWait(Process,_config->Find("Dir::bin::gzip","gzip").c_str(),false) == false)
-           return _error->Error("gzip failed, perhaps the disk is full.");
-        
+           int fd;
+           if (!DecompressFile(*I, &fd, &FileSize))
+               return _error->Errno("decompress","Decompress failed for %s", (*I).c_str());
+           Pkg.Fd(dup(fd));
         Pkg.Seek(0);
       }
       pkgTagFile Parser(&Pkg);
@@ -885,7 +902,6 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name,   /*{{{*/
       this->Section = &Section;
       string Prefix;
       unsigned long Hits = 0;
-      unsigned long Chop = 0;
       while (Parser.Step(Section) == true)
       {
         if(Progress)
@@ -903,7 +919,7 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name,   /*{{{*/
       fclose(TargetFl);
 
       if (Debug == true)
-        cout << " Processed by using Prefix '" << Prefix << "' and chop " << Chop << endl;
+        cout << " Processed by using Prefix '" << Prefix << "' and chop " << endl;
         
       if (_config->FindB("APT::CDROM::NoAct",false) == false)
       {