X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/d4273c55e34cdf5a355b4edd92df61a83cfab318..baec76f5f0f9fcbd71f6e2afaa7fc85543bd624c:/apt-pkg/cdrom.cc

diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc
index 9a9a854bf..d83d05f9e 100644
--- a/apt-pkg/cdrom.cc
+++ b/apt-pkg/cdrom.cc
@@ -1,27 +1,30 @@
 /*
  */
-#include<config.h>
-
-#include<apt-pkg/init.h>
-#include<apt-pkg/error.h>
-#include<apt-pkg/cdromutl.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 <config.h>
+
+#include <apt-pkg/error.h>
+#include <apt-pkg/cdromutl.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 <apt-pkg/indexcopy.h>
+
+
+#include <string.h>
+#include <iostream>
+#include <string>
+#include <vector>
 #include <sys/stat.h>
-#include <fcntl.h>
 #include <dirent.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <algorithm>
 #include <dlfcn.h>
-
-#include "indexcopy.h"
+#include <iostream>
+#include <sstream>
+#include <fstream>
 
 #include<apti18n.h>
 
@@ -58,10 +61,10 @@ bool pkgCdrom::FindPackages(string CD,
       return _error->Errno("chdir","Unable to change to %s",CD.c_str());
 
    // Look for a .disk subdirectory
-   if (DirectoryExists(".disk") == true)
+   if (InfoDir.empty() == true)
    {
-      if (InfoDir.empty() == true)
-	 InfoDir = CD + ".disk/";
+      if (DirectoryExists(".disk") == true)
+	 InfoDir = InfoDir + CD + ".disk/";
    }
 
    // Don't look into directories that have been marked to ingore.
@@ -153,10 +156,7 @@ bool pkgCdrom::FindPackages(string CD,
       // Skip some files..
       if (strcmp(Dir->d_name,".") == 0 ||
 	  strcmp(Dir->d_name,"..") == 0 ||
-	  //strcmp(Dir->d_name,"source") == 0 ||
 	  strcmp(Dir->d_name,".disk") == 0 ||
-	  strcmp(Dir->d_name,"experimental") == 0 ||
-	  strcmp(Dir->d_name,"binary-all") == 0 ||
           strcmp(Dir->d_name,"debian-installer") == 0)
 	 continue;
 
@@ -367,9 +367,9 @@ bool pkgCdrom::DropRepeats(vector<string> &List,const char *Name)
 									/*}}}*/
 // ReduceSourceList - Takes the path list and reduces it		/*{{{*/
 // ---------------------------------------------------------------------
-/* This takes the list of source list expressed entires and collects
+/* This takes the list of source list expressed entries and collects
    similar ones to form a single entry for each dist */
-void pkgCdrom::ReduceSourcelist(string CD,vector<string> &List)
+void pkgCdrom::ReduceSourcelist(string /*CD*/,vector<string> &List)
 {
    sort(List.begin(),List.end());
    
@@ -426,8 +426,8 @@ bool pkgCdrom::WriteDatabase(Configuration &Cnf)
 {
    string DFile = _config->FindFile("Dir::State::cdroms");
    string NewFile = DFile + ".new";
-   
-   unlink(NewFile.c_str());
+
+   RemoveFile("WriteDatabase", NewFile);
    ofstream Out(NewFile.c_str());
    if (!Out)
       return _error->Errno("ofstream::ofstream",
@@ -440,7 +440,7 @@ bool pkgCdrom::WriteDatabase(Configuration &Cnf)
    Out.close();
 
    if (FileExists(DFile) == true)
-      rename(DFile.c_str(), string(DFile + '~').c_str());
+      rename(DFile.c_str(), (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());
@@ -451,7 +451,7 @@ bool pkgCdrom::WriteDatabase(Configuration &Cnf)
 // WriteSourceList - Write an updated sourcelist			/*{{{*/
 // ---------------------------------------------------------------------
 /* This reads the old source list and copies it into the new one. It 
-   appends the new CDROM entires just after the first block of comments.
+   appends the new CDROM entries just after the first block of comments.
    This places them first in the file. It also removes any old entries
    that were the same. */
 bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
@@ -464,18 +464,18 @@ bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
    // Open the stream for reading
    ifstream F((FileExists(File)?File.c_str():"/dev/null"),
 	      ios::in );
-   if (!F != 0)
+   if (F.fail() == true)
       return _error->Errno("ifstream::ifstream","Opening %s",File.c_str());
 
    string NewFile = File + ".new";
-   unlink(NewFile.c_str());
+   RemoveFile("WriteDatabase", NewFile);
    ofstream Out(NewFile.c_str());
    if (!Out)
       return _error->Errno("ofstream::ofstream",
 			   "Failed to open %s.new",File.c_str());
 
    // Create a short uri without the path
-   string ShortURI = "cdrom:[" + Name + "]/";   
+   string ShortURI = "cdrom:[" + Name + "]/";
    string ShortURI2 = "cdrom:" + Name + "/";     // For Compatibility
 
    string Type;
@@ -483,12 +483,12 @@ bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
       Type = "deb-src";
    else
       Type = "deb";
-   
+
    char Buffer[300];
    int CurLine = 0;
    bool First = true;
    while (F.eof() == false)
-   {      
+   {
       F.getline(Buffer,sizeof(Buffer));
       CurLine++;
       if (F.fail() && !F.eof())
@@ -553,7 +553,7 @@ bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
    
    Out.close();
 
-   rename(File.c_str(),string(File + '~').c_str());
+   rename(File.c_str(), (File + '~').c_str());
    if (rename(NewFile.c_str(),File.c_str()) != 0)
       return _error->Errno("rename","Failed to rename %s.new to %s",
 			   File.c_str(),File.c_str());
@@ -561,137 +561,121 @@ bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
    return true;
 }
 									/*}}}*/
-bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)		/*{{{*/
+bool pkgCdrom::UnmountCDROM(std::string const &CDROM, pkgCdromStatus * const log)/*{{{*/
+{
+   if (_config->FindB("APT::CDROM::NoMount",false) == true)
+      return true;
+   if (log != NULL)
+      log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST);
+   return UnmountCdrom(CDROM);
+}
+									/*}}}*/
+bool pkgCdrom::MountAndIdentCDROM(Configuration &Database, std::string &CDROM, std::string &ident, pkgCdromStatus * const log, bool const interactive)/*{{{*/
 {
-   stringstream msg;
-
    // Startup
-   string CDROM = _config->FindDir("Acquire::cdrom::mount");
+   CDROM = _config->FindDir("Acquire::cdrom::mount");
    if (CDROM[0] == '.')
       CDROM= SafeGetCWD() + '/' + CDROM;
 
    if (log != NULL)
    {
-      msg.str("");
-      ioprintf(msg, _("Using CD-ROM mount point %s\nMounting CD-ROM\n"),
-		      CDROM.c_str());
-      log->Update(msg.str());
+      string msg;
+      log->SetTotal(STEP_LAST);
+      strprintf(msg, _("Using CD-ROM mount point %s\n"), CDROM.c_str());
+      log->Update(msg, STEP_PREPARE);
    }
-   if (MountCdrom(CDROM) == false)
+
+   // Unmount the CD and get the user to put in the one they want
+   if (_config->FindB("APT::CDROM::NoMount", false) == false)
+   {
+      if (interactive == true)
+      {
+	 UnmountCDROM(CDROM, log);
+
+	 if(log != NULL)
+	 {
+	    log->Update(_("Waiting for disc...\n"), STEP_WAIT);
+	    if(!log->ChangeCdrom()) {
+	       // user aborted
+	       return false;
+	    }
+	 }
+      }
+
+      // Mount the new CDROM
+      if(log != NULL)
+	 log->Update(_("Mounting CD-ROM...\n"), STEP_MOUNT);
+
+      if (MountCdrom(CDROM) == false)
+	 return _error->Error("Failed to mount the cdrom.");
+   }
+
+   if (IsMounted(CDROM) == false)
       return _error->Error("Failed to mount the cdrom.");
 
    // Hash the CD to get an ID
    if (log != NULL)
-      log->Update(_("Identifying.. "));
-   
+      log->Update(_("Identifying... "), STEP_IDENT);
 
    if (IdentCdrom(CDROM,ident) == false)
    {
       ident = "";
+      if (log != NULL)
+	 log->Update("\n");
+      UnmountCDROM(CDROM, NULL);
       return false;
    }
 
    if (log != NULL)
    {
-      msg.str("");
-      ioprintf(msg, "[%s]\n",ident.c_str());
-      log->Update(msg.str());
+      string msg;
+      strprintf(msg, "[%s]\n", ident.c_str());
+      log->Update(msg);
    }
 
    // Read the database
-   Configuration Database;
    string DFile = _config->FindFile("Dir::State::cdroms");
    if (FileExists(DFile) == true)
    {
       if (ReadConfigFile(Database,DFile) == false)
+      {
+	 UnmountCDROM(CDROM, NULL);
 	 return _error->Error("Unable to read the cdrom database %s",
 			      DFile.c_str());
+      }
    }
+   return true;
+}
+									/*}}}*/
+bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)		/*{{{*/
+{
+   Configuration Database;
+   std::string CDROM;
+   if (MountAndIdentCDROM(Database, CDROM, ident, log, false) == false)
+      return false;
+
    if (log != NULL)
    {
-      msg.str("");
-      ioprintf(msg, _("Stored label: %s\n"),
-      Database.Find("CD::"+ident).c_str());
-      log->Update(msg.str());
+      string msg;
+      strprintf(msg, _("Stored label: %s\n"),
+	    Database.Find("CD::"+ident).c_str());
+      log->Update(msg);
    }
 
    // Unmount and finish
-   if (_config->FindB("APT::CDROM::NoMount",false) == false)
-   {
-      if (log != NULL)
-	 log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST);
-      UnmountCdrom(CDROM);
-   }
-
+   UnmountCDROM(CDROM, log);
    return true;
 }
 									/*}}}*/
 bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
 {
-   stringstream msg;
-
-   // Startup
-   string CDROM = _config->FindDir("Acquire::cdrom::mount");
-   if (CDROM[0] == '.')
-      CDROM= SafeGetCWD() + '/' + CDROM;
-   
-   if(log != NULL)
-   {
-      log->SetTotal(STEP_LAST);
-      msg.str("");
-      ioprintf(msg, _("Using CD-ROM mount point %s\n"), CDROM.c_str());
-      log->Update(msg.str(), STEP_PREPARE);
-   }
-
-   // Read the database
    Configuration Database;
-   string DFile = _config->FindFile("Dir::State::cdroms");
-   if (FileExists(DFile) == true)
-   {
-      if (ReadConfigFile(Database,DFile) == false) 
-	 return _error->Error("Unable to read the cdrom database %s",
-			      DFile.c_str());
-   }
-   
-   // Unmount the CD and get the user to put in the one they want
-   if (_config->FindB("APT::CDROM::NoMount",false) == false)
-   {
-      if(log != NULL)
-	 log->Update(_("Unmounting CD-ROM\n"), STEP_UNMOUNT);
-      UnmountCdrom(CDROM);
-
-      if(log != NULL)
-      {
-	 log->Update(_("Waiting for disc...\n"), STEP_WAIT);
-	 if(!log->ChangeCdrom()) {
-	    // user aborted
-	    return false; 
-	 }
-      }
-
-      // Mount the new CDROM
-      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(log != NULL)
-      log->Update(_("Identifying.. "), STEP_IDENT);
-   string ID;
-   if (IdentCdrom(CDROM,ID) == false)
-   {
-      if (log != NULL)
-	 log->Update("\n");
+   std::string ID, CDROM;
+   if (MountAndIdentCDROM(Database, CDROM, ID, log, true) == false)
       return false;
-   }
+
    if(log != NULL)
-   {
-      log->Update("["+ID+"]\n");
-      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;
@@ -704,11 +688,15 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
    {
       if (log != NULL)
 	 log->Update("\n");
+      UnmountCDROM(CDROM, NULL);
       return false;
    }
 
    if (chdir(StartDir.c_str()) != 0)
+   {
+      UnmountCDROM(CDROM, NULL);
       return _error->Errno("chdir","Unable to change to %s", StartDir.c_str());
+   }
 
    if (_config->FindB("Debug::aptcdrom",false) == true)
    {
@@ -740,18 +728,17 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
    if (_config->FindB("APT::CDROM::DropTranslation", true) == true)
       DropTranslation(TransList);
    if(log != NULL) {
-      msg.str("");
-      ioprintf(msg, _("Found %zu package indexes, %zu source indexes, "
+      string msg;
+      strprintf(msg, _("Found %zu package indexes, %zu source indexes, "
 		      "%zu translation indexes and %zu signatures\n"), 
 	       List.size(), SourceList.size(), TransList.size(),
 	       SigList.size());
-      log->Update(msg.str(), STEP_SCAN);
+      log->Update(msg, STEP_SCAN);
    }
 
    if (List.empty() == true && SourceList.empty() == true) 
    {
-      if (_config->FindB("APT::CDROM::NoMount",false) == false) 
-	 UnmountCdrom(CDROM);
+      UnmountCDROM(CDROM, NULL);
       return _error->Error(_("Unable to locate any package files, perhaps this is not a Debian Disc or the wrong architecture?"));
    }
 
@@ -764,8 +751,8 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
       if (InfoDir.empty() == false &&
 	  FileExists(InfoDir + "/info") == true)
       {
-	 ifstream F(string(InfoDir + "/info").c_str());
-	 if (!F == 0)
+	 ifstream F((InfoDir + "/info").c_str());
+	 if (F.good() == true)
 	    getline(F,Name);
 
 	 if (Name.empty() == false)
@@ -778,9 +765,9 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
 	    
 	    if(log != NULL)
 	    {
-	       msg.str("");
-	       ioprintf(msg, _("Found label '%s'\n"), Name.c_str());
-	       log->Update(msg.str());
+	       string msg;
+	       strprintf(msg, _("Found label '%s'\n"), Name.c_str());
+	       log->Update(msg);
 	    }
 	    Database.Set("CD::" + ID + "::Label",Name);
 	 }	 
@@ -791,14 +778,14 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
       {
 	 if(log == NULL) 
          {
-	    if (_config->FindB("APT::CDROM::NoMount",false) == false) 
-	       UnmountCdrom(CDROM);
+	    UnmountCDROM(CDROM, NULL);
 	    return _error->Error("No disc name found and no way to ask for it");
 	 }
 
 	 while(true) {
 	    if(!log->AskCdromName(Name)) {
 	       // user canceld
+	       UnmountCDROM(CDROM, NULL);
 	       return false; 
 	    }
 	    cout << "Name: '" << Name << "'" << endl;
@@ -824,11 +811,25 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
    Database.Set("CD::" + ID,Name);
    if(log != NULL)
    {
-      msg.str("");
-      ioprintf(msg, _("This disc is called: \n'%s'\n"), Name.c_str());
-      log->Update(msg.str());
+      string msg;
+      strprintf(msg, _("This disc is called: \n'%s'\n"), Name.c_str());
+      log->Update(msg);
       log->Update(_("Copying package lists..."), STEP_COPY);
    }
+
+   // check for existence and possibly create state directory for copying
+   string const listDir = _config->FindDir("Dir::State::lists");
+   string const partialListDir = listDir + "partial/";
+   mode_t const mode = umask(S_IWGRP | S_IWOTH);
+   bool const creation_fail = (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::State"), partialListDir) == false &&
+	 CreateAPTDirectoryIfNeeded(listDir, partialListDir) == false);
+   umask(mode);
+   if (creation_fail == true)
+   {
+      UnmountCDROM(CDROM, NULL);
+      return _error->Errno("cdrom", _("List directory %spartial is missing."), listDir.c_str());
+   }
+
    // 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;
@@ -841,7 +842,10 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
    if (Copy.CopyPackages(CDROM,Name,List, log) == false ||
        SrcCopy.CopyPackages(CDROM,Name,SourceList, log) == false ||
        TransCopy.CopyTranslations(CDROM,Name,TransList, log) == false)
+   {
+      UnmountCDROM(CDROM, NULL);
       return false;
+   }
 
    // reduce the List so that it takes less space in sources.list
    ReduceSourcelist(CDROM,List);
@@ -851,13 +855,19 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
    if (_config->FindB("APT::cdrom::NoAct",false) == false)
    {
       if (WriteDatabase(Database) == false)
+      {
+	 UnmountCDROM(CDROM, NULL);
 	 return false;
-      
+      }
+
       if(log != NULL)
 	 log->Update(_("Writing new source list\n"), STEP_WRITE);
       if (WriteSourceList(Name,List,false) == false ||
 	  WriteSourceList(Name,SourceList,true) == false)
+      {
+	 UnmountCDROM(CDROM, NULL);
 	 return false;
+      }
    }
 
    // Print the sourcelist entries
@@ -869,14 +879,13 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
       string::size_type Space = (*I).find(' ');
       if (Space == string::npos)
       {
-	 if (_config->FindB("APT::CDROM::NoMount",false) == false) 
-	    UnmountCdrom(CDROM);
+	 UnmountCDROM(CDROM, NULL);
 	 return _error->Error("Internal error");
       }
 
       if(log != NULL)
       {
-	 msg.str("");
+	 stringstream msg;
 	 msg << "deb cdrom:[" << Name << "]/" << string(*I,0,Space) << 
 	    " " << string(*I,Space+1) << endl;
 	 log->Update(msg.str());
@@ -888,13 +897,12 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
       string::size_type Space = (*I).find(' ');
       if (Space == string::npos)
       {
-	 if (_config->FindB("APT::CDROM::NoMount",false) == false) 
-	    UnmountCdrom(CDROM);
+	 UnmountCDROM(CDROM, NULL);
 	 return _error->Error("Internal error");
       }
 
       if(log != NULL) {
-	 msg.str("");
+	 stringstream msg;
 	 msg << "deb-src cdrom:[" << Name << "]/" << string(*I,0,Space) << 
 	    " " << string(*I,Space+1) << endl;
 	 log->Update(msg.str());
@@ -902,24 +910,22 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
    }
 
    // Unmount and finish
-   if (_config->FindB("APT::CDROM::NoMount",false) == false) {
-      if (log != NULL)
-	 log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST);
-      UnmountCdrom(CDROM);
-   }
-
+   UnmountCDROM(CDROM, log);
    return true;
 }
 									/*}}}*/
-pkgUdevCdromDevices::pkgUdevCdromDevices()                     		/*{{{*/
-   : libudev_handle(NULL)
+pkgUdevCdromDevices::pkgUdevCdromDevices()				/*{{{*/
+: d(NULL), libudev_handle(NULL), udev_new(NULL), udev_enumerate_add_match_property(NULL),
+   udev_enumerate_scan_devices(NULL), udev_enumerate_get_list_entry(NULL),
+   udev_device_new_from_syspath(NULL), udev_enumerate_get_udev(NULL),
+   udev_list_entry_get_name(NULL), udev_device_get_devnode(NULL),
+   udev_enumerate_new(NULL), udev_list_entry_get_next(NULL),
+   udev_device_get_property_value(NULL), udev_enumerate_add_match_sysattr(NULL)
 {
-
 }
 									/*}}}*/
 
-bool
-pkgUdevCdromDevices::Dlopen()                     		        /*{{{*/
+bool pkgUdevCdromDevices::Dlopen()					/*{{{*/
 {
    // alread open
    if(libudev_handle != NULL)
@@ -948,18 +954,14 @@ pkgUdevCdromDevices::Dlopen()                     		        /*{{{*/
    return true;
 }
 									/*}}}*/
-                                                                        /*{{{*/
-// convenience interface, this will just call ScanForRemovable
-vector<CdromDevice>
-pkgUdevCdromDevices::Scan()
-{ 
+// convenience interface, this will just call ScanForRemovable		/*{{{*/
+vector<CdromDevice> pkgUdevCdromDevices::Scan()
+{
    bool CdromOnly = _config->FindB("APT::cdrom::CdromOnly", true);
-   return ScanForRemovable(CdromOnly); 
-};
+   return ScanForRemovable(CdromOnly);
+}
 									/*}}}*/
-                                                                        /*{{{*/
-vector<CdromDevice>
-pkgUdevCdromDevices::ScanForRemovable(bool CdromOnly)
+vector<CdromDevice> pkgUdevCdromDevices::ScanForRemovable(bool CdromOnly)/*{{{*/
 {
    vector<CdromDevice> cdrom_devices;
    struct udev_enumerate *enumerate;
@@ -1000,7 +1002,7 @@ pkgUdevCdromDevices::ScanForRemovable(bool CdromOnly)
       cdrom.DeviceName = string(devnode);
       if (mountpath != "") {
 	 cdrom.MountPath = mountpath;
-	 string s = string(mountpath);
+	 string s = mountpath;
 	 cdrom.Mounted = IsMounted(s);
       } else {
 	 cdrom.Mounted = false;
@@ -1018,3 +1020,9 @@ pkgUdevCdromDevices::~pkgUdevCdromDevices()                             /*{{{*/
       dlclose(libudev_handle);
 }
 									/*}}}*/
+
+pkgCdromStatus::pkgCdromStatus() : d(NULL), totalSteps(0) {}
+pkgCdromStatus::~pkgCdromStatus() {}
+
+pkgCdrom::pkgCdrom() : d(NULL) {}
+pkgCdrom::~pkgCdrom() {}