From a06f61bbb328ee218afbd367248f6f2338186e19 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 8 Apr 2009 22:49:23 +0200 Subject: * methods/gpgv.cc: - properly check for expired and revoked keys (closes: #433091) --- methods/gpgv.cc | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'methods') diff --git a/methods/gpgv.cc b/methods/gpgv.cc index 9f4683e6e..470b47fd4 100644 --- a/methods/gpgv.cc +++ b/methods/gpgv.cc @@ -17,13 +17,18 @@ #define GNUPGBADSIG "[GNUPG:] BADSIG" #define GNUPGNOPUBKEY "[GNUPG:] NO_PUBKEY" #define GNUPGVALIDSIG "[GNUPG:] VALIDSIG" +#define GNUPGGOODSIG "[GNUPG:] GOODSIG" +#define GNUPGKEYEXPIRED "[GNUPG:] KEYEXPIRED" +#define GNUPGREVKEYSIG "[GNUPG:] REVKEYSIG" #define GNUPGNODATA "[GNUPG:] NODATA" class GPGVMethod : public pkgAcqMethod { private: string VerifyGetSigners(const char *file, const char *outfile, - vector &GoodSigners, vector &BadSigners, + vector &GoodSigners, + vector &BadSigners, + vector &WorthlessSigners, vector &NoPubKeySigners); protected: @@ -37,6 +42,7 @@ class GPGVMethod : public pkgAcqMethod string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, vector &GoodSigners, vector &BadSigners, + vector &WorthlessSigners, vector &NoPubKeySigners) { // setup a (empty) stringstream for formating the return value @@ -179,15 +185,27 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, std::cerr << "Got NODATA! " << std::endl; BadSigners.push_back(string(buffer+sizeof(GNUPGPREFIX))); } - if (strncmp(buffer, GNUPGVALIDSIG, sizeof(GNUPGVALIDSIG)-1) == 0) + if (strncmp(buffer, GNUPGKEYEXPIRED, sizeof(GNUPGKEYEXPIRED)-1) == 0) + { + if (_config->FindB("Debug::Acquire::gpgv", false)) + std::cerr << "Got KEYEXPIRED! " << std::endl; + WorthlessSigners.push_back(string(buffer+sizeof(GNUPGPREFIX))); + } + if (strncmp(buffer, GNUPGREVKEYSIG, sizeof(GNUPGREVKEYSIG)-1) == 0) + { + if (_config->FindB("Debug::Acquire::gpgv", false)) + std::cerr << "Got REVKEYSIG! " << std::endl; + WorthlessSigners.push_back(string(buffer+sizeof(GNUPGPREFIX))); + } + if (strncmp(buffer, GNUPGGOODSIG, sizeof(GNUPGGOODSIG)-1) == 0) { char *sig = buffer + sizeof(GNUPGPREFIX); - char *p = sig + sizeof("VALIDSIG"); + char *p = sig + sizeof("GOODSIG"); while (*p && isxdigit(*p)) p++; *p = 0; if (_config->FindB("Debug::Acquire::gpgv", false)) - std::cerr << "Got VALIDSIG, key ID:" << sig << std::endl; + std::cerr << "Got GOODSIG, key ID:" << sig << std::endl; GoodSigners.push_back(string(sig)); } } @@ -227,6 +245,8 @@ bool GPGVMethod::Fetch(FetchItem *Itm) string keyID; vector GoodSigners; vector BadSigners; + // a worthless signature is a expired or revoked one + vector WorthlessSigners; vector NoPubKeySigners; FetchResult Res; @@ -235,13 +255,14 @@ bool GPGVMethod::Fetch(FetchItem *Itm) // Run gpgv on file, extract contents and get the key ID of the signer string msg = VerifyGetSigners(Path.c_str(), Itm->DestFile.c_str(), - GoodSigners, BadSigners, NoPubKeySigners); + GoodSigners, BadSigners, WorthlessSigners, + NoPubKeySigners); if (GoodSigners.empty() || !BadSigners.empty() || !NoPubKeySigners.empty()) { string errmsg; // In this case, something bad probably happened, so we just go // with what the other method gave us for an error message. - if (BadSigners.empty() && NoPubKeySigners.empty()) + if (BadSigners.empty() && WorthlessSigners.empty() && NoPubKeySigners.empty()) errmsg = msg; else { @@ -252,6 +273,13 @@ bool GPGVMethod::Fetch(FetchItem *Itm) I != BadSigners.end(); I++) errmsg += (*I + "\n"); } + if (!WorthlessSigners.empty()) + { + errmsg += _("The following signatures were invalid:\n"); + for (vector::iterator I = WorthlessSigners.begin(); + I != WorthlessSigners.end(); I++) + errmsg += (*I + "\n"); + } if (!NoPubKeySigners.empty()) { errmsg += _("The following signatures couldn't be verified because the public key is not available:\n"); -- cgit v1.2.3 From 09fab2442c2ab9a503841d3dcd56b3c0c3efb502 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 9 Apr 2009 04:36:34 +0200 Subject: * apt-pkg/contrib/strutl.cc: - fix TimeToStr i18n (LP: #289807) * [ABI break] merge support for http redirects, thanks to Jeff Licquia and Anthony Towns * [ABI break] use int for the package IDs (thanks to Steve Cotton) * apt-pkg/pkgcache.cc: - do not run "dpkg --configure pkg" if pkg is in trigger-awaited state (LP: #322955) * methods/https.cc: - add Acquire::https::AllowRedirect support * Clarify the --help for 'purge' (LP: #243948) * cmdline/apt-get.cc - fix "apt-get source pkg" if there is a binary package and a source package of the same name but from different packages (LP: #330103) * cmdline/acqprogress.cc: - Call pkgAcquireStatus::Pulse even if quiet, so that we still get dlstatus messages on the status-fd (LP: #290234). --- methods/http.cc | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- methods/http.h | 3 +++ methods/https.cc | 6 ++++- methods/makefile | 2 +- 4 files changed, 86 insertions(+), 3 deletions(-) (limited to 'methods') diff --git a/methods/http.cc b/methods/http.cc index b3c791fa0..1bf798da4 100644 --- a/methods/http.cc +++ b/methods/http.cc @@ -39,6 +39,7 @@ #include #include #include +#include #include // Internet stuff @@ -57,6 +58,7 @@ int HttpMethod::FailFd = -1; time_t HttpMethod::FailTime = 0; unsigned long PipelineDepth = 10; unsigned long TimeOut = 120; +bool AllowRedirect = false; bool Debug = false; URI Proxy; @@ -628,6 +630,12 @@ bool ServerState::HeaderLine(string Line) return true; } + if (stringcasecmp(Tag,"Location:") == 0) + { + Location = Val; + return true; + } + return true; } /*}}}*/ @@ -900,7 +908,9 @@ bool HttpMethod::ServerDie(ServerState *Srv) 1 - IMS hit 3 - Unrecoverable error 4 - Error with error content page - 5 - Unrecoverable non-server error (close the connection) */ + 5 - Unrecoverable non-server error (close the connection) + 6 - Try again with a new or changed URI + */ int HttpMethod::DealWithHeaders(FetchResult &Res,ServerState *Srv) { // Not Modified @@ -912,6 +922,27 @@ int HttpMethod::DealWithHeaders(FetchResult &Res,ServerState *Srv) return 1; } + /* Redirect + * + * Note that it is only OK for us to treat all redirection the same + * because we *always* use GET, not other HTTP methods. There are + * three redirection codes for which it is not appropriate that we + * redirect. Pass on those codes so the error handling kicks in. + */ + if (AllowRedirect + && (Srv->Result > 300 && Srv->Result < 400) + && (Srv->Result != 300 // Multiple Choices + && Srv->Result != 304 // Not Modified + && Srv->Result != 306)) // (Not part of HTTP/1.1, reserved) + { + if (!Srv->Location.empty()) + { + NextURI = Srv->Location; + return 6; + } + /* else pass through for error message */ + } + /* We have a reply we dont handle. This should indicate a perm server failure */ if (Srv->Result < 200 || Srv->Result >= 300) @@ -1026,6 +1057,7 @@ bool HttpMethod::Configuration(string Message) if (pkgAcqMethod::Configuration(Message) == false) return false; + AllowRedirect = _config->FindB("Acquire::http::AllowRedirect",true); TimeOut = _config->FindI("Acquire::http::Timeout",TimeOut); PipelineDepth = _config->FindI("Acquire::http::Pipeline-Depth", PipelineDepth); @@ -1039,6 +1071,10 @@ bool HttpMethod::Configuration(string Message) /* */ int HttpMethod::Loop() { + typedef vector StringVector; + typedef vector::iterator StringVectorIterator; + map Redirected; + signal(SIGTERM,SigTerm); signal(SIGINT,SigTerm); @@ -1225,6 +1261,46 @@ int HttpMethod::Loop() break; } + // Try again with a new URL + case 6: + { + // Clear rest of response if there is content + if (Server->HaveContent) + { + File = new FileFd("/dev/null",FileFd::WriteExists); + Server->RunData(); + delete File; + File = 0; + } + + /* Detect redirect loops. No more redirects are allowed + after the same URI is seen twice in a queue item. */ + StringVector &R = Redirected[Queue->DestFile]; + bool StopRedirects = false; + if (R.size() == 0) + R.push_back(Queue->Uri); + else if (R[0] == "STOP" || R.size() > 10) + StopRedirects = true; + else + { + for (StringVectorIterator I = R.begin(); I != R.end(); I++) + if (Queue->Uri == *I) + { + R[0] = "STOP"; + break; + } + + R.push_back(Queue->Uri); + } + + if (StopRedirects == false) + Redirect(NextURI); + else + Fail(); + + break; + } + default: Fail(_("Internal error")); break; diff --git a/methods/http.h b/methods/http.h index 6753a9901..13f02ec77 100644 --- a/methods/http.h +++ b/methods/http.h @@ -99,6 +99,7 @@ struct ServerState enum {Chunked,Stream,Closes} Encoding; enum {Header, Data} State; bool Persistent; + string Location; // This is a Persistent attribute of the server itself. bool Pipeline; @@ -143,6 +144,8 @@ class HttpMethod : public pkgAcqMethod static time_t FailTime; static void SigTerm(int); + string NextURI; + public: friend class ServerState; diff --git a/methods/https.cc b/methods/https.cc index 98dfeefa1..8bf44b52a 100644 --- a/methods/https.cc +++ b/methods/https.cc @@ -208,6 +208,11 @@ bool HttpsMethod::Fetch(FetchItem *Itm) curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout); + // set redirect options and default to 10 redirects + bool AllowRedirect = _config->FindI("Acquire::https::AllowRedirect", true); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, AllowRedirect); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10); + // debug if(_config->FindB("Debug::Acquire::https", false)) curl_easy_setopt(curl, CURLOPT_VERBOSE, true); @@ -248,7 +253,6 @@ bool HttpsMethod::Fetch(FetchItem *Itm) // cleanup if(success != 0) { - unlink(File->Name().c_str()); _error->Error("%s", curl_errorstr); Fail(); return true; diff --git a/methods/makefile b/methods/makefile index d9481dbcc..78bdbc96f 100644 --- a/methods/makefile +++ b/methods/makefile @@ -7,7 +7,7 @@ include ../buildlib/defaults.mak BIN := $(BIN)/methods # FIXME.. -LIB_APT_PKG_MAJOR = 4.6 +LIB_APT_PKG_MAJOR = 4.7 APT_DOMAIN := libapt-pkg$(LIB_APT_PKG_MAJOR) # The file method -- cgit v1.2.3 From 81e9789b12374073e848c73c79e235f82c14df44 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 9 Jun 2009 17:33:22 +0200 Subject: [ABI break] support '#' in apt.conf and /etc/apt/preferences (closes: #189866) --- methods/makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'methods') diff --git a/methods/makefile b/methods/makefile index 78bdbc96f..589f9fa1c 100644 --- a/methods/makefile +++ b/methods/makefile @@ -7,7 +7,7 @@ include ../buildlib/defaults.mak BIN := $(BIN)/methods # FIXME.. -LIB_APT_PKG_MAJOR = 4.7 +LIB_APT_PKG_MAJOR = 4.8 APT_DOMAIN := libapt-pkg$(LIB_APT_PKG_MAJOR) # The file method -- cgit v1.2.3 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