From 8e372e79de1277f3508c20c2eb486165402e5afc Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 8 Jul 2009 14:39:32 +0200 Subject: prototype for libudev dlopen() type of cdrom detection --- methods/cdrom.cc | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- methods/makefile | 2 +- 2 files changed, 62 insertions(+), 5 deletions(-) (limited to 'methods') diff --git a/methods/cdrom.cc b/methods/cdrom.cc index 601bc11c9..0310b66cd 100644 --- a/methods/cdrom.cc +++ b/methods/cdrom.cc @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -24,6 +25,23 @@ using namespace std; +struct udev; +struct udev_list_entry; + +// libudev dlopen stucture +struct udev_p { + struct udev* (*udev_new)(void); + int (*udev_enumerate_add_match_property)(struct udev_enumerate *udev_enumerate, const char *property, const char *value); + int (*udev_enumerate_scan_devices)(struct udev_enumerate *udev_enumerate); + struct udev_list_entry *(*udev_enumerate_get_list_entry)(struct udev_enumerate *udev_enumerate); + struct udev_device *(*udev_device_new_from_syspath)(struct udev *udev, const char *syspath); + struct udev *(*udev_enumerate_get_udev)(struct udev_enumerate *udev_enumerate); + const char *(*udev_list_entry_get_name)(struct udev_list_entry *list_entry); + const char *(*udev_device_get_devnode)(struct udev_device *udev_device); + struct udev_enumerate *(*udev_enumerate_new) (struct udev *udev); + struct udev_list_entry *(*udev_list_entry_get_next)(struct udev_list_entry *list_entry); +}; + class CDROMMethod : public pkgAcqMethod { bool DatabaseLoaded; @@ -31,11 +49,12 @@ class CDROMMethod : public pkgAcqMethod string CurrentID; string CDROM; bool MountedByApt; - + vector CdromDevices; + virtual bool Fetch(FetchItem *Itm); string GetID(string Name); virtual void Exit(); - + public: CDROMMethod(); @@ -50,14 +69,52 @@ CDROMMethod::CDROMMethod() : pkgAcqMethod("1.0",SingleInstance | LocalOnly | DatabaseLoaded(false), MountedByApt(false) { + // see if we can get libudev + void *h = dlopen("libudev.so.0", RTLD_LAZY); + if (h) { + // the pointers for the udev struct + struct udev_p p; + p.udev_new = (udev* (*)(void)) dlsym(h, "udev_new"); + p.udev_enumerate_add_match_property = (int (*)(udev_enumerate*, const char*, const char*))dlsym(h, "udev_enumerate_add_match_property"); + p.udev_enumerate_scan_devices = (int (*)(udev_enumerate*))dlsym(h, "udev_enumerate_scan_devices"); + p.udev_enumerate_get_list_entry = (udev_list_entry* (*)(udev_enumerate*))dlsym(h, "udev_enumerate_get_list_entry"); + p.udev_device_new_from_syspath = (udev_device* (*)(udev*, const char*))dlsym(h, "udev_device_new_from_syspath"); + p.udev_enumerate_get_udev = (udev* (*)(udev_enumerate*))dlsym(h, "udev_enumerate_get_udev"); + p.udev_list_entry_get_name = (const char* (*)(udev_list_entry*))dlsym(h, "udev_list_entry_get_name"); + p.udev_device_get_devnode = (const char* (*)(udev_device*))dlsym(h, "udev_device_get_devnode"); + p.udev_enumerate_new = (udev_enumerate* (*)(udev*))dlsym(h, "udev_enumerate_new"); + p.udev_list_entry_get_next = (udev_list_entry* (*)(udev_list_entry*))dlsym(h, "udev_list_entry_get_next"); + struct udev_enumerate *enumerate; + struct udev_list_entry *l, *devices; + struct udev *udev_ctx; + + udev_ctx = p.udev_new(); + enumerate = p.udev_enumerate_new (udev_ctx); + p.udev_enumerate_add_match_property(enumerate, "ID_CDROM", "1"); + + p.udev_enumerate_scan_devices (enumerate); + devices = p.udev_enumerate_get_list_entry (enumerate); + for (l = devices; l != NULL; l = p.udev_list_entry_get_next (l)) + { + struct udev_device *udevice; + udevice = p.udev_device_new_from_syspath (p.udev_enumerate_get_udev (enumerate), p.udev_list_entry_get_name (l)); + if (udevice == NULL) + continue; + const char* devnode = p.udev_device_get_devnode(udevice); + //std::cerr << devnode << std::endl; + CdromDevices.push_back(string(devnode)); + } + } + + }; /*}}}*/ // CDROMMethod::Exit - Unmount the disc if necessary /*{{{*/ // --------------------------------------------------------------------- /* */ void CDROMMethod::Exit() -{ - if (MountedByApt == true) +{ + if (MountedByApt == true) UnmountCdrom(CDROM); } /*}}}*/ diff --git a/methods/makefile b/methods/makefile index 78bdbc96f..c447b4732 100644 --- a/methods/makefile +++ b/methods/makefile @@ -40,7 +40,7 @@ include $(PROGRAM_H) # The cdrom method PROGRAM=cdrom -SLIBS = -lapt-pkg $(INTLLIBS) +SLIBS = -lapt-pkg -ldl $(INTLLIBS) LIB_MAKES = apt-pkg/makefile SOURCE = cdrom.cc include $(PROGRAM_H) -- cgit v1.2.3 From cbc9bed8ae85af36ad8579476ab91e89c3cd310e Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 9 Jul 2009 17:16:05 +0200 Subject: move libudev based code into libapt cdrom.cc class --- methods/cdrom.cc | 54 ------------------------------------------------------ 1 file changed, 54 deletions(-) (limited to 'methods') diff --git a/methods/cdrom.cc b/methods/cdrom.cc index 0310b66cd..7a20ae514 100644 --- a/methods/cdrom.cc +++ b/methods/cdrom.cc @@ -25,23 +25,6 @@ using namespace std; -struct udev; -struct udev_list_entry; - -// libudev dlopen stucture -struct udev_p { - struct udev* (*udev_new)(void); - int (*udev_enumerate_add_match_property)(struct udev_enumerate *udev_enumerate, const char *property, const char *value); - int (*udev_enumerate_scan_devices)(struct udev_enumerate *udev_enumerate); - struct udev_list_entry *(*udev_enumerate_get_list_entry)(struct udev_enumerate *udev_enumerate); - struct udev_device *(*udev_device_new_from_syspath)(struct udev *udev, const char *syspath); - struct udev *(*udev_enumerate_get_udev)(struct udev_enumerate *udev_enumerate); - const char *(*udev_list_entry_get_name)(struct udev_list_entry *list_entry); - const char *(*udev_device_get_devnode)(struct udev_device *udev_device); - struct udev_enumerate *(*udev_enumerate_new) (struct udev *udev); - struct udev_list_entry *(*udev_list_entry_get_next)(struct udev_list_entry *list_entry); -}; - class CDROMMethod : public pkgAcqMethod { bool DatabaseLoaded; @@ -49,7 +32,6 @@ class CDROMMethod : public pkgAcqMethod string CurrentID; string CDROM; bool MountedByApt; - vector CdromDevices; virtual bool Fetch(FetchItem *Itm); string GetID(string Name); @@ -69,42 +51,6 @@ CDROMMethod::CDROMMethod() : pkgAcqMethod("1.0",SingleInstance | LocalOnly | DatabaseLoaded(false), MountedByApt(false) { - // see if we can get libudev - void *h = dlopen("libudev.so.0", RTLD_LAZY); - if (h) { - // the pointers for the udev struct - struct udev_p p; - p.udev_new = (udev* (*)(void)) dlsym(h, "udev_new"); - p.udev_enumerate_add_match_property = (int (*)(udev_enumerate*, const char*, const char*))dlsym(h, "udev_enumerate_add_match_property"); - p.udev_enumerate_scan_devices = (int (*)(udev_enumerate*))dlsym(h, "udev_enumerate_scan_devices"); - p.udev_enumerate_get_list_entry = (udev_list_entry* (*)(udev_enumerate*))dlsym(h, "udev_enumerate_get_list_entry"); - p.udev_device_new_from_syspath = (udev_device* (*)(udev*, const char*))dlsym(h, "udev_device_new_from_syspath"); - p.udev_enumerate_get_udev = (udev* (*)(udev_enumerate*))dlsym(h, "udev_enumerate_get_udev"); - p.udev_list_entry_get_name = (const char* (*)(udev_list_entry*))dlsym(h, "udev_list_entry_get_name"); - p.udev_device_get_devnode = (const char* (*)(udev_device*))dlsym(h, "udev_device_get_devnode"); - p.udev_enumerate_new = (udev_enumerate* (*)(udev*))dlsym(h, "udev_enumerate_new"); - p.udev_list_entry_get_next = (udev_list_entry* (*)(udev_list_entry*))dlsym(h, "udev_list_entry_get_next"); - struct udev_enumerate *enumerate; - struct udev_list_entry *l, *devices; - struct udev *udev_ctx; - - udev_ctx = p.udev_new(); - enumerate = p.udev_enumerate_new (udev_ctx); - p.udev_enumerate_add_match_property(enumerate, "ID_CDROM", "1"); - - p.udev_enumerate_scan_devices (enumerate); - devices = p.udev_enumerate_get_list_entry (enumerate); - for (l = devices; l != NULL; l = p.udev_list_entry_get_next (l)) - { - struct udev_device *udevice; - udevice = p.udev_device_new_from_syspath (p.udev_enumerate_get_udev (enumerate), p.udev_list_entry_get_name (l)); - if (udevice == NULL) - continue; - const char* devnode = p.udev_device_get_devnode(udevice); - //std::cerr << devnode << std::endl; - CdromDevices.push_back(string(devnode)); - } - } }; -- cgit v1.2.3 From a6418a4b93376e0e4acf36e88eb1d0ec41e024df Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 22 Jul 2009 18:01:43 +0200 Subject: * methods/cdrom.cc: - add Acquire::Cdrom::mount "apt-udev-auto" magic to allow dynamically finding the cdrom device * apt-pkg/contrib/cdromutl.{h,cc}: - support additional (optional) DeviceName parameter for MountCdrom() --- methods/cdrom.cc | 82 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 17 deletions(-) (limited to 'methods') diff --git a/methods/cdrom.cc b/methods/cdrom.cc index 7a20ae514..cd0d4e512 100644 --- a/methods/cdrom.cc +++ b/methods/cdrom.cc @@ -9,6 +9,7 @@ /*}}}*/ // Include Files /*{{{*/ #include +#include #include #include #include @@ -33,6 +34,7 @@ class CDROMMethod : public pkgAcqMethod string CDROM; bool MountedByApt; + bool IsCorrectCD(URI want, string MountPath); virtual bool Fetch(FetchItem *Itm); string GetID(string Name); virtual void Exit(); @@ -84,6 +86,31 @@ string CDROMMethod::GetID(string Name) return string(); } /*}}}*/ + +// CDROMMethod::IsCorrectCD /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool CDROMMethod::IsCorrectCD(URI want, string MountPath) +{ + bool Debug = _config->FindB("Debug::Acquire::cdrom",false); + string NewID; + + for (unsigned int Version = 2; Version != 0; Version--) + { + if (IdentCdrom(MountPath,NewID,Version) == false) + return false; + + if (Debug == true) + clog << "ID " << Version << " " << NewID << endl; + + // A hit + if (Database.Find("CD::" + NewID) == want.Host) + return true; + } + + return false; +} + /*}}}*/ // CDROMMethod::Fetch - Fetch a file /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -134,8 +161,44 @@ bool CDROMMethod::Fetch(FetchItem *Itm) Fail(_("Wrong CD-ROM"),true); return true; } - + CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/"); + + // auto-detect mode + if (CDROM == "apt-udev-auto/") + { + pkgUdevCdromDevices udev; + if(udev.Dlopen()) + { + vector v = udev.Scan(); + for (unsigned int i=0; i < v.size(); i++) + { + if (!v[i].Mounted) + { + if (!FileExists("/media/apt")) + mkdir("/media/apt", 0755); + if(MountCdrom("/media/apt", v[i].DeviceName)) + { + if (IsCorrectCD(Get, "/media/apt")) + { + MountedByApt = true; + CDROM = "/media/apt"; + break; + } else { + UnmountCdrom("/media/apt"); + } + } + } else { + if (IsCorrectCD(Get, v[i].MountPath)) + { + CDROM = v[i].MountPath; + break; + } + } + } + } + } + if (CDROM[0] == '.') CDROM= SafeGetCWD() + '/' + CDROM; string NewID; @@ -144,23 +207,8 @@ bool CDROMMethod::Fetch(FetchItem *Itm) bool Hit = false; 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? -- cgit v1.2.3 From 49cb36fc56225b02b4c39aea43095de15da75217 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 22 Jul 2009 18:32:08 +0200 Subject: methods/cdrom.cc: move the scan into the loop that waits for a CD --- methods/cdrom.cc | 67 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 28 deletions(-) (limited to 'methods') diff --git a/methods/cdrom.cc b/methods/cdrom.cc index cd0d4e512..a677022ad 100644 --- a/methods/cdrom.cc +++ b/methods/cdrom.cc @@ -121,6 +121,8 @@ bool CDROMMethod::Fetch(FetchItem *Itm) FetchResult Res; 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 */ @@ -156,54 +158,63 @@ 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; - // auto-detect mode - if (CDROM == "apt-udev-auto/") + if (CDROM[0] == '.') + CDROM= SafeGetCWD() + '/' + CDROM; + string NewID; + pkgUdevCdromDevices udev; + + while (CurrentID.empty() == true) { - pkgUdevCdromDevices udev; - if(udev.Dlopen()) + // hrm, ugly the loop here + if (CDROM == "apt-udev-auto/") { - vector v = udev.Scan(); - for (unsigned int i=0; i < v.size(); i++) + if(udev.Dlopen()) { - if (!v[i].Mounted) + vector v = udev.Scan(); + for (unsigned int i=0; i < v.size(); i++) { - if (!FileExists("/media/apt")) - mkdir("/media/apt", 0755); - if(MountCdrom("/media/apt", v[i].DeviceName)) + if (Debug) + clog << "Have cdrom device " << v[i].DeviceName << endl; + if (!v[i].Mounted) { - if (IsCorrectCD(Get, "/media/apt")) + if (!FileExists("/media/apt")) + mkdir("/media/apt", 0755); + if(MountCdrom("/media/apt", v[i].DeviceName)) + { + if (IsCorrectCD(Get, "/media/apt")) + { + MountedByApt = true; + CDROM = "/media/apt"; + break; + } else { + UnmountCdrom("/media/apt"); + } + } + } else { + if (IsCorrectCD(Get, v[i].MountPath)) { - MountedByApt = true; - CDROM = "/media/apt"; + CDROM = v[i].MountPath; break; - } else { - UnmountCdrom("/media/apt"); } } - } else { - if (IsCorrectCD(Get, v[i].MountPath)) - { - CDROM = v[i].MountPath; - break; - } } + } else { + _error->WarningE("udev.Dlopen() failed","foo"); } } - } - if (CDROM[0] == '.') - CDROM= SafeGetCWD() + '/' + CDROM; - string NewID; - while (CurrentID.empty() == true) - { bool Hit = false; if(!IsMounted(CDROM)) MountedByApt = MountCdrom(CDROM); -- cgit v1.2.3 From 76fe5db7153957f8fda437e3bd614312b076f19e Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 23 Jul 2009 09:47:41 +0200 Subject: methods/cdrom.cc: add AutoDetectAndMount method --- methods/cdrom.cc | 105 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 44 deletions(-) (limited to 'methods') diff --git a/methods/cdrom.cc b/methods/cdrom.cc index a677022ad..9802eb46c 100644 --- a/methods/cdrom.cc +++ b/methods/cdrom.cc @@ -29,12 +29,16 @@ 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(); @@ -53,8 +57,7 @@ CDROMMethod::CDROMMethod() : pkgAcqMethod("1.0",SingleInstance | LocalOnly | DatabaseLoaded(false), MountedByApt(false) { - - + UdevCdroms.Dlopen(); }; /*}}}*/ // CDROMMethod::Exit - Unmount the disc if necessary /*{{{*/ @@ -86,13 +89,63 @@ string CDROMMethod::GetID(string Name) return string(); } /*}}}*/ +// CDROMMethod::AutoDetectAndMount /*{{{*/ +// --------------------------------------------------------------------- +/* Modifies class varaiable CDROM to the mountpoint */ +bool CDROMMethod::AutoDetectAndMount(URI Get) +{ + vector 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) { - bool Debug = _config->FindB("Debug::Acquire::cdrom",false); string NewID; for (unsigned int Version = 2; Version != 0; Version--) @@ -100,7 +153,7 @@ bool CDROMMethod::IsCorrectCD(URI want, string MountPath) if (IdentCdrom(MountPath,NewID,Version) == false) return false; - if (Debug == true) + if (Debug) clog << "ID " << Version << " " << NewID << endl; // A hit @@ -116,11 +169,12 @@ bool CDROMMethod::IsCorrectCD(URI want, string MountPath) /* */ 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; @@ -173,49 +227,12 @@ bool CDROMMethod::Fetch(FetchItem *Itm) if (CDROM[0] == '.') CDROM= SafeGetCWD() + '/' + CDROM; string NewID; - pkgUdevCdromDevices udev; while (CurrentID.empty() == true) { - // hrm, ugly the loop here if (CDROM == "apt-udev-auto/") - { - if(udev.Dlopen()) - { - vector v = udev.Scan(); - for (unsigned int i=0; i < v.size(); i++) - { - if (Debug) - clog << "Have cdrom device " << v[i].DeviceName << endl; - if (!v[i].Mounted) - { - if (!FileExists("/media/apt")) - mkdir("/media/apt", 0755); - if(MountCdrom("/media/apt", v[i].DeviceName)) - { - if (IsCorrectCD(Get, "/media/apt")) - { - MountedByApt = true; - CDROM = "/media/apt"; - break; - } else { - UnmountCdrom("/media/apt"); - } - } - } else { - if (IsCorrectCD(Get, v[i].MountPath)) - { - CDROM = v[i].MountPath; - break; - } - } - } - } else { - _error->WarningE("udev.Dlopen() failed","foo"); - } - } + AutoDetectAndMount(Get); - bool Hit = false; if(!IsMounted(CDROM)) MountedByApt = MountCdrom(CDROM); -- cgit v1.2.3