// -*- mode: cpp; mode: fold -*- // Description /*{{{*/ // $Id: cdrom.cc,v 1.8 1999/03/28 01:37:26 jgg Exp $ /* ###################################################################### CDROM URI method for APT ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ #include #include #include #include #include #include #include /*}}}*/ class CDROMMethod : public pkgAcqMethod { Configuration Database; bool DatabaseLoaded; string CurrentID; virtual bool Fetch(FetchItem *Itm); string GetID(string Name); public: CDROMMethod(); }; // CDROMMethod::CDROMethod - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ CDROMMethod::CDROMMethod() : pkgAcqMethod("1.0",SingleInstance | LocalOnly | SendConfig), DatabaseLoaded(false) { }; /*}}}*/ // CDROMMethod::GetID - Get the ID hash for /*{{{*/ // --------------------------------------------------------------------- /* We search the configuration space for the name and then return the ID tag associated with it. */ string CDROMMethod::GetID(string Name) { if (DatabaseLoaded == false) { // Read the database string DFile = _config->FindFile("Dir::State::cdroms"); if (FileExists(DFile) == true) { if (ReadConfigFile(Database,DFile) == false) { _error->Error("Unable to read the cdrom database %s", DFile.c_str()); return string(); } } DatabaseLoaded = true; } const Configuration::Item *Top = Database.Tree("CD"); if (Top != 0) Top = Top->Child; for (; Top != 0;) { if (Top->Value == Name) return Top->Tag; Top = Top->Next; } return string(); } /*}}}*/ // CDROMMethod::Fetch - Fetch a file /*{{{*/ // --------------------------------------------------------------------- /* */ bool CDROMMethod::Fetch(FetchItem *Itm) { URI Get = Itm->Uri; string File = Get.Path; FetchResult Res; /* All IMS queries are returned as a hit, CDROMs are readonly so time stamps never change */ if (Itm->LastModified != 0) { Res.LastModified = Itm->LastModified; Res.IMSHit = true; URIDone(Res); return true; } string ID = GetID(Get.Host); if (_error->PendingError() == true) return false; // All non IMS queries for package files fail. if (Itm->IndexFile == true || ID.empty() == true) { Fail("Please use apt-cdrom to make this CD recognized by APT." " apt-get update cannot be used to add new CDs"); return true; } // We already have a CD inserted, but it is the wrong one if (CurrentID.empty() == false && ID != CurrentID) { Fail("Wrong CD",true); return true; } string CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/"); if (CDROM[0] == '.') CDROM= SafeGetCWD() + '/' + CDROM; string NewID; while (1) { if (IdentCdrom(CDROM,NewID) == false) return false; // A hit if (NewID == ID) break; // I suppose this should prompt somehow? if (UnmountCdrom(CDROM) == false) return _error->Error("Unable to unmount the CD-ROM in %s, it may still be in use.", CDROM.c_str()); if (MediaFail(Get.Host,CDROM) == false) { CurrentID = "FAIL"; Fail("Wrong CD",true); return true; } MountCdrom(CDROM); } // ID matches if (NewID == ID) { Res.Filename = CDROM + File; struct stat Buf; if (stat(Res.Filename.c_str(),&Buf) != 0) return _error->Error("File not found"); CurrentID = ID; Res.LastModified = Buf.st_mtime; Res.IMSHit = true; Res.Size = Buf.st_size; URIDone(Res); return true; } return _error->Error("CDROM not found"); } /*}}}*/ int main() { CDROMMethod Mth; return Mth.Run(); }