diff options
53 files changed, 1127 insertions, 613 deletions
diff --git a/apt-inst/dirstream.cc b/apt-inst/dirstream.cc index bb0bf96c1..65d1aa188 100644 --- a/apt-inst/dirstream.cc +++ b/apt-inst/dirstream.cc @@ -46,15 +46,13 @@ bool pkgDirStream::DoItem(Item &Itm,int &Fd) // fchmod deals with umask and fchown sets the ownership if (fchmod(iFd,Itm.Mode) != 0) { - _error->Errno("fchmod",_("Failed to write file %s"), Itm.Name); close(iFd); - return false; + return _error->Errno("fchmod",_("Failed to write file %s"), Itm.Name); } if (fchown(iFd,Itm.UID,Itm.GID) != 0 && errno != EPERM) { - return _error->Errno("fchown",_("Failed to write file %s"), Itm.Name); close(iFd); - return false; + return _error->Errno("fchown",_("Failed to write file %s"), Itm.Name); } Fd = iFd; return true; 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 /*{{{*/ diff --git a/cmdline/acqprogress.cc b/cmdline/acqprogress.cc index 1ccb08804..3ac350aca 100644 --- a/cmdline/acqprogress.cc +++ b/cmdline/acqprogress.cc @@ -31,8 +31,9 @@ using namespace std; // --------------------------------------------------------------------- /* */ AcqTextStatus::AcqTextStatus(unsigned int &ScreenWidth,unsigned int Quiet) : - ScreenWidth(ScreenWidth), Quiet(Quiet) + ScreenWidth(ScreenWidth), ID(0), Quiet(Quiet) { + BlankLine[0] = 0; } /*}}}*/ // AcqTextStatus::Start - Downloading has started /*{{{*/ diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 1cd5080cc..94654ffd4 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -1739,7 +1739,7 @@ int main(int argc,const char *argv[]) /*{{{*/ {'c',"config-file",0,CommandLine::ConfigFile}, {'o',"option",0,CommandLine::ArbItem}, {0,"installed","APT::Cache::Installed",0}, - {0,"pre-depends","APT::Cache::ShowPreDepends",0}, + {0,"pre-depends","APT::Cache::ShowPre-Depends",0}, {0,"depends","APT::Cache::ShowDepends",0}, {0,"recommends","APT::Cache::ShowRecommends",0}, {0,"suggests","APT::Cache::ShowSuggests",0}, diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc index fa48debcd..0017d954e 100644 --- a/cmdline/apt-cdrom.cc +++ b/cmdline/apt-cdrom.cc @@ -150,10 +150,9 @@ bool DoAdd(CommandLine &) bool res = true; bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect", true); - unsigned int count = 0; - if (AutoDetect && UdevCdroms.Dlopen()) { + unsigned int count = 0; while (AutoDetectCdrom(UdevCdroms, count)) res &= cdrom.Add(&log); } else { @@ -178,10 +177,10 @@ bool DoIdent(CommandLine &) bool res = true; bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect"); - unsigned int count = 0; - + if (AutoDetect && UdevCdroms.Dlopen()) { + unsigned int count = 0; while (AutoDetectCdrom(UdevCdroms, count)) res &= cdrom.Ident(ident, &log); } else { diff --git a/cmdline/apt-extracttemplates.cc b/cmdline/apt-extracttemplates.cc index d5c1a3208..dc4c110a1 100644 --- a/cmdline/apt-extracttemplates.cc +++ b/cmdline/apt-extracttemplates.cc @@ -53,8 +53,8 @@ pkgCache *DebFile::Cache = 0; // --------------------------------------------------------------------- /* */ DebFile::DebFile(const char *debfile) - : File(debfile, FileFd::ReadOnly), Control(0), DepOp(0), - PreDepOp(0), Config(0), Template(0), Which(None) + : File(debfile, FileFd::ReadOnly), Size(0), Control(NULL), ControlLen(0), + DepOp(0), PreDepOp(0), Config(0), Template(0), Which(None) { } /*}}}*/ diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 32ee46980..f4ad75d1c 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -713,11 +713,32 @@ public: } virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { - APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::NEWEST); - if (verset.empty() == false) - return *(verset.begin()); - if (ShowError == true) - ioprintf(out, _("Virtual packages like '%s' can't be removed\n"), Pkg.FullName(true).c_str()); + if (Pkg->ProvidesList != 0) + { + APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::NEWEST); + if (verset.empty() == false) + return *(verset.begin()); + if (ShowError == true) + ioprintf(out, _("Virtual packages like '%s' can't be removed\n"), Pkg.FullName(true).c_str()); + } + else + { + pkgCache::GrpIterator Grp = Pkg.Group(); + pkgCache::PkgIterator P = Grp.PackageList(); + for (; P.end() != true; P = Grp.NextPkg(P)) + { + if (P == Pkg) + continue; + if (P->CurrentVer != 0) { + // TRANSLATORS: Note, this is not an interactive question + ioprintf(c1out,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"), + Pkg.FullName(true).c_str(), P.FullName(true).c_str()); + break; + } + } + if (P.end() == true) + ioprintf(c1out,_("Package '%s' is not installed, so not removed\n"),Pkg.FullName(true).c_str()); + } return pkgCache::VerIterator(Cache, 0); } @@ -904,7 +925,23 @@ struct TryToRemove { if ((Pkg->CurrentVer == 0 && PurgePkgs == false) || (PurgePkgs == true && Pkg->CurrentState == pkgCache::State::NotInstalled)) { - ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.FullName(true).c_str()); + pkgCache::GrpIterator Grp = Pkg.Group(); + pkgCache::PkgIterator P = Grp.PackageList(); + for (; P.end() != true; P = Grp.NextPkg(P)) + { + if (P == Pkg) + continue; + if (P->CurrentVer != 0 || (PurgePkgs == true && P->CurrentState != pkgCache::State::NotInstalled)) + { + // TRANSLATORS: Note, this is not an interactive question + ioprintf(c1out,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"), + Pkg.FullName(true).c_str(), P.FullName(true).c_str()); + break; + } + } + if (P.end() == true) + ioprintf(c1out,_("Package '%s' is not installed, so not removed\n"),Pkg.FullName(true).c_str()); + // MarkInstall refuses to install packages on hold Pkg->SelectedState = pkgCache::State::Hold; } diff --git a/cmdline/apt-mark.cc b/cmdline/apt-mark.cc index c7d9b6f6a..ef4331714 100644 --- a/cmdline/apt-mark.cc +++ b/cmdline/apt-mark.cc @@ -14,9 +14,15 @@ #include <apt-pkg/init.h> #include <apt-pkg/strutl.h> #include <apt-pkg/pkgsystem.h> +#include <apt-pkg/fileutl.h> #include <algorithm> +#include <errno.h> #include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <fcntl.h> #include <apti18n.h> /*}}}*/ @@ -158,13 +164,63 @@ bool DoHold(CommandLine &CmdL) if (unlikely(Cache == NULL)) return false; + // Generate the base argument list for dpkg + std::vector<const char *> Args; + string Tmp = _config->Find("Dir::Bin::dpkg","dpkg"); + { + string const dpkgChrootDir = _config->FindDir("DPkg::Chroot-Directory", "/"); + size_t dpkgChrootLen = dpkgChrootDir.length(); + if (dpkgChrootDir != "/" && Tmp.find(dpkgChrootDir) == 0) + { + if (dpkgChrootDir[dpkgChrootLen - 1] == '/') + --dpkgChrootLen; + Tmp = Tmp.substr(dpkgChrootLen); + } + } + Args.push_back(Tmp.c_str()); + + // Stick in any custom dpkg options + Configuration::Item const *Opts = _config->Tree("DPkg::Options"); + if (Opts != 0) + { + Opts = Opts->Child; + for (; Opts != 0; Opts = Opts->Next) + { + if (Opts->Value.empty() == true) + continue; + Args.push_back(Opts->Value.c_str()); + } + } + + size_t const BaseArgs = Args.size(); + // we need to detect if we can qualify packages with the architecture or not + Args.push_back("--assert-multi-arch"); + Args.push_back(NULL); + + + pid_t dpkgAssertMultiArch = ExecFork(); + if (dpkgAssertMultiArch == 0) + { + std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory"); + if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0) + _error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --assert-multi-arch", chrootDir.c_str()); + // redirect everything to the ultimate sink as we only need the exit-status + int const nullfd = open("/dev/null", O_RDONLY); + dup2(nullfd, STDIN_FILENO); + dup2(nullfd, STDOUT_FILENO); + dup2(nullfd, STDERR_FILENO); + execvp(Args[0], (char**) &Args[0]); + _error->WarningE("dpkgGo", "Can't detect if dpkg supports multi-arch!"); + _exit(2); + } + APT::PackageList pkgset = APT::PackageList::FromCommandLine(CacheFile, CmdL.FileList + 1); if (pkgset.empty() == true) return _error->Error(_("No packages found")); bool const MarkHold = strcasecmp(CmdL.FileList[0],"hold") == 0; - for (APT::PackageList::iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) + for (APT::PackageList::iterator Pkg = pkgset.begin(); Pkg != pkgset.end();) { if ((Pkg->SelectedState == pkgCache::State::Hold) == MarkHold) { @@ -172,9 +228,25 @@ bool DoHold(CommandLine &CmdL) ioprintf(c1out,_("%s was already set on hold.\n"), Pkg.FullName(true).c_str()); else ioprintf(c1out,_("%s was already not hold.\n"), Pkg.FullName(true).c_str()); - pkgset.erase(Pkg); - continue; + Pkg = pkgset.erase(Pkg, true); + } + else + ++Pkg; + } + + bool dpkgMultiArch = false; + if (dpkgAssertMultiArch > 0) + { + int Status = 0; + while (waitpid(dpkgAssertMultiArch, &Status, 0) != dpkgAssertMultiArch) + { + if (errno == EINTR) + continue; + _error->WarningE("dpkgGo", _("Waited for %s but it wasn't there"), "dpkg --assert-multi-arch"); + break; } + if (WIFEXITED(Status) == true && WEXITSTATUS(Status) == 0) + dpkgMultiArch = true; } if (pkgset.empty() == true) @@ -192,36 +264,60 @@ bool DoHold(CommandLine &CmdL) return true; } - string dpkgcall = _config->Find("Dir::Bin::dpkg", "dpkg"); - std::vector<string> const dpkgoptions = _config->FindVector("DPkg::options"); - for (std::vector<string>::const_iterator o = dpkgoptions.begin(); - o != dpkgoptions.end(); ++o) - dpkgcall.append(" ").append(*o); - dpkgcall.append(" --set-selections"); - FILE *dpkg = popen(dpkgcall.c_str(), "w"); - if (dpkg == NULL) - return _error->Errno("DoHold", "fdopen on dpkg stdin failed"); + Args.erase(Args.begin() + BaseArgs, Args.end()); + Args.push_back("--set-selections"); + Args.push_back(NULL); + + int external[2] = {-1, -1}; + if (pipe(external) != 0) + return _error->WarningE("DoHold", "Can't create IPC pipe for dpkg --set-selections"); + pid_t dpkgSelection = ExecFork(); + if (dpkgSelection == 0) + { + close(external[1]); + std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory"); + if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0) + _error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --set-selections", chrootDir.c_str()); + int const nullfd = open("/dev/null", O_RDONLY); + dup2(external[0], STDIN_FILENO); + dup2(nullfd, STDOUT_FILENO); + dup2(nullfd, STDERR_FILENO); + execvp(Args[0], (char**) &Args[0]); + _error->WarningE("dpkgGo", "Can't detect if dpkg supports multi-arch!"); + _exit(2); + } + + FILE* dpkg = fdopen(external[1], "w"); for (APT::PackageList::iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) { if (MarkHold == true) { - fprintf(dpkg, "%s hold\n", Pkg.FullName(true).c_str()); + fprintf(dpkg, "%s hold\n", Pkg.FullName(!dpkgMultiArch).c_str()); ioprintf(c1out,_("%s set on hold.\n"), Pkg.FullName(true).c_str()); } else { - fprintf(dpkg, "%s install\n", Pkg.FullName(true).c_str()); + fprintf(dpkg, "%s install\n", Pkg.FullName(!dpkgMultiArch).c_str()); ioprintf(c1out,_("Canceled hold on %s.\n"), Pkg.FullName(true).c_str()); } } + fclose(dpkg); - int const status = pclose(dpkg); - if (status == -1) - return _error->Errno("DoHold", "dpkg execution failed in the end"); - if (WIFEXITED(status) == false || WEXITSTATUS(status) != 0) - return _error->Error(_("Executing dpkg failed. Are you root?")); - return true; + if (dpkgSelection > 0) + { + int Status = 0; + while (waitpid(dpkgSelection, &Status, 0) != dpkgSelection) + { + if (errno == EINTR) + continue; + _error->WarningE("dpkgGo", _("Waited for %s but it wasn't there"), "dpkg --set-selection"); + break; + } + if (WIFEXITED(Status) == true && WEXITSTATUS(Status) == 0) + return true; + } + return _error->Error(_("Executing dpkg failed. Are you root?")); } /*}}}*/ /* ShowHold - show packages set on hold in dpkg status {{{*/ diff --git a/debian/changelog b/debian/changelog index 25563e811..32b271668 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,34 @@ -apt (0.8.16~exp13) UNRELEASED; urgency=low +apt (0.8.16~exp14) UNRELEASED; urgency=low + + [ Michael Vogt ] + * apt-pkg/packagemanager.cc: + - fix inconsistent clog/cout usage in the debug output + + [ David Kalnischkies ] + * apt-pkg/packagemanager.cc: + - recheck all dependencies if we changed a package in SmartConfigure + as this could break an earlier dependency (LP: #940396) + - recheck dependencies in SmartUnpack after a change, too + + -- David Kalnischkies <kalnischkies@gmail.com> Tue, 13 Mar 2012 12:38:35 +0100 + +apt (0.8.16~exp13) experimental; urgency=low [ David Kalnischkies ] + * apt-pkg/acquire-item.cc: + - remove 'old' InRelease file if we can't get a new one before + proceeding with Release.gpg to avoid the false impression of a still + trusted repository by a (still present) old InRelease file. + Thanks to Simon Ruderich for reporting this issue! (CVE-2012-0214) + - add Debug::pkgAcqArchive::NoQueue to disable package downloading * apt-pkg/deb/dpkgpm.cc: - chroot if needed before dpkg --assert-multi-arch - ensure that dpkg binary doesn't have the chroot-directory prefixed + - call dpkg --assert-multi-arch with execvp instead of execv + - save the universe by not printing messages about apport if a package + with this name is not installed (Closes: #619646) + - handle a SIGINT in all modes as a break after the currently running + dpkg transaction instead of ignoring it completely * apt-pkg/depcache.cc: - if a M-A:same package is marked for reinstall, mark all it's installed silbings for reinstallation as well (LP: #859188) @@ -13,8 +38,35 @@ apt (0.8.16~exp13) UNRELEASED; urgency=low - if a file without an extension is requested send an 'Accept: text/*' header to avoid that the server chooses unsupported compressed files in a content-negotation attempt (Closes: #657560) + - remove the arbitrary MAXLEN limit for response lines (Closes: #658346) * apt-pkg/aptconfiguration.cc: - chroot if needed before calling dpkg --print-foreign-architectures + - ensure that architectures are not added multiple times + * cmdline/apt-mark.cc: + - detect if dpkg has multiarch support before calling --set-selections + - correctly ignore already (un)hold packages + * apt-pkg/cachefile.cc: + - clean up lost atomic cachefiles with 'clean' (Closes: #650513) + * apt-pkg/indexrecords.cc: + - do not create empty Entries as a sideeffect of Lookup() + * apt-pkg/acquire-item.cc: + - drop support for i18n/Index file (introduced in 0.8.11) and use + the Release file instead to get the Translations (Closes: #649314) + - use pdiff for Translation-* files if available (Closes: #657902) + * ftparchive/writer.cc: + - add 'Translation-*' to the default patterns + * cmdline/apt-get.cc: + - if a package can't be removed as it is not installed, suggest to + the user an (installed) multiarch silbing with 'Did you mean?' + - improve 'error' message for packages which are only referenced + e.g. in a Depends line and are now requested for removal + * cmdline/apt-cache.cc: + - correct --pre-depends option by using dash consistently (LP: #940837) + * apt-pkg/packagemanager.cc: + - do not try to a void a breaks if the broken package pre-depends + on the breaker, but let dpkg auto-deconfigure it + * apt-pkg/contrib/fileutl.cc: + - do not warn about the ignoring of directories (Closes: #662762) [ Steve Langasek ] * cmdline/apt-get.cc: @@ -27,7 +79,9 @@ apt (0.8.16~exp13) UNRELEASED; urgency=low of them in a single iteration (Closes: #657695, LP: #922485) - use a signed int instead of short for score calculation as upgrades become so big now that it can overflow (Closes: #657732, LP: #917173) - + * Fix IndexCopy::CopyPackages and TranslationsCopy::CopyTranslations to + handle compressed files again (LP: #924182, closes: #658096) + [ Michael Vogt ] * apt-pkg/deb/dpkgpm.cc: - fix crash when a package is in removed but residual config state @@ -35,10 +89,20 @@ apt (0.8.16~exp13) UNRELEASED; urgency=low * apt-pkg/contrib/fileutl.h: - fix compat with FileFd::OpenDescriptor() in ReadOnlyGzip mode * apt-pkg/packagemanager.cc: - - when calculating pre-dependencies ensure that both unpack and - configure are considered (instead of only configure) LP: #927993 + - fix bug in predepends handling - ensure that packages that needs + unpackaging are unpacked before they are configured (LP: #927993) + + [ Julian Andres Klode ] + * apt-pkg/deb/deblistparser.cc: + - Set the Essential flag on APT instead of only Important + * apt-pkg/packagemanager.cc: + - Do not use immediate configuration for packages with the Important flag + * Treat the Important flag like the Essential flag with those differences: + - No Immediate configuration (see above) + - Not automatically installed during dist-upgrade + - No higher score for installation ordering - -- David Kalnischkies <kalnischkies@gmail.com> Mon, 30 Jan 2012 19:17:09 +0100 + -- Michael Vogt <mvo@debian.org> Tue, 06 Mar 2012 18:12:57 +0100 apt (0.8.16~exp12) experimental; urgency=low diff --git a/ftparchive/cachedb.h b/ftparchive/cachedb.h index 377c41607..b9ced9418 100644 --- a/ftparchive/cachedb.h +++ b/ftparchive/cachedb.h @@ -126,7 +126,8 @@ class CacheDB Misses += S.Misses; DeLinkBytes += S.DeLinkBytes; }; - Stats() : Bytes(0), MD5Bytes(0), SHA1Bytes(0), SHA256Bytes(0), Packages(0), Misses(0), DeLinkBytes(0) {}; + Stats() : Bytes(0), MD5Bytes(0), SHA1Bytes(0), SHA256Bytes(0), + SHA512Bytes(0),Packages(0), Misses(0), DeLinkBytes(0) {}; } Stats; bool ReadyDB(std::string const &DB); @@ -142,7 +143,7 @@ class CacheDB bool Clean(); - CacheDB(std::string const &DB) : Dbp(0), Fd(NULL), DebFile(0) {ReadyDB(DB);}; + CacheDB(std::string const &DB) : Dbp(0), Fd(NULL), DebFile(0) {TmpKey[0]='\0'; ReadyDB(DB);}; ~CacheDB() {ReadyDB(std::string()); delete DebFile;}; }; diff --git a/ftparchive/writer.cc b/ftparchive/writer.cc index 159772991..d02919969 100644 --- a/ftparchive/writer.cc +++ b/ftparchive/writer.cc @@ -941,6 +941,7 @@ ReleaseWriter::ReleaseWriter(string const &DB) AddPattern("Packages.bz2"); AddPattern("Packages.lzma"); AddPattern("Packages.xz"); + AddPattern("Translation-*"); AddPattern("Sources"); AddPattern("Sources.gz"); AddPattern("Sources.bz2"); diff --git a/methods/ftp.cc b/methods/ftp.cc index ad8a7b828..d55ac1224 100644 --- a/methods/ftp.cc +++ b/methods/ftp.cc @@ -77,6 +77,7 @@ FTPConn::FTPConn(URI Srv) : Len(0), ServerFd(-1), DataFd(-1), { Debug = _config->FindB("Debug::Acquire::Ftp",false); PasvAddr = 0; + Buffer[0] = '\0'; } /*}}}*/ // FTPConn::~FTPConn - Destructor /*{{{*/ @@ -621,8 +622,7 @@ bool FTPConn::ExtGoPasv() } // Get a new passive address. - int Res; - if ((Res = getaddrinfo(IP.c_str(),PStr,&Hints,&PasvAddr)) != 0) + if (getaddrinfo(IP.c_str(),PStr,&Hints,&PasvAddr) != 0) return true; return true; @@ -720,14 +720,13 @@ bool FTPConn::CreateDataFd() DataListenFd = -1; // Get the information for a listening socket. - struct addrinfo *BindAddr = 0; + struct addrinfo *BindAddr = NULL; struct addrinfo Hints; memset(&Hints,0,sizeof(Hints)); Hints.ai_socktype = SOCK_STREAM; Hints.ai_flags |= AI_PASSIVE; Hints.ai_family = ((struct sockaddr *)&ServerAddr)->sa_family; - int Res; - if ((Res = getaddrinfo(0,"0",&Hints,&BindAddr)) != 0) + if (getaddrinfo(0,"0",&Hints,&BindAddr) != 0 || BindAddr == NULL) return _error->Error(_("getaddrinfo was unable to get a listening socket")); // Construct the socket diff --git a/methods/http.cc b/methods/http.cc index 2721b1224..d2e03cfbc 100644 --- a/methods/http.cc +++ b/methods/http.cc @@ -42,6 +42,7 @@ #include <stdio.h> #include <errno.h> #include <string.h> +#include <climits> #include <iostream> #include <map> @@ -534,10 +535,6 @@ bool ServerState::HeaderLine(string Line) if (Line.empty() == true) return true; - // The http server might be trying to do something evil. - if (Line.length() >= MAXLEN) - return _error->Error(_("Got a single header line over %u chars"),MAXLEN); - string::size_type Pos = Line.find(' '); if (Pos == string::npos || Pos+1 > Line.length()) { @@ -561,7 +558,7 @@ bool ServerState::HeaderLine(string Line) // Evil servers return no version if (Line[4] == '/') { - int const elements = sscanf(Line.c_str(),"HTTP/%u.%u %u%[^\n]",&Major,&Minor,&Result,Code); + int const elements = sscanf(Line.c_str(),"HTTP/%3u.%3u %3u%359[^\n]",&Major,&Minor,&Result,Code); if (elements == 3) { Code[0] = '\0'; @@ -575,7 +572,7 @@ bool ServerState::HeaderLine(string Line) { Major = 0; Minor = 9; - if (sscanf(Line.c_str(),"HTTP %u%[^\n]",&Result,Code) != 2) + if (sscanf(Line.c_str(),"HTTP %3u%359[^\n]",&Result,Code) != 2) return _error->Error(_("The HTTP server sent an invalid reply header")); } @@ -585,7 +582,7 @@ bool ServerState::HeaderLine(string Line) Persistent = false; else { - if (Major == 1 && Minor <= 0) + if (Major == 1 && Minor == 0) Persistent = false; else Persistent = true; @@ -603,9 +600,10 @@ bool ServerState::HeaderLine(string Line) // The length is already set from the Content-Range header if (StartPos != 0) return true; - - if (sscanf(Val.c_str(),"%llu",&Size) != 1) - return _error->Error(_("The HTTP server sent an invalid Content-Length header")); + + Size = strtoull(Val.c_str(), NULL, 10); + if (Size == ULLONG_MAX) + return _error->Errno("HeaderLine", _("The HTTP server sent an invalid Content-Length header")); return true; } @@ -1329,7 +1327,7 @@ int HttpMethod::Loop() after the same URI is seen twice in a queue item. */ StringVector &R = Redirected[Queue->DestFile]; bool StopRedirects = false; - if (R.size() == 0) + if (R.empty() == true) R.push_back(Queue->Uri); else if (R[0] == "STOP" || R.size() > 10) StopRedirects = true; diff --git a/methods/http.h b/methods/http.h index c73d4df5c..7a3ccda54 100644 --- a/methods/http.h +++ b/methods/http.h @@ -11,8 +11,6 @@ #ifndef APT_HTTP_H #define APT_HTTP_H -#define MAXLEN 360 - #include <apt-pkg/strutl.h> #include <string> @@ -92,7 +90,7 @@ struct ServerState unsigned int Major; unsigned int Minor; unsigned int Result; - char Code[MAXLEN]; + char Code[360]; // These are some statistics from the last parsed header lines unsigned long long Size; @@ -117,9 +115,10 @@ struct ServerState bool HeaderLine(std::string Line); bool Comp(URI Other) const {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;}; - void Reset() {Major = 0; Minor = 0; Result = 0; Size = 0; StartPos = 0; - Encoding = Closes; time(&Date); ServerFd = -1; - Pipeline = true;}; + void Reset() {Major = 0; Minor = 0; Result = 0; Code[0] = '\0'; Size = 0; + StartPos = 0; Encoding = Closes; time(&Date); HaveContent = false; + State = Header; Persistent = false; ServerFd = -1; + Pipeline = true;}; /** \brief Result of the header acquire */ enum RunHeadersResult { diff --git a/methods/https.h b/methods/https.h index b7adeb880..b1961a870 100644 --- a/methods/https.h +++ b/methods/https.h @@ -8,10 +8,8 @@ ##################################################################### */ /*}}}*/ -#ifndef APT_HTTP_H -#define APT_HTTP_H - -#define MAXLEN 360 +#ifndef APT_HTTPS_H +#define APT_HTTPS_H #include <iostream> #include <curl/curl.h> diff --git a/methods/mirror.cc b/methods/mirror.cc index 3d5983efa..3b2ab8ede 100644 --- a/methods/mirror.cc +++ b/methods/mirror.cc @@ -147,7 +147,7 @@ bool MirrorMethod::DownloadMirrorFile(string mirror_uri_str) // append all architectures std::vector<std::string> vec = APT::Configuration::getArchitectures(); for (std::vector<std::string>::const_iterator I = vec.begin(); - I != vec.end(); I++) + I != vec.end(); ++I) if (I == vec.begin()) fetch += "?arch" + (*I); else diff --git a/methods/rsh.cc b/methods/rsh.cc index d249ae961..fb3782314 100644 --- a/methods/rsh.cc +++ b/methods/rsh.cc @@ -42,7 +42,9 @@ int RSHMethod::FailFd = -1; // --------------------------------------------------------------------- /* */ RSHConn::RSHConn(URI Srv) : Len(0), WriteFd(-1), ReadFd(-1), - ServerName(Srv), Process(-1) {} + ServerName(Srv), Process(-1) { + Buffer[0] = '\0'; +} /*}}}*/ // RSHConn::RSHConn - Destructor /*{{{*/ // --------------------------------------------------------------------- diff --git a/test/integration/Packages-bug-64141-install-dependencies-for-on-hold b/test/integration/Packages-bug-64141-install-dependencies-for-on-hold deleted file mode 100644 index 7005fa4f4..000000000 --- a/test/integration/Packages-bug-64141-install-dependencies-for-on-hold +++ /dev/null @@ -1,42 +0,0 @@ -Package: apt -Priority: important -Section: admin -Installed-Size: 6048 -Maintainer: APT Development Team <deity@lists.debian.org> -Architecture: i386 -Version: 0.8.10 -Provides: libapt-pkg4.10 -Depends: libc6 (>= 2.10), libdb4.8 -Breaks: oldcrap -Filename: pool/main/a/apt/apt_0.8.10_i386.deb -Size: 2160758 -MD5sum: 5aa2234f7b91056d430669cddf6e6e50 -Description: Advanced front-end for dpkg - -Package: libc6 -Priority: required -Section: libs -Installed-Size: 9356 -Maintainer: GNU Libc Maintainers <debian-glibc@lists.debian.org> -Architecture: i386 -Source: eglibc -Version: 2.11.2-7 -Provides: glibc-2.11-1 -Filename: pool/main/e/eglibc/libc6_2.11.2-7_i386.deb -Size: 3880868 -MD5sum: c48fd2854fc62125824267d086600793 -Description: Embedded GNU C Library: Shared libraries - -Package: libdb4.8 -Priority: standard -Section: libs -Installed-Size: 1488 -Maintainer: Clint Adams <clint@gnu.org> -Architecture: i386 -Source: db4.8 -Version: 4.8.30-3 -Depends: libc6 (>= 2.3.6-6~) -Filename: pool/main/d/db4.8/libdb4.8_4.8.30-3_i386.deb -Size: 681988 -MD5sum: 0d58c15898a95436d2ec480aa22693ff -Description: Berkeley v4.8 Database Libraries [runtime] diff --git a/test/integration/framework b/test/integration/framework index d7526a100..a738d27cc 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -29,7 +29,8 @@ msgtest() { while [ -n "$1" ]; do echo -n "${CINFO}$1${CCMD} " >&2; echo -n "$(echo "$2" | sed -e 's/^aptc/apt-c/' -e 's/^aptg/apt-g/' -e 's/^aptf/apt-f/')${CINFO} " >&2; - shift 2 + shift + if [ -n "$1" ]; then shift; else break; fi done echo -n "…${CNORMAL} " >&2; } @@ -114,9 +115,9 @@ addtrap() { setupenvironment() { TMPWORKINGDIRECTORY=$(mktemp -d) - local TESTDIR=$(readlink -f $(dirname $0)) + TESTDIRECTORY=$(readlink -f $(dirname $0)) msgninfo "Preparing environment for ${CCMD}$(basename $0)${CINFO} in ${TMPWORKINGDIRECTORY}… " - BUILDDIRECTORY="${TESTDIR}/../../build/bin" + BUILDDIRECTORY="${TESTDIRECTORY}/../../build/bin" test -x "${BUILDDIRECTORY}/apt-get" || msgdie "You need to build tree first" local OLDWORKINGDIRECTORY=$(pwd) addtrap "cd /; rm -rf $TMPWORKINGDIRECTORY; cd $OLDWORKINGDIRECTORY;" @@ -126,25 +127,19 @@ setupenvironment() { mkdir -p etc/apt/apt.conf.d etc/apt/sources.list.d etc/apt/trusted.gpg.d etc/apt/preferences.d mkdir -p var/cache var/lib var/log mkdir -p var/lib/dpkg/info var/lib/dpkg/updates var/lib/dpkg/triggers - local STATUSFILE=$(echo "$(basename $0)" | sed -e 's/^test-/status-/' -e 's/^skip-/status-/') - if [ -f "${TESTDIR}/${STATUSFILE}" ]; then - cp "${TESTDIR}/${STATUSFILE}" var/lib/dpkg/status - else - touch var/lib/dpkg/status - fi touch var/lib/dpkg/available mkdir -p usr/lib/apt ln -s ${BUILDDIRECTORY}/methods usr/lib/apt/methods cd .. local PACKAGESFILE=$(echo "$(basename $0)" | sed -e 's/^test-/Packages-/' -e 's/^skip-/Packages-/') - if [ -f "${TESTDIR}/${PACKAGESFILE}" ]; then - cp "${TESTDIR}/${PACKAGESFILE}" aptarchive/Packages + if [ -f "${TESTDIRECTORY}/${PACKAGESFILE}" ]; then + cp "${TESTDIRECTORY}/${PACKAGESFILE}" aptarchive/Packages fi local SOURCESSFILE=$(echo "$(basename $0)" | sed -e 's/^test-/Sources-/' -e 's/^skip-/Sources-/') - if [ -f "${TESTDIR}/${SOURCESSFILE}" ]; then - cp "${TESTDIR}/${SOURCESSFILE}" aptarchive/Sources + if [ -f "${TESTDIRECTORY}/${SOURCESSFILE}" ]; then + cp "${TESTDIRECTORY}/${SOURCESSFILE}" aptarchive/Sources fi - cp $(find $TESTDIR -name '*.pub' -o -name '*.sec') keys/ + cp $(find $TESTDIRECTORY -name '*.pub' -o -name '*.sec') keys/ ln -s ${TMPWORKINGDIRECTORY}/keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg echo "Dir \"${TMPWORKINGDIRECTORY}/rootdir\";" > aptconfig.conf echo "Dir::state::status \"${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status\";" >> aptconfig.conf @@ -156,7 +151,9 @@ setupenvironment() { echo "DPKG::options:: \"--root=${TMPWORKINGDIRECTORY}/rootdir\";" >> aptconfig.conf echo "DPKG::options:: \"--force-not-root\";" >> aptconfig.conf echo "DPKG::options:: \"--force-bad-path\";" >> aptconfig.conf - echo "DPKG::options:: \"--force-architecture\";" >> aptconfig.conf # Added to test multiarch before dpkg is ready for it… + if ! $(which dpkg) --assert-multi-arch; then + echo "DPKG::options:: \"--force-architecture\";" >> aptconfig.conf # Added to test multiarch before dpkg is ready for it… + fi echo "DPKG::options:: \"--log=${TMPWORKINGDIRECTORY}/rootdir/var/log/dpkg.log\";" >> aptconfig.conf echo 'quiet::NoUpdate "true";' >> aptconfig.conf export LC_ALL=C @@ -170,13 +167,17 @@ getarchitecture() { if [ -n "$ARCH" ]; then echo $ARCH else - dpkg-architecture -qDEB_BUILD_ARCH + dpkg --print-architecture fi else echo $1 fi } +getarchitectures() { + echo "$(aptconfig dump | grep APT::Architecture | cut -d'"' -f 2 | sed '/^$/ d' | sort | uniq | tr '\n' ' ')" +} + configarchitecture() { local CONFFILE=rootdir/etc/apt/apt.conf.d/01multiarch.conf rm -f $CONFFILE @@ -186,6 +187,30 @@ configarchitecture() { echo "APT::Architectures:: \"$(getarchitecture $1)\";" >> $CONFFILE shift done + configdpkg +} + +configdpkg() { + if [ ! -e rootdir/var/lib/dpkg/status ]; then + local STATUSFILE=$(echo "$(basename $0)" | sed -e 's/^test-/status-/' -e 's/^skip-/status-/') + if [ -f "${TESTDIRECTORY}/${STATUSFILE}" ]; then + cp "${TESTDIRECTORY}/${STATUSFILE}" rootdir/var/lib/dpkg/status + else + echo -n > rootdir/var/lib/dpkg/status + fi + fi + if $(which dpkg) --assert-multi-arch; then + local ARCHS="$(getarchitectures)" + if echo "$ARCHS" | grep -E -q '[^ ]+ [^ ]+'; then + DPKGARCH="$(dpkg --print-architecture)" + for ARCH in ${ARCHS}; do + if [ "${ARCH}" != "${DPKGARCH}" ]; then dpkg --add-architecture ${ARCH}; fi + done + if [ "0" = "$(dpkg -l dpkg 2> /dev/null | grep '^i' | wc -l)" ]; then + insertinstalledpackage 'dpkg' "all" '1.16.2~wipmultiarch~fake' + fi + fi + fi } setupsimplenativepackage() { @@ -350,7 +375,7 @@ createaptftparchiveconfig() { local ARCHS="$(find pool/ -name '*.deb' | grep -oE '_[a-z0-9-]+\.deb$' | sort | uniq | sed -e '/^_all.deb$/ d' -e 's#^_\([a-z0-9-]*\)\.deb$#\1#' | tr '\n' ' ')" if [ -z "$ARCHS" ]; then # the pool is empty, so we will operate on faked packages - let us use the configured archs - ARCHS="$(aptconfig dump | grep APT::Architecture | cut -d'"' -f 2 | sed '/^$/ d' | sort | uniq | tr '\n' ' ')" + ARCHS="$(getarchitectures)" fi echo -n 'Dir { ArchiveDir "' >> ftparchive.conf @@ -432,7 +457,7 @@ insertpackage() { local ARCHS="" for arch in $(echo "$ARCH" | sed -e 's#,#\n#g' | sed -e "s#^native\$#$(getarchitecture 'native')#"); do if [ "$arch" = "all" ]; then - ARCHS="$(aptconfig dump | grep APT::Architecture | cut -d'"' -f 2 | sed '/^$/ d' | sort | uniq | tr '\n' ' ')" + ARCHS="$(getarchitectures)" else ARCHS="$arch" fi @@ -486,7 +511,8 @@ insertinstalledpackage() { local VERSION="$3" local DEPENDENCIES="$4" local PRIORITY="${5:-optional}" - local FILE="rootdir/var/lib/dpkg/status" + local FILE='rootdir/var/lib/dpkg/status' + local INFO='rootdir/var/lib/dpkg/info' for arch in $(echo "$ARCH" | sed -e 's#,#\n#g' | sed -e "s#^native\$#$(getarchitecture 'native')#"); do echo "Package: $NAME Status: install ok installed @@ -502,6 +528,11 @@ Version: $VERSION" >> $FILE YOU did something horribly wrong! They are autogenerated und used only by testcases for APT and surf no other propose… " >> $FILE + if [ "$(dpkg-query -W --showformat='${Multi-Arch}')" = 'same' ]; then + echo -n > ${INFO}/${NAME}:${arch}.list + else + echo -n > ${INFO}/${NAME}.list + fi done } @@ -542,9 +573,6 @@ generatereleasefiles() { # both should be given in notation date/touch can understand msgninfo "\tGenerate Release files… " if [ -e aptarchive/dists ]; then - for dir in $(find ./aptarchive/dists -mindepth 3 -maxdepth 3 -type d -name 'i18n'); do - aptftparchive -qq release $dir -o APT::FTPArchive::Release::Patterns::='Translation-*' > $dir/Index - done for dir in $(find ./aptarchive/dists -mindepth 1 -maxdepth 1 -type d); do local SUITE="$(echo "$dir" | cut -d'/' -f 4)" local CODENAME="$(getcodenamefromsuite $SUITE)" diff --git a/test/integration/skip-avoid-avoiding-breaks-predepends b/test/integration/skip-avoid-avoiding-breaks-predepends new file mode 100755 index 000000000..a47e8bc2b --- /dev/null +++ b/test/integration/skip-avoid-avoiding-breaks-predepends @@ -0,0 +1,21 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework +setupenvironment +configarchitecture 'native' + +insertinstalledpackage 'looping' 'native' '1' +insertinstalledpackage 'loop1' 'native' '1' 'Depends: loop2 (= 1)' +insertinstalledpackage 'loop2' 'native' '1' 'Depends: loop1 (= 1)' + +buildsimplenativepackage 'looping' 'native' '1.15.7.2' 'stable' 'Breaks: loop2 (<= 1)' +buildsimplenativepackage 'loop1' 'native' '2' 'stable' 'Depends: loop2 (= 2)' +buildsimplenativepackage 'loop2' 'native' '2' 'stable' 'Depends: loop1 (= 2) +Pre-Depends: looping (>= 1.15)' + +setupaptarchive + +aptget dist-upgrade -y -o Debug::pkgOrderList=1 #-qq 2>&1 > /dev/null +testdpkginstalled looping loop1 loop2 diff --git a/test/integration/status-bug-64141-install-dependencies-for-on-hold b/test/integration/status-bug-64141-install-dependencies-for-on-hold deleted file mode 100644 index c82ebd19c..000000000 --- a/test/integration/status-bug-64141-install-dependencies-for-on-hold +++ /dev/null @@ -1,33 +0,0 @@ -Package: apt -Status: install ok installed -Priority: important -Section: admin -Installed-Size: 6048 -Maintainer: APT Development Team <deity@lists.debian.org> -Architecture: i386 -Version: 0.8.9 -Provides: libapt-pkg4.10 -Depends: libc6 (>= 2.3.4) -Description: Advanced front-end for dpkg - -Package: libc6 -Status: install ok installed -Priority: required -Section: libs -Installed-Size: 9356 -Maintainer: GNU Libc Maintainers <debian-glibc@lists.debian.org> -Architecture: i386 -Source: eglibc -Version: 2.3.5-7 -Provides: glibc-2.11-1 -Description: Embedded GNU C Library: Shared libraries - -Package: oldcrap -Status: install ok installed -Priority: extra -Section: oldlibs -Installed-Size: 1 -Maintainer: Joe Sixpack <joe@example.org> -Architecture: all -Version: 1-1 -Description: Old crappy nothing package diff --git a/test/integration/test-bug-549968-install-depends-of-not-installed b/test/integration/test-bug-549968-install-depends-of-not-installed index 78c0801f2..8c434b3ce 100755 --- a/test/integration/test-bug-549968-install-depends-of-not-installed +++ b/test/integration/test-bug-549968-install-depends-of-not-installed @@ -14,13 +14,13 @@ setupaptarchive # We check the Markers here as the autoremove nuker will also # prevent it, but to late - its better to fail earlier -testequal 'Reading package lists... +testequal "Reading package lists... Building dependency tree... MarkInstall coolstuff [ i386 ] < none -> 1.0 > ( other ) FU=1 Ignore MarkInstall of extracoolstuff [ i386 ] < none -> 1.0 > ( other ) as its mode (Keep) is protected -Package extracoolstuff is not installed, so not removed +Package 'extracoolstuff' is not installed, so not removed The following NEW packages will be installed: coolstuff 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Inst coolstuff (1.0 unstable [all]) -Conf coolstuff (1.0 unstable [all])' aptget install coolstuff extracoolstuff- -o Debug::pkgDepCache::Marker=1 -s +Conf coolstuff (1.0 unstable [all])" aptget install coolstuff extracoolstuff- -o Debug::pkgDepCache::Marker=1 -s diff --git a/test/integration/test-bug-612099-multiarch-conflicts b/test/integration/test-bug-612099-multiarch-conflicts index dd9efb785..530012e5d 100755 --- a/test/integration/test-bug-612099-multiarch-conflicts +++ b/test/integration/test-bug-612099-multiarch-conflicts @@ -16,7 +16,7 @@ buildsimplenativepackage 'foobar' 'amd64' '1.0' 'stable' 'Depends: libc6' setupaptarchive aptget install libc6:i386 -t stable -y -qq 2>&1 > /dev/null -testdpkginstalled libc6 +testdpkginstalled libc6:i386 testequal 'Reading package lists... Building dependency tree... Reading state information... @@ -75,8 +75,13 @@ The following packages will be upgraded: 1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. Inst libc6 [1.0] (2.0 testing [all]) Conf libc6 (2.0 testing [all])' aptget upgrade -t testing -s -aptget upgrade -y -qq 2>&1 > /dev/null -testdpkginstalled libc6 +# FIXME: on amd64 systems this test wouldn't run with a real upgrade +# as APT (here i386) disagree about the native architecture, so +# we fake it here: +#aptget upgrade -y -qq 2>&1 > /dev/null +aptget purge libc6 -y -qq 2>&1 >/dev/null +aptget install libc6:i386 -y -qq 2>&1 >/dev/null +testdpkginstalled libc6:all testequal 'Reading package lists... Building dependency tree... @@ -125,7 +130,7 @@ buildsimplenativepackage 'foobar-same' 'amd64' '1.0' 'stable' 'Depends: libc6-sa setupaptarchive aptget install libc6-same:i386 -t stable -y -qq 2>&1 > /dev/null -testdpkginstalled libc6-same +testdpkginstalled libc6-same:i386 testequal 'Reading package lists... Building dependency tree... @@ -168,8 +173,14 @@ The following packages will be upgraded: 1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. Inst libc6-same [1.0] (2.0 testing [all]) Conf libc6-same (2.0 testing [all])' aptget upgrade -t testing -s -aptget upgrade -y -qq 2>&1 > /dev/null -testdpkginstalled libc6-same +# FIXME: on amd64 systems this test wouldn't run with a real upgrade +# as APT (here i386) disagree about the native architecture, so +# we fake it here: +#aptget upgrade -y -qq 2>&1 > /dev/null +aptget purge libc6-same -y -qq 2>&1 >/dev/null +aptget install libc6-same:i386 -y -qq 2>&1 >/dev/null +testdpkginstalled libc6-same:all + testequal "Reading package lists... Building dependency tree... diff --git a/test/integration/test-bug-618288-multiarch-same-lockstep b/test/integration/test-bug-618288-multiarch-same-lockstep index 7333054cc..fde075172 100755 --- a/test/integration/test-bug-618288-multiarch-same-lockstep +++ b/test/integration/test-bug-618288-multiarch-same-lockstep @@ -16,30 +16,22 @@ buildsimplenativepackage 'apt' 'i386' '2' 'unstable' 'Depends: libsame (= 2)' '' buildsimplenativepackage 'apt2' 'amd64' '2' 'unstable' 'Depends: libsame (= 2)' '' 'required' setupaptarchive +aptget dist-upgrade -s 2>&1 > output.apt # order in switch libsame:{amd64,i386} are unpacked is irrelevant, as both are installed - but we need to do it together -testequalor2 'Reading package lists... -Building dependency tree... -The following packages will be upgraded: - apt:i386 apt2 libsame libsame:i386 -4 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. -Inst libsame:i386 [1] (2 unstable [i386]) [libsame:amd64 on libsame:i386] [libsame:i386 on libsame:amd64] [libsame:amd64 apt:i386 ] -Inst libsame [1] (2 unstable [amd64]) [apt2:amd64 apt:i386 ] -Conf libsame:i386 (2 unstable [i386]) [apt2:amd64 apt:i386 ] -Conf libsame (2 unstable [amd64]) [apt2:amd64 apt:i386 ] -Inst apt2 [1] (2 unstable [amd64]) [apt:i386 ] -Conf apt2 (2 unstable [amd64]) [apt:i386 ] -Inst apt:i386 [1] (2 unstable [i386]) -Conf apt:i386 (2 unstable [i386])' 'Reading package lists... -Building dependency tree... -The following packages will be upgraded: - apt:i386 apt2 libsame libsame:i386 -4 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. -Inst libsame [1] (2 unstable [amd64]) [libsame:amd64 on libsame:i386] [libsame:i386 on libsame:amd64] [libsame:i386 apt2:amd64 ] -Inst libsame:i386 [1] (2 unstable [i386]) [apt2:amd64 apt:i386 ] -Conf libsame:i386 (2 unstable [i386]) [apt2:amd64 apt:i386 ] -Conf libsame (2 unstable [amd64]) [apt2:amd64 apt:i386 ] -Inst apt2 [1] (2 unstable [amd64]) [apt:i386 ] -Conf apt2 (2 unstable [amd64]) [apt:i386 ] -Inst apt:i386 [1] (2 unstable [i386]) -Conf apt:i386 (2 unstable [i386])' aptget dist-upgrade -s +LS_U_AMD="$(grep -o -n '^Inst libsame ' output.apt | cut -d: -f1)" +LS_U_INT="$(grep -o -n '^Inst libsame:i386 ' output.apt | cut -d: -f1)" +LS_C_AMD="$(grep -o -n '^Conf libsame ' output.apt | cut -d: -f1)" +LS_C_INT="$(grep -o -n '^Conf libsame:i386 ' output.apt | cut -d: -f1)" + +msgtest 'Test if libsame:amd64 unpack before configure' +test "$LS_U_AMD" -lt "$LS_C_AMD" && msgpass || msgfail + +msgtest 'Test if libsame:i386 unpack before configure' +test "$LS_U_INT" -lt "$LS_C_INT" && msgpass || msgfail + +msgtest 'Test if libsame:amd64 unpack is before libsame:i386 configure' +test "$LS_U_AMD" -lt "$LS_C_INT" && msgpass || msgfail + +msgtest 'Test if libsame:i386 unpack is before libsame:amd64 configure' +test "$LS_U_INT" -lt "$LS_C_AMD" && msgpass || msgfail diff --git a/test/integration/test-bug-624218-Translation-file-handling b/test/integration/test-bug-624218-Translation-file-handling index a1e708d2e..d146b943c 100755 --- a/test/integration/test-bug-624218-Translation-file-handling +++ b/test/integration/test-bug-624218-Translation-file-handling @@ -42,16 +42,9 @@ msgtest 'Download of nothing if none is forced' 'with Index' aptget update -o Acquire::Languages=none | grep -q -e 'Translation' && msgfail || msgpass rm -rf rootdir/var/lib/apt/lists -sed -i '/i18n\/Index$/ d' $(find aptarchive -name 'Release') +sed -i '/i18n\/Translation-.*$/ d' $(find aptarchive -name 'Release') signreleasefiles -# we have to try as not every archive includes the i18n Index in the Release file - if it has one at all -msgtest 'Download no Translation- if forced language is non-existent' 'with not-announced Index' -aptget update -o Acquire::Languages=ast_DE | grep -q -e 'Translation-' && msgfail || msgpass -rm -rf rootdir/var/lib/apt/lists - -find aptarchive -name 'Index' -delete - msgtest 'Download of en as forced language' 'without Index' aptget update -o Acquire::Languages=en | grep -q -e 'Translation-en ' && msgpass || msgfail rm -rf rootdir/var/lib/apt/lists diff --git a/test/integration/test-bug-64141-install-dependencies-for-on-hold b/test/integration/test-bug-64141-install-dependencies-for-on-hold index 4633ffcc3..e2d206fdd 100755 --- a/test/integration/test-bug-64141-install-dependencies-for-on-hold +++ b/test/integration/test-bug-64141-install-dependencies-for-on-hold @@ -4,7 +4,19 @@ set -e TESTDIR=$(readlink -f $(dirname $0)) . $TESTDIR/framework setupenvironment -configarchitecture "i386" +configarchitecture 'native' 'strange-arch' + +insertpackage 'unstable' 'unrelated' 'strange-arch' '1' + +insertinstalledpackage 'apt' 'native' '0.8.9' 'Depends: libc6 (>= 2.3.4)' +insertinstalledpackage 'libc6' 'native' '2.4.1-1' +insertinstalledpackage 'oldcrap' 'all' '1-1' + +insertpackage 'unstable' 'apt' 'native' '0.8.10' 'Depends: libc6 (>= 2.10), libdb4.8 +Breaks: oldcrap' +insertpackage 'unstable' 'libc6' 'native' '2.11.2-7' +insertpackage 'unstable' 'libdb4.8' 'native' '4.8.30-3' + setupaptarchive testequal 'Reading package lists... @@ -16,11 +28,10 @@ The following NEW packages will be installed: The following packages will be upgraded: apt libc6 2 upgraded, 1 newly installed, 1 to remove and 0 not upgraded. -Need to get 0 B/6724 kB of archives. -After this operation, 1523 kB of additional disk space will be used. +After this operation, 0 B of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation.' aptget dist-upgrade --trivial-only -echo 'apt hold' | dpkg --set-selections +aptmark hold apt -qq testequal 'Reading package lists... Building dependency tree... @@ -29,6 +40,5 @@ The following packages have been kept back: The following packages will be upgraded: libc6 1 upgraded, 0 newly installed, 0 to remove and 1 not upgraded. -Need to get 0 B/3881 kB of archives. After this operation, 0 B of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation.' aptget dist-upgrade --trivial-only -o Test='hold-back-apt' diff --git a/test/integration/test-conflicts-loop b/test/integration/test-conflicts-loop index 7b5724d74..25f005969 100755 --- a/test/integration/test-conflicts-loop +++ b/test/integration/test-conflicts-loop @@ -20,14 +20,15 @@ Building dependency tree... The following packages will be upgraded: openjdk-6-jre openjdk-6-jre-headless openjdk-6-jre-lib 3 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. - openjdk-6-jre-lib conflicts with openjdk-6-jre - openjdk-6-jre conflicts with openjdk-6-jre-headless - openjdk-6-jre-headless conflicts with openjdk-6-jre + openjdk-6-jre-lib:i386 conflicts with openjdk-6-jre:i386 + openjdk-6-jre:i386 conflicts with openjdk-6-jre-headless:i386 + openjdk-6-jre-headless:i386 conflicts with openjdk-6-jre:i386 Remv openjdk-6-jre [6b16-1.8-0ubuntu1] - openjdk-6-jre-headless conflicts with openjdk-6-jre-lib + openjdk-6-jre-headless:i386 conflicts with openjdk-6-jre-lib:i386 Remv openjdk-6-jre-lib [6b16-1.8-0ubuntu1] Inst openjdk-6-jre-headless [6b16-1.8-0ubuntu1] (6b20-1.9.8-0ubuntu1~10.04.1 unstable [i386]) - openjdk-6-jre conflicts with openjdk-6-jre-lib + openjdk-6-jre:i386 conflicts with openjdk-6-jre-lib:i386 + openjdk-6-jre:i386 conflicts with openjdk-6-jre-lib:i386 Inst openjdk-6-jre [6b16-1.8-0ubuntu1] (6b20-1.9.8-0ubuntu1~10.04.1 unstable [i386]) Inst openjdk-6-jre-lib [6b16-1.8-0ubuntu1] (6b20-1.9.8-0ubuntu1~10.04.1 unstable [i386]) Conf openjdk-6-jre-lib (6b20-1.9.8-0ubuntu1~10.04.1 unstable [i386]) diff --git a/test/integration/test-pin-non-existent-package b/test/integration/test-pin-non-existent-package index c91e77844..35de22115 100755 --- a/test/integration/test-pin-non-existent-package +++ b/test/integration/test-pin-non-existent-package @@ -6,7 +6,7 @@ TESTDIR=$(readlink -f $(dirname $0)) setupenvironment configarchitecture "i386" -insertpackage 'unstable' 'apt' 'i386' '0.8.15' +insertpackage 'unstable' 'rapt' 'i386' '0.8.15' insertpackage 'unstable' 'arch' 'i386' '1.0' setupaptarchive @@ -22,40 +22,40 @@ testcandidate() { fi } -testcandidate apt '0.8.15' +testcandidate rapt '0.8.15' testequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0 testequal 'Reading package lists... Building dependency tree... -0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade --trivial-only -echo 'Package: apt +echo 'Package: rapt Pin: release a=unstable Pin-Priority: -1' > rootdir/etc/apt/preferences -testcandidate apt '(none)' +testcandidate rapt '(none)' testequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0 testequal 'Reading package lists... Building dependency tree... -0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade --trivial-only echo ' Package: doesntexist Pin: release a=unstable Pin-Priority: 1000' >> rootdir/etc/apt/preferences -testcandidate apt '(none)' +testcandidate rapt '(none)' echo ' -Package: apt +Package: rapt Pin: release a=unstable Pin-Priority: 1000' >> rootdir/etc/apt/preferences -testcandidate apt '(none)' +testcandidate rapt '(none)' testequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0 testequal 'Reading package lists... Building dependency tree... -0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade --trivial-only echo 'Package: arch:amd64 Pin: release a=unstable diff --git a/test/integration/test-releasefile-verification b/test/integration/test-releasefile-verification index 8bf02a78f..4f65cfa3b 100755 --- a/test/integration/test-releasefile-verification +++ b/test/integration/test-releasefile-verification @@ -153,6 +153,35 @@ runtest() { installaptold } +runtest2() { + prepare ${PKGFILE} + rm -rf rootdir/var/lib/apt/lists + signreleasefiles 'Joe Sixpack' + msgtest 'Cold archive signed by' 'Joe Sixpack' + aptget update 2>&1 | grep -E '^(W|E): ' > /dev/null && msgfail || msgpass + + # New .deb but now an unsigned archive. For example MITM to circumvent + # package verification. + prepare ${PKGFILE}-new + find aptarchive/ -name InRelease -delete + find aptarchive/ -name Release.gpg -delete + msgtest 'Warm archive signed by' 'nobody' + aptget update 2>&1 | grep -E '^(W|E): ' > /dev/null && msgfail || msgpass + testequal "$(cat ${PKGFILE}-new) +" aptcache show apt + failaptnew + + # Unsigned archive from the beginning must also be detected. + rm -rf rootdir/var/lib/apt/lists + msgtest 'Cold archive signed by' 'nobody' + aptget update 2>&1 | grep -E '^(W|E): ' > /dev/null && msgfail || msgpass + testequal "$(cat ${PKGFILE}-new) +" aptcache show apt + failaptnew +} +runtest2 + + DELETEFILE="InRelease" runtest DELETEFILE="Release.gpg" diff --git a/test/integration/test-suggest-installed-multiarch-silbing b/test/integration/test-suggest-installed-multiarch-silbing new file mode 100755 index 000000000..d55d250aa --- /dev/null +++ b/test/integration/test-suggest-installed-multiarch-silbing @@ -0,0 +1,80 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework +setupenvironment +configarchitecture 'amd64' 'i386' 'armel' + +insertinstalledpackage 'foo' 'i386' '1' +insertpackage 'unstable' 'foo' 'amd64,i386' '1' + +insertinstalledpackage 'foo2' 'i386' '1' +insertpackage 'unstable' 'foo2' 'i386' '1' + +insertinstalledpackage 'foo3' 'amd64' '1' +insertpackage 'unstable' 'foo3' 'amd64,i386' '1' + +insertinstalledpackage 'samefoo' 'i386,amd64' '1' 'Multi-Arch: same' +insertpackage 'unstable' 'samefoo' 'amd64,i386,armel' '1' 'Multi-Arch: same' + +insertinstalledpackage 'samefoo2' 'i386' '1' 'Multi-Arch: same' +insertpackage 'unstable' 'samefoo2' 'amd64,i386,armel' '1' 'Multi-Arch: same' + +insertinstalledpackage 'mozplugger' 'i386' '1' 'Depends: iceweasel | fireweasel' +insertinstalledpackage 'fireweasel' 'i386' '1' +insertpackage 'unstable' 'mozplugger' 'i386,amd64' '1' 'Depends: iceweasel | fireweasel' + +setupaptarchive + +testequal "Reading package lists... +Building dependency tree... +Package 'foo' is not installed, so not removed. Did you mean 'foo:i386'? +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove foo -s + +testequal "Reading package lists... +Building dependency tree... +The following packages will be REMOVED: + foo2:i386 +0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded. +Remv foo2:i386 [1]" aptget remove foo2 -s + +testequal "Reading package lists... +Building dependency tree... +The following packages will be REMOVED: + foo3 +0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded. +Remv foo3 [1]" aptget remove foo3 -s + +testequal "Reading package lists... +Building dependency tree... +Package 'foo3:i386' is not installed, so not removed. Did you mean 'foo3'? +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove foo3:i386 -s + +testequalor2 "Reading package lists... +Building dependency tree... +Package 'samefoo:armel' is not installed, so not removed. Did you mean 'samefoo'? +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." "Reading package lists... +Building dependency tree... +Package 'samefoo:armel' is not installed, so not removed. Did you mean 'samefoo:i386'? +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove samefoo:armel -s + +testequal "Reading package lists... +Building dependency tree... +Package 'samefoo2' is not installed, so not removed. Did you mean 'samefoo2:i386'? +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove samefoo2 -s + +testequal "Reading package lists... +Building dependency tree... +Package 'samefoo2:armel' is not installed, so not removed. Did you mean 'samefoo2:i386'? +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove samefoo2:armel -s + +testequal "Reading package lists... +Building dependency tree... +Package 'iceweasel' is not installed, so not removed +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove iceweasel -s + +testequal "Reading package lists... +Building dependency tree... +Package 'fireweasel' is not installed, so not removed. Did you mean 'fireweasel:i386'? +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove fireweasel:amd64 -s |