X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/78c9276d29172cbe72fc65ac56bde1627a8f86d1..e5b7e019232f89a97e8ba3cbffa295595daa0351:/apt-pkg/cdrom.cc diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc index 2c40c731d..2635ede76 100644 --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@ -1,28 +1,30 @@ /* */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include #include -#include #include #include #include #include #include -#include "indexcopy.h" - #include using namespace std; @@ -58,23 +60,21 @@ bool pkgCdrom::FindPackages(string CD, return _error->Errno("chdir","Unable to change to %s",CD.c_str()); // Look for a .disk subdirectory - struct stat Buf; - if (stat(".disk",&Buf) == 0) + if (DirectoryExists(".disk") == true) { if (InfoDir.empty() == true) InfoDir = CD + ".disk/"; } // Don't look into directories that have been marked to ingore. - if (stat(".aptignr",&Buf) == 0) + if (RealFileExists(".aptignr") == true) return true; - /* Check _first_ for a signature file as apt-cdrom assumes that all files under a Packages/Source file are in control of that file and stops the scanning */ - if (stat("Release.gpg",&Buf) == 0) + if (RealFileExists("Release.gpg") == true || RealFileExists("InRelease") == true) { SigList.push_back(CD); } @@ -86,7 +86,7 @@ bool pkgCdrom::FindPackages(string CD, for (std::vector::const_iterator c = compressor.begin(); c != compressor.end(); ++c) { - if (stat(std::string("Packages").append(c->Extension).c_str(), &Buf) != 0) + if (RealFileExists(std::string("Packages").append(c->Extension).c_str()) == false) continue; if (_config->FindB("Debug::aptcdrom",false) == true) @@ -101,7 +101,7 @@ bool pkgCdrom::FindPackages(string CD, for (std::vector::const_iterator c = compressor.begin(); c != compressor.end(); ++c) { - if (stat(std::string("Sources").append(c->Extension).c_str(), &Buf) != 0) + if (RealFileExists(std::string("Sources").append(c->Extension).c_str()) == false) continue; if (_config->FindB("Debug::aptcdrom",false) == true) @@ -136,6 +136,7 @@ bool pkgCdrom::FindPackages(string CD, { if (_config->FindB("Debug::aptcdrom",false) == true) std::clog << "Found translation " << Dir->d_name << " in " << CD << "i18n/" << std::endl; + file.erase(file.size() - fileext.size()); TransList.push_back(CD + "i18n/" + file); break; } @@ -270,6 +271,29 @@ bool pkgCdrom::DropBinaryArch(vector &List) --I; // the next entry is at the same index after the erase } + return true; +} + /*}}}*/ +// DropTranslation - Dump unwanted Translation- files /*{{{*/ +// --------------------------------------------------------------------- +/* Here we drop everything that is not configured in Acquire::Languages */ +bool pkgCdrom::DropTranslation(vector &List) +{ + for (unsigned int I = 0; I < List.size(); I++) + { + const char *Start; + if ((Start = strstr(List[I].c_str(), "/Translation-")) == NULL) + continue; + Start += strlen("/Translation-"); + + if (APT::Configuration::checkLanguage(Start, true) == true) + continue; + + // not accepted -> Erase it + List.erase(List.begin() + I); + --I; // the next entry is at the same index after the erase + } + return true; } /*}}}*/ @@ -278,6 +302,7 @@ bool pkgCdrom::DropBinaryArch(vector &List) /* Here we go and stat every file that we found and strip dup inodes. */ bool pkgCdrom::DropRepeats(vector &List,const char *Name) { + bool couldFindAllFiles = true; // Get a list of all the inodes ino_t *Inodes = new ino_t[List.size()]; for (unsigned int I = 0; I != List.size(); ++I) @@ -298,21 +323,22 @@ bool pkgCdrom::DropRepeats(vector &List,const char *Name) } if (found == false) - _error->Errno("stat","Failed to stat %s%s",List[I].c_str(), Name); + { + _error->Errno("stat","Failed to stat %s%s",List[I].c_str(), Name); + couldFindAllFiles = false; + Inodes[I] = 0; + } } - if (_error->PendingError() == true) { - delete[] Inodes; - return false; - } - // Look for dups for (unsigned int I = 0; I != List.size(); I++) { + if (Inodes[I] == 0) + continue; for (unsigned int J = I+1; J < List.size(); J++) { // No match - if (Inodes[J] != Inodes[I]) + if (Inodes[J] == 0 || Inodes[J] != Inodes[I]) continue; // We score the two paths.. and erase one @@ -338,14 +364,14 @@ bool pkgCdrom::DropRepeats(vector &List,const char *Name) List.erase(List.begin()+I); } - return true; + return couldFindAllFiles; } /*}}}*/ // ReduceSourceList - Takes the path list and reduces it /*{{{*/ // --------------------------------------------------------------------- /* This takes the list of source list expressed entires and collects similar ones to form a single entry for each dist */ -void pkgCdrom::ReduceSourcelist(string CD,vector &List) +void pkgCdrom::ReduceSourcelist(string /*CD*/,vector &List) { sort(List.begin(),List.end()); @@ -362,6 +388,7 @@ void pkgCdrom::ReduceSourcelist(string CD,vector &List) string Word1 = string(*I,Space,SSpace-Space); string Prefix = string(*I,0,Space); + string Component = string(*I,SSpace); for (vector::iterator J = List.begin(); J != I; ++J) { // Find a space.. @@ -376,9 +403,11 @@ void pkgCdrom::ReduceSourcelist(string CD,vector &List) continue; if (string(*J,Space2,SSpace2-Space2) != Word1) continue; - - *J += string(*I,SSpace); - *I = string(); + + string Component2 = string(*J, SSpace2) + " "; + if (Component2.find(Component + " ") == std::string::npos) + *J += Component; + I->clear(); } } @@ -408,28 +437,12 @@ bool pkgCdrom::WriteDatabase(Configuration &Cnf) /* Write out all of the configuration directives by walking the configuration tree */ - const Configuration::Item *Top = Cnf.Tree(0); - for (; Top != 0;) - { - // Print the config entry - if (Top->Value.empty() == false) - Out << Top->FullTag() + " \"" << Top->Value << "\";" << endl; - - if (Top->Child != 0) - { - Top = Top->Child; - continue; - } - - while (Top != 0 && Top->Next == 0) - Top = Top->Parent; - if (Top != 0) - Top = Top->Next; - } + Cnf.Dump(Out, NULL, "%f \"%v\";\n", false); Out.close(); - - link(DFile.c_str(),string(DFile + '~').c_str()); + + if (FileExists(DFile) == true) + 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()); @@ -542,7 +555,7 @@ bool pkgCdrom::WriteSourceList(string Name,vector &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()); @@ -550,45 +563,68 @@ bool pkgCdrom::WriteSourceList(string Name,vector &List,bool Source) return true; } /*}}}*/ -bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) /*{{{*/ +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); + } + + // 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) + { + if(log != NULL) + log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST); + 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."); } - 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.. ")); - + log->Update(_("Identifying... "), STEP_IDENT); if (IdentCdrom(CDROM,ident) == false) { ident = ""; + if (log != NULL) + log->Update("\n"); 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) { @@ -596,12 +632,22 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) /*{{{*/ 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 @@ -617,70 +663,13 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) /*{{{*/ /*}}}*/ 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 List; @@ -696,7 +685,8 @@ bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/ return false; } - chdir(StartDir.c_str()); + if (chdir(StartDir.c_str()) != 0) + return _error->Errno("chdir","Unable to change to %s", StartDir.c_str()); if (_config->FindB("Debug::aptcdrom",false) == true) { @@ -717,15 +707,23 @@ bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/ DropBinaryArch(List); DropRepeats(List,"Packages"); DropRepeats(SourceList,"Sources"); + // FIXME: We ignore stat() errors here as we usually have only one of those in use + // This has little potencial to drop 'valid' stat() errors as we know that one of these + // files need to exist, but it would be better if we would check it here + _error->PushToStack(); DropRepeats(SigList,"Release.gpg"); + DropRepeats(SigList,"InRelease"); + _error->RevertToStack(); DropRepeats(TransList,""); + 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) @@ -744,7 +742,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/ if (InfoDir.empty() == false && FileExists(InfoDir + "/info") == true) { - ifstream F(string(InfoDir + "/info").c_str()); + ifstream F((InfoDir + "/info").c_str()); if (!F == 0) getline(F,Name); @@ -758,9 +756,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); } @@ -804,11 +802,19 @@ 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/"; + if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::State"), partialListDir) == false && + CreateAPTDirectoryIfNeeded(listDir, partialListDir) == false) + 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; @@ -856,7 +862,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/ if(log != NULL) { - msg.str(""); + stringstream msg; msg << "deb cdrom:[" << Name << "]/" << string(*I,0,Space) << " " << string(*I,Space+1) << endl; log->Update(msg.str()); @@ -874,7 +880,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/ } 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()); @@ -932,10 +938,10 @@ pkgUdevCdromDevices::Dlopen() /*{{{*/ // convenience interface, this will just call ScanForRemovable vector pkgUdevCdromDevices::Scan() -{ +{ bool CdromOnly = _config->FindB("APT::cdrom::CdromOnly", true); - return ScanForRemovable(CdromOnly); -}; + return ScanForRemovable(CdromOnly); +} /*}}}*/ /*{{{*/ vector @@ -980,7 +986,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;