diff options
Diffstat (limited to 'apt-pkg')
-rw-r--r-- | apt-pkg/acquire-item.cc | 94 | ||||
-rw-r--r-- | apt-pkg/acquire.cc | 2 | ||||
-rw-r--r-- | apt-pkg/algorithms.cc | 15 | ||||
-rw-r--r-- | apt-pkg/aptconfiguration.cc | 6 | ||||
-rw-r--r-- | apt-pkg/cachefile.cc | 36 | ||||
-rw-r--r-- | apt-pkg/cachefilter.cc | 2 | ||||
-rw-r--r-- | apt-pkg/cacheset.h | 8 | ||||
-rw-r--r-- | apt-pkg/contrib/fileutl.cc | 86 | ||||
-rw-r--r-- | apt-pkg/contrib/fileutl.h | 6 | ||||
-rw-r--r-- | apt-pkg/contrib/strutl.cc | 6 | ||||
-rw-r--r-- | apt-pkg/deb/deblistparser.cc | 2 | ||||
-rw-r--r-- | apt-pkg/deb/debmetaindex.cc | 36 | ||||
-rw-r--r-- | apt-pkg/deb/dpkgpm.cc | 21 | ||||
-rw-r--r-- | apt-pkg/depcache.cc | 8 | ||||
-rw-r--r-- | apt-pkg/indexcopy.cc | 4 | ||||
-rw-r--r-- | apt-pkg/indexrecords.cc | 5 | ||||
-rw-r--r-- | apt-pkg/orderlist.cc | 14 | ||||
-rw-r--r-- | apt-pkg/packagemanager.cc | 623 | ||||
-rw-r--r-- | apt-pkg/pkgrecords.cc | 2 | ||||
-rw-r--r-- | apt-pkg/pkgsystem.cc | 4 | ||||
-rw-r--r-- | apt-pkg/sourcelist.cc | 2 | ||||
-rw-r--r-- | apt-pkg/srcrecords.cc | 2 | ||||
-rw-r--r-- | apt-pkg/tagfile.cc | 5 | ||||
-rw-r--r-- | apt-pkg/version.cc | 4 |
24 files changed, 612 insertions, 381 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index f231c42b4..a30e98858 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -189,14 +189,14 @@ void pkgAcquire::Item::ReportMirrorFailure(string FailCode) /*}}}*/ // AcqSubIndex::AcqSubIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- -/* Get the Index file first and see if there are languages available - * If so, create a pkgAcqIndexTrans for the found language(s). - */ +/* Get a sub-index file based on checksums from a 'master' file and + possibly query additional files */ pkgAcqSubIndex::pkgAcqSubIndex(pkgAcquire *Owner, string const &URI, string const &URIDesc, string const &ShortDesc, HashString const &ExpectedHash) : Item(Owner), ExpectedHash(ExpectedHash) { + /* XXX: Beware: Currently this class does nothing (of value) anymore ! */ Debug = _config->FindB("Debug::pkgAcquire::SubIndex",false); DestFile = _config->FindDir("Dir::State::lists") + "partial/"; @@ -236,17 +236,7 @@ void pkgAcqSubIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{* Status = StatDone; Dequeue(); - // No good Index is provided, so try guessing - std::vector<std::string> langs = APT::Configuration::getLanguages(true); - for (std::vector<std::string>::const_iterator l = langs.begin(); - l != langs.end(); ++l) - { - if (*l == "none") continue; - string const file = "Translation-" + *l; - new pkgAcqIndexTrans(Owner, Desc.URI.substr(0, Desc.URI.rfind('/')+1).append(file), - Desc.Description.erase(Desc.Description.rfind(' ')+1).append(file), - file); - } + // No good Index is provided } /*}}}*/ void pkgAcqSubIndex::Done(string Message,unsigned long long Size,string Md5Hash, /*{{{*/ @@ -305,38 +295,7 @@ bool pkgAcqSubIndex::ParseIndex(string const &IndexFile) /*{{{*/ indexRecords SubIndexParser; if (FileExists(IndexFile) == false || SubIndexParser.Load(IndexFile) == false) return false; - - std::vector<std::string> lang = APT::Configuration::getLanguages(true); - for (std::vector<std::string>::const_iterator l = lang.begin(); - l != lang.end(); ++l) - { - if (*l == "none") - continue; - - string file = "Translation-" + *l; - indexRecords::checkSum const *Record = SubIndexParser.Lookup(file); - HashString expected; - if (Record == NULL) - { - // FIXME: the Index file provided by debian currently only includes bz2 records - Record = SubIndexParser.Lookup(file + ".bz2"); - if (Record == NULL) - continue; - } - else - { - expected = Record->Hash; - if (expected.empty() == true) - continue; - } - - IndexTarget target; - target.Description = Desc.Description.erase(Desc.Description.rfind(' ')+1).append(file); - target.MetaKey = file; - target.ShortDesc = file; - target.URI = Desc.URI.substr(0, Desc.URI.rfind('/')+1).append(file); - new pkgAcqIndexTrans(Owner, &target, expected, &SubIndexParser); - } + // so something with the downloaded index return true; } /*}}}*/ @@ -1385,6 +1344,18 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify) /*{{{*/ return; } #endif + bool transInRelease = false; + { + std::vector<std::string> const keys = MetaIndexParser->MetaKeys(); + for (std::vector<std::string>::const_iterator k = keys.begin(); k != keys.end(); ++k) + // FIXME: Feels wrong to check for hardcoded string here, but what should we do else… + if (k->find("Translation-") != std::string::npos) + { + transInRelease = true; + break; + } + } + for (vector <struct IndexTarget*>::const_iterator Target = IndexTargets->begin(); Target != IndexTargets->end(); ++Target) @@ -1422,8 +1393,15 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify) /*{{{*/ if ((*Target)->IsSubIndex() == true) new pkgAcqSubIndex(Owner, (*Target)->URI, (*Target)->Description, (*Target)->ShortDesc, ExpectedIndexHash); - else - new pkgAcqIndexTrans(Owner, *Target, ExpectedIndexHash, MetaIndexParser); + else if (transInRelease == false || MetaIndexParser->Exists((*Target)->MetaKey) == true) + { + if (_config->FindB("Acquire::PDiffs",true) == true && transInRelease == true && + MetaIndexParser->Exists(string((*Target)->MetaKey).append(".diff/Index")) == true) + new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description, + (*Target)->ShortDesc, ExpectedIndexHash); + else + new pkgAcqIndexTrans(Owner, *Target, ExpectedIndexHash, MetaIndexParser); + } continue; } @@ -1620,6 +1598,13 @@ void pkgAcqMetaClearSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /* { if (AuthPass == false) { + // Remove the 'old' InRelease file if we try Release.gpg now as otherwise + // the file will stay around and gives a false-auth impression (CVE-2012-0214) + string FinalFile = _config->FindDir("Dir::State::lists"); + FinalFile.append(URItoFileName(RealURI)); + if (FileExists(FinalFile)) + unlink(FinalFile.c_str()); + new pkgAcqMetaSig(Owner, MetaSigURI, MetaSigURIDesc, MetaSigShortDesc, MetaIndexURI, MetaIndexURIDesc, MetaIndexShortDesc, @@ -1825,7 +1810,18 @@ bool pkgAcqArchive::QueueNext() else PartialSize = Buf.st_size; } - + + // Disables download of archives - useful if no real installation follows, + // e.g. if we are just interested in proposed installation order + if (_config->FindB("Debug::pkgAcqArchive::NoQueue", false) == true) + { + Complete = true; + Local = true; + Status = StatDone; + StoreFilename = DestFile = FinalFile; + return true; + } + // Create the item Local = false; Desc.URI = Index->ArchiveURI(PkgFile); diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index cdc3fba4b..573a85c2f 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -766,7 +766,7 @@ void pkgAcquire::Queue::Bump() // AcquireStatus::pkgAcquireStatus - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -pkgAcquireStatus::pkgAcquireStatus() : Update(true), MorePulses(false) +pkgAcquireStatus::pkgAcquireStatus() : d(NULL), Update(true), MorePulses(false) { Start(); } diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index c337ace87..8beb2d51c 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -471,7 +471,7 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache) // ProblemResolver::pkgProblemResolver - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -pkgProblemResolver::pkgProblemResolver(pkgDepCache *pCache) : Cache(*pCache) +pkgProblemResolver::pkgProblemResolver(pkgDepCache *pCache) : d(NULL), Cache(*pCache) { // Allocate memory unsigned long Size = Cache.Head().PackageCount; @@ -556,7 +556,8 @@ void pkgProblemResolver::MakeScores() essantial package above most other packages but low enough to allow an obsolete essential packages to be removed by a conflicts on a powerfull normal package (ie libc6) */ - if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential + || (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) Score += PrioEssentials; // We transform the priority @@ -631,7 +632,8 @@ void pkgProblemResolver::MakeScores() { if ((Flags[I->ID] & Protected) != 0) Scores[I->ID] += AddProtected; - if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential || + (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) Scores[I->ID] += AddEssential; } } @@ -1430,6 +1432,13 @@ static int PrioComp(const void *A,const void *B) if ((L.ParentPkg()->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential && (R.ParentPkg()->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) return -1; + + if ((L.ParentPkg()->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important && + (R.ParentPkg()->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important) + return 1; + if ((L.ParentPkg()->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important && + (R.ParentPkg()->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) + return -1; if (L->Priority != R->Priority) return R->Priority - L->Priority; diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index b5ad74831..4324f0e63 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -376,7 +376,7 @@ std::vector<std::string> const Configuration::getArchitectures(bool const &Cache dup2(nullfd, STDIN_FILENO); dup2(external[1], STDOUT_FILENO); dup2(nullfd, STDERR_FILENO); - execv(Args[0], (char**) &Args[0]); + execvp(Args[0], (char**) &Args[0]); _error->WarningE("getArchitecture", "Can't detect foreign architectures supported by dpkg!"); _exit(100); } @@ -392,7 +392,9 @@ std::vector<std::string> const Configuration::getArchitectures(bool const &Cache if (arch[0] != '\0') { char const* archend = arch; for (; isspace(*archend) == 0 && *archend != '\0'; ++archend); - archs.push_back(string(arch, (archend - arch))); + string a(arch, (archend - arch)); + if (std::find(archs.begin(), archs.end(), a) == archs.end()) + archs.push_back(a); } arch = strtok(NULL, " "); } diff --git a/apt-pkg/cachefile.cc b/apt-pkg/cachefile.cc index 1b8d91a44..7c2276185 100644 --- a/apt-pkg/cachefile.cc +++ b/apt-pkg/cachefile.cc @@ -30,7 +30,7 @@ // CacheFile::CacheFile - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -pkgCacheFile::pkgCacheFile() : Map(NULL), Cache(NULL), DCache(NULL), +pkgCacheFile::pkgCacheFile() : d(NULL), Map(NULL), Cache(NULL), DCache(NULL), SrcList(NULL), Policy(NULL) { } @@ -178,6 +178,40 @@ void pkgCacheFile::RemoveCaches() unlink(pkgcache.c_str()); if (srcpkgcache.empty() == false && RealFileExists(srcpkgcache) == true) unlink(srcpkgcache.c_str()); + if (pkgcache.empty() == false) + { + std::string cachedir = flNotFile(pkgcache); + std::string cachefile = flNotDir(pkgcache); + if (cachedir.empty() != true && cachefile.empty() != true && DirectoryExists(cachedir) == true) + { + cachefile.append("."); + std::vector<std::string> caches = GetListOfFilesInDir(cachedir, false); + for (std::vector<std::string>::const_iterator file = caches.begin(); file != caches.end(); ++file) + { + std::string nuke = flNotDir(*file); + if (strncmp(cachefile.c_str(), nuke.c_str(), cachefile.length()) != 0) + continue; + unlink(file->c_str()); + } + } + } + + if (srcpkgcache.empty() == true) + return; + + std::string cachedir = flNotFile(srcpkgcache); + std::string cachefile = flNotDir(srcpkgcache); + if (cachedir.empty() == true || cachefile.empty() == true || DirectoryExists(cachedir) == false) + return; + cachefile.append("."); + std::vector<std::string> caches = GetListOfFilesInDir(cachedir, false); + for (std::vector<std::string>::const_iterator file = caches.begin(); file != caches.end(); ++file) + { + std::string nuke = flNotDir(*file); + if (strncmp(cachefile.c_str(), nuke.c_str(), cachefile.length()) != 0) + continue; + unlink(file->c_str()); + } } /*}}}*/ // CacheFile::Close - close the cache files /*{{{*/ diff --git a/apt-pkg/cachefilter.cc b/apt-pkg/cachefilter.cc index 210a9a9ab..9ec3fa699 100644 --- a/apt-pkg/cachefilter.cc +++ b/apt-pkg/cachefilter.cc @@ -18,7 +18,7 @@ /*}}}*/ namespace APT { namespace CacheFilter { -PackageNameMatchesRegEx::PackageNameMatchesRegEx(std::string const &Pattern) {/*{{{*/ +PackageNameMatchesRegEx::PackageNameMatchesRegEx(std::string const &Pattern) : d(NULL) {/*{{{*/ pattern = new regex_t; int const Res = regcomp(pattern, Pattern.c_str(), REG_EXTENDED | REG_ICASE | REG_NOSUB); if (Res == 0) diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h index 91d7eec1c..6f0a0e358 100644 --- a/apt-pkg/cacheset.h +++ b/apt-pkg/cacheset.h @@ -191,6 +191,8 @@ public: /*{{{*/ inline iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; } inline bool operator!=(iterator const &i) const { return _iter != i._iter; }; inline bool operator==(iterator const &i) const { return _iter == i._iter; }; + inline iterator& operator=(iterator const &i) { _iter = i._iter; return *this; }; + inline iterator& operator=(typename Container::iterator const &i) { _iter = i; return *this; }; friend std::ostream& operator<<(std::ostream& out, iterator i) { return operator<<(out, *i); } }; /*}}}*/ @@ -201,7 +203,9 @@ public: /*{{{*/ bool empty() const { return _cont.empty(); }; void clear() { return _cont.clear(); }; + //FIXME: on ABI break, replace the first with the second without bool void erase(iterator position) { _cont.erase((typename Container::iterator)position); }; + iterator& erase(iterator &position, bool) { return position = _cont.erase((typename Container::iterator)position); }; size_t erase(const pkgCache::PkgIterator x) { return _cont.erase(x); }; void erase(iterator first, iterator last) { _cont.erase(first, last); }; size_t size() const { return _cont.size(); }; @@ -507,6 +511,8 @@ public: /*{{{*/ inline iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; } inline bool operator!=(iterator const &i) const { return _iter != i._iter; }; inline bool operator==(iterator const &i) const { return _iter == i._iter; }; + inline iterator& operator=(iterator const &i) { _iter = i._iter; return *this; }; + inline iterator& operator=(typename Container::iterator const &i) { _iter = i; return *this; }; friend std::ostream& operator<<(std::ostream& out, iterator i) { return operator<<(out, *i); } }; /*}}}*/ @@ -516,7 +522,9 @@ public: /*{{{*/ void insert(const_iterator begin, const_iterator end) { _cont.insert(begin, end); }; bool empty() const { return _cont.empty(); }; void clear() { return _cont.clear(); }; + //FIXME: on ABI break, replace the first with the second without bool void erase(iterator position) { _cont.erase((typename Container::iterator)position); }; + iterator& erase(iterator &position, bool) { return position = _cont.erase((typename Container::iterator)position); }; size_t erase(const pkgCache::VerIterator x) { return _cont.erase(x); }; void erase(iterator first, iterator last) { _cont.erase(first, last); }; size_t size() const { return _cont.size(); }; diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 28898fc34..1808489d7 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -387,6 +387,13 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c { if (RealFileExists(File.c_str()) == false) { + // do not show ignoration warnings for directories + if ( +#ifdef _DIRENT_HAVE_D_TYPE + Ent->d_type == DT_DIR || +#endif + DirectoryExists(File.c_str()) == true) + continue; if (SilentIgnore.Match(Ent->d_name) == false) _error->Notice(_("Ignoring '%s' in directory '%s' as it is not a regular file"), Ent->d_name, Dir.c_str()); continue; @@ -458,6 +465,80 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c std::sort(List.begin(),List.end()); return List; } +std::vector<string> GetListOfFilesInDir(string const &Dir, bool SortList) +{ + bool const Debug = _config->FindB("Debug::GetListOfFilesInDir", false); + if (Debug == true) + std::clog << "Accept in " << Dir << " all regular files" << std::endl; + + std::vector<string> List; + + if (DirectoryExists(Dir.c_str()) == false) + { + _error->Error(_("List of files can't be created as '%s' is not a directory"), Dir.c_str()); + return List; + } + + DIR *D = opendir(Dir.c_str()); + if (D == 0) + { + _error->Errno("opendir",_("Unable to read %s"),Dir.c_str()); + return List; + } + + for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D)) + { + // skip "hidden" files + if (Ent->d_name[0] == '.') + continue; + + // Make sure it is a file and not something else + string const File = flCombine(Dir,Ent->d_name); +#ifdef _DIRENT_HAVE_D_TYPE + if (Ent->d_type != DT_REG) +#endif + { + if (RealFileExists(File.c_str()) == false) + { + if (Debug == true) + std::clog << "Bad file: " << Ent->d_name << " → it is not a real file" << std::endl; + continue; + } + } + + // Skip bad filenames ala run-parts + const char *C = Ent->d_name; + for (; *C != 0; ++C) + if (isalpha(*C) == 0 && isdigit(*C) == 0 + && *C != '_' && *C != '-' && *C != '.') + break; + + // we don't reach the end of the name -> bad character included + if (*C != 0) + { + if (Debug == true) + std::clog << "Bad file: " << Ent->d_name << " → bad character »" << *C << "« in filename" << std::endl; + continue; + } + + // skip filenames which end with a period. These are never valid + if (*(C - 1) == '.') + { + if (Debug == true) + std::clog << "Bad file: " << Ent->d_name << " → Period as last character" << std::endl; + continue; + } + + if (Debug == true) + std::clog << "Accept file: " << Ent->d_name << " in " << Dir << std::endl; + List.push_back(File); + } + closedir(D); + + if (SortList == true) + std::sort(List.begin(),List.end()); + return List; +} /*}}}*/ // SafeGetCWD - This is a safer getcwd that returns a dynamic string /*{{{*/ // --------------------------------------------------------------------- @@ -890,6 +971,11 @@ bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compre std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors(); std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin(); std::string name; + + // compat with the old API + if (Mode == ReadOnlyGzip && Compress == None) + Compress = Gzip; + switch (Compress) { case None: name = "."; break; diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 8a5025142..1ca41cb7d 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -108,10 +108,7 @@ class FileFd bool OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compress, bool AutoClose=false); bool OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose=false); inline bool OpenDescriptor(int Fd, unsigned int const Mode, bool AutoClose=false) { - if (Mode == ReadOnlyGzip) - return OpenDescriptor(Fd, Mode, Gzip, AutoClose); - else - return OpenDescriptor(Fd, Mode, None, AutoClose); + return OpenDescriptor(Fd, Mode, None, AutoClose); }; bool Close(); bool Sync(); @@ -174,6 +171,7 @@ std::vector<std::string> GetListOfFilesInDir(std::string const &Dir, std::string bool const &SortList, bool const &AllowNoExt=false); std::vector<std::string> GetListOfFilesInDir(std::string const &Dir, std::vector<std::string> const &Ext, bool const &SortList); +std::vector<std::string> GetListOfFilesInDir(std::string const &Dir, bool SortList); std::string SafeGetCWD(); void SetCloseExec(int Fd,bool Close); void SetNonBlock(int Fd,bool Block); diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 861cdcbeb..99efa8d98 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -910,17 +910,17 @@ bool StrToTime(const string &Val,time_t &Result) // Handle RFC 1123 time Month[0] = 0; - if (sscanf(I," %d %3s %d %d:%d:%d GMT",&Tm.tm_mday,Month,&Tm.tm_year, + if (sscanf(I," %2d %3s %4d %2d:%2d:%2d GMT",&Tm.tm_mday,Month,&Tm.tm_year, &Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec) != 6) { // Handle RFC 1036 time - if (sscanf(I," %d-%3s-%d %d:%d:%d GMT",&Tm.tm_mday,Month, + if (sscanf(I," %2d-%3s-%3d %2d:%2d:%2d GMT",&Tm.tm_mday,Month, &Tm.tm_year,&Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec) == 6) Tm.tm_year += 1900; else { // asctime format - if (sscanf(I," %3s %d %d:%d:%d %d",Month,&Tm.tm_mday, + if (sscanf(I," %3s %2d %2d:%2d:%2d %4d",Month,&Tm.tm_mday, &Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec,&Tm.tm_year) != 6) { // 'ftp' time diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index bdb50f6bf..84e6c38c5 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -249,7 +249,7 @@ bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg, return false; if (strcmp(Pkg.Name(),"apt") == 0) - Pkg->Flags |= pkgCache::Flag::Important; + Pkg->Flags |= pkgCache::Flag::Essential | pkgCache::Flag::Important; if (ParseStatus(Pkg,Ver) == false) return false; diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 5d3a80aa5..bcc617da7 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -128,7 +128,7 @@ string debReleaseIndex::TranslationIndexURISuffix(const char *Type, const string { string Res =""; if (Dist[Dist.size() - 1] != '/') - Res += Section + "/i18n/"; + Res += Section + "/i18n/Translation-"; return Res + Type; } @@ -210,31 +210,17 @@ vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const { if (lang.empty() == true) return IndexTargets; - // get the Translations: - // - if its a dists-style repository get the i18n/Index first - // - if its flat try to acquire files by guessing - if (Dist[Dist.size() - 1] == '/') { - for (std::set<std::string>::const_iterator s = sections.begin(); - s != sections.end(); ++s) { - for (std::vector<std::string>::const_iterator l = lang.begin(); - l != lang.end(); ++l) { - IndexTarget * Target = new OptionalIndexTarget(); - Target->ShortDesc = "Translation-" + *l; - Target->MetaKey = TranslationIndexURISuffix(l->c_str(), *s); - Target->URI = TranslationIndexURI(l->c_str(), *s); - Target->Description = Info (Target->ShortDesc.c_str(), *s); - IndexTargets->push_back(Target); - } - } - } else { - for (std::set<std::string>::const_iterator s = sections.begin(); - s != sections.end(); ++s) { - IndexTarget * Target = new OptionalSubIndexTarget(); - Target->ShortDesc = "TranslationIndex"; - Target->MetaKey = TranslationIndexURISuffix("Index", *s); - Target->URI = TranslationIndexURI("Index", *s); + // get the Translation-* files, later we will skip download of non-existent if we have an index + for (std::set<std::string>::const_iterator s = sections.begin(); + s != sections.end(); ++s) { + for (std::vector<std::string>::const_iterator l = lang.begin(); + l != lang.end(); ++l) { + IndexTarget * Target = new OptionalIndexTarget(); + Target->ShortDesc = "Translation-" + *l; + Target->MetaKey = TranslationIndexURISuffix(l->c_str(), *s); + Target->URI = TranslationIndexURI(l->c_str(), *s); Target->Description = Info (Target->ShortDesc.c_str(), *s); - IndexTargets->push_back (Target); + IndexTargets->push_back(Target); } } diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 8c63b0c9b..c46a81209 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -51,8 +51,10 @@ using namespace std; class pkgDPkgPMPrivate { public: - pkgDPkgPMPrivate() : dpkgbuf_pos(0), term_out(NULL), history_out(NULL) + pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0), + term_out(NULL), history_out(NULL) { + dpkgbuf[0] = '\0'; } bool stdin_is_dev_null; // the buffer we use for the dpkg status-fd reading @@ -860,6 +862,8 @@ static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds, */ bool pkgDPkgPM::Go(int OutStatusFd) { + pkgPackageManager::SigINTStop = false; + // Generate the base argument list for dpkg std::vector<const char *> Args; unsigned long StartSize = 0; @@ -905,7 +909,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) dup2(nullfd, STDIN_FILENO); dup2(nullfd, STDOUT_FILENO); dup2(nullfd, STDERR_FILENO); - execv(Args[0], (char**) &Args[0]); + execvp(Args[0], (char**) &Args[0]); _error->WarningE("dpkgGo", "Can't detect if dpkg supports multi-arch!"); _exit(2); } @@ -1429,9 +1433,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) } void SigINT(int sig) { - if (_config->FindB("APT::Immediate-Configure-All",false)) - pkgPackageManager::SigINTStop = true; -} + pkgPackageManager::SigINTStop = true; +} /*}}}*/ // pkgDpkgPM::Reset - Dump the contents of the command list /*{{{*/ // --------------------------------------------------------------------- @@ -1446,6 +1449,12 @@ void pkgDPkgPM::Reset() /* */ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) { + // If apport doesn't exist or isn't installed do nothing + // This e.g. prevents messages in 'universes' without apport + pkgCache::PkgIterator apportPkg = Cache.FindPkg("apport"); + if (apportPkg.end() == true || apportPkg->CurrentVer == 0) + return; + string pkgname, reportfile, srcpkgname, pkgver, arch; string::size_type pos; FILE *report; @@ -1533,7 +1542,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) if(strstr(strbuf,"Package:") == strbuf) { char pkgname[255], version[255]; - if(sscanf(strbuf, "Package: %s %s", pkgname, version) == 2) + if(sscanf(strbuf, "Package: %254s %254s", pkgname, version) == 2) if(strcmp(pkgver.c_str(), version) == 0) { fclose(report); diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 9449c7306..1eea55560 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -963,6 +963,13 @@ struct CompareProviders { else if ((B->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) return true; } + if ((A->Flags & pkgCache::Flag::Important) != (B->Flags & pkgCache::Flag::Important)) + { + if ((A->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) + return false; + else if ((B->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) + return true; + } // higher priority seems like a good idea if (AV->Priority != BV->Priority) return AV->Priority < BV->Priority; @@ -1641,6 +1648,7 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc) { if(!(PkgState[p->ID].Flags & Flag::Auto) || (p->Flags & Flag::Essential) || + (p->Flags & Flag::Important) || userFunc.InRootSet(p) || // be nice even then a required package violates the policy (#583517) // and do the full mark process also for required packages diff --git a/apt-pkg/indexcopy.cc b/apt-pkg/indexcopy.cc index 3747e3570..e29e2819c 100644 --- a/apt-pkg/indexcopy.cc +++ b/apt-pkg/indexcopy.cc @@ -85,7 +85,7 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List, string OrigPath = string(*I,CDROM.length()); // Open the package file - FileFd Pkg(*I + GetFileName(), FileFd::ReadOnly, FileFd::Extension); + FileFd Pkg(*I + GetFileName(), FileFd::ReadOnly, FileFd::Auto); off_t const FileSize = Pkg.Size(); pkgTagFile Parser(&Pkg); @@ -797,7 +797,7 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/ string OrigPath = string(*I,CDROM.length()); // Open the package file - FileFd Pkg(*I, FileFd::ReadOnly, FileFd::Extension); + FileFd Pkg(*I, FileFd::ReadOnly, FileFd::Auto); off_t const FileSize = Pkg.Size(); pkgTagFile Parser(&Pkg); diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc index cdb9250e8..af2639beb 100644 --- a/apt-pkg/indexrecords.cc +++ b/apt-pkg/indexrecords.cc @@ -44,7 +44,10 @@ time_t indexRecords::GetValidUntil() const const indexRecords::checkSum *indexRecords::Lookup(const string MetaKey) { - return Entries[MetaKey]; + std::map<std::string, indexRecords::checkSum* >::const_iterator sum = Entries.find(MetaKey); + if (sum == Entries.end()) + return NULL; + return sum->second; } bool indexRecords::Exists(string const &MetaKey) const diff --git a/apt-pkg/orderlist.cc b/apt-pkg/orderlist.cc index 0ac9a83e3..3a179b2a2 100644 --- a/apt-pkg/orderlist.cc +++ b/apt-pkg/orderlist.cc @@ -82,16 +82,14 @@ pkgOrderList *pkgOrderList::Me = 0; // OrderList::pkgOrderList - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -pkgOrderList::pkgOrderList(pkgDepCache *pCache) : Cache(*pCache) +pkgOrderList::pkgOrderList(pkgDepCache *pCache) : Cache(*pCache), + Primary(NULL), Secondary(NULL), + RevDepends(NULL), Remove(NULL), + AfterEnd(NULL), FileList(NULL), + LoopCount(-1), Depth(0) { - FileList = 0; - Primary = 0; - Secondary = 0; - RevDepends = 0; - Remove = 0; - LoopCount = -1; Debug = _config->FindB("Debug::pkgOrderList",false); - + /* Construct the arrays, egcs 1.0.1 bug requires the package count hack */ unsigned long Size = Cache.Head().PackageCount; diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 701b64af1..698c8606f 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -36,11 +36,13 @@ bool pkgPackageManager::SigINTStop = false; // PM::PackageManager - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -pkgPackageManager::pkgPackageManager(pkgDepCache *pCache) : Cache(*pCache) +pkgPackageManager::pkgPackageManager(pkgDepCache *pCache) : Cache(*pCache), + List(NULL), Res(Incomplete) { FileNames = new string[Cache.Head().PackageCount]; - List = 0; Debug = _config->FindB("Debug::pkgPackageManager",false); + NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true); + ImmConfigureAll = _config->FindB("APT::Immediate-Configure-All",false); } /*}}}*/ // PM::PackageManager - Destructor /*{{{*/ @@ -150,7 +152,7 @@ void pkgPackageManager::ImmediateAdd(PkgIterator I, bool UseInstallVer, unsigned if(!List->IsFlag(D.TargetPkg(), pkgOrderList::Immediate)) { if(Debug) - clog << OutputInDepth(Depth) << "ImmediateAdd(): Adding Immediate flag to " << D.TargetPkg() << " cause of " << D.DepType() << " " << I.Name() << endl; + clog << OutputInDepth(Depth) << "ImmediateAdd(): Adding Immediate flag to " << D.TargetPkg() << " cause of " << D.DepType() << " " << I.FullName() << endl; List->Flag(D.TargetPkg(),pkgOrderList::Immediate); ImmediateAdd(D.TargetPkg(), UseInstallVer, Depth + 1); } @@ -169,10 +171,7 @@ bool pkgPackageManager::CreateOrderList() delete List; List = new pkgOrderList(&Cache); - - NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true); - ImmConfigureAll = _config->FindB("APT::Immediate-Configure-All",false); - + if (Debug && ImmConfigureAll) clog << "CreateOrderList(): Adding Immediate flag for all packages because of APT::Immediate-Configure-All" << endl; @@ -184,12 +183,11 @@ bool pkgPackageManager::CreateOrderList() continue; // Mark the package and its dependends for immediate configuration - if ((((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential || - (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) && + if ((((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) && NoImmConfigure == false) || ImmConfigureAll) { if(Debug && !ImmConfigureAll) - clog << "CreateOrderList(): Adding Immediate flag for " << I.Name() << endl; + clog << "CreateOrderList(): Adding Immediate flag for " << I.FullName() << endl; List->Flag(I,pkgOrderList::Immediate); if (!ImmConfigureAll) { @@ -258,7 +256,7 @@ bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D, if (EarlyRemove(D.ParentPkg()) == false) return _error->Error("Reverse conflicts early remove for package '%s' failed", - Pkg.Name()); + Pkg.FullName().c_str()); } return true; } @@ -296,9 +294,9 @@ bool pkgPackageManager::ConfigureAll() if (ConfigurePkgs == true && SmartConfigure(Pkg, 0) == false) { if (ImmConfigureAll) _error->Error(_("Could not perform immediate configuration on '%s'. " - "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),1); + "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.FullName().c_str(),1); else - _error->Error("Internal error, packages left unconfigured. %s",Pkg.Name()); + _error->Error("Internal error, packages left unconfigured. %s",Pkg.FullName().c_str()); return false; } @@ -323,11 +321,11 @@ bool pkgPackageManager::ConfigureAll() bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth) { // If this is true, only check and correct and dependencies without the Loop flag - bool PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop); + bool const PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop); if (Debug) { VerIterator InstallVer = VerIterator(Cache,Cache[Pkg].InstallVer); - clog << OutputInDepth(Depth) << "SmartConfigure " << Pkg.Name() << " (" << InstallVer.VerStr() << ")"; + clog << OutputInDepth(Depth) << "SmartConfigure " << Pkg.FullName() << " (" << InstallVer.VerStr() << ")"; if (PkgLoop) clog << " (Only Correct Dependencies)"; clog << endl; @@ -338,103 +336,135 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth) /* Because of the ordered list, most dependencies should be unpacked, however if there is a loop (A depends on B, B depends on A) this will not be the case, so check for dependencies before configuring. */ - bool Bad = false; - for (DepIterator D = instVer.DependsList(); - D.end() == false; ) - { - // Compute a single dependency element (glob or) - pkgCache::DepIterator Start; - pkgCache::DepIterator End; - D.GlobOr(Start,End); - - if (End->Type == pkgCache::Dep::Depends) - Bad = true; - - // Check for dependanices that have not been unpacked, probably due to loops. - while (End->Type == pkgCache::Dep::Depends) { - PkgIterator DepPkg; - VerIterator InstallVer; - SPtrArray<Version *> VList = Start.AllTargets(); - - // Check through each version of each package that could satisfy this dependancy - for (Version **I = VList; *I != 0; I++) { - VerIterator Ver(Cache,*I); - DepPkg = Ver.ParentPkg(); - InstallVer = VerIterator(Cache,Cache[DepPkg].InstallVer); - - // Check if the current version of the package is avalible and will satisfy this dependancy - if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true && - !List->IsFlag(DepPkg,pkgOrderList::Removed) && DepPkg.State() == PkgIterator::NeedsNothing) + bool Bad = false, Changed = false; + do { + Changed = false; + for (DepIterator D = instVer.DependsList(); D.end() == false; ) + { + // Compute a single dependency element (glob or) + pkgCache::DepIterator Start, End; + D.GlobOr(Start,End); + + if (End->Type != pkgCache::Dep::Depends) + continue; + Bad = true; + + // Search for dependencies which are unpacked but aren't configured yet (maybe loops) + for (DepIterator Cur = Start; true; ++Cur) + { + SPtrArray<Version *> VList = Cur.AllTargets(); + + for (Version **I = VList; *I != 0; ++I) { - Bad = false; - break; - } - - // Check if the version that is going to be installed will satisfy the dependancy - if (Cache[DepPkg].InstallVer == *I) { - if (List->IsFlag(DepPkg,pkgOrderList::UnPacked)) { - if (List->IsFlag(DepPkg,pkgOrderList::Loop) && PkgLoop) { - // This dependancy has already been dealt with by another SmartConfigure on Pkg - Bad = false; - break; - } else if (List->IsFlag(Pkg,pkgOrderList::Loop)) { - /* Check for a loop to prevent one forming - If A depends on B and B depends on A, SmartConfigure will - just hop between them if this is not checked. Dont remove the - loop flag after finishing however as loop is already set. - This means that there is another SmartConfigure call for this - package and it will remove the loop flag */ - Bad = !SmartConfigure(DepPkg, Depth + 1); - } else { - /* Check for a loop to prevent one forming - If A depends on B and B depends on A, SmartConfigure will - just hop between them if this is not checked */ - List->Flag(Pkg,pkgOrderList::Loop); - Bad = !SmartConfigure(DepPkg, Depth + 1); - List->RmFlag(Pkg,pkgOrderList::Loop); - } - // If SmartConfigure was succesfull, Bad is false, so break - if (!Bad) break; - } else if (List->IsFlag(DepPkg,pkgOrderList::Configured)) { - Bad = false; - break; + VerIterator Ver(Cache,*I); + PkgIterator DepPkg = Ver.ParentPkg(); + + // Check if the current version of the package is available and will satisfy this dependency + if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true && + List->IsFlag(DepPkg,pkgOrderList::Removed) == false && + DepPkg.State() == PkgIterator::NeedsNothing) + { + Bad = false; + break; + } + + // Check if the version that is going to be installed will satisfy the dependency + if (Cache[DepPkg].InstallVer != *I) + continue; + + if (List->IsFlag(DepPkg,pkgOrderList::UnPacked)) + { + if (List->IsFlag(DepPkg,pkgOrderList::Loop) && PkgLoop) + { + // This dependency has already been dealt with by another SmartConfigure on Pkg + Bad = false; + break; + } + /* Check for a loop to prevent one forming + If A depends on B and B depends on A, SmartConfigure will + just hop between them if this is not checked. Dont remove the + loop flag after finishing however as loop is already set. + This means that there is another SmartConfigure call for this + package and it will remove the loop flag */ + if (PkgLoop == false) + List->Flag(Pkg,pkgOrderList::Loop); + if (SmartConfigure(DepPkg, Depth + 1) == true) + { + Bad = false; + if (List->IsFlag(DepPkg,pkgOrderList::Loop) == false) + Changed = true; + } + if (PkgLoop == false) + List->RmFlag(Pkg,pkgOrderList::Loop); + // If SmartConfigure was succesfull, Bad is false, so break + if (Bad == false) + break; + } + else if (List->IsFlag(DepPkg,pkgOrderList::Configured)) + { + Bad = false; + break; } } - } - - /* If the dependany is still not satisfied, try, if possible, unpacking a package to satisfy it */ - if (InstallVer != 0 && Bad) { - if (List->IsNow(DepPkg)) { - Bad = false; - if (List->IsFlag(Pkg,pkgOrderList::Loop)) + if (Cur == End) + break; + } + + if (Bad == false) + continue; + + // Check for dependencies that have not been unpacked, probably due to loops. + for (DepIterator Cur = Start; true; ++Cur) + { + SPtrArray<Version *> VList = Cur.AllTargets(); + + for (Version **I = VList; *I != 0; ++I) + { + VerIterator Ver(Cache,*I); + PkgIterator DepPkg = Ver.ParentPkg(); + + // Check if the version that is going to be installed will satisfy the dependency + if (Cache[DepPkg].InstallVer != *I || List->IsNow(DepPkg) == false) + continue; + + if (PkgLoop == true) { if (Debug) std::clog << OutputInDepth(Depth) << "Package " << Pkg << " loops in SmartConfigure" << std::endl; + Bad = false; + break; } else { - List->Flag(Pkg,pkgOrderList::Loop); if (Debug) - cout << OutputInDepth(Depth) << "Unpacking " << DepPkg.Name() << " to avoid loop" << endl; - SmartUnPack(DepPkg, true, Depth + 1); - List->RmFlag(Pkg,pkgOrderList::Loop); + clog << OutputInDepth(Depth) << "Unpacking " << DepPkg.FullName() << " to avoid loop " << Cur << endl; + if (PkgLoop == false) + List->Flag(Pkg,pkgOrderList::Loop); + if (SmartUnPack(DepPkg, true, Depth + 1) == true) + { + Bad = false; + if (List->IsFlag(DepPkg,pkgOrderList::Loop) == false) + Changed = true; + } + if (PkgLoop == false) + List->RmFlag(Pkg,pkgOrderList::Loop); + if (Bad == false) + break; } } + + if (Cur == End) + break; } - - if (Start==End) { - if (Bad && Debug && List->IsFlag(DepPkg,pkgOrderList::Loop) == false) - std::clog << OutputInDepth(Depth) << "Could not satisfy dependencies for " << Pkg.Name() << std::endl; - break; - } else { - Start++; - } + + if (Bad == true && Changed == false && Debug == true) + std::clog << OutputInDepth(Depth) << "Could not satisfy " << Start << std::endl; } - } + } while (Changed == true); if (Bad) { if (Debug) - _error->Warning(_("Could not configure '%s'. "),Pkg.Name()); + _error->Warning(_("Could not configure '%s'. "),Pkg.FullName().c_str()); return false; } @@ -444,7 +474,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth) static bool const ConfigurePkgs = (conf == "all" || conf == "smart"); if (List->IsFlag(Pkg,pkgOrderList::Configured)) - return _error->Error("Internal configure error on '%s'.", Pkg.Name()); + return _error->Error("Internal configure error on '%s'.", Pkg.FullName().c_str()); if (ConfigurePkgs == true && Configure(Pkg) == false) return false; @@ -464,7 +494,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth) // Sanity Check if (List->IsFlag(Pkg,pkgOrderList::Configured) == false) - return _error->Error(_("Could not configure '%s'. "),Pkg.Name()); + return _error->Error(_("Could not configure '%s'. "),Pkg.FullName().c_str()); return true; } @@ -487,7 +517,8 @@ bool pkgPackageManager::EarlyRemove(PkgIterator Pkg) // Essential packages get special treatment bool IsEssential = false; - if ((Pkg->Flags & pkgCache::Flag::Essential) != 0) + if ((Pkg->Flags & pkgCache::Flag::Essential) != 0 || + (Pkg->Flags & pkgCache::Flag::Important) != 0) IsEssential = true; /* Check for packages that are the dependents of essential packages and @@ -497,7 +528,8 @@ bool pkgPackageManager::EarlyRemove(PkgIterator Pkg) for (DepIterator D = Pkg.RevDependsList(); D.end() == false && IsEssential == false; ++D) if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) - if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0) + if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0 || + (D.ParentPkg()->Flags & pkgCache::Flag::Important) != 0) IsEssential = true; } @@ -508,7 +540,7 @@ bool pkgPackageManager::EarlyRemove(PkgIterator Pkg) "removing the essential package %s due to a " "Conflicts/Pre-Depends loop. This is often bad, " "but if you really want to do it, activate the " - "APT::Force-LoopBreak option."),Pkg.Name()); + "APT::Force-LoopBreak option."),Pkg.FullName().c_str()); } bool Res = SmartRemove(Pkg); @@ -544,193 +576,252 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c bool PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop); if (Debug) { - clog << OutputInDepth(Depth) << "SmartUnPack " << Pkg.Name(); + clog << OutputInDepth(Depth) << "SmartUnPack " << Pkg.FullName(); VerIterator InstallVer = VerIterator(Cache,Cache[Pkg].InstallVer); if (Pkg.CurrentVer() == 0) - cout << " (install version " << InstallVer.VerStr() << ")"; + clog << " (install version " << InstallVer.VerStr() << ")"; else - cout << " (replace version " << Pkg.CurrentVer().VerStr() << " with " << InstallVer.VerStr() << ")"; + clog << " (replace version " << Pkg.CurrentVer().VerStr() << " with " << InstallVer.VerStr() << ")"; if (PkgLoop) - cout << " (Only Perform PreUnpack Checks)"; - cout << endl; + clog << " (Only Perform PreUnpack Checks)"; + clog << endl; } VerIterator const instVer = Cache[Pkg].InstVerIter(Cache); /* PreUnpack Checks: This loop checks and attempts to rectify and problems that would prevent the package being unpacked. - It addresses: PreDepends, Conflicts, Obsoletes and Breaks (DpkgBreaks). Any resolutions that do not require it should + It addresses: PreDepends, Conflicts, Obsoletes and Breaks (DpkgBreaks). Any resolutions that do not require it should avoid configuration (calling SmartUnpack with Immediate=true), this is because when unpacking some packages with - complex dependancy structures, trying to configure some packages while breaking the loops can complicate things . - This will be either dealt with if the package is configured as a dependency of Pkg (if and when Pkg is configured), + complex dependancy structures, trying to configure some packages while breaking the loops can complicate things . + This will be either dealt with if the package is configured as a dependency of Pkg (if and when Pkg is configured), or by the ConfigureAll call at the end of the for loop in OrderInstall. */ - for (DepIterator D = instVer.DependsList(); - D.end() == false; ) - { - // Compute a single dependency element (glob or) - pkgCache::DepIterator Start; - pkgCache::DepIterator End; - D.GlobOr(Start,End); - - while (End->Type == pkgCache::Dep::PreDepends) + bool Changed = false; + do { + Changed = false; + for (DepIterator D = instVer.DependsList(); D.end() == false; ) { - if (Debug) - clog << OutputInDepth(Depth) << "PreDepends order for " << Pkg.Name() << std::endl; - - // Look for possible ok targets. - SPtrArray<Version *> VList = Start.AllTargets(); - bool Bad = true; - for (Version **I = VList; *I != 0 && Bad == true; I++) - { - VerIterator Ver(Cache,*I); - PkgIterator Pkg = Ver.ParentPkg(); - - // See if the current version is ok - if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true && - Pkg.State() == PkgIterator::NeedsNothing) + // Compute a single dependency element (glob or) + pkgCache::DepIterator Start, End; + D.GlobOr(Start,End); + + if (End->Type == pkgCache::Dep::PreDepends) + { + bool Bad = true; + if (Debug) + clog << OutputInDepth(Depth) << "PreDepends order for " << Pkg.FullName() << std::endl; + + // Look for easy targets: packages that are already okay + for (DepIterator Cur = Start; Bad == true; ++Cur) { - Bad = false; - if (Debug) - clog << OutputInDepth(Depth) << "Found ok package " << Pkg.Name() << endl; - continue; - } - } - - // Look for something that could be configured. - for (Version **I = VList; *I != 0 && Bad == true; I++) - { - VerIterator Ver(Cache,*I); - PkgIterator Pkg = Ver.ParentPkg(); - - // Not the install version - if (Cache[Pkg].InstallVer != *I || - (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing)) - continue; - - if (List->IsFlag(Pkg,pkgOrderList::Configured)) { - Bad = false; - continue; + SPtrArray<Version *> VList = Start.AllTargets(); + for (Version **I = VList; *I != 0; ++I) + { + VerIterator Ver(Cache,*I); + PkgIterator Pkg = Ver.ParentPkg(); + + // See if the current version is ok + if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true && + Pkg.State() == PkgIterator::NeedsNothing) + { + Bad = false; + if (Debug) + clog << OutputInDepth(Depth) << "Found ok package " << Pkg.FullName() << endl; + break; + } + } + if (Cur == End) + break; } - // check if it needs unpack or if if configure is enough - if (!List->IsFlag(Pkg,pkgOrderList::UnPacked)) - { - if (Debug) - clog << OutputInDepth(Depth) << "Trying to SmartUnpack " << Pkg.Name() << endl; - // SmartUnpack with the ImmediateFlag to ensure its really ready - Bad = !SmartUnPack(Pkg, true, Depth + 1); - } else { - if (Debug) - clog << OutputInDepth(Depth) << "Trying to SmartConfigure " << Pkg.Name() << endl; - Bad = !SmartConfigure(Pkg, Depth + 1); - } - } + // Look for something that could be configured. + for (DepIterator Cur = Start; Bad == true; ++Cur) + { + SPtrArray<Version *> VList = Start.AllTargets(); + for (Version **I = VList; *I != 0; ++I) + { + VerIterator Ver(Cache,*I); + PkgIterator Pkg = Ver.ParentPkg(); + + // Not the install version + if (Cache[Pkg].InstallVer != *I || + (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing)) + continue; + + if (List->IsFlag(Pkg,pkgOrderList::Configured)) + { + Bad = false; + break; + } + + // check if it needs unpack or if if configure is enough + if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == false) + { + if (Debug) + clog << OutputInDepth(Depth) << "Trying to SmartUnpack " << Pkg.FullName() << endl; + // SmartUnpack with the ImmediateFlag to ensure its really ready + if (SmartUnPack(Pkg, true, Depth + 1) == true) + { + Bad = false; + if (List->IsFlag(Pkg,pkgOrderList::Loop) == false) + Changed = true; + break; + } + } + else + { + if (Debug) + clog << OutputInDepth(Depth) << "Trying to SmartConfigure " << Pkg.FullName() << endl; + if (SmartConfigure(Pkg, Depth + 1) == true) + { + Bad = false; + if (List->IsFlag(Pkg,pkgOrderList::Loop) == false) + Changed = true; + break; + } + } + } + } - /* If this or element did not match then continue on to the - next or element until a matching element is found */ - if (Bad == true) - { - // This triggers if someone make a pre-depends/depend loop. - if (Start == End) - return _error->Error("Couldn't configure pre-depend %s for %s, " - "probably a dependency cycle.", - End.TargetPkg().Name(),Pkg.Name()); - ++Start; + if (Bad == true) + { + if (Start == End) + return _error->Error("Couldn't configure pre-depend %s for %s, " + "probably a dependency cycle.", + End.TargetPkg().FullName().c_str(),Pkg.FullName().c_str()); + } + else + continue; } - else - break; - } - - if (End->Type == pkgCache::Dep::Conflicts || - End->Type == pkgCache::Dep::Obsoletes) - { - /* Look for conflicts. Two packages that are both in the install - state cannot conflict so we don't check.. */ - SPtrArray<Version *> VList = End.AllTargets(); - for (Version **I = VList; *I != 0; I++) + else if (End->Type == pkgCache::Dep::Conflicts || + End->Type == pkgCache::Dep::Obsoletes) { - VerIterator Ver(Cache,*I); - PkgIterator ConflictPkg = Ver.ParentPkg(); - VerIterator InstallVer(Cache,Cache[ConflictPkg].InstallVer); - - // See if the current version is conflicting - if (ConflictPkg.CurrentVer() == Ver && List->IsNow(ConflictPkg)) - { - cout << OutputInDepth(Depth) << Pkg.Name() << " conflicts with " << ConflictPkg.Name() << endl; - /* If a loop is not present or has not yet been detected, attempt to unpack packages - to resolve this conflict. If there is a loop present, remove packages to resolve this conflict */ - if (!List->IsFlag(ConflictPkg,pkgOrderList::Loop)) { - if (Cache[ConflictPkg].Keep() == 0 && Cache[ConflictPkg].InstallVer != 0) { - if (Debug) - cout << OutputInDepth(Depth) << OutputInDepth(Depth) << "Unpacking " << ConflictPkg.Name() << " to prevent conflict" << endl; - List->Flag(Pkg,pkgOrderList::Loop); - SmartUnPack(ConflictPkg,false, Depth + 1); - // Remove loop to allow it to be used later if needed - List->RmFlag(Pkg,pkgOrderList::Loop); - } else { - if (EarlyRemove(ConflictPkg) == false) - return _error->Error("Internal Error, Could not early remove %s",ConflictPkg.Name()); - } - } else { - if (!List->IsFlag(ConflictPkg,pkgOrderList::Removed)) { - if (Debug) - cout << OutputInDepth(Depth) << "Because of conficts knot, removing " << ConflictPkg.Name() << " to conflict violation" << endl; - if (EarlyRemove(ConflictPkg) == false) - return _error->Error("Internal Error, Could not early remove %s",ConflictPkg.Name()); - } + /* Look for conflicts. Two packages that are both in the install + state cannot conflict so we don't check.. */ + SPtrArray<Version *> VList = End.AllTargets(); + for (Version **I = VList; *I != 0; I++) + { + VerIterator Ver(Cache,*I); + PkgIterator ConflictPkg = Ver.ParentPkg(); + VerIterator InstallVer(Cache,Cache[ConflictPkg].InstallVer); + + // See if the current version is conflicting + if (ConflictPkg.CurrentVer() == Ver && List->IsNow(ConflictPkg)) + { + clog << OutputInDepth(Depth) << Pkg.FullName() << " conflicts with " << ConflictPkg.FullName() << endl; + /* If a loop is not present or has not yet been detected, attempt to unpack packages + to resolve this conflict. If there is a loop present, remove packages to resolve this conflict */ + if (List->IsFlag(ConflictPkg,pkgOrderList::Loop) == false) + { + if (Cache[ConflictPkg].Keep() == 0 && Cache[ConflictPkg].InstallVer != 0) + { + if (Debug) + clog << OutputInDepth(Depth) << OutputInDepth(Depth) << "Unpacking " << ConflictPkg.FullName() << " to prevent conflict" << endl; + List->Flag(Pkg,pkgOrderList::Loop); + if (SmartUnPack(ConflictPkg,false, Depth + 1) == true) + if (List->IsFlag(ConflictPkg,pkgOrderList::Loop) == false) + Changed = true; + // Remove loop to allow it to be used later if needed + List->RmFlag(Pkg,pkgOrderList::Loop); + } + else if (EarlyRemove(ConflictPkg) == false) + return _error->Error("Internal Error, Could not early remove %s (1)",ConflictPkg.FullName().c_str()); + } + else if (List->IsFlag(ConflictPkg,pkgOrderList::Removed) == false) + { + if (Debug) + clog << OutputInDepth(Depth) << "Because of conficts knot, removing " << ConflictPkg.FullName() << " to conflict violation" << endl; + if (EarlyRemove(ConflictPkg) == false) + return _error->Error("Internal Error, Could not early remove %s (2)",ConflictPkg.FullName().c_str()); + } } } } - } - - // Check for breaks - if (End->Type == pkgCache::Dep::DpkgBreaks) { - SPtrArray<Version *> VList = End.AllTargets(); - for (Version **I = VList; *I != 0; I++) + else if (End->Type == pkgCache::Dep::DpkgBreaks) { - VerIterator Ver(Cache,*I); - PkgIterator BrokenPkg = Ver.ParentPkg(); - VerIterator InstallVer(Cache,Cache[BrokenPkg].InstallVer); - if (BrokenPkg.CurrentVer() != Ver) + SPtrArray<Version *> VList = End.AllTargets(); + for (Version **I = VList; *I != 0; ++I) { - if (Debug) - std::clog << OutputInDepth(Depth) << " Ignore not-installed version " << Ver.VerStr() << " of " << Pkg.FullName() << " for " << End << std::endl; - continue; - } + VerIterator Ver(Cache,*I); + PkgIterator BrokenPkg = Ver.ParentPkg(); + if (BrokenPkg.CurrentVer() != Ver) + { + if (Debug) + std::clog << OutputInDepth(Depth) << " Ignore not-installed version " << Ver.VerStr() << " of " << Pkg.FullName() << " for " << End << std::endl; + continue; + } - // Check if it needs to be unpacked - if (List->IsFlag(BrokenPkg,pkgOrderList::InList) && Cache[BrokenPkg].Delete() == false && - List->IsNow(BrokenPkg)) { - if (List->IsFlag(BrokenPkg,pkgOrderList::Loop) && PkgLoop) { - // This dependancy has already been dealt with by another SmartUnPack on Pkg - break; - } else if (List->IsFlag(Pkg,pkgOrderList::Loop)) { - /* Found a break, so unpack the package, but dont remove loop as already set. - This means that there is another SmartUnPack call for this - package and it will remove the loop flag. */ - if (Debug) - cout << OutputInDepth(Depth) << " Unpacking " << BrokenPkg.Name() << " to avoid break" << endl; - - SmartUnPack(BrokenPkg, false, Depth + 1); - } else { - List->Flag(Pkg,pkgOrderList::Loop); - // Found a break, so unpack the package - if (Debug) - cout << OutputInDepth(Depth) << " Unpacking " << BrokenPkg.Name() << " to avoid break" << endl; - - SmartUnPack(BrokenPkg, false, Depth + 1); - List->RmFlag(Pkg,pkgOrderList::Loop); - } - } - - // Check if a package needs to be removed - if (Cache[BrokenPkg].Delete() == true && !List->IsFlag(BrokenPkg,pkgOrderList::Configured)) { - if (Debug) - cout << OutputInDepth(Depth) << " Removing " << BrokenPkg.Name() << " to avoid break" << endl; - SmartRemove(BrokenPkg); + // Check if it needs to be unpacked + if (List->IsFlag(BrokenPkg,pkgOrderList::InList) && Cache[BrokenPkg].Delete() == false && + List->IsNow(BrokenPkg)) + { + if (List->IsFlag(BrokenPkg,pkgOrderList::Loop) && PkgLoop) + { + // This dependancy has already been dealt with by another SmartUnPack on Pkg + break; + } + else + { + // Found a break, so see if we can unpack the package to avoid it + // but do not set loop if another SmartUnPack already deals with it + // Also, avoid it if the package we would unpack pre-depends on this one + VerIterator InstallVer(Cache,Cache[BrokenPkg].InstallVer); + bool circle = false; + for (pkgCache::DepIterator D = InstallVer.DependsList(); D.end() == false; ++D) + { + if (D->Type != pkgCache::Dep::PreDepends) + continue; + SPtrArray<Version *> VL = D.AllTargets(); + for (Version **I = VL; *I != 0; ++I) + { + VerIterator V(Cache,*I); + PkgIterator P = V.ParentPkg(); + // we are checking for installation as an easy 'protection' against or-groups and (unchosen) providers + if (P->CurrentVer == 0 || P != Pkg || (P.CurrentVer() != V && Cache[P].InstallVer != V)) + continue; + circle = true; + break; + } + if (circle == true) + break; + } + if (circle == true) + { + if (Debug) + clog << OutputInDepth(Depth) << " Avoiding " << End << " avoided as " << BrokenPkg.FullName() << " has a pre-depends on " << Pkg.FullName() << std::endl; + continue; + } + else + { + if (Debug) + { + clog << OutputInDepth(Depth) << " Unpacking " << BrokenPkg.FullName() << " to avoid " << End; + if (PkgLoop == true) + clog << " (Looping)"; + clog << std::endl; + } + if (PkgLoop == false) + List->Flag(Pkg,pkgOrderList::Loop); + if (SmartUnPack(BrokenPkg, false, Depth + 1) == true) + { + if (List->IsFlag(BrokenPkg,pkgOrderList::Loop) == false) + Changed = true; + } + if (PkgLoop == false) + List->RmFlag(Pkg,pkgOrderList::Loop); + } + } + } + // Check if a package needs to be removed + else if (Cache[BrokenPkg].Delete() == true && List->IsFlag(BrokenPkg,pkgOrderList::Configured) == false) + { + if (Debug) + clog << OutputInDepth(Depth) << " Removing " << BrokenPkg.FullName() << " to avoid " << End << endl; + SmartRemove(BrokenPkg); + } } } } - } + } while (Changed == true); // Check for reverse conflicts. if (CheckRConflicts(Pkg,Pkg.RevDependsList(), @@ -787,7 +878,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c // Perform immedate configuration of the package. if (SmartConfigure(Pkg, Depth + 1) == false) _error->Warning(_("Could not perform immediate configuration on '%s'. " - "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),2); + "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.FullName().c_str(),2); } return true; @@ -827,11 +918,11 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() { if (!List->IsFlag(Pkg,pkgOrderList::Configured) && !NoImmConfigure) { if (SmartConfigure(Pkg, 0) == false && Debug) - _error->Warning("Internal Error, Could not configure %s",Pkg.Name()); + _error->Warning("Internal Error, Could not configure %s",Pkg.FullName().c_str()); // FIXME: The above warning message might need changing } else { if (Debug == true) - clog << "Skipping already done " << Pkg.Name() << endl; + clog << "Skipping already done " << Pkg.FullName() << endl; } continue; @@ -840,7 +931,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() if (List->IsMissing(Pkg) == true) { if (Debug == true) - clog << "Sequence completed at " << Pkg.Name() << endl; + clog << "Sequence completed at " << Pkg.FullName() << endl; if (DoneSomething == false) { _error->Error("Internal Error, ordering was unable to handle the media swap"); @@ -854,7 +945,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() Pkg.State() == pkgCache::PkgIterator::NeedsNothing && (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall) { - _error->Error("Internal Error, trying to manipulate a kept package (%s)",Pkg.Name()); + _error->Error("Internal Error, trying to manipulate a kept package (%s)",Pkg.FullName().c_str()); return Failed; } @@ -887,7 +978,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() if (List->IsFlag(*I,pkgOrderList::Configured) == false) { _error->Error("Internal error, packages left unconfigured. %s", - PkgIterator(Cache,*I).Name()); + PkgIterator(Cache,*I).FullName().c_str()); return Failed; } } diff --git a/apt-pkg/pkgrecords.cc b/apt-pkg/pkgrecords.cc index c5b3bebd7..36dab3480 100644 --- a/apt-pkg/pkgrecords.cc +++ b/apt-pkg/pkgrecords.cc @@ -22,7 +22,7 @@ // Records::pkgRecords - Constructor /*{{{*/ // --------------------------------------------------------------------- /* This will create the necessary structures to access the status files */ -pkgRecords::pkgRecords(pkgCache &Cache) : Cache(Cache), +pkgRecords::pkgRecords(pkgCache &Cache) : d(NULL), Cache(Cache), Files(Cache.HeaderP->PackageFileCount) { for (pkgCache::PkgFileIterator I = Cache.FileBegin(); diff --git a/apt-pkg/pkgsystem.cc b/apt-pkg/pkgsystem.cc index f61c140fa..05ba6e0e6 100644 --- a/apt-pkg/pkgsystem.cc +++ b/apt-pkg/pkgsystem.cc @@ -26,11 +26,11 @@ unsigned long pkgSystem::GlobalListLen = 0; // System::pkgSystem - Constructor /*{{{*/ // --------------------------------------------------------------------- /* Add it to the global list.. */ -pkgSystem::pkgSystem() +pkgSystem::pkgSystem() : Label(NULL), VS(NULL) { assert(GlobalListLen < sizeof(SysList)/sizeof(*SysList)); SysList[GlobalListLen] = this; - GlobalListLen++; + ++GlobalListLen; } /*}}}*/ // System::GetSystem - Get the named system /*{{{*/ diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index f5f458099..0fddfb451 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -33,7 +33,7 @@ unsigned long pkgSourceList::Type::GlobalListLen = 0; // Type::Type - Constructor /*{{{*/ // --------------------------------------------------------------------- /* Link this to the global list of items*/ -pkgSourceList::Type::Type() +pkgSourceList::Type::Type() : Name(NULL), Label(NULL) { ItmList[GlobalListLen] = this; GlobalListLen++; diff --git a/apt-pkg/srcrecords.cc b/apt-pkg/srcrecords.cc index 48b643eac..d63d2c422 100644 --- a/apt-pkg/srcrecords.cc +++ b/apt-pkg/srcrecords.cc @@ -25,7 +25,7 @@ // SrcRecords::pkgSrcRecords - Constructor /*{{{*/ // --------------------------------------------------------------------- /* Open all the source index files */ -pkgSrcRecords::pkgSrcRecords(pkgSourceList &List) : Files(0), Current(0) +pkgSrcRecords::pkgSrcRecords(pkgSourceList &List) : d(NULL), Files(0), Current(0) { for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); ++I) { diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index ec86173df..79811899a 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -30,7 +30,10 @@ using std::string; class pkgTagFilePrivate { public: - pkgTagFilePrivate(FileFd *pFd, unsigned long long Size) : Fd(*pFd), Size(Size) + pkgTagFilePrivate(FileFd *pFd, unsigned long long Size) : Fd(*pFd), Buffer(NULL), + Start(NULL), End(NULL), + Done(false), iOffset(0), + Size(Size) { } FileFd &Fd; diff --git a/apt-pkg/version.cc b/apt-pkg/version.cc index a9d4fb763..cb2c34c0f 100644 --- a/apt-pkg/version.cc +++ b/apt-pkg/version.cc @@ -23,10 +23,10 @@ unsigned long pkgVersioningSystem::GlobalListLen = 0; // pkgVS::pkgVersioningSystem - Constructor /*{{{*/ // --------------------------------------------------------------------- /* Link to the global list of versioning systems supported */ -pkgVersioningSystem::pkgVersioningSystem() +pkgVersioningSystem::pkgVersioningSystem() : Label(NULL) { VSList[GlobalListLen] = this; - GlobalListLen++; + ++GlobalListLen; } /*}}}*/ // pkgVS::GetVS - Find a VS by name /*{{{*/ |