X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/0fffbc8ce4cb6357f59db63db5571f46a668a66b..9d39208af5c8c72d3886c70d603921cf427056ee:/apt-pkg/cdrom.cc?ds=sidebyside diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc index a9c63fd21..a5668a50a 100644 --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@ -58,66 +58,91 @@ 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); } + /* Aha! We found some package files. We assume that everything under this dir is controlled by those package files so we don't look down anymore */ - if (stat("Packages",&Buf) == 0 || stat("Packages.gz",&Buf) == 0) + std::vector const compressor = APT::Configuration::getCompressors(); + for (std::vector::const_iterator c = compressor.begin(); + c != compressor.end(); ++c) { + if (RealFileExists(std::string("Packages").append(c->Extension).c_str()) == false) + continue; + + if (_config->FindB("Debug::aptcdrom",false) == true) + std::clog << "Found Packages in " << CD << std::endl; List.push_back(CD); - + // Continue down if thorough is given if (_config->FindB("APT::CDROM::Thorough",false) == false) return true; + break; } - if (stat("Sources.gz",&Buf) == 0 || stat("Sources",&Buf) == 0) + for (std::vector::const_iterator c = compressor.begin(); + c != compressor.end(); ++c) { + if (RealFileExists(std::string("Sources").append(c->Extension).c_str()) == false) + continue; + + if (_config->FindB("Debug::aptcdrom",false) == true) + std::clog << "Found Sources in " << CD << std::endl; SList.push_back(CD); - + // Continue down if thorough is given if (_config->FindB("APT::CDROM::Thorough",false) == false) return true; + break; } - // see if we find translatin indexes - if (stat("i18n",&Buf) == 0) + // see if we find translation indices + if (DirectoryExists("i18n") == true) { D = opendir("i18n"); for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D)) { - if(strstr(Dir->d_name,"Translation") != NULL) + if(strncmp(Dir->d_name, "Translation-", strlen("Translation-")) != 0) + continue; + string file = Dir->d_name; + for (std::vector::const_iterator c = compressor.begin(); + c != compressor.end(); ++c) { - if (_config->FindB("Debug::aptcdrom",false) == true) - std::clog << "found translations: " << Dir->d_name << "\n"; - string file = Dir->d_name; - if(file.substr(file.size()-3,file.size()) == ".gz") - file = file.substr(0,file.size()-3); - TransList.push_back(CD+"i18n/"+ file); + string fileext = flExtension(file); + if (file == fileext) + fileext.clear(); + else if (fileext.empty() == false) + fileext = "." + fileext; + + if (c->Extension == fileext) + { + 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; + } } } closedir(D); } - D = opendir("."); if (D == 0) return _error->Errno("opendir","Unable to read %s",CD.c_str()); @@ -244,6 +269,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; } /*}}}*/ @@ -252,30 +300,43 @@ 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++) + for (unsigned int I = 0; I != List.size(); ++I) { struct stat Buf; - if (stat((List[I] + Name).c_str(),&Buf) != 0 && - stat((List[I] + Name + ".gz").c_str(),&Buf) != 0) - _error->Errno("stat","Failed to stat %s%s",List[I].c_str(), - Name); - Inodes[I] = Buf.st_ino; - } - - if (_error->PendingError() == true) { - delete[] Inodes; - return false; + bool found = false; + + std::vector const compressor = APT::Configuration::getCompressors(); + for (std::vector::const_iterator c = compressor.begin(); + c != compressor.end(); ++c) + { + std::string filename = std::string(List[I]).append(Name).append(c->Extension); + if (stat(filename.c_str(), &Buf) != 0) + continue; + Inodes[I] = Buf.st_ino; + found = true; + break; + } + + if (found == false) + { + _error->Errno("stat","Failed to stat %s%s",List[I].c_str(), Name); + couldFindAllFiles = false; + Inodes[I] = 0; + } } - + // 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 @@ -301,7 +362,7 @@ 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 /*{{{*/ @@ -325,6 +386,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.. @@ -339,9 +401,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(); } } @@ -371,28 +435,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(), string(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()); @@ -659,7 +707,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) { @@ -680,8 +729,16 @@ 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, " @@ -772,6 +829,14 @@ bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/ log->Update(msg.str()); 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;