diff options
Diffstat (limited to 'methods/cdrom.cc')
-rw-r--r-- | methods/cdrom.cc | 129 |
1 files changed, 104 insertions, 25 deletions
diff --git a/methods/cdrom.cc b/methods/cdrom.cc index 601bc11c9..9802eb46c 100644 --- a/methods/cdrom.cc +++ b/methods/cdrom.cc @@ -9,6 +9,7 @@ /*}}}*/ // Include Files /*{{{*/ #include <apt-pkg/acquire-method.h> +#include <apt-pkg/cdrom.h> #include <apt-pkg/cdromutl.h> #include <apt-pkg/error.h> #include <apt-pkg/configuration.h> @@ -17,6 +18,7 @@ #include <sys/stat.h> #include <unistd.h> +#include <dlfcn.h> #include <iostream> #include <apti18n.h> @@ -27,15 +29,20 @@ using namespace std; class CDROMMethod : public pkgAcqMethod { bool DatabaseLoaded; + bool Debug; + ::Configuration Database; string CurrentID; string CDROM; bool MountedByApt; - + pkgUdevCdromDevices UdevCdroms; + + bool IsCorrectCD(URI want, string MountPath); + bool AutoDetectAndMount(URI); virtual bool Fetch(FetchItem *Itm); string GetID(string Name); virtual void Exit(); - + public: CDROMMethod(); @@ -50,14 +57,15 @@ CDROMMethod::CDROMMethod() : pkgAcqMethod("1.0",SingleInstance | LocalOnly | DatabaseLoaded(false), MountedByApt(false) { + UdevCdroms.Dlopen(); }; /*}}}*/ // CDROMMethod::Exit - Unmount the disc if necessary /*{{{*/ // --------------------------------------------------------------------- /* */ void CDROMMethod::Exit() -{ - if (MountedByApt == true) +{ + if (MountedByApt == true) UnmountCdrom(CDROM); } /*}}}*/ @@ -81,16 +89,94 @@ string CDROMMethod::GetID(string Name) return string(); } /*}}}*/ +// CDROMMethod::AutoDetectAndMount /*{{{*/ +// --------------------------------------------------------------------- +/* Modifies class varaiable CDROM to the mountpoint */ +bool CDROMMethod::AutoDetectAndMount(URI Get) +{ + vector<struct CdromDevice> v = UdevCdroms.Scan(); + + // first check if its mounted somewhere already + for (unsigned int i=0; i < v.size(); i++) + { + if (v[i].Mounted) + { + if (Debug) + clog << "Checking mounted cdrom device " << v[i].DeviceName << endl; + if (IsCorrectCD(Get, v[i].MountPath)) + { + CDROM = v[i].MountPath; + return true; + } + } + } + + // we are not supposed to mount, exit + if (_config->FindB("APT::CDROM::NoMount",false) == true) + return false; + + // check if we have the mount point + if (!FileExists("/media/apt")) + mkdir("/media/apt", 0755); + + // now try mounting + for (unsigned int i=0; i < v.size(); i++) + { + if (!v[i].Mounted) + { + if(MountCdrom("/media/apt", v[i].DeviceName)) + { + if (IsCorrectCD(Get, "/media/apt")) + { + MountedByApt = true; + CDROM = "/media/apt"; + return true; + } else { + UnmountCdrom("/media/apt"); + } + } + } + } + + return false; +} + /*}}}*/ +// CDROMMethod::IsCorrectCD /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool CDROMMethod::IsCorrectCD(URI want, string MountPath) +{ + string NewID; + + for (unsigned int Version = 2; Version != 0; Version--) + { + if (IdentCdrom(MountPath,NewID,Version) == false) + return false; + + if (Debug) + clog << "ID " << Version << " " << NewID << endl; + + // A hit + if (Database.Find("CD::" + NewID) == want.Host) + return true; + } + + return false; +} + /*}}}*/ // CDROMMethod::Fetch - Fetch a file /*{{{*/ // --------------------------------------------------------------------- /* */ bool CDROMMethod::Fetch(FetchItem *Itm) { + FetchResult Res; + URI Get = Itm->Uri; string File = Get.Path; - FetchResult Res; + Debug = _config->FindB("Debug::Acquire::cdrom", false); - bool Debug = _config->FindB("Debug::Acquire::cdrom",false); + if (Debug) + clog << "CDROMMethod::Fetch " << Itm->Uri << endl; /* All IMS queries are returned as a hit, CDROMs are readonly so time stamps never change */ @@ -126,38 +212,31 @@ bool CDROMMethod::Fetch(FetchItem *Itm) } // We already have a CD inserted, but it is the wrong one - if (CurrentID.empty() == false && Database.Find("CD::" + CurrentID) != Get.Host) + if (CurrentID.empty() == false && + CurrentID != "FAIL" && + Database.Find("CD::" + CurrentID) != Get.Host) { Fail(_("Wrong CD-ROM"),true); return true; } - + CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/"); + if (Debug) + clog << "Looking for CDROM at " << CDROM << endl; + if (CDROM[0] == '.') CDROM= SafeGetCWD() + '/' + CDROM; string NewID; + while (CurrentID.empty() == true) { - bool Hit = false; + if (CDROM == "apt-udev-auto/") + AutoDetectAndMount(Get); + if(!IsMounted(CDROM)) MountedByApt = MountCdrom(CDROM); - for (unsigned int Version = 2; Version != 0; Version--) - { - if (IdentCdrom(CDROM,NewID,Version) == false) - return false; - - if (Debug == true) - clog << "ID " << Version << " " << NewID << endl; - // A hit - if (Database.Find("CD::" + NewID) == Get.Host) - { - Hit = true; - break; - } - } - - if (Hit == true) + if (IsCorrectCD(Get, CDROM)) break; // I suppose this should prompt somehow? |