* apt-pkg/cdrom.cc:
[ntk/apt.git] / apt-pkg / cdrom.cc
index 0ad1c69..699f66f 100644 (file)
@@ -1,5 +1,6 @@
 /*
  */
+#include<config.h>
 
 #include<apt-pkg/init.h>
 #include<apt-pkg/error.h>
@@ -7,11 +8,11 @@
 #include<apt-pkg/strutl.h>
 #include<apt-pkg/cdrom.h>
 #include<apt-pkg/aptconfiguration.h>
+#include<apt-pkg/configuration.h>
+#include<apt-pkg/fileutl.h>
 
 #include<sstream>
 #include<fstream>
-#include<config.h>
-#include<apti18n.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <dirent.h>
@@ -22,6 +23,8 @@
 
 #include "indexcopy.h"
 
+#include<apti18n.h>
+
 using namespace std;
 
 // FindPackages - Find the package files on the CDROM                  /*{{{*/
@@ -55,66 +58,91 @@ bool pkgCdrom::FindPackages(string CD,
       return _error->Errno("chdir","Unable to change to %s",CD.c_str());
 
    // Look for a .disk subdirectory
-   struct stat Buf;
-   if (stat(".disk",&Buf) == 0)
+   if (DirectoryExists(".disk") == true)
    {
       if (InfoDir.empty() == true)
         InfoDir = CD + ".disk/";
    }
 
    // Don't look into directories that have been marked to ingore.
-   if (stat(".aptignr",&Buf) == 0)
+   if (RealFileExists(".aptignr") == true)
       return true;
 
-
    /* Check _first_ for a signature file as apt-cdrom assumes that all files
       under a Packages/Source file are in control of that file and stops 
       the scanning
    */
-   if (stat("Release.gpg",&Buf) == 0)
+   if (RealFileExists("Release.gpg") == true || RealFileExists("InRelease") == true)
    {
       SigList.push_back(CD);
    }
+
    /* Aha! We found some package files. We assume that everything under 
       this dir is controlled by those package files so we don't look down
       anymore */
-   if (stat("Packages",&Buf) == 0 || stat("Packages.gz",&Buf) == 0)
+   std::vector<APT::Configuration::Compressor> const compressor = APT::Configuration::getCompressors();
+   for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
+       c != compressor.end(); ++c)
    {
+      if (RealFileExists(std::string("Packages").append(c->Extension).c_str()) == false)
+        continue;
+
+      if (_config->FindB("Debug::aptcdrom",false) == true)
+        std::clog << "Found Packages in " << CD << std::endl;
       List.push_back(CD);
-      
+
       // Continue down if thorough is given
       if (_config->FindB("APT::CDROM::Thorough",false) == false)
         return true;
+      break;
    }
-   if (stat("Sources.gz",&Buf) == 0 || stat("Sources",&Buf) == 0)
+   for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
+       c != compressor.end(); ++c)
    {
+      if (RealFileExists(std::string("Sources").append(c->Extension).c_str()) == false)
+        continue;
+
+      if (_config->FindB("Debug::aptcdrom",false) == true)
+        std::clog << "Found Sources in " << CD << std::endl;
       SList.push_back(CD);
-      
+
       // Continue down if thorough is given
       if (_config->FindB("APT::CDROM::Thorough",false) == false)
         return true;
+      break;
    }
 
-   // see if we find translatin indexes
-   if (stat("i18n",&Buf) == 0)
+   // see if we find translation indices
+   if (DirectoryExists("i18n") == true)
    {
       D = opendir("i18n");
       for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D))
       {
-        if(strstr(Dir->d_name,"Translation") != NULL) 
+        if(strncmp(Dir->d_name, "Translation-", strlen("Translation-")) != 0)
+           continue;
+        string file = Dir->d_name;
+        for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
+             c != compressor.end(); ++c)
         {
-           if (_config->FindB("Debug::aptcdrom",false) == true)
-              std::clog << "found translations: " << Dir->d_name << "\n";
-           string file = Dir->d_name;
-           if(file.substr(file.size()-3,file.size()) == ".gz")
-              file = file.substr(0,file.size()-3);
-           TransList.push_back(CD+"i18n/"+ file);
+           string fileext = flExtension(file);
+           if (file == fileext)
+              fileext.clear();
+           else if (fileext.empty() == false)
+              fileext = "." + fileext;
+
+           if (c->Extension == fileext)
+           {
+              if (_config->FindB("Debug::aptcdrom",false) == true)
+                 std::clog << "Found translation " << Dir->d_name << " in " << CD << "i18n/" << std::endl;
+              file.erase(file.size() - fileext.size());
+              TransList.push_back(CD + "i18n/" + file);
+              break;
+           }
         }
       }
       closedir(D);
    }
 
-   
    D = opendir(".");
    if (D == 0)
       return _error->Errno("opendir","Unable to read %s",CD.c_str());
@@ -249,30 +277,43 @@ bool pkgCdrom::DropBinaryArch(vector<string> &List)
 /* Here we go and stat every file that we found and strip dup inodes. */
 bool pkgCdrom::DropRepeats(vector<string> &List,const char *Name)
 {
+   bool couldFindAllFiles = true;
    // Get a list of all the inodes
    ino_t *Inodes = new ino_t[List.size()];
-   for (unsigned int I = 0; I != List.size(); I++)
+   for (unsigned int I = 0; I != List.size(); ++I)
    {
       struct stat Buf;
-      if (stat((List[I] + Name).c_str(),&Buf) != 0 &&
-         stat((List[I] + Name + ".gz").c_str(),&Buf) != 0)
-        _error->Errno("stat","Failed to stat %s%s",List[I].c_str(),
-                      Name);
-      Inodes[I] = Buf.st_ino;
-   }
-   
-   if (_error->PendingError() == true) {
-      delete[] Inodes;
-      return false;
+      bool found = false;
+
+      std::vector<APT::Configuration::Compressor> const compressor = APT::Configuration::getCompressors();
+      for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
+          c != compressor.end(); ++c)
+      {
+        std::string filename = std::string(List[I]).append(Name).append(c->Extension);
+         if (stat(filename.c_str(), &Buf) != 0)
+           continue;
+        Inodes[I] = Buf.st_ino;
+        found = true;
+        break;
+      }
+
+      if (found == false)
+      {
+        _error->Errno("stat","Failed to stat %s%s",List[I].c_str(), Name);
+        couldFindAllFiles = false;
+        Inodes[I] = 0;
+      }
    }
-   
+
    // Look for dups
    for (unsigned int I = 0; I != List.size(); I++)
    {
+      if (Inodes[I] == 0)
+        continue;
       for (unsigned int J = I+1; J < List.size(); J++)
       {
         // No match
-        if (Inodes[J] != Inodes[I])
+        if (Inodes[J] == 0 || Inodes[J] != Inodes[I])
            continue;
         
         // We score the two paths.. and erase one
@@ -298,7 +339,7 @@ bool pkgCdrom::DropRepeats(vector<string> &List,const char *Name)
         List.erase(List.begin()+I);
    }
    
-   return true;
+   return couldFindAllFiles;
 }
                                                                        /*}}}*/
 // ReduceSourceList - Takes the path list and reduces it               /*{{{*/
@@ -310,7 +351,7 @@ void pkgCdrom::ReduceSourcelist(string CD,vector<string> &List)
    sort(List.begin(),List.end());
    
    // Collect similar entries
-   for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+   for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
    {
       // Find a space..
       string::size_type Space = (*I).find(' ');
@@ -322,7 +363,7 @@ void pkgCdrom::ReduceSourcelist(string CD,vector<string> &List)
 
       string Word1 = string(*I,Space,SSpace-Space);
       string Prefix = string(*I,0,Space);
-      for (vector<string>::iterator J = List.begin(); J != I; J++)
+      for (vector<string>::iterator J = List.begin(); J != I; ++J)
       {
         // Find a space..
         string::size_type Space2 = (*J).find(' ');
@@ -368,28 +409,12 @@ bool pkgCdrom::WriteDatabase(Configuration &Cnf)
    
    /* Write out all of the configuration directives by walking the
       configuration tree */
-   const Configuration::Item *Top = Cnf.Tree(0);
-   for (; Top != 0;)
-   {
-      // Print the config entry
-      if (Top->Value.empty() == false)
-        Out <<  Top->FullTag() + " \"" << Top->Value << "\";" << endl;
-      
-      if (Top->Child != 0)
-      {
-        Top = Top->Child;
-        continue;
-      }
-      
-      while (Top != 0 && Top->Next == 0)
-        Top = Top->Parent;
-      if (Top != 0)
-        Top = Top->Next;
-   }   
+   Cnf.Dump(Out, NULL, "%f \"%v\";\n", false);
 
    Out.close();
-   
-   link(DFile.c_str(),string(DFile + '~').c_str());
+
+   if (FileExists(DFile) == true)
+      rename(DFile.c_str(), string(DFile + '~').c_str());
    if (rename(NewFile.c_str(),DFile.c_str()) != 0)
       return _error->Errno("rename","Failed to rename %s.new to %s",
                           DFile.c_str(),DFile.c_str());
@@ -405,7 +430,7 @@ bool pkgCdrom::WriteDatabase(Configuration &Cnf)
    that were the same. */
 bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
 {
-   if (List.size() == 0)
+   if (List.empty() == true)
       return true;
 
    string File = _config->FindFile("Dir::Etc::sourcelist");
@@ -455,7 +480,7 @@ bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
 
       if (First == true)
       {
-        for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+        for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
         {
            string::size_type Space = (*I).find(' ');
            if (Space == string::npos)
@@ -489,7 +514,7 @@ bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
    // Just in case the file was empty
    if (First == true)
    {
-      for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+      for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
       {
         string::size_type Space = (*I).find(' ');
         if (Space == string::npos)
@@ -656,18 +681,19 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                   /*{{{*/
       return false;
    }
 
-   chdir(StartDir.c_str());
+   if (chdir(StartDir.c_str()) != 0)
+      return _error->Errno("chdir","Unable to change to %s", StartDir.c_str());
 
    if (_config->FindB("Debug::aptcdrom",false) == true)
    {
       cout << "I found (binary):" << endl;
-      for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+      for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
         cout << *I << endl;
       cout << "I found (source):" << endl;
-      for (vector<string>::iterator I = SourceList.begin(); I != SourceList.end(); I++)
+      for (vector<string>::iterator I = SourceList.begin(); I != SourceList.end(); ++I)
         cout << *I << endl;
       cout << "I found (Signatures):" << endl;
-      for (vector<string>::iterator I = SigList.begin(); I != SigList.end(); I++)
+      for (vector<string>::iterator I = SigList.begin(); I != SigList.end(); ++I)
         cout << *I << endl;
    }   
 
@@ -677,7 +703,13 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                    /*{{{*/
    DropBinaryArch(List);
    DropRepeats(List,"Packages");
    DropRepeats(SourceList,"Sources");
+   // FIXME: We ignore stat() errors here as we usually have only one of those in use
+   // This has little potencial to drop 'valid' stat() errors as we know that one of these
+   // files need to exist, but it would be better if we would check it here
+   _error->PushToStack();
    DropRepeats(SigList,"Release.gpg");
+   DropRepeats(SigList,"InRelease");
+   _error->RevertToStack();
    DropRepeats(TransList,"");
    if(log != NULL) {
       msg.str("");
@@ -688,7 +720,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                     /*{{{*/
       log->Update(msg.str(), STEP_SCAN);
    }
 
-   if (List.size() == 0 && SourceList.size() == 0
+   if (List.empty() == true && SourceList.empty() == true
    {
       if (_config->FindB("APT::CDROM::NoMount",false) == false) 
         UnmountCdrom(CDROM);
@@ -712,7 +744,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                     /*{{{*/
         {
            // Escape special characters
            string::iterator J = Name.begin();
-           for (; J != Name.end(); J++)
+           for (; J != Name.end(); ++J)
               if (*J == '"' || *J == ']' || *J == '[')
                  *J = '_';
            
@@ -757,7 +789,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                     /*{{{*/
 
    // Escape special characters
    string::iterator J = Name.begin();
-   for (; J != Name.end(); J++)
+   for (; J != Name.end(); ++J)
       if (*J == '"' || *J == ']' || *J == '[')
         *J = '_';
    
@@ -804,7 +836,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                     /*{{{*/
    if(log != NULL)
       log->Update(_("Source list entries for this disc are:\n"));
 
-   for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+   for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
    {
       string::size_type Space = (*I).find(' ');
       if (Space == string::npos)
@@ -823,7 +855,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                     /*{{{*/
       }
    }
 
-   for (vector<string>::iterator I = SourceList.begin(); I != SourceList.end(); I++)
+   for (vector<string>::iterator I = SourceList.begin(); I != SourceList.end(); ++I)
    {
       string::size_type Space = (*I).find(' ');
       if (Space == string::npos)