]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/cdrom.cc
fix another hickup in the changelog
[apt.git] / apt-pkg / cdrom.cc
index 04ace10a63320cc13337c38ffaaf49ec0a797cda..872879752e93c2bff383182d24da2cf4776ba081 100644 (file)
@@ -1,5 +1,6 @@
 /*
  */
 /*
  */
+#include<config.h>
 
 #include<apt-pkg/init.h>
 #include<apt-pkg/error.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/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<sstream>
 #include<fstream>
-#include<config.h>
-#include<apti18n.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <dirent.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <dirent.h>
@@ -22,6 +23,8 @@
 
 #include "indexcopy.h"
 
 
 #include "indexcopy.h"
 
+#include<apti18n.h>
+
 using namespace std;
 
 // FindPackages - Find the package files on the CDROM                  /*{{{*/
 using namespace std;
 
 // FindPackages - Find the package files on the CDROM                  /*{{{*/
@@ -75,27 +78,45 @@ bool pkgCdrom::FindPackages(string CD,
    {
       SigList.push_back(CD);
    }
    {
       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 */
    /* 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)
-   {
-      List.push_back(CD);
+    std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+    types.push_back("");
+    for (std::vector<std::string>::const_iterator t = types.begin();
+         t != types.end(); ++t)
+    {
+       std::string filename = std::string("Packages");
+       if ((*t).size() > 0)
+          filename.append("."+*t);
+       if (stat(filename.c_str(), &Buf) == 0)
+       {
+          List.push_back(CD);
       
       
-      // Continue down if thorough is given
-      if (_config->FindB("APT::CDROM::Thorough",false) == false)
-        return true;
-   }
-   if (stat("Sources.gz",&Buf) == 0 || stat("Sources",&Buf) == 0)
-   {
-      SList.push_back(CD);
+          // Continue down if thorough is given
+          if (_config->FindB("APT::CDROM::Thorough",false) == false)
+             return true;
+          break;
+       }
+    }
+    for (std::vector<std::string>::const_iterator t = types.begin();
+         t != types.end(); ++t)
+    {
+       std::string filename = std::string("Sources");
+       if ((*t).size() > 0)
+          filename.append("."+*t);
+       {
+          SList.push_back(CD);
       
       
-      // Continue down if thorough is given
-      if (_config->FindB("APT::CDROM::Thorough",false) == false)
-        return true;
-   }
-
-   // see if we find translatin indexes
+          // Continue down if thorough is given
+          if (_config->FindB("APT::CDROM::Thorough",false) == false)
+             return true;
+          break;
+       }
+    }
+
+   // see if we find translation indices
    if (stat("i18n",&Buf) == 0)
    {
       D = opendir("i18n");
    if (stat("i18n",&Buf) == 0)
    {
       D = opendir("i18n");
@@ -106,9 +127,15 @@ bool pkgCdrom::FindPackages(string CD,
            if (_config->FindB("Debug::aptcdrom",false) == true)
               std::clog << "found translations: " << Dir->d_name << "\n";
            string file = Dir->d_name;
            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);
+            for (std::vector<std::string>::const_iterator t = types.begin();
+                 t != types.end(); ++t)
+            {
+               std::string needle = "." + *t;
+               if(file.substr(file.size()-needle.size()) == needle)
+                  file = file.substr(0, file.size()-needle.size());
+               TransList.push_back(CD+"i18n/"+ file);
+               break;
+            }
         }
       }
       closedir(D);
         }
       }
       closedir(D);
@@ -155,7 +182,11 @@ bool pkgCdrom::FindPackages(string CD,
         break;
 
       if (chdir(CD.c_str()) != 0)
         break;
 
       if (chdir(CD.c_str()) != 0)
-        return _error->Errno("chdir","Unable to change to %s",CD.c_str());
+      {
+        _error->Errno("chdir","Unable to change to %s", CD.c_str());
+        closedir(D);
+        return false;
+      }
    };
 
    closedir(D);
    };
 
    closedir(D);
@@ -250,15 +281,25 @@ bool pkgCdrom::DropRepeats(vector<string> &List,const char *Name)
    for (unsigned int I = 0; I != List.size(); I++)
    {
       struct stat Buf;
    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;
+      std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+      types.push_back("");
+      for (std::vector<std::string>::const_iterator t = types.begin();
+           t != types.end(); ++t)
+      {
+         std::string filename = List[I] + Name;
+         if ((*t).size() > 0)
+            filename.append("." + *t);
+         if (stat(filename.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)
+   if (_error->PendingError() == true) {
+      delete[] Inodes;
       return false;
       return false;
+   }
    
    // Look for dups
    for (unsigned int I = 0; I != List.size(); I++)
    
    // Look for dups
    for (unsigned int I = 0; I != List.size(); I++)
@@ -304,7 +345,7 @@ void pkgCdrom::ReduceSourcelist(string CD,vector<string> &List)
    sort(List.begin(),List.end());
    
    // Collect similar entries
    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(' ');
    {
       // Find a space..
       string::size_type Space = (*I).find(' ');
@@ -316,7 +357,7 @@ void pkgCdrom::ReduceSourcelist(string CD,vector<string> &List)
 
       string Word1 = string(*I,Space,SSpace-Space);
       string Prefix = string(*I,0,Space);
 
       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(' ');
       {
         // Find a space..
         string::size_type Space2 = (*J).find(' ');
@@ -399,7 +440,7 @@ bool pkgCdrom::WriteDatabase(Configuration &Cnf)
    that were the same. */
 bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
 {
    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");
       return true;
 
    string File = _config->FindFile("Dir::Etc::sourcelist");
@@ -449,7 +490,7 @@ bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
 
       if (First == true)
       {
 
       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)
         {
            string::size_type Space = (*I).find(' ');
            if (Space == string::npos)
@@ -483,7 +524,7 @@ bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
    // Just in case the file was empty
    if (First == true)
    {
    // 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)
       {
         string::size_type Space = (*I).find(' ');
         if (Space == string::npos)
@@ -513,7 +554,8 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)            /*{{{*/
    if (CDROM[0] == '.')
       CDROM= SafeGetCWD() + '/' + CDROM;
 
    if (CDROM[0] == '.')
       CDROM= SafeGetCWD() + '/' + CDROM;
 
-   if(log) {
+   if (log != NULL)
+   {
       msg.str("");
       ioprintf(msg, _("Using CD-ROM mount point %s\nMounting CD-ROM\n"),
                      CDROM.c_str());
       msg.str("");
       ioprintf(msg, _("Using CD-ROM mount point %s\nMounting CD-ROM\n"),
                      CDROM.c_str());
@@ -523,7 +565,7 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)            /*{{{*/
       return _error->Error("Failed to mount the cdrom.");
 
    // Hash the CD to get an ID
       return _error->Error("Failed to mount the cdrom.");
 
    // Hash the CD to get an ID
-   if(log) 
+   if (log != NULL)
       log->Update(_("Identifying.. "));
    
 
       log->Update(_("Identifying.. "));
    
 
@@ -533,10 +575,12 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)          /*{{{*/
       return false;
    }
 
       return false;
    }
 
-   msg.str("");
-   ioprintf(msg, "[%s]\n",ident.c_str());
-   log->Update(msg.str());
-
+   if (log != NULL)
+   {
+      msg.str("");
+      ioprintf(msg, "[%s]\n",ident.c_str());
+      log->Update(msg.str());
+   }
 
    // Read the database
    Configuration Database;
 
    // Read the database
    Configuration Database;
@@ -547,7 +591,8 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)            /*{{{*/
         return _error->Error("Unable to read the cdrom database %s",
                              DFile.c_str());
    }
         return _error->Error("Unable to read the cdrom database %s",
                              DFile.c_str());
    }
-   if(log) {
+   if (log != NULL)
+   {
       msg.str("");
       ioprintf(msg, _("Stored label: %s\n"),
       Database.Find("CD::"+ident).c_str());
       msg.str("");
       ioprintf(msg, _("Stored label: %s\n"),
       Database.Find("CD::"+ident).c_str());
@@ -555,8 +600,10 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)           /*{{{*/
    }
 
    // Unmount and finish
    }
 
    // Unmount and finish
-   if (_config->FindB("APT::CDROM::NoMount",false) == false) {
-      log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST);
+   if (_config->FindB("APT::CDROM::NoMount",false) == false)
+   {
+      if (log != NULL)
+        log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST);
       UnmountCdrom(CDROM);
    }
 
       UnmountCdrom(CDROM);
    }
 
@@ -572,7 +619,8 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                     /*{{{*/
    if (CDROM[0] == '.')
       CDROM= SafeGetCWD() + '/' + CDROM;
    
    if (CDROM[0] == '.')
       CDROM= SafeGetCWD() + '/' + CDROM;
    
-   if(log) {
+   if(log != NULL)
+   {
       log->SetTotal(STEP_LAST);
       msg.str("");
       ioprintf(msg, _("Using CD-ROM mount point %s\n"), CDROM.c_str());
       log->SetTotal(STEP_LAST);
       msg.str("");
       ioprintf(msg, _("Using CD-ROM mount point %s\n"), CDROM.c_str());
@@ -592,11 +640,12 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                   /*{{{*/
    // Unmount the CD and get the user to put in the one they want
    if (_config->FindB("APT::CDROM::NoMount",false) == false)
    {
    // Unmount the CD and get the user to put in the one they want
    if (_config->FindB("APT::CDROM::NoMount",false) == false)
    {
-      if(log)
+      if(log != NULL)
         log->Update(_("Unmounting CD-ROM\n"), STEP_UNMOUNT);
       UnmountCdrom(CDROM);
 
         log->Update(_("Unmounting CD-ROM\n"), STEP_UNMOUNT);
       UnmountCdrom(CDROM);
 
-      if(log) {
+      if(log != NULL)
+      {
         log->Update(_("Waiting for disc...\n"), STEP_WAIT);
         if(!log->ChangeCdrom()) {
            // user aborted
         log->Update(_("Waiting for disc...\n"), STEP_WAIT);
         if(!log->ChangeCdrom()) {
            // user aborted
@@ -605,26 +654,29 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                   /*{{{*/
       }
 
       // Mount the new CDROM
       }
 
       // Mount the new CDROM
-      log->Update(_("Mounting CD-ROM...\n"), STEP_MOUNT);
+      if(log != NULL)
+        log->Update(_("Mounting CD-ROM...\n"), STEP_MOUNT);
+
       if (MountCdrom(CDROM) == false)
         return _error->Error("Failed to mount the cdrom.");
    }
    
    // Hash the CD to get an ID
       if (MountCdrom(CDROM) == false)
         return _error->Error("Failed to mount the cdrom.");
    }
    
    // Hash the CD to get an ID
-   if(log)
+   if(log != NULL)
       log->Update(_("Identifying.. "), STEP_IDENT);
    string ID;
    if (IdentCdrom(CDROM,ID) == false)
    {
       log->Update(_("Identifying.. "), STEP_IDENT);
    string ID;
    if (IdentCdrom(CDROM,ID) == false)
    {
-      log->Update("\n");
+      if (log != NULL)
+        log->Update("\n");
       return false;
    }
       return false;
    }
-   if(log) 
+   if(log != NULL)
+   {
       log->Update("["+ID+"]\n");
       log->Update("["+ID+"]\n");
-
-   if(log) 
       log->Update(_("Scanning disc for index files..\n"),STEP_SCAN);
       log->Update(_("Scanning disc for index files..\n"),STEP_SCAN);
-   
+   }
+
    // Get the CD structure
    vector<string> List;
    vector<string> SourceList;
    // Get the CD structure
    vector<string> List;
    vector<string> SourceList;
@@ -634,7 +686,8 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                     /*{{{*/
    string InfoDir;
    if (FindPackages(CDROM,List,SourceList, SigList,TransList,InfoDir,log) == false)
    {
    string InfoDir;
    if (FindPackages(CDROM,List,SourceList, SigList,TransList,InfoDir,log) == false)
    {
-      log->Update("\n");
+      if (log != NULL)
+        log->Update("\n");
       return false;
    }
 
       return false;
    }
 
@@ -643,13 +696,13 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                   /*{{{*/
    if (_config->FindB("Debug::aptcdrom",false) == true)
    {
       cout << "I found (binary):" << endl;
    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;
         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;
         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;
    }   
 
         cout << *I << endl;
    }   
 
@@ -661,7 +714,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                     /*{{{*/
    DropRepeats(SourceList,"Sources");
    DropRepeats(SigList,"Release.gpg");
    DropRepeats(TransList,"");
    DropRepeats(SourceList,"Sources");
    DropRepeats(SigList,"Release.gpg");
    DropRepeats(TransList,"");
-   if(log) {
+   if(log != NULL) {
       msg.str("");
       ioprintf(msg, _("Found %zu package indexes, %zu source indexes, "
                      "%zu translation indexes and %zu signatures\n"), 
       msg.str("");
       ioprintf(msg, _("Found %zu package indexes, %zu source indexes, "
                      "%zu translation indexes and %zu signatures\n"), 
@@ -670,7 +723,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                     /*{{{*/
       log->Update(msg.str(), STEP_SCAN);
    }
 
       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);
    {
       if (_config->FindB("APT::CDROM::NoMount",false) == false) 
         UnmountCdrom(CDROM);
@@ -694,11 +747,12 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                   /*{{{*/
         {
            // Escape special characters
            string::iterator J = Name.begin();
         {
            // Escape special characters
            string::iterator J = Name.begin();
-           for (; J != Name.end(); J++)
+           for (; J != Name.end(); ++J)
               if (*J == '"' || *J == ']' || *J == '[')
                  *J = '_';
            
               if (*J == '"' || *J == ']' || *J == '[')
                  *J = '_';
            
-           if(log) {
+           if(log != NULL)
+           {
               msg.str("");
               ioprintf(msg, _("Found label '%s'\n"), Name.c_str());
               log->Update(msg.str());
               msg.str("");
               ioprintf(msg, _("Found label '%s'\n"), Name.c_str());
               log->Update(msg.str());
@@ -710,7 +764,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                     /*{{{*/
       if (_config->FindB("APT::CDROM::Rename",false) == true ||
          Name.empty() == true)
       {
       if (_config->FindB("APT::CDROM::Rename",false) == true ||
          Name.empty() == true)
       {
-        if(!log
+        if(log == NULL
          {
            if (_config->FindB("APT::CDROM::NoMount",false) == false) 
               UnmountCdrom(CDROM);
          {
            if (_config->FindB("APT::CDROM::NoMount",false) == false) 
               UnmountCdrom(CDROM);
@@ -738,18 +792,18 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                   /*{{{*/
 
    // Escape special characters
    string::iterator J = Name.begin();
 
    // Escape special characters
    string::iterator J = Name.begin();
-   for (; J != Name.end(); J++)
+   for (; J != Name.end(); ++J)
       if (*J == '"' || *J == ']' || *J == '[')
         *J = '_';
    
    Database.Set("CD::" + ID,Name);
       if (*J == '"' || *J == ']' || *J == '[')
         *J = '_';
    
    Database.Set("CD::" + ID,Name);
-   if(log) {
+   if(log != NULL)
+   {
       msg.str("");
       ioprintf(msg, _("This disc is called: \n'%s'\n"), Name.c_str());
       log->Update(msg.str());
       msg.str("");
       ioprintf(msg, _("This disc is called: \n'%s'\n"), Name.c_str());
       log->Update(msg.str());
+      log->Update(_("Copying package lists..."), STEP_COPY);
    }
    }
-
-   log->Update(_("Copying package lists..."), STEP_COPY);
    // take care of the signatures and copy them if they are ok
    // (we do this before PackageCopy as it modifies "List" and "SourceList")
    SigVerify SignVerify;
    // take care of the signatures and copy them if they are ok
    // (we do this before PackageCopy as it modifies "List" and "SourceList")
    SigVerify SignVerify;
@@ -774,19 +828,18 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                   /*{{{*/
       if (WriteDatabase(Database) == false)
         return false;
       
       if (WriteDatabase(Database) == false)
         return false;
       
-      if(log) {
+      if(log != NULL)
         log->Update(_("Writing new source list\n"), STEP_WRITE);
         log->Update(_("Writing new source list\n"), STEP_WRITE);
-      }
       if (WriteSourceList(Name,List,false) == false ||
          WriteSourceList(Name,SourceList,true) == false)
         return false;
    }
 
    // Print the sourcelist entries
       if (WriteSourceList(Name,List,false) == false ||
          WriteSourceList(Name,SourceList,true) == false)
         return false;
    }
 
    // Print the sourcelist entries
-   if(log
+   if(log != NULL)
       log->Update(_("Source list entries for this disc are:\n"));
 
       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)
    {
       string::size_type Space = (*I).find(' ');
       if (Space == string::npos)
@@ -796,7 +849,8 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                     /*{{{*/
         return _error->Error("Internal error");
       }
 
         return _error->Error("Internal error");
       }
 
-      if(log) {
+      if(log != NULL)
+      {
         msg.str("");
         msg << "deb cdrom:[" << Name << "]/" << string(*I,0,Space) << 
            " " << string(*I,Space+1) << endl;
         msg.str("");
         msg << "deb cdrom:[" << Name << "]/" << string(*I,0,Space) << 
            " " << string(*I,Space+1) << endl;
@@ -804,7 +858,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)
    {
       string::size_type Space = (*I).find(' ');
       if (Space == string::npos)
@@ -814,7 +868,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                     /*{{{*/
         return _error->Error("Internal error");
       }
 
         return _error->Error("Internal error");
       }
 
-      if(log) {
+      if(log != NULL) {
         msg.str("");
         msg << "deb-src cdrom:[" << Name << "]/" << string(*I,0,Space) << 
            " " << string(*I,Space+1) << endl;
         msg.str("");
         msg << "deb-src cdrom:[" << Name << "]/" << string(*I,0,Space) << 
            " " << string(*I,Space+1) << endl;
@@ -824,7 +878,8 @@ bool pkgCdrom::Add(pkgCdromStatus *log)                                     /*{{{*/
 
    // Unmount and finish
    if (_config->FindB("APT::CDROM::NoMount",false) == false) {
 
    // Unmount and finish
    if (_config->FindB("APT::CDROM::NoMount",false) == false) {
-      log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST);
+      if (log != NULL)
+        log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST);
       UnmountCdrom(CDROM);
    }
 
       UnmountCdrom(CDROM);
    }
 
@@ -854,6 +909,7 @@ pkgUdevCdromDevices::Dlopen()                                       /*{{{*/
    libudev_handle = h;
    udev_new = (udev* (*)(void)) dlsym(h, "udev_new");
    udev_enumerate_add_match_property = (int (*)(udev_enumerate*, const char*, const char*))dlsym(h, "udev_enumerate_add_match_property");
    libudev_handle = h;
    udev_new = (udev* (*)(void)) dlsym(h, "udev_new");
    udev_enumerate_add_match_property = (int (*)(udev_enumerate*, const char*, const char*))dlsym(h, "udev_enumerate_add_match_property");
+   udev_enumerate_add_match_sysattr = (int (*)(udev_enumerate*, const char*, const char*))dlsym(h, "udev_enumerate_add_match_sysattr");
    udev_enumerate_scan_devices = (int (*)(udev_enumerate*))dlsym(h, "udev_enumerate_scan_devices");
    udev_enumerate_get_list_entry = (udev_list_entry* (*)(udev_enumerate*))dlsym(h, "udev_enumerate_get_list_entry");
    udev_device_new_from_syspath = (udev_device* (*)(udev*, const char*))dlsym(h, "udev_device_new_from_syspath");
    udev_enumerate_scan_devices = (int (*)(udev_enumerate*))dlsym(h, "udev_enumerate_scan_devices");
    udev_enumerate_get_list_entry = (udev_list_entry* (*)(udev_enumerate*))dlsym(h, "udev_enumerate_get_list_entry");
    udev_device_new_from_syspath = (udev_device* (*)(udev*, const char*))dlsym(h, "udev_device_new_from_syspath");
@@ -867,8 +923,18 @@ pkgUdevCdromDevices::Dlopen()                                      /*{{{*/
    return true;
 }
                                                                        /*}}}*/
    return true;
 }
                                                                        /*}}}*/
+                                                                        /*{{{*/
+// convenience interface, this will just call ScanForRemovable
 vector<CdromDevice>
 vector<CdromDevice>
-pkgUdevCdromDevices::Scan()                                             /*{{{*/
+pkgUdevCdromDevices::Scan()
+{ 
+   bool CdromOnly = _config->FindB("APT::cdrom::CdromOnly", true);
+   return ScanForRemovable(CdromOnly); 
+};
+                                                                       /*}}}*/
+                                                                        /*{{{*/
+vector<CdromDevice>
+pkgUdevCdromDevices::ScanForRemovable(bool CdromOnly)
 {
    vector<CdromDevice> cdrom_devices;
    struct udev_enumerate *enumerate;
 {
    vector<CdromDevice> cdrom_devices;
    struct udev_enumerate *enumerate;
@@ -880,7 +946,11 @@ pkgUdevCdromDevices::Scan()                                             /*{{{*/
 
    udev_ctx = udev_new();
    enumerate = udev_enumerate_new (udev_ctx);
 
    udev_ctx = udev_new();
    enumerate = udev_enumerate_new (udev_ctx);
-   udev_enumerate_add_match_property(enumerate, "ID_CDROM", "1");
+   if (CdromOnly)
+      udev_enumerate_add_match_property(enumerate, "ID_CDROM", "1");
+   else {
+      udev_enumerate_add_match_sysattr(enumerate, "removable", "1");
+   }
 
    udev_enumerate_scan_devices (enumerate);
    devices = udev_enumerate_get_list_entry (enumerate);
 
    udev_enumerate_scan_devices (enumerate);
    devices = udev_enumerate_get_list_entry (enumerate);
@@ -892,11 +962,18 @@ pkgUdevCdromDevices::Scan()                                             /*{{{*/
       if (udevice == NULL)
         continue;
       const char* devnode = udev_device_get_devnode(udevice);
       if (udevice == NULL)
         continue;
       const char* devnode = udev_device_get_devnode(udevice);
-      const char* mountpath = udev_device_get_property_value(udevice, "FSTAB_DIR");
+
+      // try fstab_dir first
+      string mountpath;
+      const char* mp = udev_device_get_property_value(udevice, "FSTAB_DIR");
+      if (mp)
+         mountpath = string(mp);
+      else
+         mountpath = FindMountPointForDevice(devnode);
 
       // fill in the struct
       cdrom.DeviceName = string(devnode);
 
       // fill in the struct
       cdrom.DeviceName = string(devnode);
-      if (mountpath) {
+      if (mountpath != "") {
         cdrom.MountPath = mountpath;
         string s = string(mountpath);
         cdrom.Mounted = IsMounted(s);
         cdrom.MountPath = mountpath;
         string s = string(mountpath);
         cdrom.Mounted = IsMounted(s);